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:
yuzhiran
2026-07-11 12:36:01 +08:00
parent 3d596275d5
commit 7e953afbd2
39 changed files with 2418 additions and 311 deletions
+8 -4
View File
@@ -195,7 +195,7 @@
/* ========== Topic Cards (待创作) ========== */
.topic-grid {
display: grid;
grid-template-columns: repeat(auto-fill, minmax(340px, 1fr));
grid-template-columns: repeat(auto-fill, minmax(min(340px, 100%), 1fr));
gap: var(--spacing-md);
}
.topic-card {
@@ -565,7 +565,7 @@
</head>
<body>
<div id="app" v-cloak>
<uni-nav title="内容工厂" :username="currentUser.username" :is-admin="isAdmin" current-page="factory" @navigate="redirectToPage" @logout="handleLogout">
<uni-nav v-if="!isEmbed" title="内容工厂" :username="currentUser.username" :is-admin="isAdmin" current-page="factory" @navigate="redirectToPage" @logout="handleLogout">
</uni-nav>
<div class="main-content">
@@ -838,6 +838,7 @@
const FactoryApp = {
data() {
return {
isEmbed: false,
isLoggedIn: false,
isAdmin: false,
currentUser: { username: '' },
@@ -1037,7 +1038,7 @@ const FactoryApp = {
});
},
goToArticles() {
window.location.href = '/articles.html';
this.redirectToPage('/articles.html');
},
handleLogout() {
localStorage.removeItem('authToken');
@@ -1046,7 +1047,9 @@ const FactoryApp = {
window.location.href = '/login.html';
},
redirectToPage(page) {
window.location.href = page.startsWith('/') ? page : '/' + page;
const url = page.startsWith('/') ? page : '/' + page;
if (this.isEmbed) window.top.location.href = url;
else window.location.href = url;
}
},
mounted() {
@@ -1055,6 +1058,7 @@ const FactoryApp = {
window.location.href = '/login.html';
return;
}
if (new URLSearchParams(window.location.search).get('embed') === '1') { this.isEmbed = true; document.body.classList.add('embed'); }
fetch('/api/auth/me', {
headers: { 'Authorization': 'Bearer ' + token }
})