Skip to content

双语技术方案

语言版本选择

首次请求的,accept_language头部以zh开头为中文版,否则为英文版
设置cookie locale=zh|en

返回Response的中文

基础框架

# CommonBaseView, DriverBaseView
try:
    super().dispatch()
except SQLAlchemyError:
    return self.JsonErrorResponse('系统繁忙,稍后再试')
...

# LogoutJsonView
return JsonResponse({'code': 1, 'msg': '账号或密码错误,请检查后重新输入', 'data': None})
return JsonResponse({'code': 1, 'msg': '登录信息有误', 'data': None})
...

# LoginJsonView
return JsonResponse({'code': 0, 'msg': '登录成功', 'data': None})

# AjaxNoLoginView
def post(self, request, *args, **kwargs):
    return JsonResponse({
        "code": 100,
        "msg": '登录信息失效,请重新登录',
        "data": None
    }, status=200)
...

业务代码

# CustomizedView
is_enable = self.station.get('enable_customized', 0)
if is_enable == 0:
    return self.JsonErrorResponse('未启用个性化设置')
...
return self.JsonErrorResponse('获取失败,请重试')

# UpdateCustomizedView
if 'banners' in self.params and len(self.params['banners']) > 4:
    return self.JsonErrorResponse('最多只能有4张轮播图,请删除已有图片后再进行上传')
...

# PasswordChangeView
if pwd_old == pwd_new:
    return self.JsonErrorResponse('新密码与原密码相同')
...
return self.JsonErrorResponse('密码修改失败,请重试')

...(此处省略一万行)

抛出错误

抛出GMError

# TaxRuleGetView
if not tax_data:
    raise GmError(ErrCode.business_err, 'tax_id不存在')
if not addresses_data:
    raise GmError(ErrCode.business_err, '规则错误:不存在绑定商户')

# TaxRuleCreateView
if not address or not spu:
    raise GmError(ErrCode.business_err, '不能创建商户或商品为空的规则')

...(此处省略一万行)

抛出自定义Exception

# DistributeCenterStationView
if not sub_station_id.startswith('T'):
    raise Exception("station_id参数不合法。")
if action not in ['add', 'delete']:
    raise Exception("action参数必须为add或delete。")

# SaleCategoryDeleteView
if category['level'] == 1:
    if get_sale_category(upstream_id=category['_id']):
        raise ParamError('该一级分类下还有二级分类,请先删除')
else:
    if category.get('sku_ids', []):
        raise ParamError('该二级分类下还有sku,请先删除')

# StrikeBalanceUploadExcelView
if not form.is_valid():
    raise Exception('上传的文件无效')

...

解决方案

  1. 将自定义的Exception改为GmError

  2. 将非CommonBaseView返回错误的reponse改为raise GmError

  3. CommonBaseView、DriverBaseView、BaseView统一处理返回

``` from django.utils.translation import gettext_noop as _

def dispatch(request, args, *kwargs): if 'locale' not in request.COOKIES: accept_langurage = request.META.get('accept_langurage') first_lan = accept_langurage.split(',')[0] self.locale = 'zh_CN' if first_lan.startswith('zh) else 'en' else: self.locale = request.COOKIES['locale'] # http only

   try:
       super().dispatch(request)
   except SQLAlchemyError as e:
       response_obj = self.JsonErrorResponse(_(str(e)))
   ...
except GmError as e:
    response_obj = self.JsonErrorResponse(_(str(e)), code=e.err_code)

response.set_cookie('locale', self.locale)

```

微服返回错误

gm_server_order

# OrderCreateView
if field not in customer_info:
    raise GmError(1, 'customer参数缺少{}字段'.format(field))
...
res = check_state(cart_values)
if res:
    return self.JsonErrorResponse(msg='商品下架')

# PayOrderView
if pay_method not in list(PayMethod):
    raise GmError(ErrCode.param_err, 'pay_method格式不正确')

gm_server_merchandise

# Category1DeleteView
if db.categoryl2.find_one({'upstream_id': id, 'status': CategoryStatus.NORMAL}):
    return self.error_resp('该分类有下级元素,无法删除')

# Category2CreateView
if 'upstream_id' in self.params and ...:
    return self.error_resp('upstream_id不存在')

解决方案

rmi_client传accept_langurage

from common.log import threading_local

def _post(self, path, data):
    r = requests.post(url, data, headers={'accept_langurage': threading_local.locale})

返回数据的中文

# GetOrderFlow
def flow_type(self, flow):
    if isinstance(flow, PayFlow):
        if flow.pay_method == PayMethod.WX:
            return '微信支付'
    ...
def post(request)
    ...
    order_flow_map.setdefault(flow.order_no, []).append({
        'flow_type': self.flow_type(flow),
        ...
    formated_flow_map = {k: v for k, v in order_flow_map.items()}
    return self.JsonSuccessResponse(formated_flow_map)

解决方案:

from django.utils.translation import gettext as _

# GetOrderFlow
def flow_type(self, flow):
    if isinstance(flow, PayFlow):
        if flow.pay_method == PayMethod.WX:
            return _('微信支付')
    ...
def post(request)
    ...
    order_flow_map.setdefault(flow.order_no, []).append({
        'flow_type': self.flow_type(flow),
        ...
    formated_flow_map = {k: v for k, v in order_flow_map.items()}
    return self.JsonSuccessResponse(formated_flow_map)

导出文件

# station
SkuExportView 导出商品
OrderBatchExportView 导出订单
PurchaseTaskExportView 导出采购任务
RefundExportView 导出退货
TaxRuleExportView 导出税率
# ma
DailySearchExportView 每日订单导出
BillSearchView 导出对账单
BillView 导出商户报表
ReportDetailView 商户报表详情
IndexView 导出商户列表
ExportExcelView 导出订单明细
StrikeBalanceSearchView 导出冲账信息
CustomerGiftMoneyView 赠送金额流水
CustomerCashMoenyView 导出现金流水

DB数据的中文

service_time 默认服务时间
tbl_permission 权限
tbl_select_choose 各种选项
customized_info 观麦界面(SaaS默认使用)
freight 默认运费模版
wx_pay_info 观麦默认

解决方案:

service_time 
customized_info 
freight 
wx_pay_info 
tbl_permission 
tbl_select_choose 
tbl_permission. 不返回中文,前端做双语