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
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
#!/usr/bin/env python
# -*- coding: utf-8 -*-
# 问答卡片性能优化接口
from operator import itemgetter
from django.db.models import Q
from gm_rpcd.all import bind
from gm_types.error import ERROR
from gm_types.mimas import (
MEDIA_IMAGE_URL_SOURCE,
GRABBING_PLATFORM,
)
from qa.manager.qa_blend_manager import (
qa_manager,
)
from qa.utils.decorator import listing
from qa.tasks import (
add_answer_view,
)
from talos.services import UserConvertService
from utils.rpc import (
gen,
rpc_client,
get_current_user,
logging_exception,
)
from utils.group_routine import GroupRoutine
@bind('qa/question_answer/list_by_ids_v2')
@listing()
def get_qa_list_by_ids_v2(answer_ids, viewer_user_id=None):
"""
通过回答id,获取卡片数据
:param answer_ids:
:param viewer_user_id:
:return:
"""
if not answer_ids:
return []
# 回答信息
answer_ids = list(map(int, answer_ids))
answer_objs = qa_manager.get_answer_objs(
query=Q(pk__in=answer_ids, is_online=True, question__is_online=True),
order_by=[]
)
answers_dic = qa_manager.get_answer_info_by_objs(
answer_objs,
viewer_user_id=viewer_user_id,
need_social_info=True
) # sql查询
# 问题信息
question_ids = set(map(itemgetter("question_id"), answers_dic.values()))
question_objs = qa_manager.get_question_objs(
query=Q(pk__in=question_ids, is_online=True),
order_by=[]
)
questions_dic = qa_manager.get_questions_info_by_objs(question_objs) # sql查询
answer_list = []
valid_answer_ids = []
for answer_id in answer_ids:
_answer_data = answers_dic.get(answer_id, {})
if _answer_data:
_question_id = _answer_data.get("question_id", 0)
_user_info = _answer_data.get("user_info", {})
_answer_data.update({
"question": questions_dic.get(_question_id, {}),
"is_following": _user_info.get("is_following", False),
})
answer_list.append(_answer_data)
valid_answer_ids.append(answer_id)
add_answer_view.delay(answer_ids=valid_answer_ids)
return answer_list
@bind("qa/question/new_answer_list/v2")
def get_new_answer_list_v2(answer_ids, viewer_user_id=None, return_sorted=False):
"""
问题详情页回答列表,回答id来自策略推荐
:param answer_ids:
:param viewer_user_id: 当前浏览用户id
:param return_sorted: 是否需要按照ids 排序
:return:
"""
result = {}
if not answer_ids:
return result
answer_ids = qa_manager.filter_ids(answer_ids)
answer_objs = qa_manager.get_answer_objs(
query=Q(pk__in=answer_ids, is_online=True, question__is_online=True),
order_by=[]
)
# header头图
answer_header_images = qa_manager.answer_media.get_qa_header_images(qa_ids=answer_ids)
# 其他信息
user_ids = [answer.user_id for answer in answer_objs]
pub_answer_nums_dic = qa_manager.get_user_publish_answer_nums(user_ids)
vote_nums_dic = qa_manager.get_user_publish_answer_vote_nums(user_ids)
# 回答信息
answers_data = qa_manager.get_answer_info_by_objs(
answer_objs,
viewer_user_id=viewer_user_id,
need_social_info=True,
image_url_sources=[MEDIA_IMAGE_URL_SOURCE.CREATE]
)
for answer_id, answer_data in answers_data.items():
_user_id = answer_data.get("user_id", 0)
answer_data.update({
"header_images": answer_header_images.get(answer_id, []),
"answer_user_pub_nums": pub_answer_nums_dic.get(_user_id, 0),
"answer_user_pub_favor_nums": vote_nums_dic.get(_user_id, 0),
})
result[str(answer_id)] = answer_data
if return_sorted:
result = sorted(result, key=lambda item: answer_ids.index(item.get('id')))
return result
@bind("qa/answer_reply/include_sub_comments_for_answer_list")
def get_answer_reply_list_include_sub_comments(answer_ids, viewer_user_id=None, start_num=0, count=2):
"""
获取问题详情页回答列表评论
:param answer_ids:
:param viewer_user_id:当前浏览用户id
:param start_num:
:param count:
:return: {}
"""
result = {}
if not answer_ids:
return result
_reply_list, _map_dic = [], {}
for answer_id in answer_ids:
replies = list(qa_manager.get_objs_by_query_and_order(
model=qa_manager.answer_replies.model,
query=Q(answer_id=answer_id, is_online=True, first_reply__isnull=True),
order_by=["id"]
).only("id", "user", "content", "create_time", "like_num")[start_num: start_num + count])
_reply_list.extend(replies)
_map_dic[answer_id] = [reply.id for reply in replies]
replies_data = qa_manager.answer_replies.get_reply_data_by_replies_obj(
replies=_reply_list,
viewer_user_id=viewer_user_id,
need_sub_comments=True
)
for answer_id, reply_ids in _map_dic.items():
result[str(answer_id)] = [replies_data.get(reply_id, {}) for reply_id in reply_ids]
return result
@bind("qa/question/get_question_rel_infos")
def get_question_rel_infos(question_id=None, answer_id=None):
"""
获取问题关联的信息
:param question_id: 问题id
:return:
"""
result = {}
if not question_id and not answer_id:
return result
if answer_id:
answer_obj = qa_manager.get_answer_objs(
Q(pk=answer_id, is_online=True), None).only("question_id").first()
if not answer_obj:
return gen(ERROR.ANSWER_NOT_FOUND)
question_id = answer_obj.question_id
question_obj = qa_manager.get_question_objs(Q(pk=question_id), None).only("id", "user").first()
if not question_obj:
return gen(ERROR.QUESTION_NOT_FOUND)
user = get_current_user()
user_id = user and user.id
if not question_obj.user_can_view(user_id):
return gen(ERROR.QUESTION_NOT_FOUND)
_question_id = question_obj.id
v1_tags_info = qa_manager.question_manager.get_tags_info_by_question_ids([_question_id])
v3_tags_info = qa_manager.question_manager.get_tags_v3_info_by_question_ids([_question_id])
result.update({
"v1_rel_tags_info": v1_tags_info.get(_question_id, []),
"v3_rel_tags_info": v3_tags_info.get(_question_id, []),
"rel_user_info": UserConvertService.get_user_info_by_user_id(question_obj.user_id)
})
return result
@bind("qa/answer/get_answer_rel_infos")
def get_answer_rel_infos(answer_id):
"""
获取回答关联的信息
:param answer_id:
:return:
"""
result = {}
if not answer_id:
return result
answer_obj = qa_manager.get_answer_objs(
Q(pk=answer_id, is_online=True), None).only("id", "user", "question_id").first()
if not answer_obj:
return gen(ERROR.ANSWER_NOT_FOUND)
_rel_question_id = answer_obj.question_id
routine = GroupRoutine()
_map_list = [
("v1_rel_tags_info", qa_manager.question_manager.get_tags_info_by_question_ids, _rel_question_id, []),
("v3_rel_tags_info", qa_manager.answer_manager.get_tags_v3_info_by_answer_ids, answer_id, []),
("rel_user_info", UserConvertService.get_user_info_by_user_ids, answer_obj.user_id, {}),
]
for key, func, param, _ in _map_list:
routine.submit(key, func, [param])
routine.go()
for key, _, param, _default in _map_list:
_data = routine.results.get(key, {})
result.update({
key: _data.get(param, _default)
})
return result
@bind('qa/answer/answer_bulk_offline_by_ids')
def answer_bulk_offline_by_ids(answer_ids, platform=None):
"""
回答内容批量下线
:param answer_ids:
:param platform:
:return:
"""
if not answer_ids:
return
filter_query = Q(pk__in=list(map(int, answer_ids)))
if platform and platform in GRABBING_PLATFORM:
filter_query &= Q(platform=platform)
nums = qa_manager.get_objs_by_query_and_order(
model=qa_manager.answer_manager.model,
query=filter_query
).update(is_online=False)
return nums