Files
meida_front/pages/report/index.vue
T
2025-10-13 17:54:02 +08:00

1394 lines
40 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>
<view style="overflow-x: hidden; font-size: 0">
<view id="headerBox">
<!-- <Header v-if="!!userFaceInfo" :userFaceInfo="userFaceInfo" /> -->
<Header v-if="collect" :userFaceInfo="collect" />
<view class="report">
<view class="report-title"> 美学诊断报告 </view>
<view class="report-title-en"> FD Aesthetic Diagnosis Report </view>
</view>
</view>
<view :class="classFixed" style="width: 100%">
<Tabs
:tabs="tabsList"
:activeTab="activeTab"
@update:activeTab="onTabChange"
>
</Tabs>
</view>
<view
class="content"
:style="{
paddingTop: (classFixed === '' ? 0 : 60) + 'px',
overflowY: 'hidden',
}"
v-if="collect"
>
<view v-if="activeTab === 0">
<view class="style-type">
<!--
基因风格
warning:
1三个图片还未给
2type字段还未给
-->
<genetic-style
:gender="collect.gender"
:pic-list="[
collect.eye_img_url ?? '',
collect.triangular_area_img_url ?? '',
collect.full_face_img_url ?? '',
]"
:styleType="collect.type"
/>
<!-- 肤色-->
<!-- <SkinColor :skinColor="styleType?.complexion" /> -->
<SkinColor :skinColor="collect?.complexion" />
<FacialColorLatitude
:hue="collect?.hue ?? 0"
:chroma="collect?.chroma ?? 0"
:luminance="collect?.luminance ?? 0"
/>
<BodyType
:body-type="collect?.somatotype"
:gender="collect?.gender"
/>
<!-- 轮廓类型-->
<template v-if="customFigure">
<SensoryTypes
:type="styleType.straight_total_score_t"
:ai-desc="customFigure?.sensory?.desc"
/>
<!-- 量感类型-->
<TypeOfMass
:type="styleType.total_sense_of_quantity_t"
:ai-desc="customFigure?.mass?.desc"
/>
<!-- 动静类型-->
<Movementtype
:type="styleType.dynamic_static_t"
:ai-desc="customFigure?.movement?.desc"
/>
<!-- 体型-->
<!-- <BodyType
:body-type="styleType?.somatotype_t"
:gender="styleType?.gender"
/> -->
</template>
<template v-if="false">
<!-- 搭配趋势 -->
<CustomSwiper :items="items" />
<!-- 个人分格描述报告-->
<StyleDiagnosticReport :html="customerStyle" />
<BottomPic
:style-type="styleType?.type"
:psychological-style="styleType?.psychological_style"
:gender="styleType.gender"
/>
</template>
</view>
</view>
<view v-else-if="activeTab === 1">
<view class="style-type">
<view class="title">四季色彩定位</view>
<view class="swiper-container">
<view class="avatar-box">
<view class="left-btn btn" @click="chageSwiperBtn(-1)">
<img :src="pngImgUrl + 'leftRe.png'" alt="" srcset="" />
</view>
<view class="right-btn btn" @click="chageSwiperBtn(1)">
<img :src="pngImgUrl + 'rightRe.png'" alt="" srcset="" />
</view>
</view>
<swiper class="swiper" @change="chageSwiper" :current="current">
<swiper-item
v-for="(item, index) in newColorTypeList"
:key="index"
>
<view class="swiper-item">
<view class="img-box">
<view
style="
width: 235px;
height: 235px;
position: absolute;
z-index: 99;
"
>
<img
style="width: 235px; height: 235px"
:src="item.avatarFrameImgUrl"
alt=""
srcset=""
/>
</view>
<view class="avatar">
<img
:src="userFaceInfo?.avatar_img_url"
alt=""
srcset=""
/>
</view>
</view>
</view>
</swiper-item>
</swiper>
</view>
<view class="swiper-instructions">
<view class="swiper-type-name">{{ colorTypeInfo.typeName }}</view>
<view class="swiper-type-name-en">{{ colorTypeInfo.enName }}</view>
<view class="swiper-type-text">
{{
colorTypeInfo.typeName + "型" === userFaceInfo.sj_color_type
? "最佳颜色"
: "不匹配"
}}
</view>
</view>
<view class="content-box">
<view class="padding-top20">
<rich-text :nodes="colorTypeText.characteristic"></rich-text>
</view>
<view class="padding-top20">
<img
class="image"
:src="colorTypeText.colourDiscImgUrl"
alt=""
srcset=""
@click="previewImage(colorTypeText.colourDiscImgUrl)"
/>
</view>
<view class="padding-top20">
<rich-text :nodes="colorTypeText.advise"></rich-text>
</view>
<view class="padding-top20">
<img
class="image"
:src="colorTypeText.adviseImgUrl"
alt=""
srcset=""
@click="previewImage(colorTypeText.adviseImgUrl)"
/>
</view>
<view class="padding-top20">
<rich-text :nodes="fashionNeutrals"></rich-text>
</view>
<view class="padding-top20">
<img
class="image"
:src="colorTypeText.fashionNeutralsImgUrl"
alt=""
srcset=""
@click="previewImage(colorTypeText.fashionNeutralsImgUrl)"
/>
</view>
<!-- 搭配趋势 -->
<CustomSwiper :items="items" />
<view class="padding-top20"
>{{ colorTypeInfo.typeName }}人穿衣搭配全方案</view
>
<view class="padding-top20">
<rich-text :nodes="colorTypeText.scheme"></rich-text>
</view>
<view v-if="userFaceInfo?.gender === '女'" style="padding: 0 20px">
<!-- <view class="reference-title">
<img
src="https://llyz.oss-cn-beijing.aliyuncs.com/diagnostic-report-h5/reference.png"
alt=""
srcset=""
/>
</view> -->
<view class="reference-img-box">
<img
class="reference-img1"
:src="colorTypeInfo.useReferenceImgUrl"
alt=""
srcset=""
/>
<!-- <img
class="reference-img2"
src="https://llyz.oss-cn-beijing.aliyuncs.com/diagnostic-report-h5/test2.png"
alt=""
srcset=""
/> -->
</view>
</view>
<view style="padding-left: 20px">
人工智能大模型在计算中可能存在0.5%的误差
</view>
<view class="reference-complate">
------ 色彩类型报告完 ------
</view>
</view>
</view>
</view>
<!-- 依此类推 -->
<view v-else-if="activeTab === 2">
<view class="style-type">
<view class="avatar-warp">
<view
:class="index === 1 ? 'avatar-main' : 'avatar-side'"
v-for="(item, index) in avatarList"
:key="index"
>
<img
:src="item.url"
alt=""
srcset=""
@click="previewImage(item.url)"
/>
</view>
</view>
<view class="rich-text-content">
<rich-text :nodes="praiseTextList[0]"></rich-text>
<view
class="face-img-box"
:style="{
height: userFaceInfo?.gender === '男' ? '150px' : '328px',
}"
>
<img
style="object-fit: cover"
:src="faceImgUrl"
alt=""
srcset=""
/>
</view>
<rich-text :nodes="praiseTextList[1]"></rich-text>
<view class="more-hairstyle">
<view
class=""
style="
display: flex;
justify-content: center;
margin-bottom: 16px;
"
>
<view>更多发型一键试戴</view>
</view>
<view class="scroll-box">
<view
class=""
@click="toHairstyleRoom(item)"
v-for="(item, index) in hairStyleList"
:key="index"
style="height: 103px; margin-right: 8px"
>
<img
style="width: 76px; height: 100%"
:src="item.fileUrl"
alt=""
srcset=""
/>
</view>
</view>
</view>
<rich-text :nodes="praiseTextList[2]"></rich-text>
<view style="margin-top: 56px">
人工智能大模型在计算中可能存在0.5%的误差
</view>
<view
class="reference-complate"
style="margin-bottom: 0; margin-top: 10px"
>
------ 发型报告完 ------
</view>
</view>
</view>
</view>
<view v-else-if="activeTab === 3">
<view class="style-type" style="overflow-y: hidden">
<view class="lucky-color-box" style="overflow-y: hidden">
<view class="shengxiao">
<img
:src="
`https://llyz.oss-cn-beijing.aliyuncs.com/diagnostic-report-h5/chineseZodiac/` +
shegnxiaoImgUrl
"
alt=""
srcset=""
@click="
previewImage(
`https://llyz.oss-cn-beijing.aliyuncs.com/diagnostic-report-h5/chineseZodiac/` +
shegnxiaoImgUrl
)
"
/>
</view>
<rich-text :nodes="luckyTxtList[0]"></rich-text>
<view class="five-attribute-box">
<view
class="numblock"
style="
background-color: rgba(193, 156, 45, 1);
top: 286px;
left: 40px;
"
>{{ numToChinese(shengxiaoNumList[0]) }}</view
>
<view
class="numblock"
style="
background-color: rgba(62, 166, 123, 1);
top: 32px;
left: 119px;
"
>{{ numToChinese(shengxiaoNumList[1]) }}</view
>
<view
class="numblock"
style="background-color: rgba(61, 146, 168, 1); top: 136px"
>{{ numToChinese(shengxiaoNumList[2]) }}</view
>
<view
class="numblock"
style="
background-color: rgba(195, 52, 55, 1);
top: 150px;
right: 10px;
"
>{{ numToChinese(shengxiaoNumList[3]) }}</view
>
<view
class="numblock"
style="
background-color: rgba(253, 231, 73, 1);
top: 293px;
right: 70px;
"
>{{ numToChinese(shengxiaoNumList[4]) }}</view
>
<view class="five-attribute">
<view class="avatorLogo">
<img :src="userFaceInfo?.avatar_img_url" alt="" srcset="" />
</view>
<view>
<img
src="https://llshop.zglvling.com/shop/img/png/h5/baseMap.png"
alt=""
srcset=""
/>
</view>
</view>
</view>
<rich-text :nodes="luckyTxtList[1]"></rich-text>
<view style="margin-top: 56px">
人工智能大模型在计算中可能存在0.5%的误差
</view>
<view class="reference-complate" style="margin-bottom: 0">
------ 幸运色分析完 ------
</view>
</view>
</view>
</view>
</view>
</view>
<!-- 图片预览遮罩层 -->
<view v-if="showPreview" class="preview-mask" @click="closePreview">
<view class="preview-container" @click.stop>
<image
:src="currentPreviewImage"
class="preview-image"
mode="widthFix"
@click="closePreview"
></image>
</view>
</view>
</template>
<script setup>
import { ref, onMounted, onUnmounted, watchEffect } from "vue";
import Header from "./component/Header/index.vue";
import Tabs from "./component/Tabs/index.vue";
import {
fashionNeutrals,
colorTypeList,
faceList,
shengxiaoImgList,
} from "./database";
import {
uploadFormData,
downloadFile,
numToChinese,
getMaxElement,
reorderByValue,
} from "../../utils/index";
import GeneticStyle from "./component/FirstStyleType/geneticStyle.vue";
import SkinColor from "./component/FirstStyleType/SkinColor.vue";
import BottomPic from "./component/FirstStyleType/BottomPic.vue";
import StyleDiagnosticReport from "./component/FirstStyleType/StyleDiagnosticReport.vue";
import BodyType from "./component/FirstStyleType/BodyType.vue";
import FacialColorLatitude from "./component/FirstStyleType/FacialColorLatitude.vue";
import CustomSwiper from "./component/CustomSwiper/CustomSwiper";
import SensoryTypes from "./component/FirstStyleType/SensoryTypes.vue";
import TypeOfMass from "./component/FirstStyleType/TypeOfMass.vue";
import Movementtype from "./component/FirstStyleType/Movementtype.vue";
import ReportApi from "../../sheep/api/report";
import { onLoad } from '@dcloudio/uni-app';
import {hairText, shengxiaoText, shengxiaoSystem_prompt, statureText} from '@/constant/aiText'
import { praiseTextApi } from '@/sheep/api/doubao'
const {
// praiseTextApi,
getStyleApi,
exchangeHairHistoryByTaskId,
wardrobeListApi,
hairStyleListApi,
addHairApi,
getHairApi,
getAiFaceResult,
getUserInfo
} = ReportApi;
const collect = ref(null)
onLoad((options) => {
uni.setStorageSync('token', options?.token ?? '92d2805a85ca422e90dd7d50eef49a85');
console.log('🚀 ~ URL上的token ~ options?.token: ', options?.token);
Promise.all([getUserInfo(), getAiFaceResult()]).then(result => {
const [res1, res2] = result
const {data} = JSON.parse(res2.result[0].thridResp)
const target = Object.assign({}, JSON.parse(res1.data.dataJson), data.face_figure)
target.gender = target.sex
collect.value = target
console.log('collect.value: ', collect.value);
})
});
// if (
// typeof window !== "undefined" &&
// /MicroMessenger/i.test(navigator.userAgent)
// ) {
const pngImgUrl = ref("https://llshop.zglvling.com/shop/img/png/h5/");
const showPreview = ref(false);
const currentPreviewImage = ref("");
let hairStyleList = ref([]);
const previewImage = (imageUrl) => {
currentPreviewImage.value = imageUrl;
showPreview.value = true;
};
const closePreview = (e) => {
// 阻止事件冒泡
e.stopPropagation();
showPreview.value = false;
currentPreviewImage.value = "";
};
const gifAddress = "https://llshop.zglvling.com/shop/img/gif/";
const routes = new URLSearchParams(window.location.search);
const classFixed = ref("");
const openId = routes.get("openId");
const enterType = routes.get("enterType"); // 1: 个人诊断报告 2: 发型试戴
// const occupation = routes.get("occupation"); // 职业
// const forWhom = routes.get("forWhom");
let scrollHeight = ref(0);
const activeTab = ref(0);
const tabsList = ref([
{ name: "风格类型", icon: "icon-style" },
{ name: "色彩类型", icon: "icon-color" },
{ name: "发型发色", icon: "icon-body" },
{ name: "幸运色", icon: "icon-face" },
]);
const newColorTypeList = ref([]);
let shegnxiaoImgUrl = ref("wuxingLoading.png");
let colorTypeInfo = ref([]);
const colorTypeText = ref({});
let current = ref(0);
const praiseTextList = ref([]);
const userFaceInfo = ref({ avatar_img_url: "" });
const faceImgUrl = ref("");
const shengxiao = ref();
const chageSwiper = (e) => {
current.value = e.detail.current;
colorTypeInfo.value = newColorTypeList.value[current.value];
};
const clothesList = ref([]);
const styleType = ref({});
const chageSwiperBtn = (x) => {
if (x === -1 && current.value !== 0) {
current.value--;
return;
}
if (x === 1 && current.value < newColorTypeList.value.length - 1) {
current.value++;
}
};
const hairIds = ref([]);
const avatarList = ref([
{
id: 1,
url: "https://cdn.meidaojia.com/aidigitalfield/digital_cloth/static/1720084773937.png",
},
{
id: 2,
url: "https://cdn.meidaojia.com/aidigitalfield/digital_cloth/static/1720084773937.png",
},
{
id: 3,
url: "https://cdn.meidaojia.com/aidigitalfield/digital_cloth/static/1720084773937.png",
},
]);
let luckyTxtList = ref([]);
const shengxiaoNumList = ref([1, 2, 3, 4, 5]);
const formatText = (text) => {
text = text.replace(/[\u0000-\u001F]/g, (c) => {
if (c === "\n") return "\\n";
if (c === "\r") return "\\r";
if (c === "\t") return "\\t";
return "";
});
return text;
};
const formatPraiseText = (text) => {
text = formatText(text);
text = JSON.parse(text).choices[0].message.content;
text = text.replace(/<\/?strong>/g, "");
text = text.replace(/<h1>/g, "<div>").replace(/<\/h1>/g, "</div>");
text = text.replace(/<h2>/g, "<div>").replace(/<\/h2>/g, "</div>");
text = text.replace(/<h3>/g, "<div>").replace(/<\/h3>/g, "</div>");
let list = [];
const split1 = text.split("二、核心风格基因解析");
list.push(split1[0]);
split1[1] = "<p>二、核心风格基因解析</p>" + split1[1];
const split2 = split1[1].split("五、关键细节设计:刘海与发色");
split2[1] = "<p>五、关键细节设计:刘海与发色</p>" + split2[1];
list = list.concat(split2);
return list;
};
const formatShengXiao = (text) => {
text = formatText(text);
// text = JSON.parse(text).choices[0].message.content;
text = text.replace(/<h1>/g, "<div>").replace(/<\/h1>/g, "</div>");
text = text.replace(/<h2>/g, "<div>").replace(/<\/h2>/g, "</div>");
text = text.replace(/<h3>/g, "<div>").replace(/<\/h3>/g, "</div>");
let list = [];
const split1 = text.split("二、五行命理与易学幸运色推导");
list.push(split1[0]);
split1[1] = "<p>二、五行命理与易学幸运色推导</p>" + split1[1];
list.push(split1[1]);
return list;
};
const customFigure = ref();
const customerStyle = ref("");
const getPraiseText = (callWord, type) => {
let params = {
// model: "doubao-seed-1-6-250615",
model: "doubao-seed-1-6-flash-250715",
openId: openId,
text: "",
type: enterType,
tabType: "",
};
if (type === 1) {
// params.model = "doubao-1-5-thinking-vision-pro-250428";
// params.model = "doubao-seed-1-6-250615";
// params.model = "doubao-seed-1-6-flash-250715";
params.model = "doubao-1-5-thinking-pro-m-250428";
}
let customKey = `客户特征:
性别:${collect?.value?.gender}
出生年月日:${collect?.value?.birthday}
年龄:${collect?.value?.age}
身高:${collect?.value?.height}
体重:${collect?.value?.weight}
量感类型:${collect?.value?.total_sense_of_quantity_t}
轮廓类型:${collect?.value?.straight_total_score_t}
动静类型:${collect?.value?.dynamic_static_t}
基因风格类型:${collect?.value?.type}
心理风格:${collect?.value?.psychological_style}
喜欢配色:${collect?.value?.color}
心理量感类型:${collect?.value?.ling_of_quantity}
心理曲直类型:${collect?.value?.right_and_wrong}
心理动静类型:${collect?.value?.dynamic_and_static}
体型分类:${collect?.value?.somatotype}
存在的问题:${collect?.value?.question}
修饰部位:${collect?.value?.purpose}
场合需求:${collect?.value?.occasion_dressing}
三庭五眼特征:${collect?.value?.three_courts_five_eyes}
亮度:${collect?.value?.luminance}
嘴型:${collect?.value?.mouth_shape}
对比度:${collect?.value?.contrast}
法令纹:${collect?.value?.nasolabial_folds}
直曲总分:${collect?.value?.straight_total_score}
眉形:${collect?.value?.camber}
眼型:${collect?.value?.ocular_form}
瞳色:${collect?.value?.eye_color}
瞳距:${collect?.value?.interpupillary_distance}
肤色:${collect?.value?.complexion}
脖长:${collect?.value?.neck_length}
脸型:${collect?.value?.feature}
色度:${collect?.value?.chroma}
色相:${collect?.value?.hue}
量感总分:${collect?.value?.total_sense_of_quantity}
面部年龄:${collect?.value?.facial_age}
面部立体度:${collect?.value?.Facial_three_dimensionality}
面部颜色对比度:${collect?.value?.face_color_contrast}
鼻型:${collect?.value?.nose_type}
鼻子立体度:${collect?.value?.nose_stereo_degree}
肤色:${collect?.value?.complexion}
亮度:${collect?.value?.luminance}
四季色彩季型:${collect?.value?.sj_color_type}
职业: ${collect?.value?.work}
最在意谁的意见:${collect?.value?.attention}
强调:
1、客户的性别是${collect?.value?.gender},千万要以${collect?.value?.gender}性的角度去产出数据,切记,这点十分重要
2、客户为男性的时候,严禁出现裙装穿搭建议
`;
if (callWord === "one") {
params.tabType = "hair";
params.text = hairText(customKey)
}
if (callWord === "three") {
params.tabType = "shengxiao";
// if (
// openId === "oZRaI4ojHLTcwuQ6yix3QV5sSe0c" ||
// openId === "oZRaI4tfDP-HgQmyjN7GOqyv4gB0"
// ) {
// params.text = `用户生日是阳历${userFaceInfo?.value?.checkTime},性别:${userFaceInfo?.value?.gender},职业: ${styleType?.value?.work}, 最在意谁的意见:${styleType?.value?.attention},计算这个生日对应的年柱、月柱、日柱的五行属性个数,不计算时柱,不计算藏干。以v-html格式生成,只能以div、p、ul、li、ol、span标签,输出适合颜色报告,需要提到五行的个数。 报告结构严格按照以下内容:一.五行主属性分析(需要提到五行的个数) 二、五行命理与易学幸运色推导 三、场景化搭配建议 四、动态调整建议",最后以字符串格式返回。返回一个名称为arr的数组,第一个参数“属相”,用用户年龄推算,参数有鼠、牛、虎、兔、龙、蛇、马、羊、猴、鸡、狗、猪),第2到第6个数为用“年柱”, “月柱”,“日柱”,“年柱属性”, “月柱属性”,“日柱属性”,等属性推算出的五行个数,最后以数组的形式返回[“属相”, ”金属性个数“,木属性个数“,”水属性个数”,“火属性个数”,”土属性个数“]的形式返回
// 特别注意:
// 生成一个如下结构的对象
// content:{
// text: 颜色报告内容,
// arr: 属相数组,以["属相",金的个数, 木的个数, 水的个数, 火的个数, 土的个数]的格式返回
// }
// `;
// params.text = shengxiaoText(userFaceInfo?.value?.checkTime, userFaceInfo?.value?.gender, styleType?.value?.work, styleType?.value?.attention)
params.text = shengxiaoText(collect?.value?.birthday, collect?.value?.gender, collect?.value?.work)
params.system_prompt = shengxiaoSystem_prompt
}
// console.log('tttttttttttttttttttttttttttttt', callWord)
if (callWord === "four") {
params.tabType = "stature";
params.text = statureText(customKey, styleType.value.straight_total_score_t, styleType.value.total_sense_of_quantity_t, styleType.value.dynamic_static_t)
}
if (callWord === "five") {
params.tabType = "style";
params.text = styleText(customKey);
}
console.log('调用一把yyyyyyyyyyyyyy', callWord)
praiseTextApi(params).then((res) => {
// tabType
if (callWord === "one") {
// console.log("数据是什么1", res.data);
praiseTextList.value = formatPraiseText(res.data);
} else if (callWord === "two") {
return;
luckyTxtList.value = formatShengXiao(res.data);
} else if (callWord === "three") {
let obj = JSON.parse(res.data);
let shengxiaoContent = JSON.parse(obj.choices[0].message.content).content;
luckyTxtList.value = formatShengXiao(shengxiaoContent.text);
// console.log(shengxiaoContent, "shengxiaoContent");
let shengxiaoList = shengxiaoContent.arr;
shengxiao.value = shengxiaoList[0];
shengxiaoNumList.value = shengxiaoList.slice(1);
let wuxing = getMaxElement(shengxiaoNumList.value);
// console.log("wuxing: ", wuxing);
for (let i = 0; i < shengxiaoImgList.length; i++) {
if (
shengxiaoImgList[i].shengxiao === shengxiao.value &&
shengxiaoImgList[i].element === wuxing
) {
shegnxiaoImgUrl.value = shengxiaoImgList[i].imgUrl;
}
}
} else if (callWord === "four") {
const obj = JSON.parse(res.data);
// console.log("obj: ", obj);
const content = obj.choices[0].message.content;
customFigure.value = JSON.parse(content);
console.log('customFigure.value: mmmmmmmmmmmmmmmmm', customFigure.value);
} else if (callWord === "five") {
const obj = JSON.parse(res.data);
const content = obj.choices[0].message.content;
customerStyle.value = JSON.parse(content).html;
}
});
};
const items = ref([]);
const wardrobeList = () => {
// https://llshop.zglvling.com/soapi/wardrobe/clothes_list
wardrobeListApi({
open_id: openId,
// categoryId: 10140,
clothesIndex: 1,
clothesKind: 0,
clothesSize: 12,
}).then((res) => {
// console.log("衣服列表 -----------------", res.clothesList);
const goods_images = res.clothesList
.map((i) => i.goods_image)
.filter((i) => i.length >= 5);
items.value = goods_images;
// clothesList.value = res.data.wardrobeList.slice(0, 3);
});
};
wardrobeList();
const getHairstyleList = () => {
hairStyleListApi({
phone: "17600222111",
isPerson: "yes",
}).then((res) => {
hairStyleList.value = res.result;
// console.log(res, "发型列表 -----------------");
});
};
getHairstyleList();
const pollExchangeHairHistory = (requestId, maxTries = 30, interval = 2000) => {
let tries = 0;
const poll = (resolve, reject) => {
exchangeHairHistoryByTaskId({ taskId: requestId })
.then((ress) => {
// console.log("轮询结果", ress);
if (
ress.result[0].url !==
"https://cdn.meidaojia.com/aidigitalfield/digital_cloth/static/1720084773937.png" &&
ress.result[1].url !==
"https://cdn.meidaojia.com/aidigitalfield/digital_cloth/static/1720084773937.png" &&
ress.result[2].url !==
"https://cdn.meidaojia.com/aidigitalfield/digital_cloth/static/1720084773937.png"
) {
resolve(ress);
} else if (tries >= maxTries) {
reject(new Error("轮询超时"));
} else {
tries++;
setTimeout(() => poll(resolve, reject), interval);
}
})
.catch((err) => {
reject(err);
});
};
return new Promise(poll);
};
const getColorTypeText = (sj_color_type) => {
const found = newColorTypeList.value.find(
(item) => item.typeName + "型" === sj_color_type
);
if (found) {
colorTypeText.value = found;
}
};
const addHair = async (data) => {
await addHairApi({
openId: openId,
data: data,
});
};
const getHair = async (data) => {
let res = await getHairApi({
openId: openId,
});
return res.data;
};
const getUserFaceInfo = async () => {
getStyleApi({ openId: openId }).then(async (res) => {
newColorTypeList.value = reorderByValue(
colorTypeList,
res?.detail?.sj_color_type
);
colorTypeInfo.value = newColorTypeList.value[0];
userFaceInfo.value = res.data || {};
if (!userFaceInfo.value.avatar_img_url) {
userFaceInfo.value.avatar_img_url =
"https://llshop.zglvling.com/shop/img/jpg/avatar.jpg";
}
if (userFaceInfo?.value?.gender === "男") {
faceImgUrl.value =
"https://llyz.oss-cn-beijing.aliyuncs.com/diagnostic-report-h5/menhairstyles.png";
let hairInfo = faceList.find((item) => item.id === 8);
hairIds.value = hairInfo?.hairStyleIdList;
// for(let i =0)
} else {
for (let i = 0; i < faceList.length; i++) {
if (userFaceInfo?.value?.feature === faceList[i].name) {
faceImgUrl.value = faceList[i].imgUrl;
hairIds.value = faceList[i].hairStyleIdList;
}
}
}
// getPraiseText("one");
// getPraiseText("three", 1);
try {
getPraiseText("four");
} catch (error) {
console.error('error: ', error);
}
// getPraiseText("five");
getColorTypeText(res?.detail?.sj_color_type || "");
let blob = await downloadFile(userFaceInfo?.value?.avatar_img_url);
let formData = new FormData();
formData.append("phone", "17600222111");
formData.append("isHr", "false");
formData.append("sex", userFaceInfo?.value.gender);
formData.append("hairIds", hairIds.value);
// 如果有图片/文件需要上传
if (blob) {
formData.append("files", blob, "avatar.jpg");
}
let taskInfo = await uploadFormData(formData);
let ress = null;
if (enterType === "weixin") {
ress = await getHair();
} else {
ress = await pollExchangeHairHistory(taskInfo.requestId);
await addHair(ress);
}
avatarList.value = ress.result;
});
};
const toHairstyleRoom = (item) => {
wx.miniProgram.navigateTo({
url: `/pages/hairstyleRoom/index?id=${item.fileId}`,
success: function () {
// alert('成功')
},
fail(error) {
// alert('错误', error)
console.log("navigateTo error: ", error);
},
});
};
function getScrollHeight() {
const tabsEl = document.getElementById("headerBox");
if (tabsEl) {
const rect = tabsEl.getBoundingClientRect();
console.log(rect.height, "rect.height");
scrollHeight.value = rect.height;
}
}
function onPageScroll(e) {
let scrollTop = e && e.scrollTop !== undefined ? e.scrollTop : window.scrollY;
if (scrollTop > scrollHeight.value) {
//277是需要固定的地方到顶部的距离
classFixed.value = "fixed";
} else {
classFixed.value = "";
}
}
onMounted(() => {
getScrollHeight();
window.addEventListener("scroll", onPageScroll);
});
onUnmounted(() => {
window.removeEventListener("scroll", onPageScroll);
});
getStyleApi({ openId })
.then((res) => {
styleType.value = res.data;
})
// .then(() => {
// getUserFaceInfo();
// });
watchEffect(() => {
if(collect.value) {
getUserFaceInfo()
}
})
function onTabChange(tabIndex) {
// H5端滚动到id=tabs的位置
if (
typeof window !== "undefined" &&
activeTab.value !== tabIndex &&
!!window.scrollY &&
window.scrollY > scrollHeight.value
) {
window.scrollTo({ top: scrollHeight.value, behavior: "smooth" });
}
activeTab.value = tabIndex;
}
</script>
<style>
.report {
padding: 20px 20px 0;
}
.report-title {
font-family: "PingFang SC", "Microsoft YaHei", "Arial", sans-serif !important;
font-weight: 400;
font-size: 18px;
line-height: 28px !important;
letter-spacing: 0px;
}
.report-title-en {
font-family: "PingFang SC", "Microsoft YaHei", "Arial", sans-serif !important;
font-weight: 400;
font-size: 16px;
line-height: 28px !important;
letter-spacing: 0px;
color: rgba(216, 216, 216, 1);
}
.padding-top20 {
padding: 20px 20px 0;
}
.color-tab-content {
display: flex;
flex-direction: column;
align-items: center;
}
.color-img {
width: 100%;
max-width: 400px;
border-radius: 8px;
margin-bottom: 12px;
}
.color-desc {
text-align: center;
color: #666;
font-size: 16px;
}
.title {
padding: 0 20px;
}
.swiper-container {
position: relative;
}
.avatar-box {
display: flex;
position: absolute;
width: 100%;
height: 235px;
}
.avatar {
position: absolute;
width: 235px;
height: 235px;
z-index: 9;
}
.avatar img {
/* width: 235px; */
height: 235px;
transform: scale(1.2);
}
.swiper {
width: 100%;
height: 235px;
margin-top: 20px;
}
.img-box {
width: 235px;
position: relative;
}
.btn {
position: absolute;
z-index: 999;
width: 80px;
height: 100%;
background-color: #fff;
display: flex;
align-items: center;
justify-content: center;
}
.btn img {
width: 32px;
height: 32px;
}
.left-btn {
left: 0;
}
.right-btn {
right: 0;
}
.swiper-item {
/* display: block; */
height: 235px;
line-height: 28px !important;
text-align: center;
display: flex;
justify-content: center;
/* background-color: red; */
}
.swiper-instructions {
display: flex;
flex-direction: column;
align-items: center;
/* justify-content: center; */
padding-top: 10px;
}
.swiper-type-name {
font-family: "PingFang SC", "Microsoft YaHei", "Arial", sans-serif !important;
font-weight: 400;
font-size: 14px;
line-height: 28px !important;
letter-spacing: 94%;
}
.swiper-type-name-en {
font-family: "PingFang SC", "Microsoft YaHei", "Arial", sans-serif !important;
font-weight: 400;
font-size: 14px;
line-height: 28px !important;
letter-spacing: 0%;
text-transform: uppercase;
color: rgba(216, 216, 216, 1);
margin-top: 5px;
}
.swiper-type-text {
font-family: "PingFang SC", "Microsoft YaHei", "Arial", sans-serif !important;
font-weight: 400;
font-size: 12px;
line-height: 28px !important;
letter-spacing: 0%;
margin-top: 5px;
}
.image {
width: 100%;
}
.html-rich-text {
font-family: "PingFang SC", "Microsoft YaHei", "Arial", sans-serif !important;
font-weight: 400 !important;
font-size: 14px !important;
line-height: 28px !important;
letter-spacing: 0% !important;
}
.reference-title {
width: 100%;
height: 17px;
}
.reference-title img {
width: 100%;
height: 17px;
}
.reference-img-box {
height: 195.5px;
margin-top: 20px;
display: flex;
justify-content: space-between;
margin-bottom: 30px;
}
.reference-img-box .reference-img1 {
width: 100%;
height: 195.5px;
}
.reference-img-box .reference-img2 {
width: 45px;
height: 165px;
}
.reference-complate {
width: 100%;
height: 21px;
display: flex;
align-items: center;
justify-content: center;
font-family: "PingFang SC", "Microsoft YaHei", "Arial", sans-serif !important;
font-weight: 400;
font-size: 12px;
line-height: 28px !important;
letter-spacing: 0%;
text-align: center;
color: rgba(216, 216, 216, 1);
margin: 20px 0;
}
.avatar-warp {
width: 100%;
height: 192px;
display: flex;
align-items: center;
justify-content: center;
}
.avatar-main {
width: 116px;
height: 160px;
margin: 0 10px;
border-radius: 40px;
overflow: hidden;
}
.avatar-main img {
width: 100%;
height: 100%;
object-fit: cover;
}
.avatar-side {
width: 80px;
height: 120px;
/* background-color: yellow; */
border-radius: 40px;
overflow: hidden;
}
.avatar-side img {
width: 100%;
height: 100%;
object-fit: cover;
}
.rich-text-content {
padding: 0 20px 20px;
}
.face-img-box {
width: 336px;
height: 338px;
}
.face-img-box img {
width: 100%;
height: 100%;
/* border-radius: 8px; */
}
.more-hairstyle {
width: 100%;
/* height: 135px; */
margin-top: 20px;
}
.more-hairstyle img {
width: 100%;
height: 100%;
}
.lucky-color-box {
padding: 0 20px;
min-height: 950px;
/* overflow-y: hidden; */
}
.shengxiao {
width: 100%;
height: 283px;
}
.shengxiao img {
width: 100%;
height: 100%;
}
.five-attribute-box {
position: relative;
/* margin-bottom: 20px; */
}
.numblock {
width: 50px;
height: 50px;
display: flex;
border-radius: 50%;
align-items: center;
justify-content: center;
position: absolute;
color: white;
z-index: 999;
}
.five-attribute {
width: 100%;
/* height: 597px; */
position: relative;
}
.five-attribute img {
width: 100%;
height: 100%;
}
.avatorLogo {
position: absolute;
left: 50%;
transform: translateX(-50%);
top: 25%;
width: 66.5px;
height: 66.5px;
background-color: red;
border-radius: 50%;
overflow: hidden;
border: 3.22px solid rgba(167, 178, 179, 1);
}
.avatorLogo img {
width: 100%;
height: 100%;
object-fit: cover;
}
.style-type {
line-height: 28px !important;
font-family: "Microsoft YaHei", "Arial", sans-serif !important;
color: #031c24;
/* font-family: Molengo; */
font-size: 14px;
font-style: normal;
font-weight: 400;
/* height: 900px;
background-color: red; */
}
.trends-title {
font-family: "PingFang SC", "Microsoft YaHei", "Arial", sans-serif !important;
margin-bottom: 16px;
font-weight: 400;
font-size: 14px;
line-height: 28px !important;
letter-spacing: 0px;
}
.trends-img-box {
display: flex;
width: 100%;
height: 330px;
justify-content: space-between;
}
.trends-img-box1 {
width: 220px;
}
.trends-img-box1 img {
width: 100%;
height: 100%;
}
.trends-img-box2 {
width: 102px;
display: flex;
flex-direction: column;
justify-content: space-between;
}
.trends-img {
width: 102px;
height: 134px;
}
.trends-img img {
width: 100%;
height: 100%;
}
.trends-one-try-btn {
width: 102px;
height: 24px;
background-color: black;
margin-top: 28px;
font-family: "PingFang SC", "Microsoft YaHei", "Arial", sans-serif !important;
font-weight: 400;
font-style: Regular;
font-size: 12px;
color: #fff;
display: flex;
align-items: center;
justify-content: center;
line-height: 28px !important;
letter-spacing: 0px;
}
.scroll-box {
width: 100%;
overflow-x: auto;
display: flex;
white-space: nowrap;
scrollbar-width: none; /* Firefox 隐藏滚动条 */
-ms-overflow-style: none; /* IE/Edge 隐藏滚动条 */
}
.scroll-box::-webkit-scrollbar {
display: none; /* Chrome/Safari/Opera 隐藏滚动条 */
}
.fixed {
position: fixed;
top: 0;
z-index: 9999;
}
/* 预览遮罩层样式 */
.preview-mask {
position: fixed;
top: 0;
left: 0;
right: 0;
bottom: 0;
background-color: rgba(0, 0, 0, 0.8);
display: flex;
justify-content: center;
align-items: center;
z-index: 999;
}
.preview-container {
width: 90%;
height: 90%;
display: flex;
justify-content: center;
align-items: center;
}
.preview-image {
max-width: 100%;
max-height: 100%;
border-radius: 4px;
}
</style>