1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
# coding=utf-8
from __future__ import unicode_literals, absolute_import, print_function
import datetime, json
import itertools
from django.utils import timezone
from django.utils.html import escape
from django.db.models import Q, Max, Count
from gm_types.gaia import QUESTION_ORDER_TYPE
from gm_types.error import ERROR as CODES
from gm_rpcd.all import bind
from utils.rpc import rpc_client, gen, logging_exception
from qa.utils.decorator import listing
from qa.models import Question, QuestionDoctor, Answer, AnswerReply
from talos.libs.datetime_utils import get_timestamp_or_none
from talos.services.user import UserService
from talos.models.doctor import DoctorMessageList
@bind('qa/question/doctor/filter')
def question_filter():
data = {
'provinces': rpc_client['api/province/list'](display_in_filter=True).unwrap(),
}
types = [QUESTION_ORDER_TYPE.DOCTOR_LASTEST, QUESTION_ORDER_TYPE.DOCTOR_RECOMMEND]
data['orders'] = [{'id': item, 'name': QUESTION_ORDER_TYPE.getDesc(item)}
for item in types]
return data
@bind("qa/question/doctor/list")
@listing()
def question_list_for_doctor(start_num, count=10, province_id=None, order_by=QUESTION_ORDER_TYPE.DOCTOR_LASTEST):
questions = rpc_client['api/question/filter'](offset=start_num, size=count,
province_id=province_id, sort_type=order_by).unwrap()['question_ids']
question_ids = [item['question'] for item in questions]
questions = Question.objects.filter(id__in=question_ids)
q_dict = {}
for question in questions:
q_dict[question.id] = question
data = []
for q_id in question_ids:
question = q_dict.get(q_id)
if question:
data.append(question.data_for_doctor())
return {
'questions': data,
}
@bind('qa/question/add_relate_doctor')
def add_question_related_to_doctor(question_id, doctor_ids):
# 问题关联的tag,通过美购tag关联相关医生
if question_id and doctor_ids:
try:
question = Question.objects.get(id=question_id)
insert_lst = []
for d_id in doctor_ids:
insert_lst.append(QuestionDoctor(question=question, doctor_id=d_id))
QuestionDoctor.objects.bulk_create(insert_lst)
return gen(CODES.SUCCESS)
except Question.DoesNotExist:
return gen(CODES.QUESTION_NOT_FOUND)
except:
logging_exception()
return gen(CODES.UPDATE_FAIL)
else:
return gen(CODES.PARAMS_INVALID)
@bind('qa/question/related_to_doctor')
def question_lst_related_to_doctor(doctor_id, offset=0, size=10):
# 医生被邀请的问题列表
if not doctor_id:
return gen(CODES.PARAMS_INVALID)
try:
re_data_lst = []
question_doctor_info = QuestionDoctor.objects.filter(
doctor_id=doctor_id).order_by('-create_time')[offset:offset + size]
for item in question_doctor_info:
re_data_lst.append({
'question_id': item.question.id,
'question_title': item.question.title,
'user': item.question.user.nickname,
'qusetion_time': item.question.create_time.strftime("%m-%d %H:%M"),
})
return re_data_lst
except Question.DoesNotExist:
return gen(CODES.QUESTION_NOT_FOUND)
except:
logging_exception()
return gen(CODES.UPDATE_FAIL)
@bind('qa/question/doctor_unread_count')
def doctor_q_unread_count(doctor_id):
# 医生收到的问题未读数量通知
if not doctor_id:
return gen(CODES.PARAMS_INVALID)
try:
q_cout = QuestionDoctor.objects.filter(doctor_id=doctor_id, unread=True).count()
return q_cout
except:
logging_exception()
return 0
@bind('qa/question/daily_push_doctors')
def get_doctorid_to_push(start_t, end_t):
# 获取每日需要推送的医生列表
start_t = start_t if start_t else datetime.datetime.now() + datetime.timedelta(-1)
end_t = end_t if start_t else timezone.now()
try:
doctor_ids = QuestionDoctor.objects.filter(
create_time__range=(
start_t, end_t)).values_list(
'doctor_id', flat=True).distinct()
return {'doctor_ids': json.dumps(doctor_ids)}
except :
logging_exception()
return {'doctor_ids': []}
@bind('qa/question/doctor_read_votes')
def read_votes(doctor_id):
# 将未读消息已读
if not doctor_id:
return gen(CODES.PARAMS_INVALID)
try:
QuestionDoctor.objects.filter(doctor_id=doctor_id, unread=True).update(unread=False)
return gen(CODES.SUCCESS)
except:
logging_exception()
return gen(CODES.UPDATE_FAIL)
@bind("qa/question/list_messages_by_doctor_id")
def get_doctor_push_question_by_doctor_id(doctor_id, sort_type=None, offset=0, count=10):
if sort_type == "invite_time":
sort = '-created_time'
else:
sort = '-created_time'
query = Q(is_online=True, question__isnull=False, doctor_id=doctor_id)
messages_qs = DoctorMessageList.objects.filter(query).order_by(sort)
cnt = messages_qs.count()
if not cnt:
return {"total": cnt, "questions": []}
messages = messages_qs[offset: offset + count].select_related("question")
users = UserService.get_users_by_user_ids([item.user_id for item in messages])
cities_ids = [user.current_city_id for user in users.values() if user.current_city_id]
cities = {}
if cities_ids:
try:
cities = rpc_client['api/city/city_by_ids'](city_ids=cities_ids).unwrap()
except:
logging_exception()
# 获取问题最后回答时间
answers = Answer.objects.filter(is_online=True, question_id__in=[ms.question_id for ms in messages])\
.values_list("question_id").annotate(reply_time=Max('create_time'))
reply_time_info = {question_id: reply_time for question_id, reply_time in answers}
# 获取一级评论数 + 回答数
answers = Answer.objects.filter(is_online=True, question_id__in=[ms.question_id for ms in messages]) \
.values_list("question_id").annotate(cnt=Count('*'))
reply_cnt_info = {question_id: cnt for question_id, cnt in answers}
answer_ids = Answer.objects.filter(is_online=True, question_id__in=[ms.question_id for ms in messages]) \
.values_list("question_id", "id")
answer_ids_info = {}
for question_id, answer_id in answer_ids:
answer_ids_info[answer_id] = question_id
replies = AnswerReply.objects.filter(answer_id__in=list(answer_ids_info.keys()),
first_reply=None, is_online=True).values_list("answer_id"). \
annotate(cnt=Count('*'))
for answer_id, c in replies:
reply_cnt_info[answer_ids_info[answer_id]] += c
res = {"total": cnt, "questions": []}
for item in messages:
user = users.get(item.user_id)
info = {
"id": item.question.id,
"title": item.question.title,
"tags": [tag.tag for tag in item.question.tags if tag.tag],
"created_time": get_timestamp_or_none(item.question.create_time),
"update_time": get_timestamp_or_none(reply_time_info.get(item.question.id)),
"reply_num": reply_cnt_info.get(item.question_id, 0),
"status": item.process_status,
"author": {
"id": user.id if user else None,
"nickname": user.nickname if user else None,
'current_city_id': user.current_city_id,
'current_city_name': cities.get(user.current_city_id, {}).get("name"),
'city_id': user.city_id,
'city_name': user.city_name,
}
}
res["questions"].append(info)
return res