Пример #1
0
class StudentEncouragementBonusResource(Resource):

    grant_args = {
        'income_limit': fields.Decimal(required=True),
        'age_limit': fields.Int(required=True),
    }

    @use_args(grant_args, location="query")
    def get(self, args):
        """ List households and qualifying family members for Student Encouragement Bonus
        -Children less than 16 years old
        -Household income less than $150,000
        """
        data = []
        household_list = []
        household_details_dict = {}
        family_member_details_dict = {}
        family_members_list = []

        age_limit_param = args['age_limit']
        income_limit_param = args['income_limit']
        # convert age limit to datetime object
        date_limit = datetime.date.today(
        ) - dateutil.relativedelta.relativedelta(years=int(age_limit_param))

        # query for income limit
        sub_q = FamilyMember.query.with_entities(FamilyMember.household_id, func.sum(
            FamilyMember.annual_income)).group_by(FamilyMember.household_id).having(func.sum(
                FamilyMember.annual_income) < int(income_limit_param)).subquery()

        # get qualifying family members
        query_result = FamilyMember.query.filter(FamilyMember.dob > date_limit).join(
            sub_q, FamilyMember.household_id == sub_q.c.household_id).all()

        for x in query_result:
            result_dict = x.__dict__
            result_dict.pop('_sa_instance_state', None)
            data.append(result_dict)

        # group qualifying members
        data = sorted(data, key=operator.itemgetter("household_id"))
        outputList = []
        for i, g in itertools.groupby(data, key=operator.itemgetter("household_id")):
            outputList.append(list(g))

        household_list = generateFamilyMembersDict(outputList)

        return (
            {
                "data": household_list

            },
            HTTPStatus.OK,
        )
Пример #2
0
class TemperatureReadingsSchema(ma.mallow.Schema):
    # class Meta:
    # fields = ("log_id", "device_id", "temperature", "time", "url")
    log_id = fields.UUID()
    device_id = fields.UUID()
    temperature = fields.Decimal(attribute='value')
    timestamp = fields.Method('get_time')
    device_name = fields.String()
    location = fields.String()
    units = fields.String()
    url = ma.mallow.URLFor('TemperatureReadingsView:get',
                           log_id='<log_id>',
                           _external=True)

    def get_time(self, obj):
        return obj['time']
Пример #3
0
class YOLOGSTGrantResource(Resource):

    grant_args = {
        'household_type': fields.Str(required=True),
        'income_limit': fields.Decimal(required=True),
    }

    @ use_args(grant_args, location='query')
    def get(self, args):
        """ List households and qualifying family members for YOLO GST Grant
        - HDB with annual income less than $100,000
        """

        data = []
        family_members_list = []
        household_details_dict = []
        income_limit_param = args['income_limit']
        household_type_param = args['household_type']

        # query households based on household type param
        sub_q = HouseHold.query.with_entities(HouseHold.id).filter(
            HouseHold.type == household_type_param).subquery()

        # query for income limit
        query_result = FamilyMember.query.with_entities(FamilyMember.id, HouseHold).group_by(FamilyMember.household_id).having(func.sum(
            FamilyMember.annual_income) < int(income_limit_param)).join(sub_q, FamilyMember.household_id == sub_q.c.id).join(HouseHold).all()
        if query_result:
            for household in query_result:
                family_members_list = generateHouseholdsDict(
                    household[1].family)
                household_details_dict = {
                    "HouseholdId": household[1].id,
                    "HouseholdType": household[1].type,
                    "FamilyMembers": family_members_list
                }
                data.append(household_details_dict)

            return {"data": data}, HTTPStatus.OK
        return {"msg": "no households found"}, HTTPStatus.BAD_REQUEST
Пример #4
0
class AdminProductView(AdminBaseView):
    """后台-货品-货品创建&货品详情&编辑货品&批量删除货品"""

    @AdminBaseView.permission_required([AdminBaseView.staff_permissions.ADMIN_PRODUCT])
    @use_args(
        {
            "name": fields.String(
                required=True, validate=[validate.Length(1, 15)], comment="货品名"
            ),
            "group_id": fields.Integer(required=True, comment="分组id"),
            "price": fields.Decimal(
                required=True,
                validate=[validate.Range(0, min_inclusive=False)],
                comment="货品单价",
            ),
            "storage": fields.Decimal(
                required=True, validate=[validate.Range(0)], comment="商品库存"
            ),
            "code": fields.String(required=False, comment="货品编码"),
            "summary": fields.String(
                required=False, validate=[validate.Length(0, 20)], comment="货品简介"
            ),
            "pictures": fields.List(
                fields.String(),
                required=False,
                validate=[validate.Length(1, 5)],
                comment="轮播图",
            ),
            "description": fields.String(required=False, comment="图文描述"),
            "cover_image_url": fields.String(required=True, comment="首页图片"),
        },
        location="json",
    )
    def post(self, request, args):
        group_id = args.get("group_id")
        args["shop_id"] = self.current_shop.id
        product_group = get_product_group_by_shop_id_and_id(self.current_shop.id, group_id)
        if not product_group:
            return self.send_fail(error_text="货品分组不存在")
        serializer = ProductCreateSerializer(data=args, context={'self':self})
        if not serializer.is_valid():
            return self.send_error(
                error_message=serializer.errors, status_code=status.HTTP_400_BAD_REQUEST
            )
        serializer.save()
        return self.send_success(data=serializer.data)

    @AdminBaseView.permission_required([AdminBaseView.staff_permissions.ADMIN_PRODUCT])
    @use_args(
        {
            "product_id": fields.Integer(
                required=True, validate=[validate.Range(1)], comment="货品ID"
            )
        },
        location="query"
    )
    def get(self, request, args):
        current_shop = self.current_shop
        product_id = args.get("product_id")
        product = get_product_with_group_name(current_shop.id, product_id)
        if not product:
            return self.send_fail(error_text="货品不存在")
        serializer = AdminProductSerializer(product)
        return self.send_success(data=serializer.data)

    @AdminBaseView.permission_required([AdminBaseView.staff_permissions.ADMIN_PRODUCT])
    @use_args(
        {
            "name": fields.String(
                required=True, validate=[validate.Length(1, 15)], comment="货品名"
            ),
            "group_id": fields.Integer(required=True, comment="分组id"),
            "price": fields.Decimal(
                required=True,
                validate=[validate.Range(0, min_inclusive=False)],
                comment="货品单价",
            ),
            "code": fields.String(required=False, comment="货品编码"),
            "storage": fields.Decimal(
                required=True, validate=[validate.Range(0)], comment="库存"
            ),
            "summary": fields.String(
                required=False, validate=[validate.Length(0, 20)], comment="货品简介"
            ),
            "pictures": fields.List(
                fields.String(),
                required=False,
                validate=[validate.Length(1, 5)],
                comment="轮播图",
            ),
            "description": fields.String(required=False, comment="图文描述"),
            "cover_image_url": fields.String(required=False, comment="首页图片"),
            "product_id": fields.Integer(required=True, comment="货品ID"),
        },
        location="json",
    )
    def put(self, request, args):
        shop_id = self.current_shop.id
        product_id = args.pop("product_id")
        product = get_product_by_id(shop_id, product_id)
        if not product:
            return self.send_fail(error_text="货品不存在")
        group_id = args.pop("group_id")
        product_group = get_product_group_by_shop_id_and_id(shop_id, group_id)
        if not product_group:
            return self.send_fail(error_text="货品分组不存在")
        args["group_id"] = product_group.id
        serializer = AdminProductSerializer(product, data=args, context={"self":self})
        if not serializer.is_valid():
            return self.send_error(
                error_message=serializer.errors, status_code=status.HTTP_400_BAD_REQUEST
            )
        serializer.save()
        return self.send_success(data=serializer.data)
Пример #5
0
class AdminGrouponView(AdminBaseView):
    """后台-玩法-拼团-创建拼团&编辑拼团&拼团活动详情获取"""
    @AdminBaseView.permission_required(
        [AdminBaseView.staff_permissions.ADMIN_PROMOTION])
    @use_args(
        {
            "product_id":
            fields.Integer(required=True, comment="商品id"),
            "price":
            fields.Decimal(required=True, comment="拼团价"),
            "from_datetime":
            fields.DateTime(required=True, comment="拼团活动开始时间"),
            "to_datetime":
            fields.DateTime(required=True, comment="拼团活动结束时间"),
            "groupon_type":
            fields.Integer(
                required=True,
                validate=[
                    validate.OneOf([GrouponType.NORMAL, GrouponType.MENTOR])
                ],
                comment="拼团活动类型 1:普通 2:老带新",
            ),
            "success_size":
            fields.Integer(required=True,
                           validate=[validate.Range(2, 50)],
                           comment="成团人数"),
            "quantity_limit":
            fields.Integer(
                required=True, validate=[validate.Range(0)], comment="购买数量上限"),
            "success_limit":
            fields.Integer(
                required=True, validate=[validate.Range(0)], comment="成团数量上限"),
            "attend_limit":
            fields.Integer(
                required=True, validate=[validate.Range(0)], comment="参团数量上限"),
            "success_valid_hour":
            fields.Integer(required=True,
                           validate=[validate.OneOf([24, 48])],
                           comment="开团有效时间"),
        },
        location="json")
    def post(self, request, args):
        success, msg = validate_groupon_period(args["product_id"],
                                               args["from_datetime"],
                                               args["to_datetime"])
        if not success:
            return self.send_fail(error_text=msg)
        product = get_product_by_id(self.current_shop.id,
                                    args.pop("product_id"),
                                    filter_delete=False)
        if not product:
            return self.send_fail(error_text="货品不存在")
        serializer = AdminGrouponCreateSerializer(data=args,
                                                  context={
                                                      "self": self,
                                                      "product": product
                                                  })
        if not serializer.is_valid():
            return self.send_error(error_message=serializer.errors,
                                   status_code=status.HTTP_400_BAD_REQUEST)
        groupon = serializer.save()
        publish_gruopon_interface(groupon)
        expire_groupon_interface(groupon)
        return self.send_success()

    @AdminBaseView.permission_required(
        [AdminBaseView.staff_permissions.ADMIN_PROMOTION])
    @use_args({"groupon_id": fields.String(required=True, comment="拼团id")},
              location="query")
    def get(self, request, args):
        success, groupon = get_shop_groupon_by_id(self.current_shop.id,
                                                  args["groupon_id"])
        if not success:
            return self.send_fail(error_text=groupon)
        serializer = AdminGrouponSerializer(groupon)
        return self.send_success(data=serializer.data)

    @AdminBaseView.permission_required(
        [AdminBaseView.staff_permissions.ADMIN_PROMOTION])
    @use_args(
        {
            "groupon_id":
            fields.Integer(required=True, comment="拼团id"),
            "product_id":
            fields.Integer(required=True, comment="商品id"),
            "price":
            fields.Decimal(required=True, comment="拼团价"),
            "from_datetime":
            fields.DateTime(required=True, comment="拼团活动开始时间"),
            "to_datetime":
            fields.DateTime(required=True, comment="拼团活动结束时间"),
            "groupon_type":
            fields.Integer(
                required=True,
                validate=[
                    validate.OneOf([GrouponType.NORMAL, GrouponType.MENTOR])
                ],
                comment="拼团活动类型 1:普通 2:老带新",
            ),
            "success_size":
            fields.Integer(required=True,
                           validate=[validate.Range(2, 50)],
                           comment="成团人数"),
            "quantity_limit":
            fields.Integer(required=True, comment="购买数量上限"),
            "success_limit":
            fields.Integer(required=True, comment="成团数量上限"),
            "attend_limit":
            fields.Integer(required=True, comment="参团数量上限"),
            "success_valid_hour":
            fields.Integer(required=True,
                           validate=[validate.OneOf([24, 48])],
                           comment="开团有效时间"),
        },
        location="json")
    def put(self, request, args):
        shop_id = self.current_shop.id
        product = get_product_by_id(shop_id,
                                    args.pop("product_id"),
                                    filter_delete=False)
        if not product:
            return self.send_fail(error_text="货品不存在")
        success, groupon = get_shop_groupon_by_id(shop_id,
                                                  args.pop("groupon_id"))
        if not success:
            return self.send_fail(error_text=groupon)
        elif groupon.status == GrouponStatus.ON:
            return self.send_fail(error_text="拼团活动正在启用中,请停用后再进行编辑")
        success, msg = validate_groupon_period(
            product.id,
            args["from_datetime"],
            args["to_datetime"],
            groupon_id=groupon.id,
        )
        if not success:
            return self.send_fail(error_text=msg)
        states = [
            GrouponAttendStatus.CREATED,
            GrouponAttendStatus.WAITTING,
            GrouponAttendStatus.SUCCEEDED,
            GrouponAttendStatus.FAILED,
        ]
        groupon_attends = list_groupon_attends_by_groupon(groupon, states)
        if groupon_attends:
            return self.send_fail(error_text="已经有用户参团, 拼团无法编辑")
        serializer = AdminGrouponCreateSerializer(groupon,
                                                  data=args,
                                                  context={
                                                      "self": self,
                                                      "product": product
                                                  })
        # 参数已在use_args中验证,此处不在验证
        serializer.is_valid()
        groupon = serializer.save()
        publish_gruopon_interface(groupon)
        expire_groupon_interface(groupon)
        return self.send_success()
    else:
        return jsonify({"errors": messages}), 422


@app.errorhandler(400)
def handle_error2(err):
    """Flask error handler."""
    messages = err.data.get("messages", ["Invalid request."])
    return jsonify({"_0": "Internal data mismatch", "errors": messages}), 400


@app.route('/', methods=['POST'])
@use_args({
    'sender': fields.UUID(required=True),
    'receiver': fields.UUID(required=True),
    'amount': fields.Decimal(required=True, validate=lambda x: x > 0)
})
def api_main(args):
    """Put json to DB to make a transaction.

    Example:
        {
            "sender": "40e6815d-b5c6-4896-987c-f30f3678f608",
            "receiver": "6ecd8c99-4036-403d-bf84-cf8400f67836",
            "amount": 1
        }

    Args:
        args (dict):
            sender (UUID): Person who sends money.
            receiver (UUID): Person who receives money.
Пример #7
0
class MallOrderView(MallBaseView):
    """商城端-提交订单&订单详情"""
    @use_args(
        {
            "cart_items":
            fields.Nested(
                {
                    "product_id": fields.Integer(required=True,
                                                 comment="货品ID"),
                    "quantity": fields.Decimal(required=True, comment="货品下单量"),
                    "price": fields.Decimal(required=True, comment="货品单价"),
                    "amount": fields.Decimal(required=True, comment="货品总金额"),
                },
                required=True,
                validate=[validate.Length(1)],
                many=True,
                unknown=True,
                comment="订单货品详情",
            ),
            "delivery_amount":
            fields.Decimal(required=True, comment="订单运费"),
            "total_amount":
            fields.Decimal(required=True, comment="订单总金额"),
            "address":
            fields.Nested(
                {
                    "name":
                    fields.String(required=True, comment="收货人姓名"),
                    "phone":
                    fields.String(required=True, comment="收货人手机号"),
                    "sex":
                    fields.Integer(
                        required=True,
                        validate=[
                            validate.OneOf([Sex.UNKNOWN, Sex.MALE, Sex.FEMALE])
                        ],
                        comment="性别",
                    ),
                    "address":
                    fields.String(required=True, comment="详细地址"),
                    "province":
                    fields.Integer(required=True, comment="省编码"),
                    "city":
                    fields.Integer(required=True, comment="市编码"),
                    "county":
                    fields.Integer(required=True, comment="区编码"),
                },
                required=True,
                unknown=True,
                comment="订单地址",
            ),
            "delivery_method":
            fields.Integer(
                required=True,
                validate=validate.OneOf([
                    OrderDeliveryMethod.HOME_DELIVERY,
                    OrderDeliveryMethod.CUSTOMER_PICK,
                ]),
                comment="配送方式:1:送货上门,2:客户自提",
            ),
            "delivery_period":
            fields.String(comment="自提时间段(仅自提必传),举例:今天 12:00~13:00"),
            "pay_type":
            fields.Integer(
                required=True,
                validate=validate.OneOf(
                    [OrderPayType.WEIXIN_JSAPI, OrderPayType.ON_DELIVERY]),
                comment="支付方式:1:微信支付,2:货到付款",
            ),
            "wx_openid":
            fields.String(comment="微信支付openid"),
            "remark":
            fields.String(validate=validate.Length(0, 30), comment="订单备注"),
            "groupon_attend_id":
            fields.Integer(comment="拼团活动参与id"),
        },
        location="json",
    )
    def post(self, request, args, shop_code):
        self._set_current_shop(request, shop_code)
        shop_id = self.current_shop.id
        user_id = self.current_user.id
        promotion_attend_id = args.pop("groupon_attend_id", 0)
        args["promotion_attend_id"] = promotion_attend_id
        args["promotion_type"] = 1 if promotion_attend_id else 0
        # 订单数据校验
        success, order_info = order_data_check(shop_id, user_id, args)
        if not success:
            return self.send_fail(error_text=order_info)
        promotion_attend = order_info.pop("promotion_attend")
        serializer = MallOrderCreateSerializer(data=order_info,
                                               context={
                                                   "promotion_attend":
                                                   promotion_attend,
                                                   "cart_items":
                                                   args.get("cart_items")
                                               })
        if not serializer.is_valid():
            return self.send_error(error_message=serializer.errors,
                                   status_code=status.HTTP_400_BAD_REQUEST)
        order = serializer.save()
        if order.pay_type == OrderPayType.WEIXIN_JSAPI:
            success, params = jsapi_params_interface(order, args["wx_openid"])
            if not success:
                return self.send_fail(error_obj=params)
            auto_cancel_order_interface(order.shop_id, order.id)
            return self.send_success(data=params, order_id=order.id)
        else:
            set_order_paid(order)
            # 订单提交成功微信提醒, 暂时只有普通订单才发送消息,且页面没有控制按钮
            if order.order_type == OrderType.NORMAL:
                # 测试省略
                pass
                # order_commit_tplmsg_interface(order.id)
            auto_validate_groupon_attend_interface(order.shop_id,
                                                   order.groupon_attend)
            return self.send_success(order_id=order.id)

    @use_args(
        {
            "order_id":
            fields.Integer(
                required=True, validate=[validate.Range(1)], comment="订单ID")
        },
        location="query")
    def get(self, request, args, shop_code):
        customer_ids = list_customer_ids_by_user_id_interface(
            self.current_user.id)
        if not customer_ids:
            return self.send_fail(error_text="订单不存在")
        ret, info = get_customer_order_with_detail_by_id(
            customer_ids, args.get("order_id"))
        if not ret:
            return self.send_fail(error_text=info)
        # 不需要顾客信息
        info.customer = None
        serializer = MallOrderSerializer(info)
        return self.send_success(data=serializer.data)
Пример #8
0
import lime_webserver.webserver as webserver
import logging
import webargs.fields as fields
from webargs.flaskparser import use_args
from ..endpoints import api

logger = logging.getLogger(__name__)

# This describes the schema for the payload when posting a new deal
# See https://webargs.readthedocs.io/en/latest/ for more info.
args = {
    "name": fields.String(required=True),
    "company": fields.Integer(required=True),
    "coworker": fields.Integer(required=True),
    "value": fields.Integer(missing=0),
    "probability": fields.Decimal(missing=0.0),
}


class Deal(webserver.LimeResource):
    """Resource for creating deals together with todos"""
    @use_args(args)
    def post(self, args):
        """Create a new deal, connect it to a company and a coworker
        and create a todo to follow up
        """

        # Create a unit of work that will handle creating, updating, and
        # connecting objects within a database transaction.
        uow = self.application.unit_of_work()
Пример #9
0
        analitics=data,
        ticker=ticker,
    )


map_price_column = {
    "open": "start",
    "high": "high",
    "low": "low",
    "close": "last",
}


@blue.route("/<ticker>/delta/")
@use_kwargs({
    "value":
    fields.Decimal(required=True),
    "type":
    fields.Str(
        required=True,
        validate=validate.OneOf(list(map_price_column)),
    ),
})
def ticker_delta(ticker, value, type):
    data = get_delta(ticker, value, map_price_column[type])
    return render_template(
        "delta.html",
        data=data,
        ticker=ticker,
    )
Пример #10
0
"""Заготовки на развитие, которые позволят управляль таблицей налогов."""
import aiohttp
from webargs import fields
from webargs.aiohttpparser import use_args


@use_args(
    {
        'rate': fields.Decimal(required=True),
        'state': fields.Str(required=True),
    },
    error_status_code=400,
)
async def create_tax(request, args):
    """Представление созадния записи с информацией о налогоах."""
    async with request.app['db'].acquire() as conn:
        return aiohttp.web.Response()


@use_args(
    {
        'rate': fields.Decimal(),
        'state': fields.Str(),
    },
    error_status_code=400,
)
async def update_tax(request, args):
    """Представление обновления записи в таблице с налогами."""
    async with request.app['db'].acquire() as conn:
        return aiohttp.web.Response()
Пример #11
0
        wallet.id,
        timestamp,
        order,
        limit,
    )
    ops_json = [op.to_json() for op in ops]

    return responses.success(ops_json)


@login_required
@use_kwargs(
    {
        "amount": fields.Decimal(
            places=2,
            required=True,
            validate=[validate.Range(min=decimal.Decimal("0.01"))]
        ),
    },
)
async def deposit(
        request: web.Request,
        amount: decimal.Decimal,
) -> web.Response:
    user_id = await authorized_userid(request)
    wallet = await get_wallet(request.app['db'], user_id)

    if wallet is None:
        return responses.not_found("Wallet does not exist.")

    op = await create_operation_deposit(request.app['db'], wallet.id, amount)
Пример #12
0
            "price": self.price,
            "store": self.store.name
        }

    @classmethod
    def get_all(cls) -> List["ItemModel"]:
        return cls.query.all()

    @classmethod
    def get_by_name(cls, name: str) -> "ItemModel":
        return cls.query.filter_by(name=name).first()

    def save_to_db(self) -> None:
        db.session.add(self)
        db.session.commit()

    def remove_from_db(self) -> None:
        db.session.delete(self)
        db.session.commit()


item_args = {
    "name":
    fields.Str(required=True),
    "price":
    fields.Decimal(required=True, places=2, validate=lambda x: x >= 0),
    "store_id":
    fields.Integer(required=True,
                   validate=lambda x: StoreModel.get_by_id(x) is not None)
}
Пример #13
0
@bp_html.route("/<ticker>/insider/<name>", methods=["GET"])
def insider_item(ticker, name):
    return render_template('insiders.tpl',
                           data=base.insider_item(ticker, name),
                           title=ticker)


@bp_html.route("/<ticker>/analytics", methods=["GET"])
@use_args({
    "date_from": fields.Date(required=True),
    "date_to": fields.Date(required=True)
})
def analytics(args, ticker):
    return render_template('analytics.tpl',
                           data=base.analytics(args, ticker),
                           title=ticker,
                           kwargs=args)


@bp_html.route("/<ticker>/delta", methods=["GET"])
@use_args({
    "value": fields.Decimal(required=True),
    "type": fields.Str(required=True)
})
def delta(args, ticker):
    return render_template('delta.tpl',
                           data=base.delta(args, ticker)[0],
                           title=ticker,
                           kwargs=args)
Пример #14
0
    'location': fields.Str(),

    # Default value when argument is missing
    'temperature_sensor': fields.Boolean(missing=False),
    'humidity_sensor': fields.Boolean(missing=False),
    'uptime': fields.Int()

}

device_name_args = {
    'device_name': fields.Str(required=True)
}

temperature_reading_args = {
    'device_id': fields.Str(required=True),
    'temperature': fields.Decimal(required=True),
    'timestamp': fields.String(required=True),
    'units': fields.String(required=True)
}

humidity_reading_args = {
    'device_id': fields.Str(required=True),
    'humidity': fields.Decimal(required=True),
    'timestamp': fields.String(required=True),
    'units': fields.String(required=True)
}

reading_args = {
    'device_id': fields.Str(required=True),
    'measurement': fields.Decimal(required=True),
    'timestamp': fields.String(required=True),
Пример #15
0
from ..services import calculate_total_amount

__all__ = ('calculate_amount', )


class CalculateResponse(Schema):
    """Схема для сериализации ответа."""

    amount_with_discount = fields.Number()
    total_amount = fields.Number()


@use_args(
    {
        'count': fields.Int(required=True),
        'price': fields.Decimal(required=True),
        'state': fields.Str(required=True),
    },
    error_status_code=400,
)
async def calculate_amount(request, args):
    """Представление для вычисления суммы с учетом скидки и с учетом налогов."""
    async with request.app['db'].acquire() as conn:
        try:
            amount_with_discount, total_amount = await calculate_total_amount(
                conn,
                args['state'],
                args['price'],
                args['count'],
            )
        except db.RecordNotFound:
Пример #16
0
class SuperShopView(SuperBaseView):
    """总后台-商铺-商铺创建&商铺详情"""
    @use_args(
        {
            "sign":
            fields.String(required=True, comment="加密认证"),
            "timestamp":
            fields.Integer(required=True, comment="时间戳"),
            "user_id":
            fields.Integer(required=True, comment="用户ID"),
            "shop_name":
            fields.String(required=True,
                          validate=[validate.Length(0, 128)],
                          comment="店铺名"),
            "shop_img":
            fields.String(
                required=True,
                validate=[validate.Length(0, 300)],
                comment="店铺logo",
            ),
            "shop_province":
            fields.Integer(required=True, comment="省份编码"),
            "shop_city":
            fields.Integer(required=True, comment="城市编码"),
            "shop_county":
            fields.Integer(required=True, comment="区份编码"),
            "shop_address":
            fields.String(
                required=True,
                validate=[validate.Length(0, 100)],
                comment="详细地址",
            ),
            "description":
            fields.String(required=True,
                          validate=[validate.Length(0, 200)],
                          comment="描述"),
            "inviter_phone":
            fields.String(
                required=False,
                validate=[validate.Length(0, 32)],
                comment="推荐人手机号",
            ),
            "longitude":
            fields.Decimal(
                required=False,
                data_key="lng",
                allow_none=True,
                validate=[validate.Range(-180, 180)],
                comment="经度",
            ),
            "latitude":
            fields.Decimal(
                required=False,
                data_key="lat",
                allow_none=True,
                validate=[validate.Range(-90, 90)],
                comment="纬度",
            ),
            "realname":
            fields.String(
                required=False,
                allow_none=True,
                validate=[validate.Length(0, 32)],
                comment="历史真实姓名",
            ),
        },
        location="json",
    )
    @SuperBaseView.validate_sign("sign", ("user_id", "timestamp"))
    def post(self, request, args):
        user = self._get_current_user(request)
        if not user:
            return self.send_error(status_code=status.HTTP_401_UNAUTHORIZED,
                                   error_message={"error_text": "用户未登录"})
        serializer = ShopCreateSerializer(data=args, context={'user': user})
        if not serializer.is_valid():
            return self.send_error(error_message=serializer.errors,
                                   status_code=status.HTTP_400_BAD_REQUEST)
        serializer.save()
        return self.send_success(data=serializer.data)

    @use_args(
        {
            "sign": fields.String(required=True, comment="加密认证"),
            "timestamp": fields.Integer(required=True, comment="时间戳"),
            "user_id": fields.Integer(required=True, comment="用户ID"),
            "shop_id": fields.Integer(required=True, comment="商铺id"),
        },
        location="query")
    @SuperBaseView.validate_sign("sign", ("user_id", "timestamp"))
    def get(self, request, args):
        user = self._get_current_user(request)
        if not user:
            return self.send_error(status_code=status.HTTP_401_UNAUTHORIZED,
                                   error_message={"error_text": "用户未登录"})
        shop_id = args.get("shop_id")
        shop = get_shop_by_shop_id(shop_id)
        if not shop:
            return self.send_fail(error_text="店铺不存在")
        shop = get_shop_by_shop_id(shop_id)
        super_admin_data = get_user_by_id_interface(shop.super_admin.id)
        shop.super_admin_data = super_admin_data
        serializer = SuperShopSerializer(shop)
        return self.send_success(data=serializer.data)