报告页逻辑

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
http://localhost:3000/pages/fittingRoom/index?modelId=1976890366293254145&id=1977565196601040912
+1 -1
View File
@@ -100,7 +100,7 @@
{
"path": "pages/uploadClothes/index",
"style": {
"navigationBarTitleText": "1234",
"navigationBarTitleText": "",
"navigationStyle": "custom",
"titleNView": false,
"app-plus": {
@@ -2,7 +2,7 @@
* @Author: liguigong liguigong@shopline.com
* @Date: 2025-09-19 16:26:36
* @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
* @Description: 这是默认设置,可以在设置工具File Description中进行配置
-->
@@ -12,7 +12,10 @@
<uni-grid-item v-for="(item, index) in fittingRoomStore.clothes" :key="index" :index="item">
<view class="grid-item-box" style="background-color: #fff">
<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"
>
<view class="edit" @click="goEdit(item)">编辑</view>
@@ -24,7 +24,11 @@
>选择
</uni-file-picker>
</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>
<image :src="item.thumbnailFileUrl" class="item-image" mode="aspectFill"></image>
</view>
+20 -13
View File
@@ -11,13 +11,13 @@
>
<swiper
:autoplay="false"
:current="fittingRoomStore.swiperCurrentIndex"
:duration="500"
:interval="5000"
:next-margin="'160rpx'"
:previous-margin="'160rpx'"
circular
class="swiper"
current="0"
@change="swiperChange"
>
<swiper-item v-for="(item, index) in fittingRoomStore.testResults" :key="index">
@@ -76,16 +76,7 @@
fittingRoomStore.swiperCurrentIndex = event.detail.current;
}
onMounted(() => {
fittingRoomStore.getCategory();
fittingRoomStore.getCloths();
fittingRoomStore.getModelList();
timer = setInterval(() => {
// TODO: 检测到还有没生成图的, 获取最新数据
// fittingRoomStore.generatingLoading &&
// fittingRoomStore.getTestResults(fittingRoomStore.currentModel?.id);
}, 6000);
});
onMounted(() => {});
onUnload(() => {
// 移除全局监听
clearInterval(timer);
@@ -112,8 +103,24 @@
// const template = computed(() => sheep.$store('app').template?.home);
onLoad((options) => {
uni.setStorageSync('token', options?.token ?? '92d2805a85ca422e90dd7d50eef49a85');
uni.setStorageSync('token', options?.token ?? '86e0032580ac4ca8b1f4f5e9395d1cf8');
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();
if (fittingRoomStore.currentModel?.id) {
fittingRoomStore.getTestResults(fittingRoomStore.currentModel?.id).then(() => {
console.log('➤➤➤ ~ index.vue ~ L124');
console.log('➤➤➤ ~ index.vue ~ L127');
uni.stopPullDownRefresh();
});
} else {
@@ -3,6 +3,7 @@ import { defineProps, ref, watch } from "vue";
import { styleJson } from "./json/style";
const styleImage = ref("");
const psychologicalStyleImage = ref("");
const props = defineProps({
styleType: {
type: String,
@@ -19,6 +20,8 @@ const props = defineProps({
default: "女",
},
});
watch(
() => props.styleType,
(newVal) => {
@@ -26,9 +29,12 @@ watch(
},
{ deep: true, immediate: true }
);
watch(
() => props.psychologicalStyle,
(newVal) => {
console.log('newVal: sssssssssssssssssssss', newVal);
psychologicalStyleImage.value = styleJson.find(
(item) => item.type === newVal
)?.pic;
@@ -25,10 +25,12 @@ const json = ref( [
value: '静态型',
}
])
watch(
() => props.type,
(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) => ({
...item,
checked: item.value == newVal,
@@ -47,7 +49,7 @@ watch(
<CheckBox :checked="item.checked">{{ item.value }}</CheckBox>
</template>
<view class="desc">
{{ aiDesc }}
{{ props.aiDesc }}
</view>
</view>
</view>
+62 -78
View File
@@ -37,13 +37,13 @@
-->
<genetic-style
:gender="collect.gender"
:gender="collect?.sex"
:pic-list="[
collect.eye_img_url ?? '',
collect.triangular_area_img_url ?? '',
collect.full_face_img_url ?? '',
collect?.eye_img_url ?? '',
collect?.triangular_area_img_url ?? '',
collect?.full_face_img_url ?? '',
]"
:styleType="collect.type"
:styleType="collect?.基因风格"
/>
<!-- 肤色-->
@@ -56,47 +56,47 @@
: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"
: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">
<template v-if="true">
<!-- 搭配趋势 -->
<CustomSwiper :items="items" />
<!-- <h1>搭配趋势</h1> -->
<!-- <CustomSwiper :items="items" /> -->
<!-- 个人分格描述报告-->
<StyleDiagnosticReport :html="customerStyle" />
<BottomPic
:style-type="styleType?.type"
:psychological-style="styleType?.psychological_style"
:gender="styleType.gender"
:style-type="collect?.type"
:psychological-style="collect?.psychological_style"
:gender="collect.sex"
/>
</template>
@@ -443,7 +443,7 @@ 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 {hairText, shengxiaoText, shengxiaoSystem_prompt, statureText, styleText} from '@/constant/aiText'
import { praiseTextApi } from '@/sheep/api/doubao'
const {
@@ -611,7 +611,7 @@ const formatShengXiao = (text) => {
return list;
};
const customFigure = ref();
const customFigure = ref(null);
const customerStyle = ref("");
@@ -693,30 +693,14 @@ const getPraiseText = (callWord, type) => {
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)
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") {
@@ -724,9 +708,9 @@ const getPraiseText = (callWord, type) => {
params.text = styleText(customKey);
}
console.log('调用一把yyyyyyyyyyyyyy', callWord)
praiseTextApi(params).then((res) => {
console.log('res: vvvvvvvvvvvvvvvvvvvv', res);
// tabType
if (callWord === "one") {
// console.log("数据是什么1", res.data);
@@ -759,7 +743,7 @@ const getPraiseText = (callWord, type) => {
}
} else if (callWord === "four") {
const obj = JSON.parse(res.data);
// console.log("obj: ", obj);
console.log("obj: ccccccccccccccccccccccccccccc", obj);
const content = obj.choices[0].message.content;
customFigure.value = JSON.parse(content);
@@ -773,29 +757,29 @@ const getPraiseText = (callWord, type) => {
});
};
const items = ref([]);
// 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 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);
// 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);
});
};
// items.value = goods_images;
// // clothesList.value = res.data.wardrobeList.slice(0, 3);
// });
// };
wardrobeList();
// wardrobeList();
const getHairstyleList = () => {
hairStyleListApi({
@@ -893,15 +877,15 @@ const getUserFaceInfo = async () => {
}
// getPraiseText("one");
// getPraiseText("three", 1);
getPraiseText("one");
getPraiseText("three", 1);
try {
getPraiseText("four");
} catch (error) {
console.error('error: ', error);
}
// getPraiseText("five");
getPraiseText("five");
getColorTypeText(res?.detail?.sj_color_type || "");
let blob = await downloadFile(userFaceInfo?.value?.avatar_img_url);
+5 -3
View File
@@ -27,16 +27,18 @@ export const praiseTextApi = (data) => {
data: {
model: 'doubao-1-5-thinking-pro-m-250428',
messages: [
{
data.system_prompt ?{
role: 'system',
content: data.system_prompt,
},
}: null,
{
role: 'user',
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
* @Date: 2025-09-23 09:41:10
* @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
* @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) => {
return request({
url: '/userinfo/add_hair_data',
+26 -9
View File
@@ -79,6 +79,7 @@ const fittingRoom = defineStore({
// "createTime": 1758857790000
});
this.testResults = result;
return result;
console.log('🚀 ~ getTestResults 🐶76 ~ httpResponse: ', httpResponse.data?.list);
},
@@ -95,12 +96,17 @@ const fittingRoom = defineStore({
: httpResponse.result || [];
},
// 获取模特数据查询
async getModelList(templateId = null) {
async getModelList(modelId = undefined) {
const httpResponse = await FittingRoomApi.getModelList({
sex: this.sex,
});
let modelList = (httpResponse.result || []).slice(0, 4);
let modelList = httpResponse.result || [];
this.modelList = modelList;
if (modelId) {
this.currentModel = modelList.find((item) => item.id === modelId);
// this.getTestResults(modelId);
return;
}
this.currentModel = modelList?.[0] ?? {};
this.getTestResults(modelList?.[0]?.id);
},
@@ -115,13 +121,24 @@ const fittingRoom = defineStore({
return;
}
// 那改成 clothUrl 和 kuziUrl 吧,当 kuziUrl 有值时,再传个 suit: true
const httpResponse = 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,
});
const httpResponse =
this.tab === 6
? await FittingRoomApi.hairstyleTryOnApi({
modelId: this.currentModel.id,
files: this.currentModel.fileUrl,
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) {
sheep.$helper.toast(httpResponse.msg);
return;