# 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,get_talos_es
import traceback
from .es import tzlc, to_epoch,update_max_min
from doris.models.service import SubmissionCommodity, UnitRelateService, Promotion,PromotionRule,Submission, UnitActivity, Unit
from gm_types.poseidon import VisualUnitRelatedServiceType,CommodityAuditStatus
from django.db.models import Q
from rpc.tool.log_tool import logging_exception
from gm_types.poseidon.visual import UnitType
from api.models.commodity_info import CommodityCategoryRelation
from statistic.models import StatisticSkuItemSales
import redis
from api.models.commodity_info import CommodityCategoryPropertyRelation
from api.manager.service_info_manager import get_register_sku_id_to_sku_name_info


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,
]
from agile.services.tag import (TagMapOldTagService, get_tag_v3_first_demands_by_tag_v3_ids,
                                get_tag_v3_first_solutions_by_tag_v3_ids, get_tag_v3_names_by_tag_v3_ids,
                                get_tag_v3_positions_by_tag_v3_ids, get_tag_v3_second_demands_by_tag_v3_ids,
                                get_tag_v3_second_solutions_by_tag_v3_ids,get_tagv3_analysis_info,get_tagv3_ids_by_tagv3_names,
                                get_tag_v3_first_positions_by_tag_v3_ids,
                                get_tag_v3_first_positions_by_tag_v3_ids,
                                get_first_demand_ids_by_name,get_second_demand_ids_by_name,get_first_position_ids_by_name,get_second_position_ids_by_name,
                                get_first_solution_ids_by_name,get_second_solution_ids_by_name)


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_talos_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_doctor_merchant_rank(merchant_doctor_id):
    from statistic.models import MerchantUpgradeIndic
    from statistic.models import MerchantUpgradeIndicAvg
    from hippo.models.merchant import Merchant

    merchant = Merchant.objects.filter(doctor_id=merchant_doctor_id).first()

    rank = 0.0

    if merchant:
        merchant_id = merchant.id

        latest = MerchantUpgradeIndic.objects.all().order_by('-id').first().create_date
        objs = MerchantUpgradeIndic.objects.filter(create_date=latest)

        max_X = max(objs.values_list('validate_order_rate', flat=True))

        max_Y = max(objs.values_list('upgrade_order_rate', flat=True))

        max_Z = max(objs.values_list('single_upgrade_order_amount', flat=True))
        mui = MerchantUpgradeIndic.objects.filter(merchant_doctor_id=merchant_id, create_date=latest).order_by(
            '-id').first()

        if mui:
            x = mui.validate_order_rate
            y = mui.upgrade_order_rate
            z = mui.single_upgrade_order_amount

            rank = x / max_X * 100 * 0.2 + y / max_Y * 100 * 0.3 + z / max_Z * 100 * 0.5

        else:
            mui_avg = MerchantUpgradeIndicAvg.objects.all().order_by('-id').first()
            if merchant and mui_avg:
                level_dict = {1: 0.2, 2: 0.4, 3: 0.6, 4: 0.8, 5: 1.0, 6: 1.2, 7: 1.4, 8: 1.6}
                level = merchant.merchant_level

                x_avg = mui_avg.validate_order_rate_avg
                y_avg = mui_avg.upgrade_order_rate_avg
                z_avg = mui_avg.single_upgrade_order_amount_avg

                level_score = level_dict[level]

                rank = x_avg / max_X * 100 * 0.2 + y_avg / max_Y * 100 * 0.3 + z_avg / max_Z * 100 * 0.5

                rank = rank * level_score

    return rank


def lbs_get_service_info(res, service_id):
    service_instance = Service.objects.get(id=service_id)

    res['is_sink'] = service_instance.is_sink

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

    res['smart_rank'] = get_smart_rank_new(service_instance)

    if service_instance.tickets_result:
        res['ticket_sink_start_time'] = tzlc(service_instance.tickets_result.start_sink)
        res['ticket_sink_end_time'] = tzlc(service_instance.tickets_result.end_sink)

    punishment = Punishment.get_punishment_by_doctor_id_v2(service_instance.doctor.id).get('service', None)

    if punishment and punishment.get('type', None) in ['limit', ]:
        if 'range' in punishment.keys() and punishment['range'] == 1:
            res['org_sink_start_time'] = tzlc(punishment['start_time'])
            res['org_sink_end_time'] = tzlc(punishment['end_time'])
        elif service_instance.id in [int(x) for x in str(punishment['target_ids']).split(',')]:
            res['org_sink_start_time'] = tzlc(punishment['start_time'])
            res['org_sink_end_time'] = tzlc(punishment['end_time'])

    res['hospital_name'] = service_instance.doctor.hospital.name
    res['city_id'] = service_instance.doctor.hospital.city_id
    res['city_tag_id'] = service_instance.doctor.hospital.city.tag_id
    res['is_can_be_sold'] = service_instance.is_can_be_sold_for_es()

    res['city_province_tag_id'] = service_instance.doctor.hospital.city.province.tag_id

    range_list = service_instance.can_be_sold_time_range_list_for_es()

    merchant_doctor_id = doctor_merchant_map([service_instance.doctor_id])[service_instance.doctor_id]
    res['merchant_doctor_id'] = merchant_doctor_id

    if range_list:
        res['can_sold_start_time'] = tzlc(range_list[0][0])
        res['can_sold_end_time'] = tzlc(range_list[0][1])

    res['update_time'] = tzlc(datetime.datetime.now())

    return res


def get_windows_and_promotion(sku_id):
    window_results = []
    promotion_results = []
    for unit_info in UnitRelateService.objects.using(settings.POSEIDON_DB_NAME).filter(commodity_id=sku_id):
        if unit_info.is_online == 1:
            window_id = unit_info.unit_id
            window_results += [window_id]
            # promotion_results += [X.promotion_id for X in UnitActivity.objects.filter(unit=window_id)]

    for promotion_info in SubmissionCommodity.objects.using(settings.POSEIDON_DB_NAME).filter(commodity_id=sku_id):
        submission_status = Submission.objects.using(settings.POSEIDON_DB_NAME).get(id=promotion_info.submission_id).audit_status
        if promotion_info.deleted == 0 and submission_status == 3:
            promotion_id = promotion_info.promotion_id
            promotion_results += [promotion_id]
            window_results += [X.unit_id for X in UnitActivity.objects.using(settings.POSEIDON_DB_NAME).filter(promotion_id=promotion_id)]

    window_ids = []
    promotion_ids = []
    for w_id in window_results:
        try:
            unit_type = Unit.objects.using(settings.POSEIDON_DB_NAME).get(id=w_id).unit_type
            if unit_type == UnitType.GOOODS_WINDOWS:
                window_ids.append(w_id)
        except:
            pass

    for p_id in promotion_results:
        try:
            if Promotion.objects.using(settings.POSEIDON_DB_NAME).get(id=p_id).status != 6:
                promotion_ids.append(p_id)
        except:
            pass

    return window_ids, promotion_ids


def lbs_promotion_info(instance):
    # 活动信息实例
    # from doris.models.service import SubmissionCommodity, UnitRelateService, UnitActivity
    res = {}
    sku_id = instance.commodity_id
    from api.models.service import ServiceItem
    if ServiceItem.objects.get(id=sku_id).is_delete:
        res = {'id': str(sku_id) + '_2', 'origin_id': sku_id, 'item_type': 2,
               'promotion_ids': [], 'window_ids': [], 'is_online': 0}
        return res
    service_id = instance.service_id
    service_instance = Service.objects.get(id=service_id)
    if service_instance.is_online == 0 or service_instance.is_delete == 1:
        res = {'id': str(sku_id) + '_2', 'origin_id': sku_id, 'item_type': 2,
               'promotion_ids': [], 'window_ids': [], 'is_online': 0}
        return res

    try:
        Promotion.objects.using(settings.POSEIDON_DB_NAME).get(id=instance.promotion_id).status
    except:
        res = {'id': str(sku_id) + '_2', 'origin_id': sku_id, 'item_type': 2,
               'promotion_ids': [], 'window_ids': [], 'is_online': 0}
        return res

    res['origin_id'] = sku_id
    res['item_type'] = 2

    res['id'] = str(sku_id) + '_2'

    try:
        res = lbs_get_service_info(res, service_id)
    except:
        pass

    window_ids, promotion_ids = get_windows_and_promotion(sku_id)
    res['window_ids'] = window_ids
    res['promotion_ids'] = promotion_ids
    res['is_online'] = 1

    return res


def lbs_unit_info(instance):
    res = {}
    from api.models.service import ServiceItem

    # 如果实例是sku
    if instance.related_type == VisualUnitRelatedServiceType.SKU:
        sku_id = instance.commodity_id
        if ServiceItem.objects.get(id=sku_id).is_delete:
            res = {'id': str(sku_id) + '_2', 'origin_id': sku_id, 'item_type': 2,
                   'promotion_ids': [], 'window_ids': [], 'is_online': 0}
            return res
        res['item_type'] = 2
        res['origin_id'] = sku_id
        res['id'] = str(sku_id) + '_2'
        service_id = ServiceItem.objects.get(id=sku_id).service_id
        service_instance = Service.objects.get(id=service_id)
        if service_instance.is_online == 0 or service_instance.is_delete == 1:
            return {'id': str(sku_id) + '_2', 'origin_id': sku_id, 'item_type': 2,
                    'promotion_ids': [], 'window_ids': [], 'is_online': 0}
        # 找sku的组件id
        window_ids, promotion_ids = get_windows_and_promotion(sku_id)

    # 否则实例是spu
    elif instance.related_type == VisualUnitRelatedServiceType.SPU:
        service_id = instance.service_id
        service_instance = Service.objects.get(id=service_id)
        if service_instance.is_online == 0 or service_instance.is_delete == 1:
            return {'id': str(service_id) + '_1', 'item_type': 1, 'origin_id': service_id,
                    'promotion_ids': [], 'window_ids': [], 'is_online': 0}

        res['item_type'] = 1
        res['origin_id'] = service_id
        res['id'] = str(service_id) + '_1'

        window_ids = []
        promotion_ids = []

        for unit_info in UnitRelateService.objects.using(settings.POSEIDON_DB_NAME)\
                .filter(service_id=service_id, related_type=VisualUnitRelatedServiceType.SPU):
            try:
                window_id = unit_info.unit_id
                unit_type = Unit.objects.using(settings.POSEIDON_DB_NAME).get(id=window_id).unit_type
                if unit_info.is_online == 1 and unit_type == UnitType.GOOODS_WINDOWS:
                    window_ids += [window_id]
            except:
                pass
    else:
        res['id'] = '-1'
        service_id = -1
        window_ids = []
        promotion_ids = []

    window_ids = list(set(window_ids))

    res['window_ids'] = window_ids
    res['promotion_ids'] = promotion_ids
    res['is_online'] = 1
    try:
        res = lbs_get_service_info(res, service_id)
    except:
        pass

    return res


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]
    res["first_tags"] = list(
        Tag.objects.filter(name__in=res['closure_tags'], tag_type='1').values_list('name', flat=True))
    res["second_tags"] = list(
        Tag.objects.filter(name__in=res['closure_tags'], tag_type='2').values_list('name', flat=True))
    res["third_tags"] = list(
        Tag.objects.filter(name__in=res['closure_tags'], tag_type='3').values_list('name', flat=True))

    try:
        doris_redis = redis.StrictRedis.from_url(settings.DORIS_URL)
        ai_spus = json.loads(doris_redis.get("search_spu"))
        if ai_spus and res["id"] in ai_spus:
            res["ai_tags"] = ['面部分析','脸部分析', '美颜相机','ai肤质分析','整形模拟器', '打分','新氧', '我是什么脸型？', '侧脸型', '拍照', '妆', '换发型', '明星脸','模拟整容','发型分析', '换脸','优雅知性脸', '发型测试', '发型设计', '看自己脸型', '妆容测试', '一键测肤', '脸不对称', '测脸型','测发型', '妆容分析', '脸型发型', '适合什么发型','测', '小脸', '查脸型', '贴纸', '测刘海', '照相', 'AI测试', '模拟', 'AI', '拍照片', '芯氧', '拍摄', '杏仁眼', '脸型', '爱豆脸', '侧脸', '扫脸', '我的脸型适合什么发型', '脸型测发型', '适合什么发型？', '磨皮', '颜值','测脸', '怎么侧脸', '面部识别', '你的脸型适合什么发型', '全脸', '分析脸型',
                              '修图', '童颜', '如何测脸型', 'ai侧脸', '脸型配发型', '指甲','测脸型适合什么发型','圆脸适合什么发型', '脸部检测', '拍照', '测五官', '检测脸型', '适合的发型', '照相机', '拍照测脸型', '杏眼', '识别脸型', '整容模拟器', '新氧魔镜测脸', '免费测脸型', 'P图', '改脸型','方脸发型', '查看脸型', '适合自己的发型', '鹅蛋脸发型', '发型', '测福气', '脸型报告', '镜子', '新氧魔镜', '脸部不对称', '相机', '测颜值', '皮肤测试', '測臉型', '自拍', '怎么看脸型', '看看我适合什么发型', '批图', '照片','护肤日记', '测量脸型', '眼型', '发色', '照相机', '测发型','果汁少女脸', '脸型什么发型', '口红王子投票', '脸型适合什么头型', '模拟器', '脸型适合的发型', '怎么测发型', '合适发型', '测妆容', '测试发型', 'ai测脸','魔滴', '更美模拟器', '英气玫瑰脸','适合妆容', '适合什么样的发型', '手术瘦脸', '仙甜脸','脸型决定发型', '测眉形', '方脸适合什么发型','魔镜侧脸','看脸', '测评', '测试', '文艺优雅脸','测明星脸', '魔镜', '设计发型', '脸型判断', '拍脸型', '检测','轻甜少女脸', '测测', '我要拍照', '颜值打分','试发型', '怎么测脸型', '我是什么脸', '长脸发型', 'Al测脸', '模拟整形', '侧脸功能', '适合发型', '相机', '面孔起源', '评分', '脸型', '面部测试', '颜值报告', '脸型适合什么发型', '侧脸形','测试脸型','选发型', '墨镜侧脸','娃娃脸适合什么发型', '魔镜', '发型检测','左右脸不对称','测皮肤','男士发型','测一测','测试脸', '看我适合什么发型', '颜值检测','适合什么妆', '测测你是什么脸', '三庭五眼', '发型', '明艳娇媚脸','脸型测试', '网红脸', '冷艳古典脸', '长脸适合什么发型', '更美ai', '烫发','染发', '侧脸','皮肤检测','测脸部', '扎头发', '测脸型','颜值分析','肤质测试']
    except:
        logging_exception()

    sku_items_name_dict = dict()
    try:
        from api.models.service import ServiceItem
        res['items_name'] = ServiceItem.objects.filter(service__id=s.id).first().new_items_name
        res["items_name_keyword"] = res['items_name']

        sku_items_name_list = ServiceItem.objects.filter(service__id=s.id)
        for sku_item in sku_items_name_list:
            sku_items_name_dict[int(sku_item.id)] = sku_item.new_items_name
            if not sku_items_name_dict[int(sku_item.id)]:
                sku_items_name_dict[int(sku_item.id)] = sku_item.items_name
    except:
        logging_exception()

    # 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)
    update_max_min("service_score", res["smart_rank_v4"])
    # 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()]

    try:
        res["unit_ids"] = list(UnitRelateService.objects.filter(is_online=True,
                                                                service_id=s.id,
                                                                related_type=VisualUnitRelatedServiceType.SPU)
                               .values_list('unit_id', flat=True))
    except:
        logging_exception()

    sku_type_list = [VisualUnitRelatedServiceType.SKU, VisualUnitRelatedServiceType.APPLICATION]
    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)

        try:
            sku_sales = StatisticSkuItemSales.objects.get(id=p['sku_id']).sales
        except:
            sku_sales = 0

        if parent_id == 0:
            new_sku_tags = get_new_sku_tags(p['sku_id'])
            instrument, materials = get_instrument_and_materials(p['sku_id'])
            new_sku_name = get_sku_standard_new_sku_name(p['sku_id'])
            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'],
                "new_sku_tags": new_sku_tags,
                "new_sku_tags_keyword": new_sku_tags,
                "sku_sales": sku_sales,
                "instrument": instrument,
                "materials": materials,
                "new_sku_name": new_sku_name
            }
            if int(p["sku_id"]) in sku_items_name_dict:
                data["sku_item_names"] = sku_items_name_dict[int(p["sku_id"])]
            promotion_info = get_submission_info(service_id=s.id, sku_id=p["sku_id"], price=p["price"])
            data.update(promotion_info)

            promotion_info = get_submission_info(service_id=s.id, sku_id=p["sku_id"], price=p["price"])
            data.update(promotion_info)

            try:
                submission_ids = list(SubmissionCommodity.objects.filter(commodity_id=data['sku_id'])
                                      .values_list('submission_id', flat=True))
                if submission_ids:
                    q = Q(id__in=submission_ids) & ~Q(audit_status__in=[CommodityAuditStatus.UN_AUDITED,
                                                                        CommodityAuditStatus.REJECTED])
                    active_submission_ids = list(Submission.objects
                                                 .filter(q).values_list('id', flat=True))
                    if active_submission_ids:
                        promotion_id_list = list(SubmissionCommodity.objects
                                                 .filter(commodity_id=data['sku_id'],
                                                         submission_id__in=active_submission_ids,
                                                         deleted=0)
                                                 .values_list('promotion_id', flat=True))

                        if promotion_id_list:
                            data["promotion_ids"] = list(Promotion.objects.filter(id__in=promotion_id_list,
                                                                                  offline_time__gte=datetime.datetime.now())
                                                         .values_list('id', flat=True))
            except:
                logging_exception()
                #     SubmissionCommodity.DoesNotExist:
                #                 # pass
            try:
                data["unit_ids"] = list(UnitRelateService.objects.filter(is_online=True,
                                                                         commodity_id=p['sku_id'],
                                                                         related_type__in=sku_type_list)
                                        .values_list('unit_id', flat=True))

            except:
                logging_exception()
            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["operation_cpt"] = res['advertise_info']

    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()))

    punishment = Punishment.get_punishment_by_doctor_id_v2(s.doctor.id).get('service', None)
    try:
        if punishment and punishment.get('type', None) in ['limit', ]:
            if 'range' in punishment.keys() and punishment['range'] == 1:
                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()))
            elif s.id in [int(x) for x in str(punishment['target_ids']).split(',')]:
                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()))
    except:
        logging.error("catch exception,err_msg:%s" % traceback.format_exc())

    # 美购医生的商户医生id
    merchant_doctor_id = doctor_merchant_map([s.doctor_id])[s.doctor_id]
    res['merchant_doctor_id'] = merchant_doctor_id
    try:
        res['merchant_doctor_rank'] = get_doctor_merchant_rank(merchant_doctor_id)
    except:
        res['merchant_doctor_rank'] = 0.0
        logging.error("catch exception,err_msg:%s" % traceback.format_exc())


    # 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()

    # 新标签v3相关字段

    (need_refresh_data,second_demands_set,second_solutions_set,second_positions_set,first_demands_set,first_solutions_set,
     first_positions_set,project_tags_set,first_classify_ids_set,second_classify_ids_set,first_classify_names_set,
     second_classify_names_set)=get_tagv3_analysis_info(content_id=res["id"],content_type="service")
    if need_refresh_data:
        tagv3_ids = list()
        if len(project_tags_set)>0:
            tagv3_ids = get_tagv3_ids_by_tagv3_names(names_list=list(project_tags_set))
            first_demands_set = first_demands_set.union(set(get_tag_v3_first_demands_by_tag_v3_ids(tagv3_ids)))
            first_solutions_set = first_solutions_set.union(set(get_tag_v3_first_solutions_by_tag_v3_ids(tagv3_ids)))
            first_positions_set = first_positions_set.union(set(get_tag_v3_first_positions_by_tag_v3_ids(tagv3_ids)))
            second_demands_set = second_demands_set.union(set(get_tag_v3_second_demands_by_tag_v3_ids(tagv3_ids)))
            second_solutions_set = second_solutions_set.union(set(get_tag_v3_second_solutions_by_tag_v3_ids(tagv3_ids)))
            second_positions_set = second_positions_set.union(set(get_tag_v3_positions_by_tag_v3_ids(tagv3_ids)))

        res["tags_v3"] = list(project_tags_set)
        res["first_demands"] = list(first_demands_set)
        res["second_demands"] = list(second_demands_set)
        res["first_solutions"] = list(first_solutions_set)
        res["second_solutions"] = list(second_solutions_set)
        res["positions"] = list(first_positions_set)
        res["second_positions"] = list(second_positions_set)

        res["tagv3_ids"] = tagv3_ids
        res["first_demands_ids"] = get_first_demand_ids_by_name(list(first_demands_set))
        res["second_demands_ids"] = get_second_demand_ids_by_name(list(second_demands_set))
        res["first_solutions_ids"] = get_first_solution_ids_by_name(list(first_solutions_set))
        res["second_solutions_ids"] = get_second_solution_ids_by_name(list(second_solutions_set))
        res["first_positions_ids"] = get_first_position_ids_by_name(list(first_positions_set))
        res["second_positions_ids"] = get_second_position_ids_by_name(list(second_positions_set))

        res["first_classify_ids"] = list(first_classify_ids_set)
        res["first_classify_names"] = list(first_classify_names_set)
        res["second_classify_ids"] = list(second_classify_ids_set)
        res["second_classify_names"] = list(second_classify_names_set)

    # tag_v3_ids = TagMapOldTagService.get_tag_v3_ids_by_old_tag_ids(res['closure_tag_ids'])
    # res["tags_v3"] = get_tag_v3_names_by_tag_v3_ids(tag_v3_ids)
    # res["first_demands"] = get_tag_v3_first_demands_by_tag_v3_ids(tag_v3_ids)
    # res["second_demands"] = get_tag_v3_second_demands_by_tag_v3_ids(tag_v3_ids)
    # res["first_solutions"] = get_tag_v3_first_solutions_by_tag_v3_ids(tag_v3_ids)
    # res["second_solutions"] = get_tag_v3_second_solutions_by_tag_v3_ids(tag_v3_ids)
    # res["positions"] = get_tag_v3_positions_by_tag_v3_ids(tag_v3_ids)

    res["update_time"] = tzlc(datetime.datetime.now())

    return res

def get_submission_info(service_id, sku_id, price):
    ret = {
        "promotion_price": 999999,
        "is_valid": False,
        "submission_id": 9999999,
        "sort_price": price
    }
    try:
        row = SubmissionCommodity.objects.filter(service_id=service_id, commodity_id=sku_id, is_valid=1).order_by('activity_price').first()
        if row:
            ret["promotion_price"] = row.activity_price
            ret["submission_id"] = row.submission_id
            if row.is_valid:
                ret["is_valid"] = True
                ret["sort_price"] = row.activity_price
            else:
                ret["is_valid"] = False
                ret["sort_price"] = price
    except Exception as e:
        logging_exception()
    return ret


def get_new_sku_tags(sku_id):
    """
    获取sku的新标签列表
    :param sku_id:
    :return:
    """
    tags = []
    try:
        sku_model = CommodityCategoryRelation.objects.filter(commodity_id=sku_id).first()
        if sku_model:
            tag_info = sku_model.category_info()
            if tag_info:
                tags = [item.get("name","") for item in tag_info]
    except Exception as e:
        logging_exception()
    return tags



#add standrad sku by zgd
def get_instrument_and_materials(sku_id):
    materials = ""
    instrument = ""
    try:
        instrument_obj = CommodityCategoryPropertyRelation.objects.filter(commodity_id=sku_id,property_type=2,is_online=1).first()
        if instrument_obj:
            instrument = instrument_obj.property_name
        materials_obj = CommodityCategoryPropertyRelation.objects.filter(commodity_id=sku_id,property_type=3,is_online=1).first()
        if materials_obj:
            materials = materials_obj.property_name
    except Exception as e:
        logging_exception()
    return instrument,materials


def get_sku_standard_new_sku_name(sku_id):
    from api.models.service import ServiceItem
    new_sku_name = ""
    try:
        property_id = ServiceItem.objects.get(id=sku_id).property_id
        if property_id:
            tmp = get_register_sku_id_to_sku_name_info([property_id]).get(str(property_id),{}).get("property_infos",[])
            if tmp:
                for item in tmp:
                    new_sku_name = new_sku_name + " " + item.get("value","") + " " + item.get("alias","")
    except Exception as e:
        logging_exception()
    return new_sku_name
