upload project source code
This commit is contained in:
292
前端源码/uni-app/components/NamingResult.vue
Normal file
292
前端源码/uni-app/components/NamingResult.vue
Normal file
@@ -0,0 +1,292 @@
|
||||
<template>
|
||||
<view class="naming-result">
|
||||
<view class="naming-result-header">
|
||||
<text class="naming-result-title">甄选吉名</text>
|
||||
<view class="naming-result-reset" @click="$emit('reset')">
|
||||
<text>重测</text>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<view class="naming-result-list">
|
||||
<view v-for="item in results" :key="item.id" class="naming-result-item">
|
||||
<view class="naming-result-item-bg">✦</view>
|
||||
<view class="naming-result-item-actions">
|
||||
<view class="naming-result-action-btn" @click.stop="checkDup(item.id)">查重</view>
|
||||
<view
|
||||
class="naming-result-action-btn naming-result-action-btn-heart"
|
||||
:class="item.isFavorite ? 'naming-result-action-btn-heart-active' : ''"
|
||||
@click.stop="toggleFav(item.id)"
|
||||
>❤</view>
|
||||
</view>
|
||||
|
||||
<view class="naming-result-item-content" @click="handleItemClick(item)">
|
||||
<text class="naming-result-item-name">{{ item.name }}</text>
|
||||
<text class="naming-result-item-pinyin">{{ item.pinyin }}</text>
|
||||
</view>
|
||||
|
||||
<view class="naming-result-item-tags" @click="handleItemClick(item)">
|
||||
<text v-for="(t, i) in item.tags" :key="i" class="naming-result-tag">{{ t }}</text>
|
||||
<text v-if="item.duplicateRate" class="naming-result-tag naming-result-tag-gold">
|
||||
重名率: {{ item.duplicateRate }}
|
||||
</text>
|
||||
</view>
|
||||
|
||||
<view class="naming-result-item-divider"></view>
|
||||
|
||||
<view class="naming-result-item-details" @click="handleItemClick(item)">
|
||||
<view class="naming-result-detail-row">
|
||||
<text class="naming-result-detail-label naming-result-detail-label-primary">寓意</text>
|
||||
<text class="naming-result-detail-text">{{ item.meaning }}</text>
|
||||
</view>
|
||||
<view class="naming-result-detail-row">
|
||||
<text class="naming-result-detail-label">出处</text>
|
||||
<text class="naming-result-detail-text naming-result-detail-text-small">{{ item.source }}</text>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { ref, watch } from "vue";
|
||||
import { userApi } from "@/api";
|
||||
|
||||
declare const uni: any;
|
||||
|
||||
export interface GeneratedName {
|
||||
id: string;
|
||||
name: string;
|
||||
pinyin: string;
|
||||
meaning: string;
|
||||
source: string;
|
||||
tags: string[];
|
||||
isFavorite?: boolean;
|
||||
duplicateRate?: string;
|
||||
score?: number;
|
||||
zodiac?: string;
|
||||
wuxing?: string;
|
||||
constellation?: string;
|
||||
}
|
||||
|
||||
const props = withDefaults(defineProps<{
|
||||
data: GeneratedName[];
|
||||
category?: 'personal' | 'company';
|
||||
payBusinessId?: number;
|
||||
payAmount?: number;
|
||||
}>(), {
|
||||
category: 'company',
|
||||
payAmount: 9.9,
|
||||
});
|
||||
|
||||
const emit = defineEmits<{
|
||||
reset: [];
|
||||
showDetail: [data: GeneratedName];
|
||||
}>();
|
||||
|
||||
const results = ref<GeneratedName[]>([]);
|
||||
|
||||
watch(() => props.data, (newData: GeneratedName[]) => {
|
||||
if (newData) {
|
||||
results.value = newData.map((item: GeneratedName) => ({ ...item }));
|
||||
}
|
||||
}, { immediate: true });
|
||||
|
||||
const toggleFav = async (id: string) => {
|
||||
const idx = results.value.findIndex((r: GeneratedName) => r.id === id);
|
||||
if (idx < 0) return;
|
||||
|
||||
const solutionId = Number(id);
|
||||
const prev = !!results.value[idx].isFavorite;
|
||||
|
||||
if (!prev) {
|
||||
const res = await userApi.favoriteSolution({ solution_id: solutionId, category: props.category });
|
||||
results.value[idx].isFavorite = true;
|
||||
uni.showToast({ title: res?.msg || '收藏成功', icon: 'success' });
|
||||
} else {
|
||||
const res = await userApi.unfavoriteSolution({ solution_id: solutionId });
|
||||
results.value[idx].isFavorite = false;
|
||||
uni.showToast({ title: res?.msg || '已取消收藏', icon: 'success' });
|
||||
}
|
||||
};
|
||||
|
||||
const checkDup = (id: string) => {
|
||||
const rates = ["低 (<100人)", "中 (~1000人)", "高 (>10000人)"];
|
||||
const rate = rates[Math.floor(Math.random() * rates.length)];
|
||||
results.value = results.value.map((r: GeneratedName) =>
|
||||
r.id === id ? { ...r, duplicateRate: rate } : r
|
||||
);
|
||||
};
|
||||
|
||||
const handleItemClick = (item: GeneratedName) => {
|
||||
emit("showDetail", item);
|
||||
};
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
.naming-result {
|
||||
padding-bottom: 80rpx;
|
||||
}
|
||||
|
||||
.naming-result-header {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
margin-bottom: 24rpx;
|
||||
}
|
||||
|
||||
.naming-result-title {
|
||||
font-size: 18px;
|
||||
font-weight: 700;
|
||||
color: #8b2323;
|
||||
}
|
||||
|
||||
.naming-result-reset {
|
||||
border: none;
|
||||
background: transparent;
|
||||
font-size: 12px;
|
||||
color: #5a5a5a;
|
||||
}
|
||||
|
||||
.naming-result-list {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 16rpx;
|
||||
}
|
||||
|
||||
.naming-result-item {
|
||||
background-color: #f9f7f2;
|
||||
border-radius: 16rpx;
|
||||
border: 1px solid #dcd3c9;
|
||||
padding: 28rpx 24rpx 24rpx;
|
||||
position: relative;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.naming-result-item-bg {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
right: 0;
|
||||
padding: 8rpx;
|
||||
opacity: 0.08;
|
||||
pointer-events: none;
|
||||
}
|
||||
|
||||
.naming-result-item-actions {
|
||||
position: absolute;
|
||||
top: 12rpx;
|
||||
right: 12rpx;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 8rpx;
|
||||
z-index: 2;
|
||||
}
|
||||
|
||||
.naming-result-action-btn {
|
||||
border-radius: 999rpx;
|
||||
border: 1px solid #dcd3c9;
|
||||
background: rgba(255, 255, 255, 0.6);
|
||||
font-size: 12px;
|
||||
color: #5a5a5a;
|
||||
padding:7rpx 12rpx;
|
||||
}
|
||||
|
||||
.naming-result-action-btn-heart {
|
||||
padding: 6rpx;
|
||||
width: 15px;
|
||||
height: 15px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
border-radius: 50%;
|
||||
}
|
||||
|
||||
.naming-result-action-btn-heart-active {
|
||||
color: #8b2323;
|
||||
}
|
||||
|
||||
.naming-result-item-content {
|
||||
padding-right: 80rpx;
|
||||
}
|
||||
|
||||
.naming-result-item-name {
|
||||
font-size: 22px;
|
||||
font-weight: 700;
|
||||
color: #2c2c2c;
|
||||
margin-bottom: 4rpx;
|
||||
display: block;
|
||||
}
|
||||
|
||||
.naming-result-item-pinyin {
|
||||
font-size: 12px;
|
||||
color: #5a5a5a;
|
||||
margin-bottom: 8rpx;
|
||||
display: block;
|
||||
}
|
||||
|
||||
.naming-result-item-tags {
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
gap: 8rpx;
|
||||
margin-bottom: 8rpx;
|
||||
}
|
||||
|
||||
.naming-result-tag {
|
||||
font-size: 10px;
|
||||
padding: 4rpx 8rpx;
|
||||
border-radius: 6rpx;
|
||||
border: 1px solid rgba(139, 35, 35, 0.2);
|
||||
color: #8b2323;
|
||||
background: rgba(139, 35, 35, 0.04);
|
||||
}
|
||||
|
||||
.naming-result-tag-gold {
|
||||
border-color: #d4af37;
|
||||
color: #d4af37;
|
||||
background: rgba(212, 175, 55, 0.08);
|
||||
}
|
||||
|
||||
.naming-result-item-divider {
|
||||
height: 1px;
|
||||
margin: 12rpx 0;
|
||||
background-color: #e5e5e5;
|
||||
}
|
||||
|
||||
.naming-result-item-details {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 8rpx;
|
||||
}
|
||||
|
||||
.naming-result-detail-row {
|
||||
display: flex;
|
||||
align-items: flex-start;
|
||||
gap: 12rpx;
|
||||
}
|
||||
|
||||
.naming-result-detail-label {
|
||||
font-size: 10px;
|
||||
padding: 4rpx 8rpx;
|
||||
border-radius: 4rpx;
|
||||
border: 1px solid #5a5a5a;
|
||||
color: #5a5a5a;
|
||||
margin-top: 4rpx;
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
.naming-result-detail-label-primary {
|
||||
border-color: #8b2323;
|
||||
color: #8b2323;
|
||||
}
|
||||
|
||||
.naming-result-detail-text {
|
||||
font-size: 14px;
|
||||
color: #2c2c2c;
|
||||
}
|
||||
|
||||
.naming-result-detail-text-small {
|
||||
font-size: 12px;
|
||||
color: #5a5a5a;
|
||||
font-style: italic;
|
||||
}
|
||||
</style>
|
||||
Reference in New Issue
Block a user