优化了部分ui
This commit is contained in:
@@ -95,6 +95,7 @@ module.exports = {
|
||||
vnVerifCodePath: '/public/vn_verif_code',
|
||||
vnVerifyLoginCodePath: '/vn/verify_login_code',
|
||||
vnBindUrlPath: '/vn/bind_url',
|
||||
vnBindInfoPath: '/vn/bind_info',
|
||||
vnBackPath: '/vn/back',
|
||||
clientSource: 'ct-client',
|
||||
deviceId: '-',
|
||||
|
||||
@@ -1,13 +1,13 @@
|
||||
{
|
||||
"syncFromCreatedAt": "2026-05-02T10:53:28.550Z",
|
||||
"lastRunStartedAt": "2026-05-03T15:01:47.533Z",
|
||||
"lastRunFinishedAt": "2026-05-03T15:01:48.438Z",
|
||||
"lastRunStartedAt": "2026-05-03T15:58:17.921Z",
|
||||
"lastRunFinishedAt": "2026-05-03T15:58:18.685Z",
|
||||
"lastRunStatus": "success",
|
||||
"lastErrorMessage": "",
|
||||
"fetchedCount": 40,
|
||||
"syncedCount": 0,
|
||||
"ignoredCount": 40,
|
||||
"lastOrderCreatedAt": "2026-05-03T15:01:23.000Z",
|
||||
"syncedCount": 1,
|
||||
"ignoredCount": 39,
|
||||
"lastOrderCreatedAt": "2026-05-03T15:57:42.000Z",
|
||||
"watchMode": "normal",
|
||||
"watchOrders": []
|
||||
}
|
||||
|
||||
@@ -1,4 +1,30 @@
|
||||
{
|
||||
"enabled": true,
|
||||
"items": []
|
||||
"items": [
|
||||
{
|
||||
"id": "套装-浪漫天命",
|
||||
"enabled": true,
|
||||
"priority": 100,
|
||||
"provider": "khhao",
|
||||
"platform": "kuaishou",
|
||||
"shopId": "4269276762",
|
||||
"internalSkuCode": "套装-浪漫天命",
|
||||
"internalSkuName": "测试1",
|
||||
"externalSkuCode": "830",
|
||||
"externalItemId": "830",
|
||||
"externalSkuName": "测试1",
|
||||
"resolvedSkuName": "测试1",
|
||||
"cloudSourceKey": "default",
|
||||
"cloudSkuId": 28,
|
||||
"cloudSkuName": "套装-浪漫天命",
|
||||
"vnKey": "1",
|
||||
"autoBuyEnabled": true,
|
||||
"minAssetReserve": 0,
|
||||
"autoReturnNumberAfterDispatch": true,
|
||||
"autoConsumeAfterDispatch": true,
|
||||
"kuaishouConsumeShopId": "4269276762",
|
||||
"kuaishouConsumeShopName": "稚嫩游戏交易店",
|
||||
"notes": "从 khhao 订单 2612300173165561 导入"
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
@@ -156,12 +156,22 @@ function normalizeKuaishouCloudFlow(value) {
|
||||
},
|
||||
binding: {
|
||||
prepareStatus: String(binding.prepareStatus || 'pending').trim() || 'pending',
|
||||
cloudSourceKey: String(binding.cloudSourceKey || '').trim(),
|
||||
skuId: Number(binding.skuId || 0) || 0,
|
||||
skuName: String(binding.skuName || '').trim(),
|
||||
vnKey: String(binding.vnKey || '').trim(),
|
||||
vnId: Number(binding.vnId || 0) || 0,
|
||||
vnPhone: String(binding.vnPhone || '').trim(),
|
||||
bindUrl: String(binding.bindUrl || '').trim(),
|
||||
bindPreparedAt: binding.bindPreparedAt || null,
|
||||
},
|
||||
consume: {
|
||||
status: String(consume.status || 'pending').trim() || 'pending',
|
||||
shopId: String(consume.shopId || '').trim(),
|
||||
shopName: String(consume.shopName || '').trim(),
|
||||
autoConsumeEnabled: consume.autoConsumeEnabled === true,
|
||||
consumedAt: consume.consumedAt || null,
|
||||
errorMessage: String(consume.errorMessage || '').trim(),
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
@@ -115,6 +115,7 @@ export {}
|
||||
* vnVerifCodePath: string
|
||||
* vnVerifyLoginCodePath: string
|
||||
* vnBindUrlPath: string
|
||||
* vnBindInfoPath: string
|
||||
* vnBackPath: string
|
||||
* publicKeyPem: string
|
||||
* clientSource: string
|
||||
|
||||
Vendored
+3
@@ -22,6 +22,9 @@ declare module 'vue' {
|
||||
ElFormItem: typeof import('element-plus/es')['ElFormItem']
|
||||
ElInput: typeof import('element-plus/es')['ElInput']
|
||||
ElInputNumber: typeof import('element-plus/es')['ElInputNumber']
|
||||
ElOption: typeof import('element-plus/es')['ElOption']
|
||||
ElSelect: typeof import('element-plus/es')['ElSelect']
|
||||
ElSwitch: typeof import('element-plus/es')['ElSwitch']
|
||||
ElTabPane: typeof import('element-plus/es')['ElTabPane']
|
||||
ElTabs: typeof import('element-plus/es')['ElTabs']
|
||||
RouterLink: typeof import('vue-router')['RouterLink']
|
||||
|
||||
@@ -912,80 +912,104 @@ onMounted(loadConfigs)
|
||||
<span>核销店铺:{{ getConsumeShopSummary(item) }}</span>
|
||||
</div>
|
||||
|
||||
<div v-else class="binding-grid">
|
||||
<label class="field-block">
|
||||
<span>内部 SKU</span>
|
||||
<input v-model="item.internalSkuCode" class="text-input" maxlength="80" placeholder="必填,用于生成任务" />
|
||||
</label>
|
||||
<label class="field-block field-wide">
|
||||
<span>内部商品名</span>
|
||||
<input v-model="item.internalSkuName" class="text-input" maxlength="120" placeholder="展示用,可选但建议填" />
|
||||
</label>
|
||||
<label class="field-block">
|
||||
<span>优先级</span>
|
||||
<input v-model.number="item.priority" class="text-input" min="1" type="number" />
|
||||
</label>
|
||||
<label class="field-block">
|
||||
<span>来源 provider</span>
|
||||
<input v-model="item.provider" class="text-input" maxlength="32" placeholder="默认 khhao" />
|
||||
</label>
|
||||
<label class="field-block">
|
||||
<span>来源 platform</span>
|
||||
<input v-model="item.platform" class="text-input" maxlength="32" placeholder="默认 kuaishou" />
|
||||
</label>
|
||||
<label class="field-block">
|
||||
<span>店铺 ID</span>
|
||||
<input v-model="item.shopId" class="text-input" maxlength="80" placeholder="留空表示跨店铺共用" />
|
||||
</label>
|
||||
<label class="field-block field-wide">
|
||||
<span>解析商品名</span>
|
||||
<input v-model="item.resolvedSkuName" class="text-input" maxlength="120" placeholder="可作为商品名兜底" />
|
||||
</label>
|
||||
<div v-else class="mapping-editor">
|
||||
<section class="mapping-panel mapping-panel--external">
|
||||
<div class="mapping-panel-head">
|
||||
<strong>外部商品</strong>
|
||||
<span>khhao / 快手侧命中条件</span>
|
||||
</div>
|
||||
|
||||
<label class="field-block">
|
||||
<span>外部 SKU</span>
|
||||
<input v-model="item.externalSkuCode" class="text-input" maxlength="120" placeholder="例如 khhao 的 skuCode" />
|
||||
</label>
|
||||
<label class="field-block">
|
||||
<span>外部商品 ID</span>
|
||||
<input v-model="item.externalItemId" class="text-input" maxlength="120" placeholder="平台商品 ID" />
|
||||
</label>
|
||||
<label class="field-block field-wide">
|
||||
<span>外部商品名</span>
|
||||
<input v-model="item.externalSkuName" class="text-input" maxlength="200" placeholder="用于名称匹配" />
|
||||
</label>
|
||||
<div class="mapping-grid">
|
||||
<label class="field-block">
|
||||
<span>来源 provider</span>
|
||||
<input v-model="item.provider" class="text-input" maxlength="32" placeholder="默认 khhao" />
|
||||
</label>
|
||||
<label class="field-block">
|
||||
<span>来源 platform</span>
|
||||
<input v-model="item.platform" class="text-input" maxlength="32" placeholder="默认 kuaishou" />
|
||||
</label>
|
||||
<label class="field-block field-wide">
|
||||
<span>店铺 ID</span>
|
||||
<input v-model="item.shopId" class="text-input" maxlength="80" placeholder="留空表示跨店铺共用" />
|
||||
</label>
|
||||
<label class="field-block">
|
||||
<span>外部 SKU</span>
|
||||
<input v-model="item.externalSkuCode" class="text-input" maxlength="120" placeholder="例如 khhao 的 skuCode" />
|
||||
</label>
|
||||
<label class="field-block">
|
||||
<span>外部商品 ID</span>
|
||||
<input v-model="item.externalItemId" class="text-input" maxlength="120" placeholder="平台商品 ID" />
|
||||
</label>
|
||||
<label class="field-block field-wide">
|
||||
<span>外部商品名</span>
|
||||
<input v-model="item.externalSkuName" class="text-input" maxlength="200" placeholder="用于名称匹配" />
|
||||
</label>
|
||||
<label class="field-block field-wide">
|
||||
<span>解析商品名</span>
|
||||
<input v-model="item.resolvedSkuName" class="text-input" maxlength="120" placeholder="可作为商品名兜底" />
|
||||
</label>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<label class="field-block">
|
||||
<span>cloudSourceKey</span>
|
||||
<input v-model="item.cloudSourceKey" class="text-input" maxlength="60" placeholder="默认 default" />
|
||||
</label>
|
||||
<label class="field-block">
|
||||
<span>cloud SKU ID</span>
|
||||
<select
|
||||
v-model.number="item.cloudSkuId"
|
||||
class="text-input"
|
||||
@change="handleCloudSkuSelected(item, item.cloudSkuId)"
|
||||
@focus="handleCloudSkuDropdownVisible(item, true)"
|
||||
>
|
||||
<option :value="0">请选择 cloud SKU</option>
|
||||
<option v-for="sku in getCloudSkuOptions(item)" :key="sku.id" :value="sku.id">
|
||||
{{ formatCloudSkuOptionLabel(sku) }}
|
||||
</option>
|
||||
</select>
|
||||
<small class="field-help">先填内部 SKU / 商品名,再选择会更容易匹配。</small>
|
||||
</label>
|
||||
<label class="field-block field-wide">
|
||||
<span>cloud SKU 名称</span>
|
||||
<input :value="item.cloudSkuName" class="text-input text-input--readonly" placeholder="选择 cloud SKU 后自动带出" readonly />
|
||||
</label>
|
||||
<label class="field-block">
|
||||
<span>虚拟号 VN Key</span>
|
||||
<input class="text-input text-input--readonly" value="1" readonly />
|
||||
</label>
|
||||
<label class="field-block">
|
||||
<span>最低保留余额</span>
|
||||
<input v-model.number="item.minAssetReserve" class="text-input" min="0" type="number" />
|
||||
</label>
|
||||
<div class="mapping-arrow" aria-hidden="true">
|
||||
<span>映射到</span>
|
||||
</div>
|
||||
|
||||
<section class="mapping-panel mapping-panel--internal">
|
||||
<div class="mapping-panel-head">
|
||||
<strong>内部履约</strong>
|
||||
<span>内部 SKU + cloud 资源</span>
|
||||
</div>
|
||||
|
||||
<div class="mapping-grid">
|
||||
<label class="field-block">
|
||||
<span>内部 SKU</span>
|
||||
<input v-model="item.internalSkuCode" class="text-input" maxlength="80" placeholder="必填,用于生成任务" />
|
||||
</label>
|
||||
<label class="field-block">
|
||||
<span>优先级</span>
|
||||
<input v-model.number="item.priority" class="text-input" min="1" type="number" />
|
||||
</label>
|
||||
<label class="field-block field-wide">
|
||||
<span>内部商品名</span>
|
||||
<input v-model="item.internalSkuName" class="text-input" maxlength="120" placeholder="展示用,可选但建议填" />
|
||||
</label>
|
||||
<label class="field-block">
|
||||
<span>cloudSourceKey</span>
|
||||
<input v-model="item.cloudSourceKey" class="text-input" maxlength="60" placeholder="默认 default" />
|
||||
</label>
|
||||
<label class="field-block">
|
||||
<span>cloud SKU ID</span>
|
||||
<select
|
||||
v-model.number="item.cloudSkuId"
|
||||
class="text-input"
|
||||
@change="handleCloudSkuSelected(item, item.cloudSkuId)"
|
||||
@focus="handleCloudSkuDropdownVisible(item, true)"
|
||||
>
|
||||
<option :value="0">请选择 cloud SKU</option>
|
||||
<option v-for="sku in getCloudSkuOptions(item)" :key="sku.id" :value="sku.id">
|
||||
{{ formatCloudSkuOptionLabel(sku) }}
|
||||
</option>
|
||||
</select>
|
||||
<small class="field-help">先填内部 SKU / 商品名,再选择会更容易匹配。</small>
|
||||
</label>
|
||||
<label class="field-block field-wide">
|
||||
<span>cloud SKU 名称</span>
|
||||
<input :value="item.cloudSkuName" class="text-input text-input--readonly" placeholder="选择 cloud SKU 后自动带出" readonly />
|
||||
</label>
|
||||
<label class="field-block">
|
||||
<span>虚拟号 VN Key</span>
|
||||
<input class="text-input text-input--readonly" value="1" readonly />
|
||||
</label>
|
||||
<label class="field-block">
|
||||
<span>最低保留余额</span>
|
||||
<input v-model.number="item.minAssetReserve" class="text-input" min="0" type="number" />
|
||||
</label>
|
||||
</div>
|
||||
</section>
|
||||
</div>
|
||||
|
||||
<div v-if="!isCollapsed(item.localId)" class="mapping-extra">
|
||||
<label class="field-block">
|
||||
<span>快手核销店铺 ID</span>
|
||||
<input v-model="item.kuaishouConsumeShopId" class="text-input" maxlength="80" placeholder="预留给后续自动核销" />
|
||||
@@ -2040,6 +2064,81 @@ onMounted(loadConfigs)
|
||||
gap: 12px;
|
||||
}
|
||||
|
||||
.mapping-editor {
|
||||
display: grid;
|
||||
grid-template-columns: minmax(0, 1fr) 74px minmax(0, 1fr);
|
||||
gap: 12px;
|
||||
align-items: stretch;
|
||||
}
|
||||
|
||||
.mapping-panel {
|
||||
display: grid;
|
||||
align-content: start;
|
||||
gap: 12px;
|
||||
padding: 14px;
|
||||
border-radius: 16px;
|
||||
border: 1px solid rgba(148, 163, 184, 0.18);
|
||||
}
|
||||
|
||||
.mapping-panel--external {
|
||||
background: rgba(239, 246, 255, 0.72);
|
||||
}
|
||||
|
||||
.mapping-panel--internal {
|
||||
background: rgba(255, 255, 255, 0.86);
|
||||
border-color: rgba(15, 93, 216, 0.16);
|
||||
}
|
||||
|
||||
.mapping-panel-head {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
gap: 10px;
|
||||
align-items: baseline;
|
||||
}
|
||||
|
||||
.mapping-panel-head strong {
|
||||
color: #1d3555;
|
||||
font-size: 15px;
|
||||
}
|
||||
|
||||
.mapping-panel-head span {
|
||||
color: #64748b;
|
||||
font-size: 12px;
|
||||
}
|
||||
|
||||
.mapping-grid,
|
||||
.mapping-extra {
|
||||
display: grid;
|
||||
grid-template-columns: repeat(2, minmax(0, 1fr));
|
||||
gap: 10px 12px;
|
||||
}
|
||||
|
||||
.mapping-arrow {
|
||||
display: grid;
|
||||
place-items: center;
|
||||
color: #175cd3;
|
||||
font-size: 12px;
|
||||
font-weight: 700;
|
||||
}
|
||||
|
||||
.mapping-arrow span {
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
min-height: 30px;
|
||||
min-width: 54px;
|
||||
padding: 0 10px;
|
||||
border-radius: 999px;
|
||||
background: rgba(15, 93, 216, 0.08);
|
||||
border: 1px solid rgba(15, 93, 216, 0.14);
|
||||
}
|
||||
|
||||
.mapping-extra {
|
||||
margin-top: 12px;
|
||||
padding-top: 12px;
|
||||
border-top: 1px dashed rgba(86, 108, 138, 0.18);
|
||||
}
|
||||
|
||||
.checkbox-line {
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
@@ -2068,10 +2167,15 @@ onMounted(loadConfigs)
|
||||
@media (max-width: 1100px) {
|
||||
.overview-stats,
|
||||
.khhao-toolbar,
|
||||
.binding-grid {
|
||||
.binding-grid,
|
||||
.mapping-editor {
|
||||
grid-template-columns: repeat(2, minmax(0, 1fr));
|
||||
}
|
||||
|
||||
.mapping-arrow {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.field-wide {
|
||||
grid-column: span 2;
|
||||
}
|
||||
@@ -2089,7 +2193,10 @@ onMounted(loadConfigs)
|
||||
|
||||
.overview-stats,
|
||||
.khhao-toolbar,
|
||||
.binding-grid {
|
||||
.binding-grid,
|
||||
.mapping-editor,
|
||||
.mapping-grid,
|
||||
.mapping-extra {
|
||||
grid-template-columns: 1fr;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user