示例#1
0
    def modify_email(self, jwt):
        try:
            jwt_dict = authorization.toolkit.decode_jwt_token(jwt)  # type:dict
        except PyJWTError:
            raise exception.api.InvalidRequest('修改电子邮件地址的链接已过期或者激活请求非法')

        if 'sub' not in jwt_dict.keys(
        ) or jwt_dict['sub'] != JwtSub.ModifyEmail.value:
            raise exception.api.InvalidRequest('修改电子邮件地址的请求非法')

        if 'uuid' not in jwt_dict.keys() or 'email' not in jwt_dict.keys():
            raise exception.api.InvalidRequest('修改电子邮件地址的请求非法')

        uuid = jwt_dict['uuid']
        with session_scope() as session:
            user = session.query(User).filter(User.uuid == uuid).first()

            email = jwt_dict['email']
            if user.email == email:
                raise exception.api.Conflict('电子邮箱地址已经成功完成了变更,无法重复变更')

            user.email = email

            jwt_token = authorization.toolkit.derive_jwt_token(user_id=user.id,
                                                               user_uuid=uuid)
            result = ApiResult('电子邮箱地址修改成功', 201, payload={'jwt': jwt_token})
            return result.to_response()
示例#2
0
    def execute(self):
        today = date.today()
        deadline = today - self.THRESHOLD
        with session_scope() as session:
            while True:
                services = session.query(Service) \
                    .filter(Service.status == Service.STATUS.SUSPENDED,
                            Service.billing_date <= deadline) \
                    .limit(500).all()

                if services is None or len(services) == 0:
                    break

                for service in services:  # type: Service
                    service.status = Service.STATUS.INVALID

                    # TODO 对交易订单进行退款,而不是暴力关闭
                    trade_orders = session.query(TradeOrder) \
                        .filter(ServiceTradeOrder.service_uuid == service.uuid,
                                ServiceTradeOrder.status == ServiceTradeOrder.STATUS.VALID.value,
                                TradeOrder.uuid == ServiceTradeOrder.trade_order_uuid,
                                TradeOrder.status.in_([TradeOrder.STATUS.INITIALIZATION.value,
                                                       TradeOrder.STATUS.PAYING.value,
                                                       TradeOrder.STATUS.PARTIAL_PAY.value])) \
                        .all()
                    for trade_order in trade_orders:  # type: TradeOrder
                        trade_order.status = TradeOrder.STATUS.CANCEL.value

                    session.commit()
示例#3
0
    def update_password(self):
        """
        修改密码

        :return:
        """
        old_password = self.get_post_data('old_password',
                                          require=True,
                                          error_message='请输入旧密码')
        password = self.get_post_data('password',
                                      require=True,
                                      error_message='请输入密码')

        with session_scope() as session:
            user = session.query(User).filter(
                User.uuid == self.user_uuid).first()
            if user is None:
                raise exception.api.Unauthorized('请先登录')

            hashed_old_password = authorization.toolkit.hash_plaintext(
                old_password)
            if hashed_old_password != user.password:
                raise exception.api.InvalidRequest('旧密码错误')

            user.password = authorization.toolkit.hash_plaintext(password)
            return ApiResult('修改密码成功', 201).to_response()
示例#4
0
    def delete(self):
        """
        取消订单

        :return:
        """
        uuid = self.get_data('uuid', require=True, error_message='缺少uuid字段')
        with session_scope() as session:
            order = session.query(TradeOrder) \
                .filter(TradeOrder.uuid == uuid,
                        TradeOrder.status != TradeOrder.STATUS.DELETED.value).first()  # type: TradeOrder

            if order is None:
                raise exception.api.NotFound('订单不存在')

            if order.user_uuid != self.user_uuid:
                raise exception.api.Forbidden('无权修改他人的订单')

            if order.status == TradeOrder.STATUS.CANCEL.value:
                raise exception.api.Conflict('订单已取消,无法重复取消')

            if order.status not in [
                    TradeOrder.STATUS.INITIALIZATION.value,
                    TradeOrder.STATUS.PAYING.value
            ]:
                raise exception.api.InvalidRequest(
                    '订单已进入支付流程,无法取消,请完成支付后进行退款操作')

            order.status = TradeOrder.STATUS.CANCEL.value

            result = ApiResult('订单取消成功')
            return result.to_response()
示例#5
0
    def reset_password(self, jwt: str):
        """
        重设密码

        :return:
        """
        password = self.get_post_data('password',
                                      require=True,
                                      error_message='请输入新密码')
        try:
            jwt_dict = authorization.toolkit.decode_jwt_token(jwt)  # type:dict
        except PyJWTError:
            raise exception.api.InvalidRequest('重设密码的链接已过期或者重设密码请求非法')

        if 'sub' not in jwt_dict.keys(
        ) or jwt_dict['sub'] != JwtSub.ResetPassword.value:
            raise exception.api.InvalidRequest('重设密码的请求非法')

        if 'uuid' not in jwt_dict.keys():
            raise exception.api.InvalidRequest('重设密码的请求非法')

        uuid = jwt_dict['uuid']
        with session_scope() as session:
            user = session.query(User).filter(User.uuid == uuid).first()

            user.password = authorization.toolkit.hash_plaintext(password)

            result = ApiResult('密码重设成功,以后请使用新密码登录', 201)
            return result.to_response()
    def get(self):
        with session_scope() as session:
            invitation_list = []
            query = self.derive_query_for_get_method(session, InvitationCode) \
                .filter(InvitationCode.status != InvitationCode.Status.DELETED.value)
            page, page_size, offset, max_page = self.derive_page_parameter(query.count())
            invitations = query.limit(page_size).offset(offset).all()
            for invitation in invitations:  # type: InvitationCode
                invitation_dict = invitation.to_dict()
                inviter_username = session.query(User.username) \
                    .filter(User.uuid == invitation.inviter_uuid,
                            User.status != User.STATUS.DELETED).first()
                inviter_username = inviter_username.username if inviter_username is not None else ''
                invitee_username = session.query(User.username) \
                    .filter(User.uuid == invitation.invitee_uuid,
                            User.status != User.STATUS.DELETED).first()
                invitee_username = invitee_username.username if invitee_username is not None else ''
                invitation_dict['inviter_username'] = inviter_username
                invitation_dict['invitee_username'] = invitee_username
                invitation_list.append(invitation_dict)

            result = ApiResult('获取邀请码信息成功', payload={
                'invitations': invitation_list,
                'page': page,
                'page_size': page_size,
                'max_page': max_page,
            })
            return result.to_response()
示例#7
0
    def send_activation_email(self):
        with session_scope() as session:
            user = session.query(User).filter(
                User.uuid == self.user_uuid).first()

            expired_in = 48
            extra_payload = {'sub': JwtSub.Activation.value}
            jwt = authorization.toolkit.derive_jwt_token(
                user_id=self.user_id,
                user_uuid=self.user_uuid,
                expired_in=expired_in,
                extra_payload=extra_payload)
            if configs.DEBUG:
                domain = 'http://localhost:8080'
            else:
                domain = 'http://www.celerysoft.science'
            activate_url = '{}/activation?jwt={}'.format(domain, jwt)

            background_task.send_activation_email.delay(
                user_email=user.email,
                username=user.username,
                activate_url=activate_url)

            return ApiResult('激活邮件已发送至注册邮箱{},请查收'.format(user.email),
                             201).to_response()
示例#8
0
    def get(self):
        with session_scope() as db_session:
            if not permission.toolkit.check_manage_role_permission(
                    db_session, self.user_id):
                raise exception.api.Forbidden('当前用户无法管理角色')

            # 查询用户当前角色
            user_role = None
            target_user_id = self.get_data('user_id')
            if self.valid_data(target_user_id):
                user_role = db_session.query(Role) \
                    .filter(User.id == UserRole.user_id) \
                    .filter(UserRole.role_id == Role.id) \
                    .filter(User.id == target_user_id).first()

            # 查询所有角色列表
            roles = db_session.query(Role).order_by(Role.id).all()

            role_list = []
            for role in roles:
                role_list.append(to_dict(role))

            payload = {'roles': role_list}
            if user_role is not None:
                payload['user_role'] = to_dict(user_role)

        result = ApiResult('获取角色信息成功', 200, payload)
        return make_response(result.to_response())
示例#9
0
    def post(self):
        name = self.get_post_data('name',
                                  require=True,
                                  error_message='缺少name字段')
        label = self.get_post_data('label',
                                   require=True,
                                   error_message='缺少label字段')
        description = self.get_post_data('description')
        permissions = self.get_post_data('permissions')

        with session_scope() as session:
            if not permission.toolkit.check_manage_role_permission(
                    session, self.user_id):
                raise exception.api.Forbidden('当前用户无法管理角色')

            role = Role(name, label, description)
            session.add(role)
            session.flush()

            role_id = role.id
            for permission_id in permissions:
                role_permission = RolePermission(role_id, permission_id)
                session.add(role_permission)

        result = ApiResult('创建角色成功', 201, {'role_id': role_id})
        return make_response(result.to_response())
示例#10
0
    def get(self):
        with session_scope() as session:
            event_list = []
            query = self.derive_query_for_get_method(session, Event) \
                .filter(Event.status != Event.Status.DELETED.value)
            page, page_size, offset, max_page = self.derive_page_parameter(
                query.count())
            events = query.limit(page_size).offset(offset).all()
            for event in events:  # type: Event
                event_dict = event.to_dict('content')
                author_username = session.query(User.username) \
                    .filter(User.uuid == event.author_uuid,
                            User.status != User.STATUS.DELETED).first()
                author_username = author_username.username if author_username is not None else ''
                event_dict['author_username'] = author_username
                event_list.append(event_dict)

            result = ApiResult('获取公告成功',
                               payload={
                                   'events': event_list,
                                   'page': page,
                                   'page_size': page_size,
                                   'max_page': max_page,
                               })
            return result.to_response()
示例#11
0
    def get_user_services(self, user_uuid):
        with session_scope() as db_session:
            query = db_session.query(Service, ServiceTemplate.title) \
                .outerjoin(ServiceTemplate, Service.template_uuid == ServiceTemplate.uuid) \
                .filter(Service.user_uuid == user_uuid) \
                .filter(Service.status != Service.STATUS.DELETED) \
                .order_by(Service.created_at)

            page, page_size, offset, max_page = self._derive_page_parameter(query.count())

            services = query.offset(offset).limit(page_size).all()

            service_list = []
            for record in services:
                service = record.Service
                service_dict = service.to_dict()
                service_dict['title'] = record.title
                service_list.append(service_dict)

            result = ApiResult('获取用户学术服务信息成功', payload={
                'page': page,
                'page_size': page_size,
                'max_page': max_page,
                'services': service_list
            })
            return result.to_response()
示例#12
0
    def validate_email(self, jwt):
        try:
            jwt_dict = authorization.toolkit.decode_jwt_token(jwt)  # type:dict
        except PyJWTError:
            raise exception.api.InvalidRequest('激活链接已过期或者激活请求非法')

        if 'sub' not in jwt_dict.keys(
        ) or jwt_dict['sub'] != JwtSub.Activation.value:
            raise exception.api.InvalidRequest('激活请求非法')

        uuid = jwt_dict['uuid']
        with session_scope() as session:
            user = session.query(User).filter(User.uuid == uuid).first()
            if user.status == 1:
                raise exception.api.Conflict('邮箱已完成验证,无需重复验证')

            user.status = 1

            scholar_payment_account = session.query(ScholarPaymentAccount) \
                .filter(ScholarPaymentAccount.user_uuid == uuid,
                        ScholarPaymentAccount.status == ScholarPaymentAccount.STATUS.VALID.value) \
                .first()  # type: ScholarPaymentAccount
            if scholar_payment_account is not None:
                scholar_payment_account.balance = configs.NEW_USER_SCHOLAR_BALANCE

            jwt_token = authorization.toolkit.derive_jwt_token(user_id=user.id,
                                                               user_uuid=uuid)

            result = ApiResult('邮箱验证成功', 201, payload={'jwt': jwt_token})
            return result.to_response()
示例#13
0
    def put(self):
        service_uuid = self.get_post_data('uuid',
                                          require=True,
                                          error_message='缺少uuid字段')
        password = self.get_post_data('password',
                                      require=True,
                                      error_message='请输入长度至少为1位的新密码')

        with session_scope() as session:
            service = session.query(Service).filter(
                Service.uuid == service_uuid).first()
            if service is None:
                raise exception.api.NotFound('套餐不存在')

            if service.user_uuid != self.user_uuid:
                raise exception.api.Forbidden('无权修改其他用户的学术服务密码')

            service.password = password

            if service.status == Service.STATUS.ACTIVATED:
                background_task.modify_port_password.delay(port=service.port,
                                                           password=password)

            result = ApiResult('修改连接密码成功', 201)
            return result.to_response()
示例#14
0
    def get_template_by_type(self, template_type: Union[str, int]):
        try:
            template_type = int(template_type)
        except ValueError:
            return exception.api.InvalidRequest('请输入正确的服务类型')

        if template_type == ServiceTemplate.TYPE.RECOMMENDATION:
            return self.get_recommendation_template()

        with session_scope() as session:
            query = session.query(ServiceTemplate).filter(
                ServiceTemplate.type == template_type,
                ServiceTemplate.status == ServiceTemplate.STATUS.VALID)
            page, page_size, offset, max_page = self.derive_page_parameter(
                query.count())

            templates = query.offset(offset).limit(page_size).all()

            result = ApiResult(
                '获取服务模板信息成功', 200, {
                    'templates': self.models_to_list(templates),
                    'page': page,
                    'page_size': page_size,
                    'max_page': max_page,
                })
            return result.to_response()
示例#15
0
    def put(self):
        """
        订单支付

        :return:
        """
        payment_method_uuid = self.get_post_data(
            'payment_method_uuid',
            require=True,
            error_message='缺少payment_method_uuid字段')
        trade_order_uuid = self.get_post_data(
            'trade_order_uuid',
            require=True,
            error_message='缺少trade_order_uuid字段')

        with session_scope() as session:
            trade_order = session.query(TradeOrder) \
                .filter(TradeOrder.uuid == trade_order_uuid).first()  # type: TradeOrder
            if trade_order is None:
                raise exception.api.NotFound('订单不存在')
            if trade_order.status == TradeOrder.STATUS.PAYING.value:
                raise exception.api.Conflict('订单正在支付中,请不要重复支付')
            if trade_order.status == TradeOrder.STATUS.FINISH.value:
                raise exception.api.Conflict('订单已完成支付,请不要重复支付')

            if payment_method_uuid != configs.SCHOLAR_PAYMENT_SYSTEM_UUID_IN_PAYMENT_METHOD:
                return self.pay_order()

            return self.pay_order_by_scholar_payment_system(trade_order_uuid)
示例#16
0
    def generate_creation_order(self, service_template_uuid: str):
        """
        生成创建新的学术服务的订单

        :param service_template_uuid:
        :return:
        """
        with session_scope() as session:
            conflict, snapshot = trade_order.toolkit.check_is_order_conflict(
                session,
                self.user_uuid,
                service_template_uuid=service_template_uuid)
            if conflict:
                raise exception.api.Conflict('有尚未支付的『{}』的订单,请勿重复下单'.format(
                    snapshot.title))

            password = self.get_post_data('password',
                                          require=True,
                                          error_message='缺少password字段')
            auto_renew = self.get_post_data('auto_renew')

            service_template = session.query(ServiceTemplate) \
                .filter(ServiceTemplate.uuid == service_template_uuid,
                        ServiceTemplate.status != ServiceTemplate.STATUS.DELETED).first()  # type: ServiceTemplate
            if service_template is None:
                raise exception.api.NotFound('套餐不存在,无法办理')
            if service_template.status == ServiceTemplate.STATUS.SUSPEND:
                raise exception.api.ServiceUnavailable('该套餐已下架,故无法办理')

            total_payment = service_template.initialization_fee + service_template.price

            order = TradeOrder(user_uuid=self.user_uuid,
                               order_type=TradeOrder.TYPE.CONSUME.value,
                               amount=total_payment,
                               description='开通学术服务,服务模板UUID:{}'.format(
                                   service_template.uuid))
            session.add(order)
            session.flush()

            auto_renew = auto_renew if self.valid_data(auto_renew) else 0
            snapshot = SubscribeServiceSnapshot(
                trade_order_uuid=order.uuid,
                user_uuid=self.user_uuid,
                service_password=password,
                auto_renew=auto_renew,
                service_template_uuid=service_template_uuid,
                service_type=service_template.type,
                title=service_template.title,
                subtitle=service_template.subtitle,
                description=service_template.description,
                package=service_template.package,
                price=service_template.price,
                initialization_fee=service_template.initialization_fee)
            session.add(snapshot)

            result = ApiResult('订单创建成功', 201, {
                'uuid': order.uuid,
            })
            return result.to_response()
示例#17
0
 def delete(self):
     with session_scope() as session:
         self.delete_model(session,
                           Event,
                           delete_status=Event.Status.DELETED.value,
                           not_found_error_message='需要删除的公告不存在')
         result = ApiResult('删除公告成功')
         return result.to_response()
示例#18
0
    def recharge(self, payload: dict):
        try:
            app_id = payload['app_id']
            timestamp = payload['timestamp']
            user_uuid = payload['user_uuid']
            amount = payload['amount']
            signature = payload['signature']
        except KeyError:
            raise RuntimeError('非法请求')

        amount = Decimal(amount)

        expect_signature = self._derive_signature(
            timestamp, app_id, configs.SCHOLAR_PAYMENT_SYSTEM_APP_SECRET)
        if signature != expect_signature:
            raise RuntimeError('签名不合法')

        with session_scope() as session:
            account = session.query(ScholarPaymentAccount) \
                .filter(ScholarPaymentAccount.user_uuid == user_uuid,
                        ScholarPaymentAccount.status == ScholarPaymentAccount.STATUS.VALID.value) \
                .first()  # type: ScholarPaymentAccount

            old_balance = account.balance
            new_balance = old_balance + amount

            trade_order = self._create_trade_order(
                session=session, user_uuid=user_uuid,
                amount=amount)  # type: TradeOrder

            pay_order = self._create_pay_order(
                session=session,
                amount=trade_order.amount,
                trade_order_uuid=trade_order.uuid,
            )  # type: PayOrder

            log = self.increase(
                session=session,
                account_uuid=account.uuid,
                pay_order_uuid=pay_order.uuid,
                old_balance=old_balance,
                amount=amount,
                new_balance=new_balance,
                purpose_type=ScholarPaymentAccountLog.PurposeType.RECHARGE
            )  # type: ScholarPaymentAccountLog

            if log is not None:
                pay_order.payment_method_token = log.uuid
                pay_order.status = PayOrder.Status.FINISH.value

            if pay_order.status == PayOrder.Status.FINISH.value and trade_order.amount == pay_order.amount:
                trade_order.status = TradeOrder.STATUS.FINISH.value

            if trade_order.status == TradeOrder.STATUS.FINISH.value:
                account.balance = new_balance

            print('已收到为用户{}充值{}学术积分的请求'.format(user_uuid, amount))
            return True
示例#19
0
    def create_order_for_service(self, service_type: Service.TYPE, now: datetime):
        with session_scope() as session:
            services = session.query(Service) \
                .filter(Service.type == service_type,
                        Service.status.in_([Service.STATUS.INITIALIZATION, Service.STATUS.ACTIVATED,
                                            Service.STATUS.SUSPENDED, Service.STATUS.OUT_OF_CREDIT]),
                        Service.billing_date <= now)
            for service in services:  # type: Service
                conflict, snapshot = trade_order.toolkit.check_is_order_conflict(
                    session, service.user_uuid, service_uuid=service.uuid,
                )
                if conflict:
                    print('有尚未支付的『{}』的订单,请勿重复下单'.format(snapshot.title))
                    continue

                service_template = session.query(ServiceTemplate) \
                    .filter(ServiceTemplate.uuid == service.template_uuid,
                            ServiceTemplate.status != ServiceTemplate.STATUS.DELETED).first()  # type: ServiceTemplate
                if service_template is None:
                    print('套餐不存在,无法办理')
                    continue
                if service_template.status == ServiceTemplate.STATUS.SUSPEND:
                    print('该套餐已下架,无法办理')
                    continue

                total_payment = service_template.price

                order = TradeOrder(
                    user_uuid=service.user_uuid,
                    order_type=TradeOrder.TYPE.CONSUME.value,
                    amount=total_payment,
                    description='续费学术服务,服务UUID:{}'.format(service.uuid)
                )
                session.add(order)
                session.flush()

                snapshot = SubscribeServiceSnapshot(
                    trade_order_uuid=order.uuid,
                    user_uuid=service.user_uuid,
                    service_password=service.password,
                    auto_renew=service.auto_renew,
                    service_template_uuid=service.template_uuid,
                    service_type=service.type,
                    title=service_template.title,
                    subtitle=service_template.subtitle,
                    description=service_template.description,
                    package=service_template.package,
                    price=service_template.price,
                    initialization_fee=service_template.initialization_fee
                )
                session.add(snapshot)

                relationship = ServiceTradeOrder(
                    service_uuid=service.uuid,
                    trade_order_uuid=order.uuid,
                )
                session.add(relationship)
示例#20
0
    def handle_permission(view: MethodView):
        with session_scope() as session:
            # permission_required = view.get_permission_required
            # if not permission.toolkit.check_permission(view.user_uuid, permission_required):
            #     raise exception.api.Forbidden(view.permission_denied_message)

            if not permission.toolkit.check_manage_permission(
                    session, view.user_uuid):
                raise exception.api.Forbidden(view.permission_denied_message)
示例#21
0
    def post(self):
        with session_scope() as session:
            invitation = InvitationCode(self.user_uuid)
            session.add(invitation)
            session.flush()

            result = ApiResult('创建邀请码成功', 201, payload={
                'invitation': invitation.to_dict(),
            })
            return result.to_response()
 def execute(self) -> bool:
     with legacy_session_scope() as legacy_session, session_scope(
     ) as session:
         try:
             self._send_email_to_old_user(legacy_session, session)
         except BaseException as e:
             if configs.DEBUG:
                 raise RuntimeError(e)
             return False
         return True
示例#23
0
    def put(self):
        with session_scope() as session:
            event = self.update_model(session, Event)

            result = ApiResult('修改公告成功',
                               200,
                               payload={
                                   'event': event.to_dict(),
                               })
            return result.to_response()
示例#24
0
    def put(self):
        with session_scope() as session:
            template = self.update_model(session, ServiceTemplate)

            result = ApiResult('修改学术服务模板成功',
                               200,
                               payload={
                                   'template': template.to_dict(),
                               })
            return result.to_response()
示例#25
0
    def get_order_by_uuid(self, uuid: str):
        with session_scope() as session:
            order = session.query(TradeOrder) \
                .filter(TradeOrder.uuid == uuid,
                        TradeOrder.status != TradeOrder.STATUS.DELETED.value).first()  # type: TradeOrder
            if order is None:
                raise exception.api.NotFound('订单不存在')

            result = ApiResult('获取订单信息成功', payload={'order': order.to_dict()})
            return result.to_response()
示例#26
0
    def get(self):
        with session_scope() as db_session:
            permissions = permission.toolkit.derive_user_permissions(
                db_session, self.user_uuid)
            permission_list = []
            for p in permissions:  # type: Permission
                permission_list.append(p.to_dict())

        result = ApiResult('获取用户权限成功',
                           payload={'permissions': permission_list})
        return make_response(result.to_response())
示例#27
0
    def get_template_by_uuid(self, uuid: str):
        with session_scope() as session:
            service_template = session.query(ServiceTemplate) \
                .filter(ServiceTemplate.uuid == uuid).first()  # type: ServiceTemplate

            if service_template is None:
                raise exception.api.NotFound('服务模版不存在')

            result = ApiResult(
                '获取服务模板信息成功', payload={'template': service_template.to_dict()})
            return result.to_response()
示例#28
0
    def post(self):
        with session_scope() as session:
            event = self.create_model_from_http_post(Event)
            session.add(event)
            session.flush()

            result = ApiResult('发布公告成功',
                               201,
                               payload={
                                   'event': event.to_dict(),
                               })
            return result.to_response()
    def get_single_account(self, user_uuid):
        with session_scope() as session:
            account = session.query(ScholarPaymentAccount) \
                .filter(ScholarPaymentAccount.user_uuid == user_uuid,
                        ScholarPaymentAccount.status != ScholarPaymentAccount.STATUS.DELETED.value) \
                .first()  # type: ScholarPaymentAccount

            if account is None:
                raise exception.api.NotFound('学术积分账户不存在')

            result = ApiResult('获取学术积分账户信息成功',
                               payload={'account': account.to_dict()})
            return result.to_response()
示例#30
0
    def post(self):
        # service_type = self.get_post_data('type', require=True, error_message='缺少type字段')
        # title = self.get_post_data('title', require=True, error_message='缺少title字段')
        # subtitle = self.get_post_data('subtitle', require=True, error_message='缺少subtitle字段')
        # description = self.get_post_data('description', require=True, error_message='缺少description字段')
        # package = self.get_post_data('package', require=True, error_message='缺少package字段')
        # try:
        #     package = int(package)
        # except:
        #     raise exception.api.InvalidRequest('请输入合法的package字段')
        # price = self.get_post_data('price', require=True, error_message='缺少price字段')
        # try:
        #     price = float(price)
        # except:
        #     raise exception.api.InvalidRequest('请输入合法的price字段')
        # initialization_fee = self.get_post_data('initialization_fee', require=True,
        #                                         error_message='缺少initialization_fee字段')
        # try:
        #     initialization_fee = float(initialization_fee)
        # except:
        #     raise exception.api.InvalidRequest('请输入合法的initialization_fee字段')
        #
        # with session_scope() as session:
        #     template = ServiceTemplate(
        #         service_type=service_type,
        #         title=title,
        #         subtitle=subtitle,
        #         description=description,
        #         package=package,
        #         price=price,
        #         initialization_fee=initialization_fee,
        #     )
        #     session.add(template)
        #     session.flush()
        #
        #     result = ApiResult('创建学术服务模板成功', 201, payload={
        #         'template': template.to_dict(),
        #     })
        #     return result.to_response()
        with session_scope() as session:
            template = self.create_model_from_http_post(ServiceTemplate)
            session.add(template)
            session.flush()

            result = ApiResult('创建学术服务模板成功',
                               201,
                               payload={
                                   'template': template.to_dict(),
                               })
            return result.to_response()