Files
cmsp/frontend/src/App.vue
T
QiuSWandClaude Opus 5 2cefa67001 feat: 初始化 Wails v2 + Vue3 骨架与 SQLite 存储 (#4)
建立可运行、可构建的 Go 骨架,供后续 R1~R5 在其上叠加。

后端:
- main.go / app.go:Wails v2 窗口与 14 个前端可调方法。Wails 专有 API
  只出现在这两个文件,internal/ 对 Wails 零依赖,便于将来迁移 v3
- internal/config:config.yaml 的读写、校验、脱敏。保存时按固定模板
  渲染以保留注释,不用 yaml.Marshal
- internal/store:SQLite(modernc.org/sqlite,无需 CGO)。建表迁移、
  商品仓储、KV。重复同步不会覆盖本地下载与上传状态
- internal/logx:9 条脱敏规则,覆盖淘宝 token、Cookie、Authorization、
  密码和图片 base64;并发安全的内存日志缓冲

前端(Vue 3 + Naive UI,按已确认原型 v4):
- Sidebar:176px 可折叠,仅商品列表与参数设置两项,底部是登录状态的
  唯一显示位置
- ProductListView:两行工具栏(四项筛选 + 重置搜索 / 四个操作按钮)、
  商品表格、分页
- SettingsView:四张卡片,路径用文件与目录选择框
- LogWindow:运行日志子窗口,按级别过滤、自动滚动、导出

配置改用 YAML:分 huohanhan / taobao / download 三段。taobao 段刻意
没有账号密码字段,并有单元测试挡住后续加入。

构建相关:
- .gitignore 只忽略 build/bin/,不忽略 build/。Wails 把 build/ 当源码
  目录(图标、manifest),忽略掉会让别人克隆后构建失败
- .gitignore 忽略 config.yaml、payloads/ 和 *.har(含真实手机号与凭据)

未实现的下载数据、下载视频、上传数据三个方法返回明确的「还没实现」,
不静默失败。

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01LbdtsD3ohhSMy3KPoCgARq
2026-09-02 15:59:54 +08:00

62 lines
1.6 KiB
Vue

<script setup>
/**
* 应用外壳:左边导航,右边内容。
*
* 页面切换用 v-show 而不是 v-if,这样从设置页切回商品列表时
* 表格不用重新查一遍数据库。
*/
import { ref } from 'vue'
import { NConfigProvider, NDialogProvider, NMessageProvider, zhCN, dateZhCN } from 'naive-ui'
import Sidebar from './components/Sidebar.vue'
import LogWindow from './components/LogWindow.vue'
import ProductListView from './views/ProductListView.vue'
import SettingsView from './views/SettingsView.vue'
// 'list' 或 'set'
const page = ref('list')
const collapsed = ref(false)
const showLogs = ref(false)
// 登录状态。R1 和 R2 实现后由后端事件更新,现在先都当未登录。
const huohanhanOk = ref(false)
const taobaoOk = ref(false)
</script>
<template>
<n-config-provider :locale="zhCN" :date-locale="dateZhCN">
<n-message-provider>
<n-dialog-provider>
<div class="shell">
<Sidebar
:active="page"
:collapsed="collapsed"
:huohanhan-ok="huohanhanOk"
:taobao-ok="taobaoOk"
@navigate="page = $event"
@toggle="collapsed = !collapsed"
/>
<main class="content">
<ProductListView v-show="page === 'list'" @open-logs="showLogs = true" />
<SettingsView v-show="page === 'set'" />
</main>
<LogWindow v-model:show="showLogs" />
</div>
</n-dialog-provider>
</n-message-provider>
</n-config-provider>
</template>
<style scoped>
.shell {
display: flex;
height: 100vh;
}
.content {
flex: 1;
min-width: 0;
height: 100%;
}
</style>