475 lines
11 KiB
Vue

<template>
<div class="certificate-new">
<div class="top-section">
<h1 class="page-title">新建证书11</h1>
<!-- 右侧区域 -->
<div class="right-section" :class="{ 'collapsed': isCollapsed }">
<div class="content">
<!-- 顶部按钮 -->
<div class="header-buttons">
<button class="btn btn-preview">证书预览</button>
<button class="btn btn-save">保存</button>
</div>
<!-- 证书背景 -->
<div class="section">
<h3 class="section-title">证书背景</h3>
<div class="color-palette">
<div class="color-item rainbow" :class="{ 'selected': selectedColor === customColor }" @click="showColorPicker = !showColorPicker">
<input
v-if="showColorPicker"
type="color"
:value="customColor"
@input="selectCustomColor($event.target.value)"
class="color-input-inline"
@click.stop
/>
</div>
<div class="color-item black" :class="{ 'selected': selectedColor === '#000000' }" @click="selectColor('#000000')"></div>
<div class="color-item dark-gray" :class="{ 'selected': selectedColor === '#333333' }" @click="selectColor('#333333')"></div>
<div class="color-item gray" :class="{ 'selected': selectedColor === '#666666' }" @click="selectColor('#666666')"></div>
<div class="color-item light-gray" :class="{ 'selected': selectedColor === '#999999' }" @click="selectColor('#999999')"></div>
<div class="color-item white" :class="{ 'selected': selectedColor === '#ffffff' }" @click="selectColor('#ffffff')"></div>
<div class="color-item red" :class="{ 'selected': selectedColor === '#ff0000' }" @click="selectColor('#ff0000')"></div>
<div class="color-item orange" :class="{ 'selected': selectedColor === '#ff8000' }" @click="selectColor('#ff8000')"></div>
<div class="color-item pink" :class="{ 'selected': selectedColor === '#ff80ff' }" @click="selectColor('#ff80ff')"></div>
<div class="color-item purple" :class="{ 'selected': selectedColor === '#8000ff' }" @click="selectColor('#8000ff')"></div>
<div class="color-item green" :class="{ 'selected': selectedColor === '#00ff00' }" @click="selectColor('#00ff00')"></div>
<div class="color-item teal" :class="{ 'selected': selectedColor === '#00ffff' }" @click="selectColor('#00ffff')"></div>
<div class="color-item light-blue" :class="{ 'selected': selectedColor === '#80ffff' }" @click="selectColor('#80ffff')"></div>
<div class="color-item blue" :class="{ 'selected': selectedColor === '#0080ff' }" @click="selectColor('#0080ff')"></div>
</div>
<div class="template-preview">
<div class="certificate-template">
<img src="/images/teacher/certificate.png" alt="证书模板" />
</div>
</div>
<button class="btn btn-replace btn-full-width">替换背景图</button>
</div>
<!-- 添加元素 -->
<div class="section">
<h3 class="section-title">添加元素</h3>
<div class="element-buttons">
<button class="btn btn-add">添加文字</button>
<button class="btn btn-add">添加图片</button>
</div>
</div>
<!-- 证书信息 -->
<div class="section">
<h3 class="section-title">证书信息</h3>
<div class="info-fields">
<div class="field">证书编号</div>
<div class="field">发证日期</div>
<div class="field">颁发机构</div>
<div class="field">有效期至</div>
<div class="field">核验二维码</div>
</div>
</div>
<!-- 学员信息 -->
<div class="section">
<h3 class="section-title">学员信息</h3>
<div class="info-fields">
<div class="field">学员姓名</div>
<div class="field">学员帐号</div>
<div class="field">班级名称</div>
<div class="field">自定义文字</div>
</div>
</div>
<!-- 考试信息 -->
<div class="section">
<h3 class="section-title">考试信息</h3>
<div class="info-fields">
<div class="field">考试名称</div>
<div class="field">考试分数</div>
<div class="field">考试评语</div>
</div>
</div>
</div>
<!-- 收起/展开按钮 -->
<div class="collapse-button" @click="toggleCollapse">
<img src="/images/teacher/上传2.png" alt="收起/展开" class="arrow" :class="{ 'collapsed': isCollapsed }" />
</div>
</div>
</div>
<div class="certificate-content" :style="{ backgroundColor: selectedColor }">
<img src="/images/teacher/certificate.png" alt="">
</div>
</div>
</template>
<script setup lang="ts">
import { ref, onMounted, onUnmounted } from 'vue'
import { useRoute } from 'vue-router'
const route = useRoute()
// 保存原始样式
let originalPadding = ''
// 右侧面板收起状态
const isCollapsed = ref(false)
// 选中的背景颜色
const selectedColor = ref('#ffffff')
// 自定义颜色
const customColor = ref('#ff0000')
// 显示颜色选择器
const showColorPicker = ref(false)
// 切换收起/展开状态
const toggleCollapse = () => {
isCollapsed.value = !isCollapsed.value
}
// 选择背景颜色
const selectColor = (color: string) => {
selectedColor.value = color
}
// 选择自定义颜色
const selectCustomColor = (color: string) => {
customColor.value = color
selectedColor.value = color
showColorPicker.value = false
}
// 获取URL参数
onMounted(() => {
console.log('新建证书页面参数:', route.query)
// 动态修改上级容器的内边距,只影响当前页面
const routerViewContainer = document.querySelector('.router-view-container') as HTMLElement
if (routerViewContainer) {
// 保存原始样式
originalPadding = routerViewContainer.style.padding
// 设置新样式
routerViewContainer.style.padding = '0'
}
})
// 组件卸载时恢复原始样式
onUnmounted(() => {
const routerViewContainer = document.querySelector('.router-view-container') as HTMLElement
if (routerViewContainer) {
routerViewContainer.style.padding = originalPadding
}
})
</script>
<style scoped>
/* 只在当前页面覆盖上级容器的内边距 */
.certificate-new:deep(.router-view-container) {
padding: 0 !important;
}
.certificate-new:deep(.router-view-container.full-width) {
padding: 0 !important;
}
/* 确保页面内容不受上级容器影响 */
.certificate-new {
margin: 0;
padding: 0;
width: 100%;
min-height: 100vh;
background: #F6F6F6;
display: flex;
flex-direction: column;
}
.top-section {
width: 100%;
height: 80px;
background-color: #fff;
position: relative;
margin-bottom: 20px;
}
.right-section {
position: absolute;
top: 0;
right: 0;
width: 240px;
height: 100vh;
background: #fff;
transition: transform 0.3s ease;
}
.right-section.collapsed {
transform: translateX(240px);
}
.collapse-button {
position: absolute;
left: -40px;
top: 50%;
transform: translateY(-50%);
height: 0;
width: 60px;
border-bottom: 20px solid #fff;
border-left: 10px solid transparent;
border-right: 10px solid transparent;
transform: rotate(-90deg);
transform-origin: center;
display: flex;
align-items: center;
justify-content: center;
cursor: pointer;
z-index: 10;
transition: all 0.3s ease;
}
.collapse-button:hover {
background: #f5f5f5;
}
.arrow {
margin-top: 20px;
width: 10px;
height: 6px;
transition: transform 0.3s ease;
transform: rotate(180deg);
}
.arrow.collapsed {
transform: rotate(0);
}
.content {
margin: auto;
background: #fff;
padding: 20px;
height: 100%;
overflow-y: auto;
}
.header-buttons {
display: flex;
gap: 10px;
margin-bottom: 20px;
}
.btn {
min-width: 90px;
padding: 6px 16px;
border-radius: 2px;
border: 1px solid #E6E6E6;
background: #fff;
cursor: pointer;
font-size: 14px;
transition: all 0.3s ease;
}
.btn-preview {
background: #E3F2FD;
color: #0288D1;
border-color: #0288D1;
}
.btn-save {
background: #0288D1;
color: #fff;
border-color: #0288D1;
}
.btn-add,
.btn-replace {
background: #F5F5F5;
color: #666666;
font-size: 12px;
border: none;
padding: 8px 0;
}
.btn-full-width {
width: 100%;
border: none;
color: #666666;
font-size: 12px;
}
.btn:hover {
opacity: 0.8;
}
.section {
margin-bottom: 20px;
}
.section-title {
font-size: 14px;
font-weight: 500;
color: #333;
margin-bottom: 10px;
}
.color-palette {
padding: 10px;
background-color: #F7F8FA;
display: grid;
grid-template-columns: repeat(7, 1fr);
gap: 4px;
margin-bottom: 15px;
}
.color-item {
width: 20px;
height: 20px;
border-radius: 2px;
cursor: pointer;
border: 1px solid #E6E6E6;
}
.color-item.rainbow {
background: linear-gradient(45deg, #ff0000, #ff8000, #ffff00, #80ff00, #00ff00, #00ff80, #00ffff, #0080ff, #0000ff, #8000ff, #ff00ff, #ff0080);
}
.color-item.black {
background: #000;
}
.color-item.dark-gray {
background: #333;
}
.color-item.gray {
background: #666;
}
.color-item.light-gray {
background: #999;
}
.color-item.white {
background: #fff;
}
.color-item.red {
background: #ff0000;
}
.color-item.orange {
background: #ff8000;
}
.color-item.pink {
background: #ff80ff;
}
.color-item.purple {
background: #8000ff;
}
.color-item.green {
background: #00ff00;
}
.color-item.teal {
background: #00ffff;
}
.color-item.light-blue {
background: #80ffff;
}
.color-item.blue {
background: #0080ff;
}
.color-item.selected {
border: 2px solid #0288D1;
transform: scale(1.1);
}
.template-preview {
margin-bottom: 15px;
}
.certificate-template {
width: 100%;
height: 100px;
background-color: #F7F8FA;
position: relative;
display: flex;
align-items: center;
justify-content: center;
overflow: hidden;
}
.certificate-template img {
width: 111px;
height: 83px;
object-fit: cover;
}
.element-buttons {
display: grid;
grid-template-columns: 1fr 1fr;
gap: 10px;
}
.info-fields {
display: grid;
grid-template-columns: 1fr 1fr;
gap: 8px;
text-align: center;
}
.field {
padding: 7px 12px;
background: #F7F8FA;
border: none;
border-radius: 4px;
font-size: 12px;
color: #666666;
cursor: pointer;
}
.field:hover {
background: #E8E8E8;
}
/* 内联颜色选择器样式 */
.color-input-inline {
width: 100%;
height: 100%;
border: none;
border-radius: 2px;
cursor: pointer;
opacity: 0;
position: absolute;
top: 0;
left: 0;
}
.color-item.rainbow {
position: relative;
}
.certificate-content {
width: 1000px;
height: 89vh;
margin: 0 auto;
background-color: #fff;
display: flex;
justify-content: center;
align-items: center;
}
.certificate-content img {
width: 800px;
}
</style>