报告页逻辑

This commit is contained in:
kenny
2025-10-13 19:35:32 +08:00
11 changed files with 147 additions and 110 deletions
+3
View File
@@ -52,3 +52,6 @@ https://docs.qq.com/sheet/DS0pybm5Yc1ViakNj
换发型: https://leops128e7.feishu.cn/docx/HVCHdCAV8ok4bkxcaXVc6q6enXb 换发型: https://leops128e7.feishu.cn/docx/HVCHdCAV8ok4bkxcaXVc6q6enXb
http://localhost:3000/pages/fittingRoom/index?modelId=1976890366293254145&id=1977565196601040912
+1 -1
View File
@@ -100,7 +100,7 @@
{ {
"path": "pages/uploadClothes/index", "path": "pages/uploadClothes/index",
"style": { "style": {
"navigationBarTitleText": "1234", "navigationBarTitleText": "",
"navigationStyle": "custom", "navigationStyle": "custom",
"titleNView": false, "titleNView": false,
"app-plus": { "app-plus": {
@@ -2,7 +2,7 @@
* @Author: liguigong liguigong@shopline.com * @Author: liguigong liguigong@shopline.com
* @Date: 2025-09-19 16:26:36 * @Date: 2025-09-19 16:26:36
* @LastEditors: liguigong liguigong@shopline.com * @LastEditors: liguigong liguigong@shopline.com
* @LastEditTime: 2025-09-28 14:54:34 * @LastEditTime: 2025-10-13 15:22:56
* @FilePath: pages/fittingRoom/components/s-grid-clothes.vue * @FilePath: pages/fittingRoom/components/s-grid-clothes.vue
* @Description: 这是默认设置,可以在设置工具File Description中进行配置 * @Description: 这是默认设置,可以在设置工具File Description中进行配置
--> -->
@@ -12,7 +12,10 @@
<uni-grid-item v-for="(item, index) in fittingRoomStore.clothes" :key="index" :index="item"> <uni-grid-item v-for="(item, index) in fittingRoomStore.clothes" :key="index" :index="item">
<view class="grid-item-box" style="background-color: #fff"> <view class="grid-item-box" style="background-color: #fff">
<view <view
v-if="fittingRoomStore.currentClothes.some((v) => v.clothId === item.clothId)" v-if="
fittingRoomStore.currentClothes.some((v) => v.clothId === item.clothId) &&
fittingRoomStore.tab !== 6
"
class="inUse" class="inUse"
> >
<view class="edit" @click="goEdit(item)">编辑</view> <view class="edit" @click="goEdit(item)">编辑</view>
@@ -24,7 +24,11 @@
>选择 >选择
</uni-file-picker> </uni-file-picker>
</view> </view>
<view v-for="item of fittingRoom.modelList" class="item" @click="switchModels(item)"> <view
v-for="item of fittingRoom.modelList.slice(0, 4)"
class="item"
@click="switchModels(item)"
>
<view class="item-text"></view> <view class="item-text"></view>
<image :src="item.thumbnailFileUrl" class="item-image" mode="aspectFill"></image> <image :src="item.thumbnailFileUrl" class="item-image" mode="aspectFill"></image>
</view> </view>
+20 -13
View File
@@ -11,13 +11,13 @@
> >
<swiper <swiper
:autoplay="false" :autoplay="false"
:current="fittingRoomStore.swiperCurrentIndex"
:duration="500" :duration="500"
:interval="5000" :interval="5000"
:next-margin="'160rpx'" :next-margin="'160rpx'"
:previous-margin="'160rpx'" :previous-margin="'160rpx'"
circular circular
class="swiper" class="swiper"
current="0"
@change="swiperChange" @change="swiperChange"
> >
<swiper-item v-for="(item, index) in fittingRoomStore.testResults" :key="index"> <swiper-item v-for="(item, index) in fittingRoomStore.testResults" :key="index">
@@ -76,16 +76,7 @@
fittingRoomStore.swiperCurrentIndex = event.detail.current; fittingRoomStore.swiperCurrentIndex = event.detail.current;
} }
onMounted(() => { onMounted(() => {});
fittingRoomStore.getCategory();
fittingRoomStore.getCloths();
fittingRoomStore.getModelList();
timer = setInterval(() => {
// TODO: 检测到还有没生成图的, 获取最新数据
// fittingRoomStore.generatingLoading &&
// fittingRoomStore.getTestResults(fittingRoomStore.currentModel?.id);
}, 6000);
});
onUnload(() => { onUnload(() => {
// 移除全局监听 // 移除全局监听
clearInterval(timer); clearInterval(timer);
@@ -112,8 +103,24 @@
// const template = computed(() => sheep.$store('app').template?.home); // const template = computed(() => sheep.$store('app').template?.home);
onLoad((options) => { onLoad((options) => {
uni.setStorageSync('token', options?.token ?? '92d2805a85ca422e90dd7d50eef49a85'); uni.setStorageSync('token', options?.token ?? '86e0032580ac4ca8b1f4f5e9395d1cf8');
console.log('🚀 ~ URL上的token ~ options?.token: ', options?.token); console.log('🚀 ~ URL上的token ~ options?.token: ', options?.token);
fittingRoomStore.getCategory();
fittingRoomStore.getCloths();
timer = setInterval(() => {
// TODO: 检测到还有没生成图的, 获取最新数据
// fittingRoomStore.generatingLoading &&
// fittingRoomStore.getTestResults(fittingRoomStore.currentModel?.id);
}, 6000);
if (options?.modelId && options?.id) {
fittingRoomStore.getModelList(options?.modelId);
fittingRoomStore.getTestResults(options?.modelId).then((res) => {
console.log('🚀 ~ index.vue ~ L118');
fittingRoomStore.swiperCurrentIndex = res.findIndex((res) => res.id === options?.id);
});
} else {
fittingRoomStore.getModelList();
}
}); });
// 下拉刷新 // 下拉刷新
@@ -121,7 +128,7 @@
// sheep.$store('app').init(); // sheep.$store('app').init();
if (fittingRoomStore.currentModel?.id) { if (fittingRoomStore.currentModel?.id) {
fittingRoomStore.getTestResults(fittingRoomStore.currentModel?.id).then(() => { fittingRoomStore.getTestResults(fittingRoomStore.currentModel?.id).then(() => {
console.log('➤➤➤ ~ index.vue ~ L124'); console.log('➤➤➤ ~ index.vue ~ L127');
uni.stopPullDownRefresh(); uni.stopPullDownRefresh();
}); });
} else { } else {
@@ -3,6 +3,7 @@ import { defineProps, ref, watch } from "vue";
import { styleJson } from "./json/style"; import { styleJson } from "./json/style";
const styleImage = ref(""); const styleImage = ref("");
const psychologicalStyleImage = ref(""); const psychologicalStyleImage = ref("");
const props = defineProps({ const props = defineProps({
styleType: { styleType: {
type: String, type: String,
@@ -19,6 +20,8 @@ const props = defineProps({
default: "女", default: "女",
}, },
}); });
watch( watch(
() => props.styleType, () => props.styleType,
(newVal) => { (newVal) => {
@@ -26,9 +29,12 @@ watch(
}, },
{ deep: true, immediate: true } { deep: true, immediate: true }
); );
watch( watch(
() => props.psychologicalStyle, () => props.psychologicalStyle,
(newVal) => { (newVal) => {
console.log('newVal: sssssssssssssssssssss', newVal);
psychologicalStyleImage.value = styleJson.find( psychologicalStyleImage.value = styleJson.find(
(item) => item.type === newVal (item) => item.type === newVal
)?.pic; )?.pic;
@@ -25,10 +25,12 @@ const json = ref( [
value: '静态型', value: '静态型',
} }
]) ])
watch( watch(
() => props.type, () => props.type,
(newVal) => { (newVal) => {
console.log('动静类型: props.type: ', newVal); console.log('动静类型: props.type: ', newVal, props.aiDesc);
// console.log('props.aiDesc: ---------', props.aiDesc);
json.value = json.value.map((item) => ({ json.value = json.value.map((item) => ({
...item, ...item,
checked: item.value == newVal, checked: item.value == newVal,
@@ -47,7 +49,7 @@ watch(
<CheckBox :checked="item.checked">{{ item.value }}</CheckBox> <CheckBox :checked="item.checked">{{ item.value }}</CheckBox>
</template> </template>
<view class="desc"> <view class="desc">
{{ aiDesc }} {{ props.aiDesc }}
</view> </view>
</view> </view>
</view> </view>
+62 -78
View File
@@ -37,13 +37,13 @@
--> -->
<genetic-style <genetic-style
:gender="collect.gender" :gender="collect?.sex"
:pic-list="[ :pic-list="[
collect.eye_img_url ?? '', collect?.eye_img_url ?? '',
collect.triangular_area_img_url ?? '', collect?.triangular_area_img_url ?? '',
collect.full_face_img_url ?? '', collect?.full_face_img_url ?? '',
]" ]"
:styleType="collect.type" :styleType="collect?.基因风格"
/> />
<!-- 肤色--> <!-- 肤色-->
@@ -56,47 +56,47 @@
:luminance="collect?.luminance ?? 0" :luminance="collect?.luminance ?? 0"
/> />
<BodyType
<!-- 轮廓类型-->
<template v-if="customFigure">
<SensoryTypes
:type="collect.straight_total_score_t"
:ai-desc="customFigure?.sensory?.desc"
/>
<!-- 量感类型-->
<TypeOfMass
:type="collect.total_sense_of_quantity_t"
:ai-desc="customFigure?.mass?.desc"
/>
<!-- <h1>动静类型</h1> -->
<!-- 动静类型-->
<Movementtype
:type="collect.dynamic_static_t"
:ai-desc="customFigure?.movement?.desc"
/>
<!-- 体型-->
<BodyType
:body-type="collect?.somatotype" :body-type="collect?.somatotype"
:gender="collect?.gender" :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>
<template v-if="false"> <template v-if="true">
<!-- 搭配趋势 --> <!-- 搭配趋势 -->
<CustomSwiper :items="items" /> <!-- <h1>搭配趋势</h1> -->
<!-- <CustomSwiper :items="items" /> -->
<!-- 个人分格描述报告--> <!-- 个人分格描述报告-->
<StyleDiagnosticReport :html="customerStyle" /> <StyleDiagnosticReport :html="customerStyle" />
<BottomPic <BottomPic
:style-type="styleType?.type" :style-type="collect?.type"
:psychological-style="styleType?.psychological_style" :psychological-style="collect?.psychological_style"
:gender="styleType.gender" :gender="collect.sex"
/> />
</template> </template>
@@ -443,7 +443,7 @@ import Movementtype from "./component/FirstStyleType/Movementtype.vue";
import ReportApi from "../../sheep/api/report"; import ReportApi from "../../sheep/api/report";
import { onLoad } from '@dcloudio/uni-app'; import { onLoad } from '@dcloudio/uni-app';
import {hairText, shengxiaoText, shengxiaoSystem_prompt, statureText} from '@/constant/aiText' import {hairText, shengxiaoText, shengxiaoSystem_prompt, statureText, styleText} from '@/constant/aiText'
import { praiseTextApi } from '@/sheep/api/doubao' import { praiseTextApi } from '@/sheep/api/doubao'
const { const {
@@ -611,7 +611,7 @@ const formatShengXiao = (text) => {
return list; return list;
}; };
const customFigure = ref(); const customFigure = ref(null);
const customerStyle = ref(""); const customerStyle = ref("");
@@ -693,30 +693,14 @@ const getPraiseText = (callWord, type) => {
if (callWord === "three") { if (callWord === "three") {
params.tabType = "shengxiao"; 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.text = shengxiaoText(collect?.value?.birthday, collect?.value?.gender, collect?.value?.work)
params.system_prompt = shengxiaoSystem_prompt params.system_prompt = shengxiaoSystem_prompt
} }
// console.log('tttttttttttttttttttttttttttttt', callWord)
if (callWord === "four") { if (callWord === "four") {
params.tabType = "stature"; 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) params.text = statureText(customKey, collect.value?.straight_total_score_t, collect.value?.total_sense_of_quantity_t, collect.value.dynamic_static_t)
} }
if (callWord === "five") { if (callWord === "five") {
@@ -724,9 +708,9 @@ const getPraiseText = (callWord, type) => {
params.text = styleText(customKey); params.text = styleText(customKey);
} }
console.log('调用一把yyyyyyyyyyyyyy', callWord)
praiseTextApi(params).then((res) => { praiseTextApi(params).then((res) => {
console.log('res: vvvvvvvvvvvvvvvvvvvv', res);
// tabType // tabType
if (callWord === "one") { if (callWord === "one") {
// console.log("数据是什么1", res.data); // console.log("数据是什么1", res.data);
@@ -759,7 +743,7 @@ const getPraiseText = (callWord, type) => {
} }
} else if (callWord === "four") { } else if (callWord === "four") {
const obj = JSON.parse(res.data); const obj = JSON.parse(res.data);
// console.log("obj: ", obj); console.log("obj: ccccccccccccccccccccccccccccc", obj);
const content = obj.choices[0].message.content; const content = obj.choices[0].message.content;
customFigure.value = JSON.parse(content); customFigure.value = JSON.parse(content);
@@ -773,29 +757,29 @@ const getPraiseText = (callWord, type) => {
}); });
}; };
const items = ref([]); // const items = ref([]);
const wardrobeList = () => { // const wardrobeList = () => {
// https://llshop.zglvling.com/soapi/wardrobe/clothes_list // // https://llshop.zglvling.com/soapi/wardrobe/clothes_list
wardrobeListApi({ // wardrobeListApi({
open_id: openId, // open_id: openId,
// categoryId: 10140, // // categoryId: 10140,
clothesIndex: 1, // clothesIndex: 1,
clothesKind: 0, // clothesKind: 0,
clothesSize: 12, // clothesSize: 12,
}).then((res) => { // }).then((res) => {
// console.log("衣服列表 -----------------", res.clothesList); // // console.log("衣服列表 -----------------", res.clothesList);
const goods_images = res.clothesList // const goods_images = res.clothesList
.map((i) => i.goods_image) // .map((i) => i.goods_image)
.filter((i) => i.length >= 5); // .filter((i) => i.length >= 5);
items.value = goods_images; // items.value = goods_images;
// clothesList.value = res.data.wardrobeList.slice(0, 3); // // clothesList.value = res.data.wardrobeList.slice(0, 3);
}); // });
}; // };
wardrobeList(); // wardrobeList();
const getHairstyleList = () => { const getHairstyleList = () => {
hairStyleListApi({ hairStyleListApi({
@@ -893,15 +877,15 @@ const getUserFaceInfo = async () => {
} }
// getPraiseText("one"); getPraiseText("one");
// getPraiseText("three", 1); getPraiseText("three", 1);
try { try {
getPraiseText("four"); getPraiseText("four");
} catch (error) { } catch (error) {
console.error('error: ', error); console.error('error: ', error);
} }
// getPraiseText("five"); getPraiseText("five");
getColorTypeText(res?.detail?.sj_color_type || ""); getColorTypeText(res?.detail?.sj_color_type || "");
let blob = await downloadFile(userFaceInfo?.value?.avatar_img_url); let blob = await downloadFile(userFaceInfo?.value?.avatar_img_url);
+5 -3
View File
@@ -27,16 +27,18 @@ export const praiseTextApi = (data) => {
data: { data: {
model: 'doubao-1-5-thinking-pro-m-250428', model: 'doubao-1-5-thinking-pro-m-250428',
messages: [ messages: [
{ data.system_prompt ?{
role: 'system', role: 'system',
content: data.system_prompt, content: data.system_prompt,
}, }: null,
{ {
role: 'user', role: 'user',
content: data.text, content: data.text,
}, },
], ].filter(i => i),
}, },
}).then(res => {
return { data: JSON.stringify(res.data) };
}); });
}; };
+10 -1
View File
@@ -2,7 +2,7 @@
* @Author: liguigong liguigong@shopline.com * @Author: liguigong liguigong@shopline.com
* @Date: 2025-09-23 09:41:10 * @Date: 2025-09-23 09:41:10
* @LastEditors: liguigong liguigong@shopline.com * @LastEditors: liguigong liguigong@shopline.com
* @LastEditTime: 2025-09-28 16:27:38 * @LastEditTime: 2025-10-13 14:30:53
* @FilePath: sheep/api/fittingRoom/index.js * @FilePath: sheep/api/fittingRoom/index.js
* @Description: 这是默认设置,可以在设置》工具》File Description中进行配置 * @Description: 这是默认设置,可以在设置》工具》File Description中进行配置
*/ */
@@ -148,6 +148,15 @@ const FittingRoomApi = {
}); });
}, },
//发型试穿
hairstyleTryOnApi: (data) => {
return request({
url: '/digital/on-record/exchange-hair',
method: 'POST',
data: data,
});
},
addHairApi: (data) => { addHairApi: (data) => {
return request({ return request({
url: '/userinfo/add_hair_data', url: '/userinfo/add_hair_data',
+26 -9
View File
@@ -79,6 +79,7 @@ const fittingRoom = defineStore({
// "createTime": 1758857790000 // "createTime": 1758857790000
}); });
this.testResults = result; this.testResults = result;
return result;
console.log('🚀 ~ getTestResults 🐶76 ~ httpResponse: ', httpResponse.data?.list); console.log('🚀 ~ getTestResults 🐶76 ~ httpResponse: ', httpResponse.data?.list);
}, },
@@ -95,12 +96,17 @@ const fittingRoom = defineStore({
: httpResponse.result || []; : httpResponse.result || [];
}, },
// 获取模特数据查询 // 获取模特数据查询
async getModelList(templateId = null) { async getModelList(modelId = undefined) {
const httpResponse = await FittingRoomApi.getModelList({ const httpResponse = await FittingRoomApi.getModelList({
sex: this.sex, sex: this.sex,
}); });
let modelList = (httpResponse.result || []).slice(0, 4); let modelList = httpResponse.result || [];
this.modelList = modelList; this.modelList = modelList;
if (modelId) {
this.currentModel = modelList.find((item) => item.id === modelId);
// this.getTestResults(modelId);
return;
}
this.currentModel = modelList?.[0] ?? {}; this.currentModel = modelList?.[0] ?? {};
this.getTestResults(modelList?.[0]?.id); this.getTestResults(modelList?.[0]?.id);
}, },
@@ -115,13 +121,24 @@ const fittingRoom = defineStore({
return; return;
} }
// 那改成 clothUrl 和 kuziUrl 吧,当 kuziUrl 有值时,再传个 suit: true // 那改成 clothUrl 和 kuziUrl 吧,当 kuziUrl 有值时,再传个 suit: true
const httpResponse = await FittingRoomApi.tryOnApi({ const httpResponse =
modelId: this.currentModel.id, this.tab === 6
modelImageUrl: this.currentModel.fileUrl, ? await FittingRoomApi.hairstyleTryOnApi({
clothUrl: this.currentClothes[0]?.fileUrl, modelId: this.currentModel.id,
kuziUrl: this.currentClothes?.[1]?.fileUrl ? this.currentClothes[1]?.fileUrl : undefined, files: this.currentModel.fileUrl,
suit: this.currentClothes?.[1]?.fileUrl ? true : undefined, isHr: true,
}); hairIds: this.currentClothes[0]?.clothId,
sex: 'female',
})
: await FittingRoomApi.tryOnApi({
modelId: this.currentModel.id,
modelImageUrl: this.currentModel.fileUrl,
clothUrl: this.currentClothes[0]?.fileUrl,
kuziUrl: this.currentClothes?.[1]?.fileUrl
? this.currentClothes[1]?.fileUrl
: undefined,
suit: this.currentClothes?.[1]?.fileUrl ? true : undefined,
});
if (httpResponse.code !== 0) { if (httpResponse.code !== 0) {
sheep.$helper.toast(httpResponse.msg); sheep.$helper.toast(httpResponse.msg);
return; return;