265 lines
10 KiB
Vue
265 lines
10 KiB
Vue
<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>
|