feat(goauto): add SYB product variation filters (#269)
This commit is contained in:
@@ -0,0 +1,6 @@
|
||||
import request from '@/utils/request'
|
||||
const base = '/api/admin/v1/syb-product-filters'
|
||||
export function listSybProductFilters(params) { return request({ url: base, method: 'get', params }) }
|
||||
export function createSybProductFilter(data) { return request({ url: base, method: 'post', data }) }
|
||||
export function setSybProductFilterEnabled(id, data) { return request({ url: `${base}/${id}/enabled`, method: 'patch', data }) }
|
||||
export function deleteSybProductFilter(id) { return request({ url: `${base}/${id}`, method: 'delete' }) }
|
||||
@@ -0,0 +1,19 @@
|
||||
<template>
|
||||
<BasicLayout><template #wrapper><el-card class="page-card" shadow="never">
|
||||
<el-alert v-if="!isAdmin" title="当前账号只有查看权限。新增、编辑、启用、停用和删除关键词需要管理员操作。" type="info" :closable="false" show-icon class="notice" />
|
||||
<el-alert title="关键词匹配 variationSku,不匹配商品标题。" type="info" :closable="false" show-icon class="notice" />
|
||||
<section><h3>结构过滤(不可增删,仅可停用)</h3><p class="muted">这两个字符是识别档口商品的判据,命中即不入库。需要变更判据请另行建单评估。</p>
|
||||
<el-table v-loading="loading" :data="chars" border stripe><el-table-column label="字符" prop="keyword" width="180"/><el-table-column label="状态" width="150"><template #default="{row}"><el-switch v-if="isAdmin" v-model="row.enabled" @change="toggle(row)"/><el-tag v-else :type="row.enabled?'success':'info'">{{row.enabled?'已启用':'已停用'}}</el-tag></template></el-table-column><el-table-column label="最近命中" width="140"><template #default="{row}">{{ row.lastHitCount == null ? '尚未同步' : row.lastHitCount }}</template></el-table-column><el-table-column label="最近变更" min-width="220"><template #default="{row}">{{ row.lastChangedAt ? `${format(row.lastChangedAt)} ${row.lastChangedBy || ''} ${row.enabled ? '启用' : '停用'}` : '尚未记录' }}</template></el-table-column><el-table-column label="操作" width="110"><template #default><span class="muted">不可删除</span></template></el-table-column></el-table></section>
|
||||
<section class="keyword-section"><div class="section-head"><div><h3>关键词过滤</h3><p class="muted">在结构过滤之后执行,命中数为结构过滤未覆盖的部分。</p></div><el-button v-if="isAdmin" type="primary" @click="editor.open=true">新增关键词</el-button></div>
|
||||
<el-table v-loading="loading" :data="keywords" border stripe empty-text="还没有配置过滤关键词。结构过滤(variationSku 含 - 或 #)仍然生效,本页只影响额外的关键词过滤。"><el-table-column label="关键词" prop="keyword" min-width="260"/><el-table-column label="状态" width="140"><template #default="{row}"><el-switch v-if="isAdmin" v-model="row.enabled" @change="toggle(row)"/><el-tag v-else :type="row.enabled?'success':'info'">{{row.enabled?'已启用':'已停用'}}</el-tag></template></el-table-column><el-table-column label="最近命中" width="130"><template #default="{row}">{{ row.lastHitCount == null ? '尚未同步' : row.lastHitCount }}</template></el-table-column><el-table-column label="备注" prop="note" min-width="180"><template #default="{row}">{{ row.note || '—' }}</template></el-table-column><el-table-column label="操作" width="100"><template #default="{row}"><el-button v-if="isAdmin" type="danger" link @click="remove(row)">删除</el-button><span v-else class="muted">只读</span></template></el-table-column></el-table></section>
|
||||
<p class="scope-note">停用或删除只影响后续同步,已经入库的商品明细不会被删除。</p>
|
||||
<el-dialog v-model="editor.open" title="新增关键词" width="520px"><el-form label-position="top"><el-form-item label="关键词"><el-input v-model="editor.keyword" maxlength="200" /></el-form-item><el-form-item label="备注"><el-input v-model="editor.note" /></el-form-item></el-form><template #footer><el-button @click="editor.open=false">取消</el-button><el-button type="primary" @click="save">保存</el-button></template></el-dialog>
|
||||
</el-card></template></BasicLayout>
|
||||
</template>
|
||||
<script>
|
||||
import { ElMessage, ElMessageBox } from 'element-plus'
|
||||
import { listSybProductFilters, createSybProductFilter, setSybProductFilterEnabled, deleteSybProductFilter } from '@/api/goauto/syb-product-filters'
|
||||
export default { name:'GoAutoSybProductFilters', data(){return {loading:false,chars:[],keywords:[],editor:{open:false,keyword:'',note:''}}}, computed:{isAdmin(){return (this.$store.getters.roles||[]).includes('admin')}}, created(){this.load()}, methods:{ async load(){this.loading=true;try{const r=await listSybProductFilters({page:1,pageSize:200});const rows=r.data.items||[];this.chars=rows.filter(x=>x.kind==='char');this.keywords=rows.filter(x=>x.kind==='keyword')}finally{this.loading=false}}, format(v){return new Intl.DateTimeFormat('zh-CN',{dateStyle:'medium',timeStyle:'short'}).format(new Date(v))}, async toggle(row){if(row.kind==='char'&&!row.enabled){await ElMessageBox.confirm(`停用「${row.keyword}」后,SYB 同步将不再过滤含 ${row.keyword} 的档口商品。按最近一次同步数据估算,约 ${row.lastHitCount||0} 条明细会恢复入库。确认停用?`,'确认停用结构过滤',{type:'warning'}).catch(()=>{row.enabled=true;throw new Error('cancel')})}try{await setSybProductFilterEnabled(row.id,{enabled:row.enabled});ElMessage.success(row.enabled?'规则已启用':'规则已停用')}catch(e){row.enabled=!row.enabled; if(e.message!=='cancel')throw e}},async save(){if(!this.editor.keyword.trim())return;await createSybProductFilter({kind:'keyword',keyword:this.editor.keyword,note:this.editor.note||undefined});ElMessage.success('关键词已添加');this.editor={open:false,keyword:'',note:''};this.load()},async remove(row){await ElMessageBox.confirm(`删除关键词「${row.keyword}」?`,'删除关键词',{type:'warning'});await deleteSybProductFilter(row.id);ElMessage.success('关键词已删除');this.load()}}
|
||||
}
|
||||
</script>
|
||||
<style lang="scss" scoped>.page-card{min-height:calc(100vh - 124px)}.notice{margin-bottom:16px}section{margin-bottom:28px}h3{margin:0 0 8px}.muted,.scope-note{font-size:12px;color:#606266}.section-head{display:flex;justify-content:space-between;align-items:center}.keyword-section{border-top:1px solid #ebeef5;padding-top:20px}.scope-note{margin-top:12px}</style>
|
||||
@@ -48,6 +48,8 @@
|
||||
<el-descriptions-item label="商品明细">{{ detail.item.detailCount }} 条</el-descriptions-item>
|
||||
<el-descriptions-item label="符合店铺">{{ detail.item.acceptedCount }} 张</el-descriptions-item>
|
||||
<el-descriptions-item label="跳过店铺">{{ detail.item.shopSkipped }} 张</el-descriptions-item>
|
||||
<el-descriptions-item label="结构过滤命中">{{ detail.item.charFilterSkipped || 0 }} 条</el-descriptions-item>
|
||||
<el-descriptions-item label="关键词过滤命中">{{ detail.item.keywordFilterSkipped || 0 }} 条</el-descriptions-item>
|
||||
<el-descriptions-item label="新增 / 覆盖">{{ detail.item.created }} / {{ detail.item.updated }}</el-descriptions-item>
|
||||
<el-descriptions-item label="操作人">{{ detail.item.operatorName || `用户 ${detail.item.operatorId || '-'}` }}</el-descriptions-item>
|
||||
<el-descriptions-item label="开始时间">{{ formatTime(detail.item.startedAt) }}</el-descriptions-item>
|
||||
|
||||
Reference in New Issue
Block a user