upload project source code
This commit is contained in:
391
前端源码/uni-app/components/screens/NamingSolutionsList.vue
Normal file
391
前端源码/uni-app/components/screens/NamingSolutionsList.vue
Normal file
@@ -0,0 +1,391 @@
|
||||
<template>
|
||||
<view class="solutions-screen">
|
||||
<view class="solutions-bg"></view>
|
||||
<view class="status-bar-placeholder"></view>
|
||||
|
||||
<view class="solutions-header">
|
||||
<view class="solutions-back-btn" @click="$emit('back')">
|
||||
<text class="solutions-back-icon">‹</text>
|
||||
</view>
|
||||
<view class="solutions-header-center">
|
||||
<text class="solutions-title">起名方案列表</text>
|
||||
</view>
|
||||
<view class="solutions-header-placeholder"></view>
|
||||
</view>
|
||||
|
||||
<scroll-view scroll-y class="solutions-scroll">
|
||||
<view class="solutions-content">
|
||||
<view v-if="!solutions.length" class="solutions-empty">
|
||||
<text class="solutions-empty-icon">✦</text>
|
||||
<text class="solutions-empty-text">暂无方案</text>
|
||||
</view>
|
||||
|
||||
<view
|
||||
v-for="(it, idx) in solutions"
|
||||
:key="String(it?.id || it?.solution_id || idx)"
|
||||
class="solutions-item"
|
||||
:style="{ animationDelay: (idx * 0.04) + 's' }"
|
||||
@click="open(it)"
|
||||
>
|
||||
<view class="solutions-item-main">
|
||||
<view class="solutions-item-header">
|
||||
<view>
|
||||
<text class="solutions-item-name">{{ titleOf(it) }}</text>
|
||||
<text class="solutions-item-pinyin">{{ pinyinOf(it) }}</text>
|
||||
</view>
|
||||
<view class="solutions-item-actions">
|
||||
<view class="solutions-item-view-btn" @click.stop="open(it)">
|
||||
<text class="solutions-item-view-icon">⌕</text>
|
||||
<text class="solutions-item-view-text">查看</text>
|
||||
</view>
|
||||
<view class="solutions-item-badge">
|
||||
<text class="solutions-item-badge-text">{{ idx + 1 }}</text>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
<view class="solutions-item-meta">
|
||||
<text class="solutions-tag">{{ tagAOf(it) }}</text>
|
||||
<text class="solutions-tag">{{ tagBOf(it) }}</text>
|
||||
</view>
|
||||
<view class="solutions-item-meta-sub">
|
||||
<text v-if="scoreOf(it)" class="solutions-chip">评分 {{ scoreOf(it) }}</text>
|
||||
</view>
|
||||
<view v-if="poetryOf(it)" class="solutions-item-poetry">
|
||||
<text class="solutions-item-poetry-label">出处</text>
|
||||
<text class="solutions-item-poetry-text">{{ poetryOf(it) }}</text>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</scroll-view>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { computed } from "vue";
|
||||
import { namingApi } from "@/api/naming";
|
||||
import { parseMaybeJson } from "@/utils/poll-test-solution-detail";
|
||||
|
||||
declare const uni: any;
|
||||
|
||||
const props = defineProps<{
|
||||
reportId: number;
|
||||
solutions: any[];
|
||||
category?: string;
|
||||
serviceType?: string;
|
||||
}>();
|
||||
|
||||
const emit = defineEmits<{
|
||||
back: [];
|
||||
showDetail: [data: any, category?: string, serviceType?: string];
|
||||
}>();
|
||||
|
||||
const solutions = computed(() => (Array.isArray(props.solutions) ? props.solutions : []));
|
||||
|
||||
const titleOf = (it: any) => {
|
||||
const name = String(it?.name || it?.solution_name || it?.title || it?.label || "").trim();
|
||||
if (name) return name;
|
||||
const fallback = String(it?.given_name || it?.full_name || it?.company_name || "").trim();
|
||||
return fallback || "方案";
|
||||
};
|
||||
const pinyinOf = (it: any) => String(it?.pinyin || it?.name_pinyin || "").trim() || "Pīn Yīn";
|
||||
const tagAOf = (it: any) => String(it?.wuxing || it?.wuxing_tag || it?.element_tag || "五行均衡");
|
||||
const tagBOf = (it: any) => String(it?.style || it?.style_tag || it?.feature_tag || "温文尔雅");
|
||||
const poetryOf = (it: any) => String(it?.poetry_source || it?.poetry || it?.source || "").trim();
|
||||
const scoreOf = (it: any) => {
|
||||
const v = it?.total_score ?? it?.score;
|
||||
if (v === null || v === undefined || v === "") return "";
|
||||
return String(v);
|
||||
};
|
||||
|
||||
const open = async (it: any) => {
|
||||
const id = it?.id || it?.solution_id;
|
||||
if (!id) {
|
||||
uni.showToast({ title: "方案ID不存在", icon: "none" });
|
||||
return;
|
||||
}
|
||||
try {
|
||||
uni.showLoading({ title: "加载中..." });
|
||||
const detailRaw: any = await namingApi.getSolutionDetail(id);
|
||||
uni.hideLoading();
|
||||
const parsed = parseMaybeJson(detailRaw);
|
||||
if (!parsed || typeof parsed !== "object") {
|
||||
uni.showToast({ title: "详情数据格式异常", icon: "none" });
|
||||
return;
|
||||
}
|
||||
emit("showDetail", parsed, props.category, String(props.serviceType || ""));
|
||||
} catch (e: any) {
|
||||
uni.hideLoading();
|
||||
uni.showToast({ title: e?.msg || e?.message || "加载失败", icon: "none" });
|
||||
}
|
||||
};
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
.solutions-screen{
|
||||
min-height: 100%;
|
||||
position: relative;
|
||||
overflow: hidden;
|
||||
}
|
||||
.solutions-bg{
|
||||
position: fixed;
|
||||
inset: 0;
|
||||
background:
|
||||
/* 纸张底色 */
|
||||
radial-gradient(1200px 900px at 30% 20%, rgba(255,255,255,.92), rgba(245,241,232,.88) 45%, rgba(235,229,214,.92) 100%),
|
||||
/* 纸纹颗粒 */
|
||||
radial-gradient(2px 2px at 12% 18%, rgba(0,0,0,.06), transparent 55%),
|
||||
radial-gradient(2px 2px at 48% 62%, rgba(0,0,0,.05), transparent 55%),
|
||||
radial-gradient(2px 2px at 78% 34%, rgba(0,0,0,.04), transparent 55%),
|
||||
radial-gradient(2px 2px at 32% 84%, rgba(0,0,0,.04), transparent 55%),
|
||||
/* 墨韵晕染 */
|
||||
radial-gradient(900px 520px at 12% 8%, rgba(25,28,33,.10), transparent 60%),
|
||||
radial-gradient(760px 520px at 92% 22%, rgba(120,75,40,.08), transparent 62%),
|
||||
radial-gradient(900px 640px at 40% 92%, rgba(90,35,35,.08), transparent 62%),
|
||||
linear-gradient(180deg, #f6f2e8 0%, #efe7d6 60%, #f6f2e8 100%);
|
||||
z-index: -1;
|
||||
}
|
||||
.status-bar-placeholder{
|
||||
height: 24px;
|
||||
}
|
||||
.solutions-header{
|
||||
display:flex;
|
||||
align-items:center;
|
||||
justify-content:space-between;
|
||||
padding: 10px 14px 12px;
|
||||
}
|
||||
.solutions-back-btn{
|
||||
width: 36px;
|
||||
height: 36px;
|
||||
border-radius: 12px;
|
||||
border: 1px solid rgba(120,90,40,.26);
|
||||
background: linear-gradient(180deg, rgba(255,255,255,.70), rgba(244,236,220,.65));
|
||||
box-shadow: 0 6px 16px rgba(40,30,20,.10);
|
||||
display:flex;
|
||||
align-items:center;
|
||||
justify-content:center;
|
||||
}
|
||||
.solutions-back-icon{
|
||||
font-size: 22px;
|
||||
color: rgba(82,60,28,.92);
|
||||
line-height: 1;
|
||||
}
|
||||
.solutions-header-center{
|
||||
display:flex;
|
||||
flex-direction:column;
|
||||
align-items:center;
|
||||
gap: 3px;
|
||||
}
|
||||
.solutions-title{
|
||||
font-size: 17px;
|
||||
font-weight: 900;
|
||||
color: rgba(28,24,20,.92);
|
||||
letter-spacing: .08em;
|
||||
font-family: "STSong","Songti SC","SimSun","STSong","Noto Serif SC",serif;
|
||||
}
|
||||
.solutions-subtitle{
|
||||
font-size: 11px;
|
||||
color: rgba(70,58,44,.72);
|
||||
font-family: "STSong","Songti SC","SimSun","STSong","Noto Serif SC",serif;
|
||||
}
|
||||
.solutions-header-placeholder{
|
||||
width: 36px;
|
||||
height: 36px;
|
||||
}
|
||||
.solutions-scroll{
|
||||
height: calc(100vh - 24px - 58px);
|
||||
}
|
||||
.solutions-content{
|
||||
padding: 2px 14px 24px;
|
||||
box-sizing:border-box;
|
||||
}
|
||||
.solutions-empty{
|
||||
padding: 26px 10px;
|
||||
border-radius: 18px;
|
||||
border: 1px solid rgba(120,90,40,.18);
|
||||
background: linear-gradient(180deg, rgba(255,255,255,.76), rgba(247,239,224,.66));
|
||||
box-shadow: 0 10px 26px rgba(40,30,20,.10);
|
||||
text-align:center;
|
||||
}
|
||||
.solutions-empty-icon{
|
||||
display:block;
|
||||
font-size: 18px;
|
||||
color: rgba(132,98,52,.85);
|
||||
margin-bottom: 6px;
|
||||
}
|
||||
.solutions-empty-text{
|
||||
font-size: 13px;
|
||||
color: rgba(50,40,28,.78);
|
||||
font-family: "STSong","Songti SC","SimSun","STSong","Noto Serif SC",serif;
|
||||
}
|
||||
.solutions-item{
|
||||
position: relative;
|
||||
display:flex;
|
||||
align-items:stretch;
|
||||
justify-content:space-between;
|
||||
border-radius: 18px;
|
||||
border: 1px solid rgba(178,120,120,.45);
|
||||
background:
|
||||
linear-gradient(180deg, rgba(255,255,255,.84), rgba(249,243,232,.78));
|
||||
overflow:hidden;
|
||||
padding: 14px 14px 13px 14px;
|
||||
margin-bottom: 14px;
|
||||
animation: solFadeUp .22s ease both;
|
||||
box-shadow:
|
||||
0 14px 30px rgba(40,30,20,.14),
|
||||
inset 0 1px 0 rgba(255,255,255,.55);
|
||||
}
|
||||
.solutions-item-main{
|
||||
flex: 1;
|
||||
}
|
||||
.solutions-item-header{
|
||||
display:flex;
|
||||
align-items:flex-start;
|
||||
justify-content:space-between;
|
||||
gap: 10px;
|
||||
}
|
||||
.solutions-item-name{
|
||||
font-size: 18px;
|
||||
font-weight: 900;
|
||||
color: #20252e;
|
||||
letter-spacing: .04em;
|
||||
font-family: "STSong","Songti SC","SimSun","STSong","Noto Serif SC",serif;
|
||||
display: block;
|
||||
}
|
||||
.solutions-item-pinyin{
|
||||
display: block;
|
||||
margin-top: 4px;
|
||||
font-size: 12px;
|
||||
color: rgba(32,37,46,.72);
|
||||
letter-spacing: .08em;
|
||||
}
|
||||
.solutions-item-badge{
|
||||
width: 24px;
|
||||
height: 24px;
|
||||
border-radius: 999px;
|
||||
border: 1px solid rgba(202,166,96,.62);
|
||||
background:
|
||||
linear-gradient(180deg, rgba(255,245,220,.90), rgba(248,229,184,.82));
|
||||
display:flex;
|
||||
align-items:center;
|
||||
justify-content:center;
|
||||
flex: 0 0 24px;
|
||||
}
|
||||
.solutions-item-badge-text{
|
||||
font-size: 11px;
|
||||
font-weight: 900;
|
||||
color: rgba(128,96,42,.92);
|
||||
}
|
||||
.solutions-item-actions{
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 8px;
|
||||
}
|
||||
.solutions-item-view-btn{
|
||||
height: 26px;
|
||||
padding: 0 10px;
|
||||
border-radius: 999px;
|
||||
border: 1px solid rgba(188,170,136,.78);
|
||||
background: rgba(255,255,255,.70);
|
||||
display:flex;
|
||||
align-items:center;
|
||||
gap: 4px;
|
||||
box-shadow: 0 2px 6px rgba(40,30,20,.08);
|
||||
}
|
||||
.solutions-item-view-icon{
|
||||
font-size: 12px;
|
||||
color: rgba(55,60,68,.75);
|
||||
}
|
||||
.solutions-item-view-text{
|
||||
font-size: 12px;
|
||||
font-weight: 700;
|
||||
color: rgba(55,60,68,.85);
|
||||
}
|
||||
.solutions-item-meta{
|
||||
display:flex;
|
||||
gap: 8px;
|
||||
margin-top: 8px;
|
||||
flex-wrap: wrap;
|
||||
}
|
||||
.solutions-tag{
|
||||
font-size: 11px;
|
||||
padding: 3px 8px;
|
||||
border-radius: 7px;
|
||||
border: 1px solid rgba(188,114,114,.52);
|
||||
color: rgba(130,58,58,.90);
|
||||
background: rgba(255,250,248,.78);
|
||||
font-family: "STSong","Songti SC","SimSun","STSong","Noto Serif SC",serif;
|
||||
}
|
||||
.solutions-item-meta-sub{
|
||||
display:flex;
|
||||
gap: 8px;
|
||||
margin-top: 9px;
|
||||
flex-wrap: wrap;
|
||||
}
|
||||
.solutions-chip{
|
||||
font-size: 10px;
|
||||
padding: 3px 8px;
|
||||
border-radius: 999px;
|
||||
border: 1px solid rgba(196,168,106,.42);
|
||||
color: rgba(128,96,42,.88);
|
||||
background: rgba(250,239,211,.65);
|
||||
font-family: ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace;
|
||||
}
|
||||
.solutions-item-poetry{
|
||||
margin-top: 8px;
|
||||
display:flex;
|
||||
align-items:flex-start;
|
||||
gap: 8px;
|
||||
}
|
||||
.solutions-item-poetry-label{
|
||||
flex: 0 0 auto;
|
||||
font-size: 11px;
|
||||
line-height: 1.5;
|
||||
color: rgba(130,58,58,.90);
|
||||
border: 1px solid rgba(188,114,114,.50);
|
||||
border-radius: 6px;
|
||||
padding: 1px 6px;
|
||||
background: rgba(255,250,248,.78);
|
||||
}
|
||||
.solutions-item-poetry-text{
|
||||
flex: 1;
|
||||
font-size: 12px;
|
||||
line-height: 1.6;
|
||||
color: rgba(40,34,26,.82);
|
||||
font-family: "STSong","Songti SC","SimSun","STSong","Noto Serif SC",serif;
|
||||
}
|
||||
@keyframes solFadeUp{
|
||||
from{opacity:0;transform:translateY(6px)}
|
||||
to{opacity:1;transform:translateY(0)}
|
||||
}
|
||||
|
||||
/* 细节:内侧金线与“卷轴边” */
|
||||
.solutions-item::before{
|
||||
content:"";
|
||||
position:absolute;
|
||||
inset: 9px 9px 9px 9px;
|
||||
border-radius: 12px;
|
||||
border: 1px solid rgba(188,170,136,.28);
|
||||
pointer-events:none;
|
||||
}
|
||||
.solutions-item::after{
|
||||
content:"";
|
||||
position:absolute;
|
||||
top:-40px;
|
||||
right:-60px;
|
||||
width: 160px;
|
||||
height: 160px;
|
||||
background: radial-gradient(closest-side, rgba(188,114,114,.08), transparent 70%);
|
||||
transform: rotate(18deg);
|
||||
pointer-events:none;
|
||||
}
|
||||
|
||||
/* 轻微按压反馈 */
|
||||
.solutions-item:active{
|
||||
transform: translateY(1px);
|
||||
box-shadow:
|
||||
0 10px 22px rgba(40,30,20,.12),
|
||||
inset 0 1px 0 rgba(255,255,255,.55);
|
||||
}
|
||||
</style>
|
||||
|
||||
Reference in New Issue
Block a user