refactor: split project into web and server directories

- Move frontend to web/ directory
- Add server/ directory for backend
- Restructure project for前后端分离架构

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
This commit is contained in:
2026-05-06 11:00:38 +08:00
parent 9a7b0794a1
commit 9785fb527b
85 changed files with 10474 additions and 10047 deletions

286
web/src/views/AuditView.vue Normal file
View File

@@ -0,0 +1,286 @@
<template>
<section class="skill-center">
<Transition name="skill-view" mode="out-in">
<article v-if="selectedSkill" key="detail" class="skill-detail">
<div class="detail-scroll">
<section class="detail-hero panel">
<div class="hero-title">
<div class="skill-badge" :class="selectedSkill.badgeTone">{{ selectedSkill.scope }}</div>
<h2>{{ selectedSkill.name }}</h2>
<p>{{ selectedSkill.summary }}</p>
</div>
<div class="hero-stats">
<div class="hero-stat">
<span>版本</span>
<strong>{{ selectedSkill.version }}</strong>
</div>
<div class="hero-stat">
<span>状态</span>
<b :class="['status-pill', selectedSkill.statusTone]">{{ selectedSkill.status }}</b>
</div>
<div class="hero-stat">
<span>触发命中率</span>
<strong>{{ selectedSkill.hitRate }}</strong>
</div>
<div class="hero-stat">
<span>负责人</span>
<strong>{{ selectedSkill.owner }}</strong>
</div>
</div>
</section>
<div class="detail-grid">
<section class="detail-main">
<article class="detail-card panel">
<div class="card-head">
<div>
<h3>基础配置</h3>
<p>定义 skill 的定位适用场景和默认执行策略</p>
</div>
<button class="mini-btn">保存草稿</button>
</div>
<div class="form-grid">
<label class="field">
<span>技能名称</span>
<input :value="selectedSkill.name" />
</label>
<label class="field">
<span>技能分类</span>
<input :value="selectedSkill.category" />
</label>
<label class="field span-2">
<span>适用描述</span>
<textarea rows="3" :value="selectedSkill.summary"></textarea>
</label>
<label class="field">
<span>触发方式</span>
<input :value="selectedSkill.triggerMode" />
</label>
<label class="field">
<span>默认模型</span>
<input :value="selectedSkill.model" />
</label>
</div>
</article>
<article class="detail-card panel">
<div class="card-head">
<div>
<h3>提示词结构</h3>
<p>按系统约束输入期望输出格式三个层级组织 skill 行为</p>
</div>
<span class="edit-badge">{{ selectedSkill.promptSections.length }} </span>
</div>
<div class="prompt-stack">
<section v-for="section in selectedSkill.promptSections" :key="section.title" class="prompt-block">
<header>
<strong>{{ section.title }}</strong>
<span>{{ section.intent }}</span>
</header>
<textarea rows="5" :value="section.content"></textarea>
</section>
</div>
</article>
<article class="detail-card panel">
<div class="card-head">
<div>
<h3>输出契约与测试样例</h3>
<p>确保 skill 在高频场景下输出稳定格式清晰</p>
</div>
<button class="mini-btn primary">运行测试</button>
</div>
<div class="contract-grid">
<div class="contract-panel">
<h4>输出要求</h4>
<ul>
<li v-for="rule in selectedSkill.outputRules" :key="rule">{{ rule }}</li>
</ul>
</div>
<div class="contract-panel">
<h4>测试样例</h4>
<div v-for="test in selectedSkill.tests" :key="test.name" class="test-row">
<div>
<strong>{{ test.name }}</strong>
<span>{{ test.input }}</span>
</div>
<b :class="['test-state', test.tone]">{{ test.result }}</b>
</div>
</div>
</div>
</article>
</section>
<aside class="detail-side">
<article class="side-card panel">
<div class="card-head">
<div>
<h3>触发规则</h3>
<p>当前命中策略</p>
</div>
</div>
<div class="tag-list">
<span v-for="item in selectedSkill.triggers" :key="item">{{ item }}</span>
</div>
</article>
<article class="side-card panel">
<div class="card-head">
<div>
<h3>工具权限</h3>
<p>可调用能力</p>
</div>
</div>
<div class="tool-list">
<div v-for="tool in selectedSkill.tools" :key="tool.name" class="tool-row">
<div>
<strong>{{ tool.name }}</strong>
<span>{{ tool.scope }}</span>
</div>
<b :class="['tool-state', tool.tone]">{{ tool.mode }}</b>
</div>
</div>
</article>
<article class="side-card panel">
<div class="card-head">
<div>
<h3>版本历史</h3>
<p>最近变更</p>
</div>
</div>
<div class="history-list">
<div v-for="item in selectedSkill.history" :key="item.version" class="history-row">
<strong>{{ item.version }}</strong>
<span>{{ item.note }}</span>
<small>{{ item.time }}</small>
</div>
</div>
</article>
<article class="side-card panel publish-card">
<div>
<h3>发布控制</h3>
<p>当前配置已通过核心检查可进入灰度或正式发布</p>
</div>
<div class="publish-summary">
<span>最近评审2026-05-05 14:20</span>
<strong>可发布</strong>
</div>
</article>
</aside>
</div>
</div>
<footer class="detail-actions">
<button class="back-action" type="button" @click="selectedSkill = null">
<i class="mdi mdi-arrow-left"></i>
<span>返回技能列表</span>
</button>
<div class="detail-action-group">
<button class="minor-action" type="button">
<i class="mdi mdi-content-save-outline"></i>
<span>保存草稿</span>
</button>
<button class="minor-action" type="button">
<i class="mdi mdi-flask-outline"></i>
<span>运行测试</span>
</button>
<button class="major-action" type="button">
<i class="mdi mdi-rocket-launch-outline"></i>
<span>正式上线</span>
</button>
</div>
</footer>
</article>
<article v-else key="list" class="skill-list panel">
<nav class="status-tabs" aria-label="技能状态">
<button
v-for="tab in tabs"
:key="tab"
type="button"
:class="{ active: activeTab === tab }"
@click="activeTab = tab"
>
{{ tab }}
</button>
</nav>
<div class="list-toolbar">
<div class="filter-set">
<button v-for="filter in filters" :key="filter" type="button" class="filter-btn">
<span>{{ filter }}</span>
<i class="mdi mdi-chevron-down"></i>
</button>
</div>
<button class="create-btn" type="button">
<i class="mdi mdi-plus"></i>
<span>新建 Skill</span>
</button>
</div>
<p class="hint"><i class="mdi mdi-information-outline"></i> 点击任意技能行进入设计与编辑界面</p>
<div class="table-wrap">
<table>
<thead>
<tr>
<th>技能名称</th>
<th>分类</th>
<th>负责人</th>
<th>适用范围</th>
<th>模型</th>
<th>版本</th>
<th>状态</th>
<th>命中率</th>
<th>最近更新</th>
<th>操作</th>
</tr>
</thead>
<tbody>
<tr
v-for="skill in visibleSkills"
:key="skill.id"
:class="{ spotlight: skill.spotlight }"
@click="selectedSkill = skill"
>
<td>
<div class="skill-name-cell">
<span class="skill-avatar" :class="skill.badgeTone">{{ skill.short }}</span>
<div>
<strong>{{ skill.name }}</strong>
<span>{{ skill.summary }}</span>
</div>
</div>
</td>
<td>{{ skill.category }}</td>
<td>{{ skill.owner }}</td>
<td><span class="scope-pill">{{ skill.scope }}</span></td>
<td>{{ skill.model }}</td>
<td>{{ skill.version }}</td>
<td><span class="status-pill" :class="skill.statusTone">{{ skill.status }}</span></td>
<td>{{ skill.hitRate }}</td>
<td>{{ skill.updatedAt }}</td>
<td>
<button class="row-action" type="button" @click.stop="selectedSkill = skill">
编辑
</button>
</td>
</tr>
</tbody>
</table>
</div>
</article>
</Transition>
</section>
</template>
<script src="./scripts/AuditView.js"></script>
<style scoped src="../assets/styles/views/audit-view.css"></style>