Files
order_site/apps/frontend/src/components/admin/AdminPlatformKhhaoSection.vue
T

265 lines
10 KiB
Vue
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
<script setup lang="ts">
import AdminResultCard from '@/components/admin/AdminResultCard.vue'
import type {
AdminKhhaoLoginTestResult,
AdminKhhaoOrderQueryResult,
AdminKhhaoOrderSyncResult,
AdminKhhaoSyncState,
} from '@/types/admin'
import { formatAdminDateTime } from '@/utils/admin-time'
type KhhaoForm = {
baseUrl: string
username: string
password: string
page: number
limit: number
maxCaptchaAttempts: number
autoSyncEnabled: boolean
autoSyncIntervalMinutes: number
autoSyncPages: number
autoSyncPageSize: number
}
type Props = {
khhaoFilePath: string
khhaoStateFilePath: string
khhaoForm: KhhaoForm
khhaoSaving: boolean
khhaoTesting: boolean
khhaoQuerying: boolean
khhaoSyncing: boolean
khhaoResultError: string
khhaoLoginResult: AdminKhhaoLoginTestResult | null
khhaoQueryResult: AdminKhhaoOrderQueryResult | null
khhaoSyncResult: AdminKhhaoOrderSyncResult | null
khhaoAutoSyncState: AdminKhhaoSyncState | null
handleKhhaoSaveSource: () => void | Promise<void>
handleKhhaoTestLogin: () => void | Promise<void>
handleKhhaoQueryOrders: () => void | Promise<void>
handleKhhaoSyncOrders: () => void | Promise<void>
}
defineProps<Props>()
</script>
<template>
<section class="meta-card">
<div class="meta-line">
<span class="meta-label">配置文件</span>
<code>{{ khhaoFilePath || '-' }}</code>
</div>
<div class="meta-line">
<span class="meta-label">状态文件</span>
<code>{{ khhaoStateFilePath || '-' }}</code>
</div>
<div class="meta-line">
<span class="meta-label">职责</span>
<span>管理 khhao 的来源地址、登录账号、密码与验证码重试次数,并执行测试登录、查询订单与手动同步。</span>
</div>
</section>
<section class="table-card">
<div class="section-title-row">
<div>
<h3>khhao 来源配置</h3>
<p>先保存 khhao 凭据,再按需执行登录测试、订单查询或同步。履约规则请前往“履约配置”页处理。</p>
</div>
<div class="section-actions">
<el-button :loading="khhaoSaving" round @click="handleKhhaoSaveSource">保存来源配置</el-button>
<el-button :loading="khhaoTesting" round @click="handleKhhaoTestLogin">测试登录</el-button>
<el-button :loading="khhaoQuerying" round @click="handleKhhaoQueryOrders">查询订单</el-button>
<el-button :loading="khhaoSyncing" round type="primary" @click="handleKhhaoSyncOrders">同步订单</el-button>
</div>
</div>
<div class="form-grid">
<label class="field-block field-wide">
<span>Base URL</span>
<input v-model="khhaoForm.baseUrl" class="text-input" placeholder="https://admin.khhao.com" />
</label>
<label class="field-block">
<span>账号</span>
<input v-model="khhaoForm.username" class="text-input" placeholder="khhao 登录账号" />
</label>
<label class="field-block">
<span>密码</span>
<input v-model="khhaoForm.password" class="text-input" type="password" placeholder="khhao 登录密码" />
</label>
<label class="field-block">
<span>页码</span>
<input v-model.number="khhaoForm.page" class="text-input" type="number" min="1" />
</label>
<label class="field-block">
<span>每页条数</span>
<input v-model.number="khhaoForm.limit" class="text-input" type="number" min="1" max="50" />
</label>
<label class="field-block">
<span>验证码重试次数</span>
<input v-model.number="khhaoForm.maxCaptchaAttempts" class="text-input" type="number" min="1" max="5" />
</label>
<label class="field-block">
<span>自动同步开关</span>
<label class="checkbox-line checkbox-box">
<input v-model="khhaoForm.autoSyncEnabled" type="checkbox" />
<span>启用自动同步</span>
</label>
</label>
<label class="field-block">
<span>同步间隔(分钟)</span>
<input v-model.number="khhaoForm.autoSyncIntervalMinutes" class="text-input" type="number" min="1" max="60" />
</label>
<label class="field-block">
<span>同步页数</span>
<input v-model.number="khhaoForm.autoSyncPages" class="text-input" type="number" min="1" max="5" />
</label>
<label class="field-block">
<span>每页条数</span>
<input v-model.number="khhaoForm.autoSyncPageSize" class="text-input" type="number" min="1" max="50" />
</label>
</div>
<p v-if="khhaoResultError" class="error-copy">{{ khhaoResultError }}</p>
<div class="result-grid">
<AdminResultCard label="登录结果" :value="khhaoLoginResult ? '成功' : '未执行'">
<p v-if="khhaoLoginResult">
第 {{ khhaoLoginResult.attempt }} 次成功,验证码识别 {{ khhaoLoginResult.captcha.recognizedText || '-' }},
{{ formatAdminDateTime(khhaoLoginResult.loggedInAt) }}
</p>
<p v-else>可先点击“测试登录”验证账号密码与 OCR。</p>
</AdminResultCard>
<AdminResultCard label="查询结果" :value="`${khhaoQueryResult?.itemCount || 0} 条`">
<p v-if="khhaoQueryResult">当前页 {{ khhaoQueryResult.page }} / 总计 {{ khhaoQueryResult.total }} 条</p>
<p v-else>可先点击“查询订单”验证拉单链路。</p>
</AdminResultCard>
<AdminResultCard label="同步结果" :value="`${khhaoSyncResult?.syncedCount || 0} 条`">
<p v-if="khhaoSyncResult">忽略 {{ khhaoSyncResult.ignoredCount }} 条,拉取 {{ khhaoSyncResult.fetchedCount }} 条</p>
<p v-else>完成履约配置后可在这里手动同步。</p>
</AdminResultCard>
</div>
<div v-if="khhaoAutoSyncState" class="meta-card compact-meta">
<div class="meta-line">
<span class="meta-label">自动同步状态</span>
<span>{{ khhaoAutoSyncState.lastRunStatus || 'idle' }}</span>
</div>
<div class="meta-line">
<span class="meta-label">当前节奏</span>
<span>{{ khhaoAutoSyncState.watchMode === 'boosted' ? '提频观察中(3-5 秒)' : '常规同步' }}</span>
</div>
<div class="meta-line">
<span class="meta-label">同步基线</span>
<span>{{ formatAdminDateTime(khhaoAutoSyncState.syncFromCreatedAt) }}</span>
</div>
<div class="meta-line">
<span class="meta-label">最近开始</span>
<span>{{ formatAdminDateTime(khhaoAutoSyncState.lastRunStartedAt) }}</span>
</div>
<div class="meta-line">
<span class="meta-label">最近完成</span>
<span>{{ formatAdminDateTime(khhaoAutoSyncState.lastRunFinishedAt) }}</span>
</div>
<div class="meta-line">
<span class="meta-label">最近结果</span>
<span>拉取 {{ khhaoAutoSyncState.fetchedCount }} 条,成功 {{ khhaoAutoSyncState.syncedCount }} 条,忽略 {{ khhaoAutoSyncState.ignoredCount }} 条</span>
</div>
<div v-if="khhaoAutoSyncState.watchOrders.length > 0" class="meta-line">
<span class="meta-label">观察订单</span>
<span>{{ khhaoAutoSyncState.watchOrders.map((item) => `${item.shopName || item.shopId || '-'} / ${item.platformOrderId}`).join(';') }}</span>
</div>
<div v-if="khhaoAutoSyncState.lastErrorMessage" class="meta-line">
<span class="meta-label">最近错误</span>
<span class="error-copy">{{ khhaoAutoSyncState.lastErrorMessage }}</span>
</div>
</div>
</section>
<section v-if="khhaoQueryResult" class="table-card">
<div class="section-title-row">
<div>
<h3>khhao 查询结果</h3>
<p>当前页 {{ khhaoQueryResult.page }},本页 {{ khhaoQueryResult.itemCount }} 条,总数 {{ khhaoQueryResult.total }}。</p>
</div>
</div>
<table class="data-table">
<thead>
<tr>
<th>订单</th>
<th>店铺</th>
<th>商品</th>
<th>金额</th>
<th>状态</th>
</tr>
</thead>
<tbody>
<tr v-for="item in khhaoQueryResult.items" :key="`${item.platformOrderId}:${item.skuCode}:${item.itemId}`">
<td>
<div class="cell-stack">
<strong>{{ item.platformOrderId }}</strong>
<span class="cell-subtle">{{ item.platformLabel || item.platform || '-' }}</span>
</div>
</td>
<td>
<div class="cell-stack">
<strong>{{ item.shopName || item.shopId || '-' }}</strong>
<span class="cell-subtle">ID: {{ item.shopId || '-' }}</span>
</div>
</td>
<td>
<div class="cell-stack">
<strong>{{ item.itemTitle || '-' }}</strong>
<span class="cell-subtle">SKU: {{ item.skuCode || '-' }}</span>
</div>
</td>
<td>{{ (item.totalAmountFen / 100).toFixed(2) }}</td>
<td>{{ item.statusLabel || item.status || '-' }}</td>
</tr>
</tbody>
</table>
</section>
<section v-if="khhaoSyncResult" class="table-card">
<div class="section-title-row">
<div>
<h3>khhao 同步结果</h3>
<p>拉取 {{ khhaoSyncResult.fetchedCount }} 条,成功 {{ khhaoSyncResult.syncedCount }} 条,忽略 {{ khhaoSyncResult.ignoredCount }} 条。</p>
</div>
</div>
<table class="data-table">
<thead>
<tr>
<th>订单</th>
<th>店铺</th>
<th>商品</th>
<th>结果</th>
</tr>
</thead>
<tbody>
<tr v-for="item in khhaoSyncResult.results" :key="`${item.platformOrderId}:${item.skuCode}`">
<td>{{ item.platformOrderId }}</td>
<td>{{ item.shopId || '-' }}</td>
<td>{{ item.itemTitle || item.skuCode || '-' }}</td>
<td>
<span v-if="item.ignored">已忽略:{{ item.ignoreReason || '-' }}</span>
<span v-else>已入库,订单 {{ item.orderId || '-' }},任务 {{ item.taskCount }}</span>
</td>
</tr>
</tbody>
</table>
</section>
</template>