683 lines
30 KiB
Go
683 lines
30 KiB
Go
package api
|
|
|
|
import (
|
|
"database/sql"
|
|
"encoding/json"
|
|
"io"
|
|
"log"
|
|
"net/http"
|
|
"strings"
|
|
"time"
|
|
"fmt"
|
|
)
|
|
|
|
type TemplatesAPI struct {
|
|
meta *sql.DB
|
|
marketing *sql.DB
|
|
}
|
|
|
|
func TemplatesHandler(meta, marketing *sql.DB) http.Handler {
|
|
api := &TemplatesAPI{meta: meta, marketing: marketing}
|
|
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
|
p := strings.TrimPrefix(r.URL.Path, "/api/templates")
|
|
if r.Method == http.MethodPost && p == "" {
|
|
api.createTemplate(w, r)
|
|
return
|
|
}
|
|
if r.Method == http.MethodGet && p == "" {
|
|
api.listTemplates(w, r)
|
|
return
|
|
}
|
|
if strings.HasPrefix(p, "/") {
|
|
id := strings.TrimPrefix(p, "/")
|
|
if r.Method == http.MethodGet {
|
|
api.getTemplate(w, r, id)
|
|
return
|
|
}
|
|
if r.Method == http.MethodPatch {
|
|
api.patchTemplate(w, r, id)
|
|
return
|
|
}
|
|
if r.Method == http.MethodDelete {
|
|
api.deleteTemplate(w, r, id)
|
|
return
|
|
}
|
|
if r.Method == http.MethodPost && strings.HasSuffix(p, "/validate") {
|
|
id = strings.TrimSuffix(id, "/validate")
|
|
api.validateTemplate(w, r, id)
|
|
return
|
|
}
|
|
}
|
|
fail(w, r, http.StatusNotFound, "not found")
|
|
})
|
|
}
|
|
|
|
type TemplatePayload struct {
|
|
Name string `json:"name"`
|
|
Datasource string `json:"datasource"`
|
|
MainTable string `json:"main_table"`
|
|
Fields []string `json:"fields"`
|
|
Filters map[string]interface{} `json:"filters"`
|
|
FileFormat string `json:"file_format"`
|
|
OwnerID uint64 `json:"owner_id"`
|
|
Visibility string `json:"visibility"`
|
|
}
|
|
|
|
func (a *TemplatesAPI) createTemplate(w http.ResponseWriter, r *http.Request) {
|
|
b, _ := io.ReadAll(r.Body)
|
|
var p TemplatePayload
|
|
json.Unmarshal(b, &p)
|
|
r = WithPayload(r, p)
|
|
uidStr := r.URL.Query().Get("userId")
|
|
if uidStr != "" {
|
|
var uid uint64
|
|
_, _ = fmt.Sscan(uidStr, &uid)
|
|
if uid > 0 { p.OwnerID = uid }
|
|
}
|
|
now := time.Now()
|
|
tplSQL := "INSERT INTO export_templates (name, datasource, main_table, fields_json, filters_json, file_format, visibility, owner_id, enabled, stats_enabled, last_validated_at, created_at, updated_at) VALUES (?,?,?,?,?,?,?,?,?,?,?,?,?)"
|
|
tplArgs := []interface{}{p.Name, p.Datasource, p.MainTable, toJSON(p.Fields), toJSON(p.Filters), p.FileFormat, p.Visibility, p.OwnerID, 1, 0, now, now, now}
|
|
log.Printf("trace_id=%s sql=%s args=%v", TraceIDFrom(r), tplSQL, tplArgs)
|
|
_, err := a.meta.Exec(tplSQL, tplArgs...)
|
|
if err != nil {
|
|
fail(w, r, http.StatusInternalServerError, err.Error())
|
|
return
|
|
}
|
|
writeJSON(w, r, http.StatusCreated, 0, "ok", nil)
|
|
}
|
|
|
|
func (a *TemplatesAPI) listTemplates(w http.ResponseWriter, r *http.Request) {
|
|
uidStr := r.URL.Query().Get("userId")
|
|
sqlText := "SELECT id,name,datasource,main_table,file_format,visibility,owner_id,enabled,last_validated_at,created_at,updated_at, COALESCE(JSON_LENGTH(fields_json),0) AS field_count, (SELECT COUNT(1) FROM export_jobs ej WHERE ej.template_id = export_templates.id) AS exec_count FROM export_templates"
|
|
args := []interface{}{}
|
|
if uidStr != "" {
|
|
sqlText += " WHERE owner_id IN (0, ?)"
|
|
args = append(args, uidStr)
|
|
}
|
|
sqlText += " ORDER BY updated_at DESC LIMIT 200"
|
|
rows, err := a.meta.Query(sqlText, args...)
|
|
if err != nil {
|
|
fail(w, r, http.StatusInternalServerError, err.Error())
|
|
return
|
|
}
|
|
defer rows.Close()
|
|
out := []map[string]interface{}{}
|
|
for rows.Next() {
|
|
var id uint64
|
|
var name, datasource, mainTable, fileFormat, visibility string
|
|
var ownerID uint64
|
|
var enabled int
|
|
var lastValidatedAt sql.NullTime
|
|
var createdAt, updatedAt time.Time
|
|
var fieldCount, execCount int64
|
|
err := rows.Scan(&id, &name, &datasource, &mainTable, &fileFormat, &visibility, &ownerID, &enabled, &lastValidatedAt, &createdAt, &updatedAt, &fieldCount, &execCount)
|
|
if err != nil {
|
|
fail(w, r, http.StatusInternalServerError, err.Error())
|
|
return
|
|
}
|
|
m := map[string]interface{}{"id": id, "name": name, "datasource": datasource, "main_table": mainTable, "file_format": fileFormat, "visibility": visibility, "owner_id": ownerID, "enabled": enabled == 1, "last_validated_at": lastValidatedAt.Time, "created_at": createdAt, "updated_at": updatedAt, "field_count": fieldCount, "exec_count": execCount}
|
|
out = append(out, m)
|
|
}
|
|
ok(w, r, out)
|
|
}
|
|
|
|
func (a *TemplatesAPI) getTemplate(w http.ResponseWriter, r *http.Request, id string) {
|
|
row := a.meta.QueryRow("SELECT id,name,datasource,main_table,fields_json,filters_json,file_format,visibility,owner_id,enabled,explain_score,last_validated_at,created_at,updated_at FROM export_templates WHERE id=?", id)
|
|
var m = map[string]interface{}{}
|
|
var tid uint64
|
|
var name, datasource, mainTable, fileFormat, visibility string
|
|
var ownerID uint64
|
|
var enabled int
|
|
var explainScore sql.NullInt64
|
|
var lastValidatedAt sql.NullTime
|
|
var createdAt, updatedAt time.Time
|
|
var fields, filters []byte
|
|
err := row.Scan(&tid, &name, &datasource, &mainTable, &fields, &filters, &fileFormat, &visibility, &ownerID, &enabled, &explainScore, &lastValidatedAt, &createdAt, &updatedAt)
|
|
if err != nil {
|
|
fail(w, r, http.StatusNotFound, "not found")
|
|
return
|
|
}
|
|
m["id"] = tid
|
|
m["name"] = name
|
|
m["datasource"] = datasource
|
|
m["main_table"] = mainTable
|
|
m["file_format"] = fileFormat
|
|
m["visibility"] = visibility
|
|
m["owner_id"] = ownerID
|
|
m["enabled"] = enabled == 1
|
|
m["explain_score"] = explainScore.Int64
|
|
m["last_validated_at"] = lastValidatedAt.Time
|
|
m["created_at"] = createdAt
|
|
m["updated_at"] = updatedAt
|
|
m["fields"] = fromJSON(fields)
|
|
m["filters"] = fromJSON(filters)
|
|
ok(w, r, m)
|
|
}
|
|
|
|
func (a *TemplatesAPI) patchTemplate(w http.ResponseWriter, r *http.Request, id string) {
|
|
b, _ := io.ReadAll(r.Body)
|
|
var p map[string]interface{}
|
|
json.Unmarshal(b, &p)
|
|
set := []string{}
|
|
args := []interface{}{}
|
|
for k, v := range p {
|
|
switch k {
|
|
case "name", "visibility", "file_format":
|
|
set = append(set, k+"=?")
|
|
args = append(args, v)
|
|
case "fields":
|
|
set = append(set, "fields_json=?")
|
|
args = append(args, toJSON(v))
|
|
case "filters":
|
|
set = append(set, "filters_json=?")
|
|
args = append(args, toJSON(v))
|
|
case "enabled":
|
|
set = append(set, "enabled=?")
|
|
if v.(bool) {
|
|
args = append(args, 1)
|
|
} else {
|
|
args = append(args, 0)
|
|
}
|
|
}
|
|
}
|
|
if len(set) == 0 {
|
|
fail(w, r, http.StatusBadRequest, "no patch")
|
|
return
|
|
}
|
|
// ensure updated_at
|
|
set = append(set, "updated_at=?")
|
|
args = append(args, time.Now(), id)
|
|
_, err := a.meta.Exec("UPDATE export_templates SET "+strings.Join(set, ",")+" WHERE id= ?", args...)
|
|
if err != nil {
|
|
fail(w, r, http.StatusInternalServerError, err.Error())
|
|
return
|
|
}
|
|
ok(w, r, nil)
|
|
}
|
|
|
|
func (a *TemplatesAPI) deleteTemplate(w http.ResponseWriter, r *http.Request, id string) {
|
|
var cnt int64
|
|
row := a.meta.QueryRow("SELECT COUNT(1) FROM export_jobs WHERE template_id=?", id)
|
|
_ = row.Scan(&cnt)
|
|
if cnt > 0 {
|
|
fail(w, r, http.StatusBadRequest, "template in use")
|
|
return
|
|
}
|
|
_, err := a.meta.Exec("DELETE FROM export_templates WHERE id= ?", id)
|
|
if err != nil {
|
|
fail(w, r, http.StatusInternalServerError, err.Error())
|
|
return
|
|
}
|
|
ok(w, r, nil)
|
|
}
|
|
|
|
func (a *TemplatesAPI) validateTemplate(w http.ResponseWriter, r *http.Request, id string) {
|
|
row := a.meta.QueryRow("SELECT main_table, fields_json, filters_json FROM export_templates WHERE id=?", id)
|
|
var main string
|
|
var fields, filters []byte
|
|
err := row.Scan(&main, &fields, &filters)
|
|
if err != nil {
|
|
fail(w, r, http.StatusNotFound, "not found")
|
|
return
|
|
}
|
|
var fs []string
|
|
var fl map[string]interface{}
|
|
json.Unmarshal(fields, &fs)
|
|
json.Unmarshal(filters, &fl)
|
|
ok(w, r, nil)
|
|
}
|
|
|
|
func toJSON(v interface{}) []byte {
|
|
b, _ := json.Marshal(v)
|
|
return b
|
|
}
|
|
|
|
func fromJSON(b []byte) interface{} {
|
|
var v interface{}
|
|
json.Unmarshal(b, &v)
|
|
return v
|
|
}
|
|
|
|
func Whitelist() map[string]bool {
|
|
m := map[string]bool{
|
|
"order.order_number": true,
|
|
"order.key": true,
|
|
"order.creator": true,
|
|
"order.out_trade_no": true,
|
|
"order.type": true,
|
|
"order.status": true,
|
|
"order.account": true,
|
|
"order.product_id": true,
|
|
"order.reseller_id": true,
|
|
"order.plan_id": true,
|
|
"order.key_batch_id": true,
|
|
"order.code_batch_id": true,
|
|
"order.pay_type": true,
|
|
"order.pay_status": true,
|
|
"order.use_coupon": true,
|
|
"order.deliver_status": true,
|
|
"order.expire_time": true,
|
|
"order.recharge_time": true,
|
|
"order.contract_price": true,
|
|
"order.num": true,
|
|
"order.total": true,
|
|
"order.pay_amount": true,
|
|
"order.create_time": true,
|
|
"order.update_time": true,
|
|
"order.official_price": true,
|
|
"order.merchant_name": true,
|
|
"order.activity_name": true,
|
|
"order.goods_name": true,
|
|
"order.pay_time": true,
|
|
"order.coupon_id": true,
|
|
"order.discount_amount": true,
|
|
"order.supplier_product_name": true,
|
|
"order.is_inner": true,
|
|
"order.icon": true,
|
|
"order.cost_price": true,
|
|
"order.success_num": true,
|
|
"order.is_reset": true,
|
|
"order.is_retry": true,
|
|
"order.channel": true,
|
|
"order.is_store": true,
|
|
"order.trace_id": true,
|
|
"order.out_order_no": true,
|
|
"order.next_retry_time": true,
|
|
"order.recharge_suc_time": true,
|
|
"order.supplier_id": true,
|
|
"order.supplier_product_id": true,
|
|
"order.merchant_id": true,
|
|
"order.goods_id": true,
|
|
"order.activity_id": true,
|
|
"order.key_batch_name": true,
|
|
"order_detail.plan_title": true,
|
|
"order_detail.reseller_name": true,
|
|
"order_detail.product_name": true,
|
|
"order_detail.show_url": true,
|
|
"order_detail.official_price": true,
|
|
"order_detail.cost_price": true,
|
|
"order_detail.create_time": true,
|
|
"order_detail.update_time": true,
|
|
"order_cash.channel": true,
|
|
"order_cash.order_no": true,
|
|
"order_cash.trade_no": true,
|
|
"order_cash.wechat_detail_id": true,
|
|
"order_cash.denomination": true,
|
|
"order_cash.account": true,
|
|
"order_cash.receive_name": true,
|
|
"order_cash.app_id": true,
|
|
"order_cash.cash_activity_id": true,
|
|
"order_cash.receive_status": true,
|
|
"order_cash.receive_time": true,
|
|
"order_cash.success_time": true,
|
|
"order_cash.cash_packet_id": true,
|
|
"order_cash.cash_id": true,
|
|
"order_cash.amount": true,
|
|
"order_cash.activity_id": true,
|
|
"order_cash.goods_id": true,
|
|
"order_cash.merchant_id": true,
|
|
"order_cash.supplier_id": true,
|
|
"order_cash.user_id": true,
|
|
"order_cash.status": true,
|
|
"order_cash.expire_time": true,
|
|
"order_cash.create_time": true,
|
|
"order_cash.update_time": true,
|
|
"order_cash.version": true,
|
|
"order_cash.is_confirm": true,
|
|
"order_voucher.channel": true,
|
|
"order_voucher.channel_activity_id": true,
|
|
"order_voucher.channel_voucher_id": true,
|
|
"order_voucher.status": true,
|
|
"order_voucher.receive_mode": true,
|
|
"order_voucher.grant_time": true,
|
|
"order_voucher.usage_time": true,
|
|
"order_voucher.refund_time": true,
|
|
"order_voucher.status_modify_time": true,
|
|
"order_voucher.overdue_time": true,
|
|
"order_voucher.refund_amount": true,
|
|
"order_voucher.official_price": true,
|
|
"order_voucher.out_biz_no": true,
|
|
"order_voucher.account_no": true,
|
|
"plan.id": true,
|
|
"plan.title": true,
|
|
"plan.status": true,
|
|
"plan.begin_time": true,
|
|
"plan.end_time": true,
|
|
"key_batch.id": true,
|
|
"key_batch.batch_name": true,
|
|
"key_batch.bind_object": true,
|
|
"key_batch.quantity": true,
|
|
"key_batch.stock": true,
|
|
"key_batch.begin_time": true,
|
|
"key_batch.end_time": true,
|
|
"code_batch.id": true,
|
|
"code_batch.title": true,
|
|
"code_batch.status": true,
|
|
"code_batch.begin_time": true,
|
|
"code_batch.end_time": true,
|
|
"code_batch.quantity": true,
|
|
"code_batch.usage": true,
|
|
"code_batch.stock": true,
|
|
"voucher.channel": true,
|
|
"voucher.channel_activity_id": true,
|
|
"voucher.price": true,
|
|
"voucher.balance": true,
|
|
"voucher.used_amount": true,
|
|
"voucher.denomination": true,
|
|
"voucher_batch.channel_activity_id": true,
|
|
"voucher_batch.temp_no": true,
|
|
"voucher_batch.provider": true,
|
|
"voucher_batch.weight": true,
|
|
"merchant_key_send.merchant_id": true,
|
|
"merchant_key_send.out_biz_no": true,
|
|
"merchant_key_send.key": true,
|
|
"merchant_key_send.status": true,
|
|
"merchant_key_send.usage_time": true,
|
|
"merchant_key_send.create_time": true,
|
|
"order_digit.order_no": true,
|
|
"order_digit.card_no": true,
|
|
"order_digit.account": true,
|
|
"order_digit.goods_id": true,
|
|
"order_digit.merchant_id": true,
|
|
"order_digit.supplier_id": true,
|
|
"order_digit.activity_id": true,
|
|
"order_digit.user_id": true,
|
|
"order_digit.success_time": true,
|
|
"order_digit.supplier_product_no": true,
|
|
"order_digit.order_type": true,
|
|
"order_digit.end_time": true,
|
|
"order_digit.create_time": true,
|
|
"order_digit.update_time": true,
|
|
"order_digit.code": true,
|
|
"order_digit.sms_channel": true,
|
|
"goods_voucher_batch.channel_batch_no": true,
|
|
"goods_voucher_batch.voucher_subject_id": true,
|
|
"goods_voucher_batch.id": true,
|
|
"goods_voucher_batch.goods_voucher_id": true,
|
|
"goods_voucher_batch.supplier_id": true,
|
|
"goods_voucher_batch.temp_no": true,
|
|
"goods_voucher_batch.index": true,
|
|
"goods_voucher_batch.create_time": true,
|
|
"goods_voucher_batch.update_time": true,
|
|
"goods_voucher_subject_config.id": true,
|
|
"goods_voucher_subject_config.name": true,
|
|
"goods_voucher_subject_config.type": true,
|
|
"goods_voucher_subject_config.create_time": true,
|
|
"merchant.id": true,
|
|
"merchant.name": true,
|
|
"merchant.user_id": true,
|
|
"merchant.merchant_no": true,
|
|
"merchant.subject": true,
|
|
"merchant.third_party": true,
|
|
"merchant.status": true,
|
|
"merchant.balance": true,
|
|
"merchant.total_consumption": true,
|
|
"merchant.contact_name": true,
|
|
"merchant.contact_phone": true,
|
|
"merchant.contact_email": true,
|
|
"merchant.create_time": true,
|
|
"merchant.update_time": true,
|
|
"activity.id": true,
|
|
"activity.name": true,
|
|
"activity.user_id": true,
|
|
"activity.merchant_id": true,
|
|
"activity.user_name": true,
|
|
"activity.activity_no": true,
|
|
"activity.status": true,
|
|
"activity.key_total_num": true,
|
|
"activity.key_generate_num": true,
|
|
"activity.key_usable_num": true,
|
|
"activity.domain_url": true,
|
|
"activity.theme_login_id": true,
|
|
"activity.theme_list_id": true,
|
|
"activity.theme_verify_id": true,
|
|
"activity.settlement_type": true,
|
|
"activity.key_expire_type": true,
|
|
"activity.key_valid_day": true,
|
|
"activity.key_begin_time": true,
|
|
"activity.key_end_time": true,
|
|
"activity.key_style": true,
|
|
"activity.begin_time": true,
|
|
"activity.end_time": true,
|
|
"activity.is_retry": true,
|
|
"activity.create_time": true,
|
|
"activity.update_time": true,
|
|
"activity.discard_time": true,
|
|
"activity.delete_time": true,
|
|
"activity.auto_charge": true,
|
|
"activity.stock": true,
|
|
"activity.approval_trade_no": true,
|
|
"activity.amount": true,
|
|
"activity.channels": true,
|
|
"activity.key_begin": true,
|
|
"activity.key_end": true,
|
|
"activity.key_unit": true,
|
|
"activity.key_pay_button_text": true,
|
|
"activity.goods_pay_button_text": true,
|
|
"activity.is_open_db_transaction": true,
|
|
"activity.bank_tag": true,
|
|
}
|
|
return m
|
|
}
|
|
|
|
func FieldLabels() map[string]string {
|
|
return map[string]string{
|
|
"order.order_number": "订单编号",
|
|
"order.key": "KEY",
|
|
"order.creator": "创建者ID",
|
|
"order.out_trade_no": "支付流水号",
|
|
"order.type": "订单类型",
|
|
"order.status": "订单状态",
|
|
"order.account": "账号",
|
|
"order.product_id": "商品ID",
|
|
"order.reseller_id": "分销商ID",
|
|
"order.plan_id": "计划ID",
|
|
"order.key_batch_id": "KEY批次ID",
|
|
"order.code_batch_id": "兑换批次ID",
|
|
"order.pay_type": "支付方式",
|
|
"order.pay_status": "支付状态",
|
|
"order.use_coupon": "是否使用优惠券",
|
|
"order.deliver_status": "投递状态",
|
|
"order.expire_time": "过期处理时间",
|
|
"order.recharge_time": "充值时间",
|
|
"order.contract_price": "合同单价",
|
|
"order.num": "数量",
|
|
"order.total": "总金额",
|
|
"order.pay_amount": "支付金额",
|
|
"order.create_time": "创建时间",
|
|
"order.update_time": "更新时间",
|
|
"order.official_price": "官方价",
|
|
"order.merchant_name": "分销商名称",
|
|
"order.activity_name": "活动名称",
|
|
"order.goods_name": "商品名称",
|
|
"order.pay_time": "支付时间",
|
|
"order.coupon_id": "优惠券ID",
|
|
"order.discount_amount": "优惠金额",
|
|
"order.supplier_product_name": "供应商产品名称",
|
|
"order.is_inner": "内部供应商订单",
|
|
"order.icon": "订单图片",
|
|
"order.cost_price": "成本价",
|
|
"order.success_num": "到账数量",
|
|
"order.is_reset": "是否重置",
|
|
"order.is_retry": "是否重试",
|
|
"order.channel": "支付渠道",
|
|
"order.is_store": "是否退还库存",
|
|
"order.trace_id": "TraceID",
|
|
"order.out_order_no": "外部订单号",
|
|
"order.next_retry_time": "下次重试时间",
|
|
"order.recharge_suc_time": "充值成功时间",
|
|
"order.supplier_id": "供应商ID",
|
|
"order.supplier_product_id": "供应商产品ID",
|
|
"order.merchant_id": "分销商ID",
|
|
"order.goods_id": "商品ID",
|
|
"order.activity_id": "活动ID",
|
|
"order.key_batch_name": "key批次名称",
|
|
"order_detail.plan_title": "计划标题",
|
|
"order_detail.reseller_name": "分销商名称",
|
|
"order_detail.product_name": "商品名称",
|
|
"order_detail.show_url": "商品图片URL",
|
|
"order_detail.official_price": "官方价",
|
|
"order_detail.cost_price": "成本价",
|
|
"order_detail.create_time": "创建时间",
|
|
"order_detail.update_time": "更新时间",
|
|
"order_cash.order_no": "订单号",
|
|
"order_cash.trade_no": "交易号",
|
|
"order_cash.wechat_detail_id": "微信明细单号",
|
|
"order_cash.channel": "渠道",
|
|
"order_cash.denomination": "红包面额",
|
|
"order_cash.account": "领取账号",
|
|
"order_cash.receive_name": "真实姓名",
|
|
"order_cash.app_id": "转账AppID",
|
|
"order_cash.cash_activity_id": "红包批次号",
|
|
"order_cash.receive_status": "领取状态",
|
|
"order_cash.receive_time": "拆红包时间",
|
|
"order_cash.success_time": "成功时间",
|
|
"order_cash.cash_packet_id": "红包ID",
|
|
"order_cash.cash_id": "红包规则ID",
|
|
"order_cash.amount": "红包额度",
|
|
"order_cash.activity_id": "活动ID",
|
|
"order_cash.goods_id": "商品ID",
|
|
"order_cash.merchant_id": "分销商ID",
|
|
"order_cash.supplier_id": "供应商ID",
|
|
"order_cash.user_id": "创建者ID",
|
|
"order_cash.status": "状态",
|
|
"order_cash.expire_time": "过期时间",
|
|
"order_cash.create_time": "创建时间",
|
|
"order_cash.update_time": "更新时间",
|
|
"order_cash.version": "版本",
|
|
"order_cash.is_confirm": "是否确认",
|
|
"order_voucher.channel": "渠道",
|
|
"order_voucher.channel_activity_id": "渠道立减金批次",
|
|
"order_voucher.channel_voucher_id": "渠道立减金ID",
|
|
"order_voucher.status": "状态",
|
|
"order_voucher.receive_mode": "领取方式",
|
|
"order_voucher.grant_time": "领取时间",
|
|
"order_voucher.usage_time": "核销时间",
|
|
"order_voucher.refund_time": "退款时间",
|
|
"order_voucher.status_modify_time": "状态更新时间",
|
|
"order_voucher.overdue_time": "过期时间",
|
|
"order_voucher.refund_amount": "退款金额",
|
|
"order_voucher.official_price": "官方价",
|
|
"order_voucher.out_biz_no": "外部业务号",
|
|
"order_voucher.account_no": "账户号",
|
|
"plan.id": "计划ID",
|
|
"plan.title": "计划标题",
|
|
"plan.status": "状态",
|
|
"plan.begin_time": "开始时间",
|
|
"plan.end_time": "结束时间",
|
|
"key_batch.id": "批次ID",
|
|
"key_batch.batch_name": "批次名称",
|
|
"key_batch.bind_object": "绑定对象",
|
|
"key_batch.quantity": "发放数量",
|
|
"key_batch.stock": "剩余库存",
|
|
"key_batch.begin_time": "开始时间",
|
|
"key_batch.end_time": "结束时间",
|
|
"code_batch.id": "兑换批次ID",
|
|
"code_batch.title": "标题",
|
|
"code_batch.status": "状态",
|
|
"code_batch.begin_time": "开始时间",
|
|
"code_batch.end_time": "结束时间",
|
|
"code_batch.quantity": "数量",
|
|
"code_batch.usage": "使用数",
|
|
"code_batch.stock": "库存",
|
|
"voucher.channel": "渠道",
|
|
"voucher.channel_activity_id": "渠道批次号",
|
|
"voucher.price": "合同单价",
|
|
"voucher.balance": "剩余额度",
|
|
"voucher.used_amount": "已用额度",
|
|
"voucher.denomination": "面额",
|
|
"voucher_batch.channel_activity_id": "渠道批次号",
|
|
"voucher_batch.temp_no": "模板编号",
|
|
"voucher_batch.provider": "服务商",
|
|
"voucher_batch.weight": "权重",
|
|
"merchant_key_send.merchant_id": "商户ID",
|
|
"merchant_key_send.out_biz_no": "商户业务号",
|
|
"merchant_key_send.key": "券码",
|
|
"merchant_key_send.status": "状态",
|
|
"merchant_key_send.usage_time": "核销时间",
|
|
"merchant_key_send.create_time": "创建时间",
|
|
"order_digit.order_no": "订单号",
|
|
"order_digit.card_no": "卡号",
|
|
"order_digit.account": "充值账号",
|
|
"order_digit.goods_id": "商品ID",
|
|
"order_digit.merchant_id": "分销商ID",
|
|
"order_digit.supplier_id": "供应商ID",
|
|
"order_digit.activity_id": "活动ID",
|
|
"order_digit.user_id": "创建者ID",
|
|
"order_digit.success_time": "到账时间",
|
|
"order_digit.supplier_product_no": "供应商产品编码",
|
|
"order_digit.order_type": "订单类型",
|
|
"order_digit.end_time": "卡密有效期",
|
|
"order_digit.create_time": "创建时间",
|
|
"order_digit.update_time": "更新时间",
|
|
"order_digit.code": "验证码",
|
|
"order_digit.sms_channel": "短信渠道",
|
|
"goods_voucher_batch.channel_batch_no": "渠道批次号",
|
|
"goods_voucher_batch.voucher_subject_id": "主体配置ID",
|
|
"goods_voucher_batch.id": "ID",
|
|
"goods_voucher_batch.goods_voucher_id": "立减金ID",
|
|
"goods_voucher_batch.supplier_id": "供应商ID",
|
|
"goods_voucher_batch.temp_no": "模板编号",
|
|
"goods_voucher_batch.index": "权重",
|
|
"goods_voucher_batch.create_time": "创建时间",
|
|
"goods_voucher_batch.update_time": "更新时间",
|
|
"goods_voucher_subject_config.id": "主体配置ID",
|
|
"goods_voucher_subject_config.name": "主体名称",
|
|
"goods_voucher_subject_config.type": "主体类型",
|
|
"goods_voucher_subject_config.create_time": "创建时间",
|
|
"merchant.id": "客户ID",
|
|
"merchant.name": "客户名称",
|
|
"merchant.user_id": "用户中心ID",
|
|
"merchant.merchant_no": "商户编码",
|
|
"merchant.subject": "客户主体",
|
|
"merchant.third_party": "来源类型",
|
|
"merchant.status": "状态",
|
|
"merchant.balance": "客户余额",
|
|
"merchant.total_consumption": "累计消费",
|
|
"merchant.contact_name": "联系人名称",
|
|
"merchant.contact_phone": "联系人电话",
|
|
"merchant.contact_email": "联系人Email",
|
|
"merchant.create_time": "创建时间",
|
|
"merchant.update_time": "编辑时间",
|
|
"activity.id": "活动ID",
|
|
"activity.name": "活动名称",
|
|
"activity.user_id": "创建者ID",
|
|
"activity.merchant_id": "客户ID",
|
|
"activity.user_name": "创建者名称",
|
|
"activity.activity_no": "活动编号",
|
|
"activity.status": "状态",
|
|
"activity.key_total_num": "Key码总量",
|
|
"activity.key_generate_num": "Key码已生成数量",
|
|
"activity.key_usable_num": "Key可使用次数",
|
|
"activity.domain_url": "域名",
|
|
"activity.theme_login_id": "登录模版ID",
|
|
"activity.theme_list_id": "列表模版ID",
|
|
"activity.theme_verify_id": "验证模版ID",
|
|
"activity.settlement_type": "结算方式",
|
|
"activity.key_expire_type": "Key有效期类型",
|
|
"activity.key_valid_day": "有效天数",
|
|
"activity.key_begin_time": "Key有效开始时间",
|
|
"activity.key_end_time": "Key有效结束时间",
|
|
"activity.key_style": "Key样式",
|
|
"activity.begin_time": "开始时间",
|
|
"activity.end_time": "结束时间",
|
|
"activity.is_retry": "是否自动重试",
|
|
"activity.create_time": "创建时间",
|
|
"activity.update_time": "修改时间",
|
|
"activity.discard_time": "作废时间",
|
|
"activity.delete_time": "删除时间",
|
|
"activity.auto_charge": "是否充值到账",
|
|
"activity.stock": "已使用库存",
|
|
"activity.approval_trade_no": "审批交易号",
|
|
"activity.amount": "支付金额",
|
|
"activity.channels": "支付渠道",
|
|
"activity.key_begin": "开始月份",
|
|
"activity.key_end": "截止月份",
|
|
"activity.key_unit": "时间单位",
|
|
"activity.key_pay_button_text": "Key支付按钮文本",
|
|
"activity.goods_pay_button_text": "商品支付按钮文本",
|
|
"activity.is_open_db_transaction": "是否开启事务",
|
|
"activity.bank_tag": "银行标识",
|
|
}
|
|
}
|