def delete(self): form = request.get_json(True, True) user_id = auth_helper() task_id = form.get("task_id") if not task_id: return jsonify(error='任务ID不能为空'), 400 task = Task.get(task_id=task_id) if not task: return jsonify(error='该任务不存在'), 400 task = task[0] if task.creator_id != user_id: return jsonify(error='权限不足'), 403 participates = Participate.get(task_id=task_id) if participates: # 有用户已经开始做任务/完成任务时无法取消 for participate in participates: if participate.status != ParticipateStatus.APPLYING.value: return dict(error='任务已经有人参与,无法取消'), 400 # 通知所有申请该任务的用户: 该任务已取消 for participate in participates: message = Message(user_id=participate.user_id, content=f'您申请参与的任务"{task.title}"已取消') # 把押金还给申请者 change_balance(participate.user_id, PLEDGE) db.session.add(message) db.session.commit() # 数据库外键约束,删除任务自动删除所有participate # db.session.delete(participates) # db.session.commit() # 把押金还给发起者 change_balance(user_id, task.reward * task.max_participate) # 数据库中删除任务 db.session.delete(task) db.session.commit() return dict(data='取消任务成功'), 200
def add_data(self): logging.basicConfig(level=logging.INFO) logging.info('testing add data...') try: for i in range(0, 10): user = User(id=i + 1, student_id=f"{i+1}", username=f"ct{i+1}", password=encrypt_helper("123"), email=f"bz{i}@163.com", phone=f"123{i}") db.session.add(user) db.session.flush() except Exception as e: logging.error(f'error when adding users: {e}') try: for i in range(0, 10): task = Task(id=i + 1, title='cbbmjm哈哈', creator_id=f"{i%2+1}", task_type=f"{i%3+1}", reward=100, description="pptmjj", due_time="2019-07-02 18:00", max_participate=i % 3 + 1) db.session.add(task) db.session.flush() except Exception as e: logging.error(f'error when adding tasks: {e}') try: for i in range(0, 10): comment = Comment(user_id=i + 1, task_id=i + 1, content="Nice!") db.session.add(comment) db.session.flush() except Exception as e: logging.error(f'error when adding comments: {e}') try: for i in range(0, 10): collect = Collect(user_id=i + 1, task_id=i + 1) db.session.add(collect) db.session.flush() except Exception as e: logging.error(f'error when adding collects: {e}') try: for i in range(0, 10): participate = Participate(user_id=i + 1, task_id=i % 2 + 1, status=1) db.session.add(participate) db.session.flush() except Exception as e: logging.error(f'error when adding participates: {e}') db.session.commit() logging.info('testing add data succeed')
def delete(self): form = request.get_json(True, True) user_id = auth_helper() task_id = form.get('task_id') if not task_id: return dict(error="请指定任务"), 400 task = Task.get(task_id=task_id) if not task: return dict(error="该任务不存在"), 400 task = task[0] participator_id = form.get('participator_id') if not participator_id: return dict(error="参与者不能为空"), 400 participate = Participate.get(user_id=participator_id, task_id=task_id) if not participate: return dict(error="该参与信息不存在"), 400 if user_id != participator_id: # 参与者才能取消参与任务 return dict(error="您没有操作权限"), 403 participate = participate[0] db.session.delete(participate) db.session.commit() # 发消息给甲方,乙方退出了任务 user = User.get_by_id(user_id) message = Message(user_id=task.creator_id, content=f'用户 {user.username} 退出了您的任务 {task.title}') db.session.add(message) db.session.commit() # 不退还乙方押金 return dict(data="ok"), 200
def appeal_task(): # 乙方(是否)申诉甲方的审核结果 user_id = auth_helper() form = request.get_json(True, True) task_id = form.get('task_id') view = form.get('view') if not task_id: return jsonify(error='请指定任务'), 400 task = Task.get(task_id=task_id) if not task: return jsonify(error='任务不存在'), 400 task = task[0] if not view or (view != 'yes' and view != 'no'): return jsonify(error='请指定正确的申诉请求'), 400 participate = Participate.get(user_id=user_id, task_id=task_id) if not participate: return jsonify(error='未参与该任务'), 400 participate = participate[0] if participate.status != ParticipateStatus.FINISH.value: return jsonify(error='未完成该任务'), 400 if view == 'yes': # 确认申诉 # 发消息给admin user = User.get_by_id(user_id) message = Message( user_id=ADMIN_ID, content=f'用户 {user.username} 对任务 {task.title} 的结果进行申诉') db.session.add(message) db.session.commit() else: # 不申诉 # 不退还乙方押金 pass return jsonify(data='申诉完成'), 200
def delete_task(self): logging.info('testing delete task') for id in range(0, 10, 2): task = Task.get(task_id=id + 1) task = task[0] db.session.delete(task) db.session.commit() participates = Participate.get() assert len(participates) == 5, 'testing delete task failed' logging.info('testing delete task succeed')
def add_submission(self): logging.info('testing add submission') try: for participate in Participate.get(): participate.status = ParticipateStatus.ONGOING.value answer = json.dumps({'question1': 1, 'question2': "母鸡"}) submission = Submission(user_id=participate.user_id, task_id=participate.task_id, answer=answer) db.session.add(submission) db.session.commit() except Exception as e: logging.error(f'testing add submission failed: {e}') else: logging.info('testing add submission succeed')
def get(self): user_id = request.args.get('user_id') task_id = request.args.get('task_id') status = request.args.get('status') participates = Participate.get(user_id=user_id, task_id=task_id, status=status) result = [{"id": participate.id, "user_id": participate.user_id, "task_id": participate.task_id, "status": ParticipateStatusCN[participate.status]} for participate in participates] for r in result: user = User.get(user_id=r["user_id"])[0] r["email"] = user.email r["phone"] = user.phone r["username"] = user.username return dict(data=result), 200
def get_extra(): # 获取任务的具体内容,仅甲方和通过申请的乙方可查看 user_id = auth_helper() task_id = request.args.get("task_id") if not task_id: return jsonify(error='请指定任务'), 400 task = Task.get(task_id=task_id) if not task: return jsonify(error='任务不存在'), 400 task = task[0] participate = Participate.get(user_id=user_id, task_id=task_id) # 未参与、申请中、非创建者 if (not participate or (participate and participate[0].status == ParticipateStatus.APPLYING.value))\ and task.creator_id != user_id: return jsonify(error='没有权限查看'), 403 return jsonify(data=json.loads(task.extra)), 200
def review_participate(): # 甲方审批乙方的申请 form = request.get_json(True, True) user_id = auth_helper() participator_id = form.get('participator_id') view = form.get('view') if not participator_id: return jsonify(error="请指定申请者"), 400 task_id = form.get('task_id') if not task_id: return jsonify(error="请指定任务"), 400 task = Task.get(task_id=task_id) if not task: return jsonify(error="该任务不存在"), 400 task = task[0] if user_id != task.creator_id: return jsonify(error="您没有操作权限"), 403 participate = Participate.get(user_id=participator_id, task_id=task_id) if not participate: return jsonify(error='申请不存在'), 400 participate = participate[0] if participate.status != ParticipateStatus.APPLYING.value: return jsonify(error='该用户已在任务中'), 400 if not view or (view != 'yes' and view != 'no'): return jsonify(error='请指定正确的审批结果') if view == 'yes': # 同意乙方参与任务 participate.status = ParticipateStatus.ONGOING.value db.session.commit() # 发消息给乙方 申请已通过 message = Message(user_id=participator_id, content=f'您对任务 {task.title} 的申请已通过') db.session.add(message) db.session.commit() else: # 不同意乙方参与任务 db.session.delete(participate) db.session.commit() # 发消息给乙方 申请未通过 message = Message(user_id=participator_id, content=f'您对任务 {task.title} 的申请未通过') db.session.add(message) db.session.commit() # 退还乙方押金 change_balance(participator_id, PLEDGE) return jsonify(data='审批完成'), 200
def review_task(): # 甲方审核乙方的任务完成结果 creator_id = auth_helper() form = request.get_json(True, True) participator_id = form.get('participator_id') view = form.get('view') task_id = form.get('task_id') if not participator_id: return jsonify(error='请指定任务参与者'), 400 if not task_id: return jsonify(error='请指定任务'), 400 task = Task.get(task_id=task_id) if not task: return jsonify(error='任务不存在'), 400 task = task[0] if task.creator_id != creator_id: return jsonify(error='没有操作权限'), 403 participate = Participate.get(user_id=participator_id, task_id=task_id) if not participate: return jsonify(error='用户未参与此任务'), 400 participate = participate[0] if participate.status != ParticipateStatus.CHECK.value: return jsonify(error='用户未完成此任务'), 400 if not view or (view != 'yes' and view != 'no'): return jsonify(error='请指定正确的审核结果'), 400 if view == 'yes': # 甲方满意,审核通过 # 发消息告知乙方 message = Message(user_id=participator_id, content=f'您参与的任务 {task.title} 完成情况通过审核,赏金和押金将送至您的账户') participate.status = ParticipateStatus.FINISH.value db.session.add(message) db.session.commit() # 支付乙方reward change_balance(participator_id, task.reward) # 退还乙方押金 change_balance(participator_id, PLEDGE) else: # 甲方不满意,审核不通过 # 发消息告知乙方 message = Message(user_id=participator_id, content=f'您参与的任务 {task.title} 完成情况未通过审核,暂时无法获得赏金和押金', msg_type=MessageType.COMPLAIN.value) db.session.add(message) db.session.commit() return jsonify(data='审核完成'), 200
def update_task_status(): # 检查任务是否到期 tasks = Task.get() for task in tasks: # 任务截止时间已过 if task.due_time.strftime("%Y-%m-%d %H:%M") < get_cur_time(): participates = Participate.get(task_id=task.id) ids = [] count = 0 for participate in participates: if participate.status == ParticipateStatus.APPLYING.value: # 取消申请,发消息告知乙方并退还押金 ids.append(participate.id) message = Message( user_id=participate.user_id, content=f'您申请的任务 {task.title} 截止时间已过,申请已取消') db.session.add(message) db.session.commit() change_balance(participate.user_id, PLEDGE) elif participate.status == ParticipateStatus.ONGOING.value: # 乙方任务失败,改变参与状态,不退还押金并发送消息 participate.status = ParticipateStatus.FAILED.value db.session.commit() message = Message( user_id=participate.user_id, content=f'您正在进行的任务 {task.title} 截止时间已过,您未完成任务,无法退还押金') db.session.add(message) db.session.commit() elif participate.status == ParticipateStatus.FINISH.value: count += 1 # 取消所有申请 stmt = Participate.__table__.delete().where( Participate.id.in_(ids)) db.session.execute(stmt) db.session.commit() # 退还甲方剩余押金并发送消息 change_balance(task.creator_id, (task.max_participate - count) * task.reward) message = Message(user_id=task.creator_id, content=f'您发起的任务 {task.title} 截止时间已过,剩余押金已退还') db.session.add(message) db.session.commit()
def post(self): user_id = auth_helper() form = request.get_json(True, True) task_id = form.get('task_id') answer = form.get('answer') if not answer: return dict(error='问卷不能为空'), 400 if not task_id: return dict(error='请指定任务'), 400 task = Task.get(task_id=task_id) if not task: return dict(error='任务不存在'), 400 participates = Participate.get(user_id=user_id, task_id=task_id) if not participates or (participates and participates[0].status == ParticipateStatus.APPLYING.value): return dict(error='未参与该任务'), 403 print("hi") try: answer = json.dumps(answer) except Exception: return dict(error='请提交正确的答案'), 400 try: submission = Submission(user_id=user_id, task_id=task_id, answer=answer) participates[0].status = ParticipateStatus.CHECK.value db.session.add(submission) db.session.commit() print(answer) except exc.IntegrityError as e: logging.error(f'submit answer failed, msg: {e}') if re.search(r"Duplicate entry '\S*' for key '\S*'", e.orig.args[1]): return dict(error='不能重复提交问卷'), 400 else: return dict(error=f'{e}'), 400 return dict(data='问卷提交成功'), 200
def post(self): user_id = auth_helper() form = request.get_json(True, True) task_id = form.get('task_id') if not task_id: return dict(error='请指定任务'), 400 task = Task.get(task_id=task_id) if not task: return dict(error='该任务不存在'), 400 task = task[0] if task.creator_id == user_id: return dict(error='发起者无需申请参与该任务'), 400 # 支付押金 try: change_balance(user_id, -1 * PLEDGE) except RuntimeError as e: return dict(error=f'{e}'), 400 try: participate = Participate(user_id=user_id, task_id=task_id, status=ParticipateStatus.APPLYING.value) db.session.add(participate) db.session.commit() except exc.IntegrityError as e: logging.error(f'participate failed, msg: {e}') if re.search(r"Duplicate entry '\S*' for key '\S*'", e.orig.args[1]): return dict(error='您已经提交过该任务的申请'), 400 elif re.search(r"Cannot add or update a child row", e.orig.args[1]): return dict(error='该任务不存在'), 400 else: return dict(error=f'{e}'), 400 # 发申请消息给甲方 user = User.get_by_id(user_id) message = Message(user_id=task.creator_id, content=f'用户 {user.username} 申请参加任务 {task.title}', msg_type=MessageType.APPLY.value, send_from=user_id) db.session.add(message) db.session.commit() return dict(data="已成功发出申请"), 200
def finish_participate(): # 乙方确认完成任务 user_id = auth_helper() form = request.get_json(True, True) task_id = form.get('task_id') if not task_id: return jsonify(error='请指定任务'), 400 task = Task.get_by_id(task_id) if not task: return jsonify(error='任务不存在'), 400 participate = Participate.get(user_id=user_id, task_id=task_id) if not participate or participate[0].status == ParticipateStatus.APPLYING.value: return jsonify(error='未参与该任务'), 400 participate = participate[0] if participate.status == ParticipateStatus.FINISH.value: return jsonify(error='已完成该任务') participate.status = ParticipateStatus.CHECK.value db.session.commit() # 发消息告知甲方 乙方完成任务 user = User.get_by_id(user_id) message = Message(user_id=task.creator_id, content=f'用户 {user.username} 已完成任务 {task.title}, 请进行验收', msg_type=MessageType.FINISH.value, send_from=user.id) db.session.add(message) db.session.commit() return jsonify(data='确认成功'), 200
def get(self): find_collect = request.args.get('find_collect') user_id = request.args.get('user_id') tasks = [] if find_collect and find_collect is True and user_id: collects = Collect.get(user_id=user_id) for collect in collects: task = Task.get(task_id=collect.task_id) if task: tasks.append(task[0]) else: creator_id = request.args.get("creator_id") title = request.args.get('title') task_type = request.args.get("task_type") min_reward = request.args.get("min_reward") max_reward = request.args.get("max_reward") offset = request.args.get("offset") limit = request.args.get("limit") tasks = Task.get(creator_id=creator_id, title=title, task_type=task_type, min_reward=min_reward, max_reward=max_reward, offset=offset, limit=limit) if len(tasks) != 1: # 按发布时间逆序 for i in range(0, len(tasks) - 1): for j in range(i + 1, len(tasks)): if tasks[i].id < tasks[j].id: t = tasks[i] tasks[i] = tasks[j] tasks[j] = t result = [{ "task_id": task.id, "title": task.title, "task_type": task.task_type, "reward": task.reward, "description": task.description, "due_time": task.due_time.strftime("%Y-%m-%d %H:%M"), "max_participate": task.max_participate, "creator_id": task.creator_id, "image": task.image.decode() if task.image else None } for task in tasks] for value in result: creator = User.get(value["creator_id"])[0] value["creator_name"] = creator.username participators = [{ "user_id": p.user_id, "status": ParticipateStatusCN[p.status] } for p in Participate.get(task_id=value["task_id"])] for p in participators: user = User.get(user_id=p["user_id"])[0] p["username"] = user.username p["phone"] = user.phone p["email"] = user.email p["avatar"] = user.avatar.decode() if user.avatar else None value["participators"] = participators user_id = auth_helper() collect = Collect.get(user_id=user_id, task_id=value['task_id']) value['is_collect'] = True if collect else False # 是否收藏该任务 comments = Comment.get(task_id=value['task_id']) value['num_comments'] = len(comments) if comments else 0 # 任务的评论数 return dict(data=result, count=len(result)), 200
def patch(self): form = request.get_json(True, True) user_id = auth_helper() if not form: return dict(error="表单不能为空"), 400 task_id = form.get("task_id") if not task_id: return dict(error="任务ID不能为空"), 400 task = Task.get(task_id=task_id) if not task: return dict(error="该任务不存在"), 400 task = task[0] if task.creator_id != user_id: return dict(error="权限不足"), 403 participates = Participate.get(task_id=task_id) if participates: # 有用户已经开始做任务/完成任务时无法修改 for participate in participates: if participate.status != ParticipateStatus.APPLYING.value: return dict(error='任务已经有人参与,无法修改'), 400 # 撤销所有的申请并通知申请者 ids = [] for participate in participates: ids.append(participate.id) message = Message( user_id=participate.user_id, content=f'您申请参与的任务 "{task.title}" 有改动,请确认并重新申请') db.session.add(message) db.session.commit() # 把押金还给申请者 change_balance(participate.user_id, PLEDGE) stmt = Participate.__table__.delete().where( Participate.id.in_(ids)) db.session.execute(stmt) db.session.commit() title = form.get('title') task_type = form.get('task_type') reward = form.get('reward') max_participate = form.get('max_participant') if title or task_type or reward or max_participate: return dict(error='只允许修改任务截止时间、简介、内容、图片'), 400 due_time = form.get('due_time') if due_time and due_time < get_cur_time(): return dict(error='截止时间已过'), 400 description = form.get('description') extra = form.get('extra') if extra: try: extra = json.dumps(extra) except Exception: return dict(error='请指定正确的任务内容'), 400 Task.patch(task_id=task_id, title=title, task_type=task_type, reward=reward, description=description, due_time=due_time, max_participate=max_participate, extra=extra) return dict(data='修改任务成功'), 200