generated from duanshuwen/webapp-vue-frontend
Compare commits
2 Commits
76b6bf5bd3
...
453d2f0580
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
453d2f0580 | ||
|
|
ef62e52746 |
BIN
src/assets/images/guide_error.png
Normal file
BIN
src/assets/images/guide_error.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 1.1 KiB |
BIN
src/assets/images/guide_success.png
Normal file
BIN
src/assets/images/guide_success.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 998 B |
106
src/views/components/AgreementTip.vue
Normal file
106
src/views/components/AgreementTip.vue
Normal file
@@ -0,0 +1,106 @@
|
|||||||
|
<template>
|
||||||
|
<div class="tip-wrapper">
|
||||||
|
<!-- 标题 -->
|
||||||
|
<h2 class="tip-title">温馨提示</h2>
|
||||||
|
|
||||||
|
<!-- 正文内容 -->
|
||||||
|
<div class="tip-content">
|
||||||
|
欢迎使用【智念科技服务有限公司】提供的AI生成合影服务。
|
||||||
|
本服务通过人工智能技术(AIGC)将您上传的照片与景区场景模板进行创意合成,
|
||||||
|
为您生成具有特定风格的纪念图片。请您仔细阅读
|
||||||
|
<span class="link-text" @click.stop="handleViewRule">《智念AI用户规则》</span>
|
||||||
|
,您点击“我同意”等进行下一步操作的行为均视为您同意受本规则约束。
|
||||||
|
如您不同意,您可以直接关闭页面。
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- 底部按钮 -->
|
||||||
|
<div class="tip-footer">
|
||||||
|
<button class="btn-cancel" @click="$emit('cancel')">取消</button>
|
||||||
|
<button class="btn-confirm" @click="$emit('confirm')">我同意</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script setup>
|
||||||
|
const emit = defineEmits(['cancel', 'confirm', 'view-rule']);
|
||||||
|
|
||||||
|
const handleViewRule = () => {
|
||||||
|
emit('view-rule');
|
||||||
|
};
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style scoped>
|
||||||
|
.tip-wrapper {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
align-items: center;
|
||||||
|
background-color: #fff;
|
||||||
|
/* 宽度自适应 popup */
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 标题样式 */
|
||||||
|
.tip-title {
|
||||||
|
font-size: 18px;
|
||||||
|
font-weight: bold;
|
||||||
|
color: #000;
|
||||||
|
margin: 0 0 20px 0;
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 正文样式 */
|
||||||
|
.tip-content {
|
||||||
|
font-size: 14px;
|
||||||
|
color: #666;
|
||||||
|
line-height: 1.6;
|
||||||
|
text-align: justify;
|
||||||
|
/* 两端对齐,更接近原图感 */
|
||||||
|
margin-bottom: 30px;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 绿色链接文字 */
|
||||||
|
.link-text {
|
||||||
|
color: #07c160;
|
||||||
|
/* 微信绿 */
|
||||||
|
font-weight: 500;
|
||||||
|
cursor: pointer;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 底部按钮布局 */
|
||||||
|
.tip-footer {
|
||||||
|
display: flex;
|
||||||
|
justify-content: space-between;
|
||||||
|
width: 100%;
|
||||||
|
gap: 15px;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 通用按钮基础 */
|
||||||
|
button {
|
||||||
|
flex: 1;
|
||||||
|
height: 44px;
|
||||||
|
border-radius: 22px;
|
||||||
|
font-size: 16px;
|
||||||
|
font-weight: 500;
|
||||||
|
cursor: pointer;
|
||||||
|
transition: opacity 0.2s;
|
||||||
|
outline: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
button:active {
|
||||||
|
opacity: 0.7;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 取消按钮:白底黑字带边框 */
|
||||||
|
.btn-cancel {
|
||||||
|
background-color: #fff;
|
||||||
|
color: #333;
|
||||||
|
border: 1px solid #e0e0e0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 同意按钮:黑底白字 */
|
||||||
|
.btn-confirm {
|
||||||
|
background-color: #000;
|
||||||
|
color: #fff;
|
||||||
|
border: none;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
189
src/views/components/PhotoGuide.vue
Normal file
189
src/views/components/PhotoGuide.vue
Normal file
@@ -0,0 +1,189 @@
|
|||||||
|
<template>
|
||||||
|
<div class="guide-wrapper">
|
||||||
|
<!-- 顶部标题栏 -->
|
||||||
|
<div class="guide-header">
|
||||||
|
选图说明
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- 中间滚动区域 -->
|
||||||
|
<div class="guide-content">
|
||||||
|
<!-- 正确示例 -->
|
||||||
|
<section class="example-section">
|
||||||
|
<h2 class="section-title">正确照片示例</h2>
|
||||||
|
<div class="example-grid">
|
||||||
|
<div v-for="(item, index) in correctExamples" :key="index" class="example-item">
|
||||||
|
<div class="img-box border-success">
|
||||||
|
<img :src="item.url" class="main-img" />
|
||||||
|
</div>
|
||||||
|
<div class="status-label color-success">
|
||||||
|
<!-- 替换为成功图标图片 -->
|
||||||
|
<img src="@/assets/images/guide_success.png" class="status-icon-img" />
|
||||||
|
{{ item.text }}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
|
||||||
|
<!-- 错误示例 -->
|
||||||
|
<section class="example-section">
|
||||||
|
<h2 class="section-title">错误照片示例</h2>
|
||||||
|
<div class="example-grid">
|
||||||
|
<div v-for="(item, index) in errorExamples" :key="index" class="example-item">
|
||||||
|
<div class="img-box border-error">
|
||||||
|
<img :src="item.url" class="main-img" />
|
||||||
|
</div>
|
||||||
|
<div class="status-label color-error">
|
||||||
|
<!-- 替换为错误图标图片 -->
|
||||||
|
<img src="@/assets/images/guide_error.png" class="status-icon-img" />
|
||||||
|
{{ item.text }}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- 底部固定按钮 -->
|
||||||
|
<div class="guide-footer">
|
||||||
|
<button class="action-btn" @click="$emit('start')">
|
||||||
|
已了解,开始选图
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script setup>
|
||||||
|
const emit = defineEmits(['start']);
|
||||||
|
|
||||||
|
// 测试数据保持不变
|
||||||
|
const correctExamples = [
|
||||||
|
{ url: 'https://picsum.photos/id/64/200', text: '单人正脸' },
|
||||||
|
{ url: 'https://picsum.photos/id/65/200', text: '多表情' },
|
||||||
|
{ url: 'https://picsum.photos/id/66/200', text: '多背景' },
|
||||||
|
];
|
||||||
|
|
||||||
|
const errorExamples = [
|
||||||
|
{ url: 'https://picsum.photos/id/177/200', text: '非清晰正脸' },
|
||||||
|
{ url: 'https://picsum.photos/id/103/200', text: '面部有遮挡' },
|
||||||
|
{ url: 'https://picsum.photos/id/104/200', text: '多人合照' },
|
||||||
|
];
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style scoped>
|
||||||
|
.guide-wrapper {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
height: 100%;
|
||||||
|
background-color: #fff;
|
||||||
|
font-family: -apple-system, system-ui, sans-serif;
|
||||||
|
}
|
||||||
|
|
||||||
|
.guide-header {
|
||||||
|
height: 60px;
|
||||||
|
line-height: 60px;
|
||||||
|
text-align: center;
|
||||||
|
font-size: 18px;
|
||||||
|
font-weight: 600;
|
||||||
|
color: #333;
|
||||||
|
flex-shrink: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.guide-content {
|
||||||
|
flex: 1;
|
||||||
|
overflow-y: auto;
|
||||||
|
padding: 0 20px;
|
||||||
|
-webkit-overflow-scrolling: touch;
|
||||||
|
}
|
||||||
|
|
||||||
|
.example-section {
|
||||||
|
margin-bottom: 25px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.section-title {
|
||||||
|
font-size: 14px;
|
||||||
|
color: #999;
|
||||||
|
margin-bottom: 12px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.example-grid {
|
||||||
|
display: grid;
|
||||||
|
grid-template-columns: repeat(3, 1fr);
|
||||||
|
gap: 12px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.example-item {
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.img-box {
|
||||||
|
width: 100%;
|
||||||
|
aspect-ratio: 1 / 1;
|
||||||
|
border-radius: 8px;
|
||||||
|
overflow: hidden;
|
||||||
|
background-color: #f5f5f5;
|
||||||
|
border: 1px dashed #ddd;
|
||||||
|
box-sizing: border-box;
|
||||||
|
}
|
||||||
|
|
||||||
|
.main-img {
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
object-fit: cover;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 状态标签样式 */
|
||||||
|
.status-label {
|
||||||
|
margin-top: 8px;
|
||||||
|
font-size: 12px;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
gap: 4px;
|
||||||
|
line-height: 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 状态图标图片样式 */
|
||||||
|
.status-icon-img {
|
||||||
|
width: 14px;
|
||||||
|
/* 根据UI图调整大小 */
|
||||||
|
height: 14px;
|
||||||
|
object-fit: contain;
|
||||||
|
}
|
||||||
|
|
||||||
|
.color-success {
|
||||||
|
color: #07c160;
|
||||||
|
}
|
||||||
|
|
||||||
|
.color-error {
|
||||||
|
color: #ee0a24;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 特殊边框色微调(可选) */
|
||||||
|
.border-success {
|
||||||
|
border-color: rgba(7, 193, 96, 0.3);
|
||||||
|
}
|
||||||
|
|
||||||
|
.border-error {
|
||||||
|
border-color: rgba(238, 10, 36, 0.3);
|
||||||
|
}
|
||||||
|
|
||||||
|
.guide-footer {
|
||||||
|
padding: 15px 20px 30px;
|
||||||
|
flex-shrink: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.action-btn {
|
||||||
|
width: 100%;
|
||||||
|
height: 50px;
|
||||||
|
background-color: #000;
|
||||||
|
color: #fff;
|
||||||
|
border: none;
|
||||||
|
border-radius: 25px;
|
||||||
|
font-size: 16px;
|
||||||
|
font-weight: 500;
|
||||||
|
cursor: pointer;
|
||||||
|
}
|
||||||
|
|
||||||
|
.action-btn:active {
|
||||||
|
opacity: 0.8;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
@@ -31,7 +31,7 @@
|
|||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import { useRouter } from 'vue-router';
|
import { useRouter } from 'vue-router';
|
||||||
// @ts-ignore
|
// @ts-ignore
|
||||||
import NavBar from '../components/navBar.vue';
|
import NavBar from '../components/NavBar.vue';
|
||||||
|
|
||||||
const router = useRouter();
|
const router = useRouter();
|
||||||
|
|
||||||
|
|||||||
@@ -43,7 +43,7 @@
|
|||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import { useRouter } from 'vue-router';
|
import { useRouter } from 'vue-router';
|
||||||
// @ts-ignore
|
// @ts-ignore
|
||||||
import NavBar from '../components/navBar.vue';
|
import NavBar from '../components/NavBar.vue';
|
||||||
|
|
||||||
interface TaskItem {
|
interface TaskItem {
|
||||||
id: number
|
id: number
|
||||||
|
|||||||
@@ -33,12 +33,26 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<!-- 协议提示 -->
|
||||||
|
<van-popup v-model:show="showAgree" round :close-on-click-overlay="false"
|
||||||
|
:style="{ padding: '30px 24px', width: '80%' }">
|
||||||
|
<AgreementTip @cancel="showAgree = false" @confirm="onAgree" @view-rule="onViewRule" />
|
||||||
|
</van-popup>
|
||||||
|
|
||||||
|
<!-- 选图说明 -->
|
||||||
|
<van-popup v-model:show="showGuide" round position="bottom" closeable close-icon-position="top-left">
|
||||||
|
<PhotoGuide @start="onStartSelect" />
|
||||||
|
</van-popup>
|
||||||
|
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup>
|
<script setup>
|
||||||
import { ref, computed } from 'vue';
|
import { ref, computed } from 'vue';
|
||||||
import { useRouter } from 'vue-router';
|
import { useRouter } from 'vue-router';
|
||||||
import NavBar from '../components/navBar.vue';
|
import NavBar from '../components/NavBar.vue';
|
||||||
|
import PhotoGuide from '../components/PhotoGuide.vue';
|
||||||
|
import AgreementTip from '../components/AgreementTip.vue';
|
||||||
|
|
||||||
// --- 测试数据 ---
|
// --- 测试数据 ---
|
||||||
const styles = [
|
const styles = [
|
||||||
@@ -62,11 +76,26 @@ const mockData = {
|
|||||||
]
|
]
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const router = useRouter();
|
||||||
|
|
||||||
// --- 状态 ---
|
// --- 状态 ---
|
||||||
const activeStyleId = ref('real');
|
const activeStyleId = ref('real');
|
||||||
const activeSceneIndex = ref(0);
|
const activeSceneIndex = ref(0);
|
||||||
|
const showGuide = ref(false);
|
||||||
|
|
||||||
|
const showAgree = ref(true);
|
||||||
|
|
||||||
|
const onAgree = () => {
|
||||||
|
console.log("用户同意了协议");
|
||||||
|
showAgree.value = false;
|
||||||
|
// 执行下一步选图逻辑
|
||||||
|
};
|
||||||
|
|
||||||
|
const onViewRule = () => {
|
||||||
|
console.log("跳转到规则详情页");
|
||||||
|
// 可以是打开另一个 popup 或者 router.push
|
||||||
|
};
|
||||||
|
|
||||||
const router = useRouter();
|
|
||||||
|
|
||||||
const onBack = () => {
|
const onBack = () => {
|
||||||
router.back();
|
router.back();
|
||||||
@@ -77,9 +106,17 @@ const onHistory = () => {
|
|||||||
};
|
};
|
||||||
|
|
||||||
const generateAction = () => {
|
const generateAction = () => {
|
||||||
router.push('/generate');
|
showGuide.value = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const onStartSelect = () => {
|
||||||
|
console.log("用户已阅读说明,开始打开相册逻辑...");
|
||||||
|
showGuide.value = false;
|
||||||
|
// 这里写调用系统相册的代码
|
||||||
|
router.push('/generate');
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
// --- 计算属性 ---
|
// --- 计算属性 ---
|
||||||
const currentScenes = computed(() => mockData[activeStyleId.value] || []);
|
const currentScenes = computed(() => mockData[activeStyleId.value] || []);
|
||||||
const activeScene = computed(() => currentScenes.value[activeSceneIndex.value] || {});
|
const activeScene = computed(() => currentScenes.value[activeSceneIndex.value] || {});
|
||||||
|
|||||||
@@ -32,7 +32,7 @@
|
|||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import { useRouter, useRoute } from 'vue-router';
|
import { useRouter, useRoute } from 'vue-router';
|
||||||
// @ts-ignore
|
// @ts-ignore
|
||||||
import NavBar from '../components/navBar.vue';
|
import NavBar from '../components/NavBar.vue';
|
||||||
import { ref, computed } from 'vue';
|
import { ref, computed } from 'vue';
|
||||||
// @ts-ignore
|
// @ts-ignore
|
||||||
import VueEasyLightbox from 'vue-easy-lightbox';
|
import VueEasyLightbox from 'vue-easy-lightbox';
|
||||||
|
|||||||
Reference in New Issue
Block a user