first commit

This commit is contained in:
Vicky committed 2026-10-12 17:35:07 +08:00
commit db15eb3ee0
42 files changed
+4620

No files matched your search

+23
View File
@@ -0,0 +1,23 @@
<script setup>
import { useRouter } from 'vue-router'
import { VideoCamera, User, Clock, CaretRight, Plus } from '@element-plus/icons-vue'
import { dramas } from '@/data/dramas'
import { useRbac } from '@/stores/rbac'
import { statusClass } from '@/utils/status'
const router = useRouter()
const { can } = useRbac()
</script>
<template>
<div class="page-heading"><div><div class="eyebrow">内容概览</div><h1>工作台</h1><p>查看短剧内容与近期处理事项。</p></div><el-button v-if="can('创建短剧')" type="primary" class="primary-button" @click="router.push({name:'dramas'})"><el-icon><Plus /></el-icon>上传新短剧</el-button></div>
<div class="stats-grid">
<div class="stat-card"><div class="stat-top"><span>短剧总数</span><span class="stat-icon"><el-icon><VideoCamera /></el-icon></span></div><div class="stat-value">{{dramas.length}} <small>部</small></div></div>
<div class="stat-card"><div class="stat-top"><span>累计播放量</span><span class="stat-icon"><el-icon><CaretRight /></el-icon></span></div><div class="stat-value">8.64 <small>千万</small></div></div>
<div class="stat-card"><div class="stat-top"><span>待审核内容</span><span class="stat-icon"><el-icon><Clock /></el-icon></span></div><div class="stat-value">06 <small>项</small></div></div>
<div class="stat-card"><div class="stat-top"><span>本月新增用户</span><span class="stat-icon"><el-icon><User /></el-icon></span></div><div class="stat-value">12,486 <small>人</small></div></div>
</div>
<section class="panel recent-panel"><div class="panel-heading"><div><h2>最近更新</h2><p>短剧内容与发布状态</p></div><el-button text class="view-all" @click="router.push({name:'dramas'})">短剧管理</el-button></div>
<el-table :data="dramas.slice(0,5)" row-key="id" class="dashboard-el-table"><el-table-column prop="title" label="短剧名称" min-width="280"/><el-table-column prop="genre" label="类型" width="150"/><el-table-column label="集数" width="120"><template #default="{row}">{{row.episodes}} 集</template></el-table-column><el-table-column prop="views" label="播放量" width="140"/><el-table-column label="状态" width="130"><template #default="{row}"><el-tag :class="['status-badge',statusClass(row.status)]" effect="light">{{row.status}}</el-tag></template></el-table-column><el-table-column prop="updatedAt" label="更新时间" width="160"/></el-table>
</section>
</template>
+73
View File
@@ -0,0 +1,73 @@
<script setup>
import { ref } from 'vue'
import { useRouter } from 'vue-router'
import { ElMessage } from 'element-plus'
import { useAuth } from '@/stores/auth'
const router = useRouter()
const { login } = useAuth()
const form = ref({ username: 'admin', password: '' })
const error = ref('')
function submit() {
if (!login(form.value.username, form.value.password)) {
error.value = '账号或密码不正确。'
return
}
error.value = ''
ElMessage.success('登录成功')
router.replace({ name: 'dashboard' })
}
</script>
<template>
<main class="login-screen">
<section class="login-cover">
<div class="cover-decoration decoration-one"></div><div class="cover-decoration decoration-two"></div>
<div class="cover-logo"><div class="brand-mark"><span></span><span></span><span></span></div><span>reelshort</span><small>STUDIO CONSOLE</small></div>
<div class="cover-copy"><span>REELSHORT STUDIO</span><h2>每一个故事<br>都值得被看见</h2><p>短剧内容创作与运营管理平台</p></div>
<div class="cover-bottom">SHORT DRAMA · CONTENT STUDIO</div>
</section>
<section class="login-panel">
<div class="login-content">
<div class="login-heading"><h1>登录管理后台</h1><p>使用工作空间账号继续</p></div>
<el-form label-position="top" @submit.prevent="submit">
<el-form-item label="账号"><el-input v-model="form.username" placeholder="请输入账号" autocomplete="username" /></el-form-item>
<el-form-item label="密码"><el-input v-model="form.password" type="password" placeholder="请输入密码" autocomplete="current-password" show-password @keyup.enter="submit" /></el-form-item>
<div v-if="error" class="login-error">{{error}}</div>
<el-button type="primary" class="login-submit primary-button" @click="submit">登录</el-button>
</el-form>
<div class="demo-credentials">演示账号:admin <i></i> 密码:admin123</div>
</div>
<footer class="login-footer">© 2026 ReelShort Studio</footer>
</section>
</main>
</template>
<style scoped>
.login-screen { min-height:100vh; display:grid; grid-template-columns:1.05fr .95fr; overflow:hidden; background:#f8f9fb; }
.login-cover { position:relative; min-height:100vh; overflow:hidden; padding:42px 7vw; color:#fff; background:radial-gradient(ellipse at 72% 42%,rgba(196,167,150,.42),transparent 31%),radial-gradient(ellipse at 77% 44%,rgba(224,191,166,.62),transparent 16%),linear-gradient(160deg,#263d59 0%,#344d6c 44%,#1c2d44 100%); }
.login-cover::after { content:''; position:absolute; inset:0; background:linear-gradient(180deg,rgba(22,37,58,.05) 30%,rgba(16,27,42,.72)); }
.cover-logo,.cover-copy,.cover-bottom { position:relative; z-index:1; }
.cover-logo { display:flex; align-items:center; gap:8px; width:max-content; font:800 16px Manrope,'Noto Sans SC',sans-serif; letter-spacing:-.5px; }
.cover-logo small { margin-left:6px; padding-left:14px; border-left:1px solid rgba(255,255,255,.32); color:rgba(255,255,255,.66); font:600 9px Manrope,sans-serif; letter-spacing:1.7px; }
.brand-mark { width:28px; height:28px; border-radius:8px; background:rgba(255,255,255,.2); display:flex; align-items:center; justify-content:center; gap:2px; transform:rotate(-8deg); }
.brand-mark span { width:3px; border-radius:5px; background:#fff; transform:skew(-15deg); }
.brand-mark span:nth-child(1) { height:11px; opacity:.75; }.brand-mark span:nth-child(2) { height:17px; }.brand-mark span:nth-child(3) { height:13px; opacity:.85; }
.cover-copy { position:absolute; left:7vw; bottom:15%; }
.cover-copy span { color:#d9b49d; font:600 10px Manrope,sans-serif; letter-spacing:2.4px; }
.cover-copy h2 { margin:15px 0 12px; color:#fff; font-size:clamp(34px,4.1vw,56px); font-weight:700; line-height:1.35; letter-spacing:2px; }
.cover-copy p { margin:0; color:rgba(255,255,255,.7); font-size:15px; letter-spacing:1px; }
.cover-bottom { position:absolute; left:7vw; bottom:38px; color:rgba(255,255,255,.4); font:600 9px Manrope,sans-serif; letter-spacing:2px; }
.cover-decoration { position:absolute; pointer-events:none; width:min(39vw,520px); aspect-ratio:.72; right:7%; top:14%; border:1px solid rgba(255,255,255,.13); border-radius:48% 48% 18px 18px; transform:rotate(7deg); background:linear-gradient(150deg,rgba(231,190,163,.14),rgba(25,42,64,.2) 62%); }
.decoration-two { width:min(32vw,430px); right:12%; top:18%; transform:rotate(-7deg); opacity:.8; }
.login-panel { position:relative; min-height:100vh; display:flex; flex-direction:column; justify-content:center; padding:64px clamp(42px,7vw,110px); background:#f8f9fb; }
.login-content { width:min(100%,390px); align-self:center; }
.login-heading { margin:0 0 27px; }.login-heading h1 { margin:0; color:#252d38; font-size:24px; font-weight:700; letter-spacing:-.5px; }.login-heading p { margin:8px 0 0; color:#7f8998; font-size:13px; }
.login-panel :deep(.el-form-item) { margin-bottom:19px; }.login-panel :deep(.el-form-item__label) { padding-bottom:8px; color:#424c5a; font-size:14px; font-weight:600; }
.login-panel :deep(.el-input__wrapper) { min-height:44px; border-radius:7px; background:#fff; box-shadow:0 0 0 1px #dce2e9 inset; }.login-panel :deep(.el-input__wrapper.is-focus) { box-shadow:0 0 0 1px #4773b3 inset; }.login-panel :deep(.el-input__inner) { font-size:15px; }
.login-error { margin:-7px 0 14px; color:#d94b4b; font-size:13px; }.login-submit { width:100%; height:46px; margin-top:3px; border-radius:7px; background:#4773b3; border-color:#4773b3; font-size:15px; font-weight:600; }.login-submit:hover { background:#3d669f; border-color:#3d669f; }
.demo-credentials { display:flex; align-items:center; justify-content:center; gap:8px; margin-top:18px; color:#8791a0; font-size:12px; }.demo-credentials i { width:3px; height:3px; border-radius:50%; background:#b6bec8; }
.login-footer { position:absolute; left:clamp(42px,7vw,110px); bottom:32px; color:#a5acb7; font-size:11px; }
@media(max-width:700px) { .login-screen { grid-template-columns:1fr; }.login-cover { min-height:250px; padding:24px 26px; }.cover-copy { left:26px; bottom:38px; }.cover-copy h2 { margin:9px 0 5px; font-size:30px; }.cover-copy p { font-size:12px; }.cover-bottom { display:none; }.cover-decoration { width:160px; right:10%; top:8%; }.decoration-two { width:135px; right:14%; top:12%; }.login-panel { min-height:auto; padding:42px 28px 72px; }.login-footer { left:28px; bottom:25px; } }
@media(max-width:480px) { .login-cover { min-height:220px; padding:20px 22px; }.cover-copy { left:22px; bottom:30px; }.cover-copy h2 { font-size:26px; }.cover-logo small { display:none; }.login-panel { padding:34px 22px 68px; }.login-footer { left:22px; } }
</style>