qs_xinchun2026_h5/components/AICoupletForm.vue

292 lines
5.3 KiB
Vue
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<template>
<div class="form-modal" v-if="visible">
<div class="modal-overlay"></div>
<div class="modal-content">
<div class="modal-body">
<div class="couplet-form">
<div class="form-row">
<div class="input-group">
<label class="label">上联首字</label>
<input
v-model="topKeyword"
type="text"
maxlength="1"
class="underline-input"
@input="validateCharacter('top')"
/>
</div>
<div class="input-group">
<label class="label">下联首字:</label>
<input
v-model="bottomKeyword"
type="text"
maxlength="1"
class="underline-input"
@input="validateCharacter('bottom')"
/>
</div>
</div>
<div class="form-actions">
<img
src="/static/images/btn_submit.png"
class="submit-btn-image"
@click="generateCouplet"
/>
</div>
</div>
</div>
</div>
<div class="close-button-area">
<img
src="/static/images/btn_close.png"
class="close-button-image"
@click="$emit('close')"
/>
</div>
</div>
</template>
<script setup>
import { ref, computed } from 'vue'
const props = defineProps({
visible: {
type: Boolean,
default: false
}
})
const emit = defineEmits(['close', 'generate'])
const topKeyword = ref('')
const bottomKeyword = ref('')
// 校验是否为汉字
const isChineseCharacter = (char) => {
return /^[\u4e00-\u9fa5]$/.test(char)
}
// 校验输入字符
const validateCharacter = (type) => {
if (type === 'top' && topKeyword.value) {
if (!isChineseCharacter(topKeyword.value)) {
topKeyword.value = ''
uni.showToast({
title: '请输入汉字',
icon: 'none',
duration: 2000
})
}
}
if (type === 'bottom' && bottomKeyword.value) {
if (!isChineseCharacter(bottomKeyword.value)) {
bottomKeyword.value = ''
uni.showToast({
title: '请输入汉字',
icon: 'none',
duration: 2000
})
}
}
}
// 表单是否有效
const isFormValid = computed(() => {
return topKeyword.value && bottomKeyword.value
})
// 生成春联
const generateCouplet = () => {
if (!isFormValid.value) {
uni.showToast({
title: '请输入完整的上下联首字',
icon: 'none',
duration: 2000
})
return
}
emit('generate', topKeyword.value + bottomKeyword.value)
topKeyword.value = ''
bottomKeyword.value = ''
}
</script>
<style scoped>
.form-modal {
position: fixed;
top: 0;
left: 0;
width: 100%;
height: 100%;
z-index: 999;
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
}
.modal-overlay {
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
background: rgba(0, 0, 0, 0.7);
}
.modal-content {
position: relative;
z-index: 99;
width: 697rpx;
height: 417rpx;
background-image: url('/static/info/couplet_info_box.png');
background-size: 100% 100%;
background-repeat: no-repeat;
display: flex;
flex-direction: column;
}
.modal-header {
display: flex;
justify-content: space-between;
align-items: center;
padding: 30rpx;
}
.modal-header h3 {
margin: 0;
font-size: 36rpx;
color: #333;
}
.close-btn {
background: none;
border: none;
font-size: 48rpx;
cursor: pointer;
color: #666;
}
.modal-body {
flex: 1;
display: flex;
align-items: center;
justify-content: center;
padding: 0 55rpx;
}
.couplet-form {
width: 100%;
margin-top: 150rpx;
text-align: center;
}
.form-title {
font-size: 48rpx;
color: #fff;
margin-bottom: 80rpx;
font-weight: bold;
text-shadow: 2rpx 2rpx 4rpx rgba(0, 0, 0, 0.3);
}
.form-row {
display: flex;
flex-direction: row;
justify-content: space-between;
align-items: center;
margin-bottom: 60rpx;
flex-wrap: wrap;
}
.input-group {
width: 45%;
display: flex;
flex-direction: row;
align-items: flex-end;
gap: 10rpx;
}
.label {
color: white;
font-size: 32rpx;
text-shadow: 1rpx 1rpx 2rpx rgba(0, 0, 0, 0.3);
align-self: flex-end;
}
.underline-input {
width: 80rpx;
height: 32rpx;
line-height: 32rpx;
background-color: transparent;
border: none;
border-bottom: 2rpx solid white;
color: white;
font-size: 32rpx;
text-align: center;
outline: none;
padding: 0;
}
.underline-input:focus {
border-bottom: 3rpx solid #fff;
}
/* 响应式设计 */
@media (max-width: 750rpx) {
.form-row {
flex-direction: column;
gap: 20rpx;
}
.input-group {
margin-bottom: 15rpx;
}
}
.form-actions {
display: flex;
justify-content: center;
}
.submit-btn-image {
width: 306rpx;
height: 97rpx;
cursor: pointer;
transition: all 0.3s;
}
.submit-btn-image:hover {
transform: scale(1.05);
}
.submit-btn-image.disabled {
opacity: 0.5;
cursor: not-allowed;
}
.submit-btn-image.disabled:hover {
transform: none;
}
.close-button-area {
display: flex;
justify-content: center;
align-items: center;
padding: 30rpx 0;
z-index: 99;
}
.close-button-image {
width: 61rpx;
height: 60rpx;
cursor: pointer;
transition: all 0.3s;
}
.close-button-image:hover {
transform: scale(1.1);
}
</style>