feat: 创作工作台统一 + AI味检测/白标 + 移动端补全 + 合规发布闭环
- 新增创作工作台 studio.html:合并选题/内容工厂/文章管理为单一 tab 入口(iframe embed 模式) - 新增 AI味检测模块(ai_slop API + 页面,合规软硬问题分级) - 新增白标品牌配置(branding API + 页面 + deploy 私有化交付包) - 发布闭环:publishing 放宽至 editor + records/mark-published 接口 - 移动端响应式补全(admin/calendar/ai-slop 表格卡片兜底) - 修复菜单幂等播种缺陷(按 path 对齐,避免功能页孤立) - 新增短视频脚本 shortvideo.py 与 2026 市场调研简报
This commit is contained in:
@@ -0,0 +1,81 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="zh-CN">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>宇之然内容创作平台 - 创作工作台</title>
|
||||
<link rel="stylesheet" href="element-plus.css">
|
||||
<link rel="stylesheet" href="theme-modern.css">
|
||||
<style>
|
||||
html, body { margin: 0; height: 100%; }
|
||||
[v-cloak] { display: none; }
|
||||
#app { display: flex; flex-direction: column; height: 100vh; }
|
||||
.studio-body { flex: 1; display: flex; flex-direction: column; min-height: 0; padding-top: var(--nav-height); }
|
||||
.studio-tabs { flex: 0 0 auto; padding: 0 16px; background: var(--color-bg-raised); border-bottom: 1px solid var(--color-border); }
|
||||
.studio-tabs .el-tabs__header { margin-bottom: 0; }
|
||||
.studio-iframe-wrap { flex: 1; position: relative; min-height: 0; background: var(--color-bg); }
|
||||
.studio-iframe-wrap iframe { position: absolute; inset: 0; width: 100%; height: 100%; border: none; }
|
||||
@media (max-width: 768px) { .studio-tabs { padding: 0 8px; } }
|
||||
</style>
|
||||
<script src="uni-nav.js"></script>
|
||||
</head>
|
||||
<body>
|
||||
<div id="app" v-cloak>
|
||||
<uni-nav title="创作工作台" :username="currentUser.username" :is-admin="isAdmin" current-page="studio" @navigate="redirectToPage" @logout="handleLogout">
|
||||
</uni-nav>
|
||||
<div class="studio-body">
|
||||
<div class="studio-tabs">
|
||||
<el-tabs v-model="activeTab" @tab-change="onTabChange">
|
||||
<el-tab-pane label="选题" name="topics"></el-tab-pane>
|
||||
<el-tab-pane label="内容生成" name="factory"></el-tab-pane>
|
||||
<el-tab-pane label="文章管理" name="articles"></el-tab-pane>
|
||||
</el-tabs>
|
||||
</div>
|
||||
<div class="studio-iframe-wrap">
|
||||
<iframe v-if="tabs.topics" src="topics.html?embed=1" frameborder="0"></iframe>
|
||||
<iframe v-if="tabs.factory" src="factory.html?embed=1" frameborder="0"></iframe>
|
||||
<iframe v-if="tabs.articles" src="articles.html?embed=1" frameborder="0"></iframe>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<script src="vue.global.prod.js"></script>
|
||||
<script src="element-plus.js"></script>
|
||||
<script src="element-plus-icons.js"></script>
|
||||
<script>
|
||||
const { createApp } = Vue;
|
||||
const StudioApp = {
|
||||
data() {
|
||||
return {
|
||||
isLoggedIn: false, isAdmin: false, currentUser: { username: '' },
|
||||
activeTab: 'topics',
|
||||
tabs: { topics: true, factory: false, articles: false },
|
||||
};
|
||||
},
|
||||
methods: {
|
||||
onTabChange(name) { this.tabs[name] = true; },
|
||||
redirectToPage(page) { window.location.href = page.startsWith('/') ? page : '/' + page; },
|
||||
handleLogout() {
|
||||
localStorage.removeItem('authToken');
|
||||
localStorage.removeItem('userRole');
|
||||
localStorage.removeItem('currentUser');
|
||||
window.location.href = '/login.html';
|
||||
},
|
||||
},
|
||||
mounted() {
|
||||
const token = localStorage.getItem('authToken');
|
||||
if (!token) { window.location.href = '/login.html'; return; }
|
||||
fetch('/api/auth/me', { headers: { 'Authorization': 'Bearer ' + token } })
|
||||
.then(r => r.ok ? r.json() : Promise.reject())
|
||||
.then(data => { this.currentUser = data.user; this.isAdmin = data.user.role === 'admin'; this.isLoggedIn = true; })
|
||||
.catch(() => { localStorage.removeItem('authToken'); localStorage.removeItem('userRole'); localStorage.removeItem('currentUser'); window.location.href = '/login.html'; });
|
||||
}
|
||||
};
|
||||
const app = Vue.createApp(StudioApp);
|
||||
app.use(ElementPlus);
|
||||
if (window.installIcons) { window.installIcons(app); }
|
||||
if (window.installUniNav) { window.installUniNav(app); }
|
||||
app.mount('#app');
|
||||
</script>
|
||||
<script src="ai-assistant.js"></script>
|
||||
</body>
|
||||
</html>
|
||||
Reference in New Issue
Block a user