feat: add aigc record, video preview & custom recharge
- create useAigcRecordStore to centralize current AIGC generation record state - add video media type support to ResultPreview component - update RecordCard to only display view button for completed tasks - implement custom recharge amount with input validation and 9999 max limit - refactor detail page to load record from Pinia store instead of mock data - clean up TemplateCarousel markup and remove unused badge styles - fix minor formatting and code style issues
This commit is contained in:
@@ -5,7 +5,7 @@
|
||||
<view class="aigc-detail-content">
|
||||
<ResultPreview :result="result" />
|
||||
<ResultMeta :items="metaItems" />
|
||||
<ContinuationCard :info="continuationInfo" @upgrade="handleUpgradeToVideo" />
|
||||
<ContinuationCard v-if="continuationInfo" :info="continuationInfo" @upgrade="handleUpgradeToVideo" />
|
||||
<ResultActions @save="handleSave" @share="handleShare" />
|
||||
|
||||
<view class="aigc-detail-text-actions">
|
||||
@@ -20,8 +20,10 @@
|
||||
<script setup>
|
||||
import { computed } from "vue";
|
||||
import { onShow } from "@dcloudio/uni-app";
|
||||
import { storeToRefs } from "pinia";
|
||||
import AigcTopBar from "@/pages-aigc/components/AigcTopBar/index.vue";
|
||||
import { useCurrentCredit } from "@/pages-aigc/hooks/useCurrentCredit.js";
|
||||
import { useAigcRecordStore } from "@/store";
|
||||
import ContinuationCard from "./components/ContinuationCard/index.vue";
|
||||
import ResultActions from "./components/ResultActions/index.vue";
|
||||
import ResultMeta from "./components/ResultMeta/index.vue";
|
||||
@@ -29,33 +31,94 @@ import ResultPreview from "./components/ResultPreview/index.vue";
|
||||
import { aigcDetailResult } from "./data/result.js";
|
||||
|
||||
const { pointBalance, fetchCurrentCredit } = useCurrentCredit();
|
||||
const result = aigcDetailResult;
|
||||
const aigcRecordStore = useAigcRecordStore();
|
||||
const { currentRecord } = storeToRefs(aigcRecordStore);
|
||||
|
||||
const GENERATOR_TYPE_TEXT = {
|
||||
0: "图片版",
|
||||
1: "视频版",
|
||||
};
|
||||
|
||||
const result = computed(() => {
|
||||
const record = currentRecord.value;
|
||||
if (!record) return aigcDetailResult;
|
||||
|
||||
const imageUrl = record.imageResultUrl || "";
|
||||
const videoUrl = record.videoResultUrl || "";
|
||||
const isVideo = Boolean(videoUrl) && (record.generatorType === 1 || !imageUrl);
|
||||
const typeText =
|
||||
GENERATOR_TYPE_TEXT[record.generatorType] ||
|
||||
(record.generatorType === undefined ? "生成结果" : `类型${record.generatorType}`);
|
||||
const consumedText =
|
||||
record.generatorCost === undefined || record.generatorCost === null || record.generatorCost === ""
|
||||
? "-"
|
||||
: `${record.generatorCost}积分`;
|
||||
|
||||
return {
|
||||
id: record.taskId,
|
||||
title: record.itemTitle || record.taskId || "生成结果",
|
||||
cover: isVideo ? videoUrl : imageUrl || videoUrl,
|
||||
mediaType: isVideo ? "video" : "image",
|
||||
accent: "#0a4d46",
|
||||
variantLabel: typeText,
|
||||
resultLabel: typeText,
|
||||
consumedText,
|
||||
desc: record.itemSubTitle || "生成任务已完成",
|
||||
};
|
||||
});
|
||||
|
||||
onShow(() => {
|
||||
fetchCurrentCredit();
|
||||
});
|
||||
|
||||
const metaItems = computed(() => [
|
||||
{
|
||||
label: "结果",
|
||||
value: result.resultLabel,
|
||||
},
|
||||
{
|
||||
label: "已消耗",
|
||||
value: result.consumedText,
|
||||
},
|
||||
{
|
||||
label: "余额",
|
||||
value: `${pointBalance.value}积分`,
|
||||
},
|
||||
]);
|
||||
const metaItems = computed(() => {
|
||||
if (currentRecord.value) {
|
||||
const record = currentRecord.value;
|
||||
const completeTime =
|
||||
record.videoGeneratorCompleteTime || record.imageGeneratorCompleteTime || record.createTime || "-";
|
||||
|
||||
const continuationInfo = computed(() => ({
|
||||
title: result.continuationTitle,
|
||||
desc: result.continuationDesc,
|
||||
cost: result.continuationCost,
|
||||
buttonText: result.continuationButtonText,
|
||||
}));
|
||||
return [
|
||||
{
|
||||
label: "结果",
|
||||
value: result.value.resultLabel,
|
||||
},
|
||||
{
|
||||
label: "已消耗",
|
||||
value: result.value.consumedText,
|
||||
},
|
||||
{
|
||||
label: "完成时间",
|
||||
value: completeTime,
|
||||
},
|
||||
];
|
||||
}
|
||||
|
||||
return [
|
||||
{
|
||||
label: "结果",
|
||||
value: result.value.resultLabel,
|
||||
},
|
||||
{
|
||||
label: "已消耗",
|
||||
value: result.value.consumedText,
|
||||
},
|
||||
{
|
||||
label: "余额",
|
||||
value: `${pointBalance.value}积分`,
|
||||
},
|
||||
];
|
||||
});
|
||||
|
||||
const continuationInfo = computed(() => {
|
||||
if (currentRecord.value) return null;
|
||||
|
||||
return {
|
||||
title: result.value.continuationTitle,
|
||||
desc: result.value.continuationDesc,
|
||||
cost: result.value.continuationCost,
|
||||
buttonText: result.value.continuationButtonText,
|
||||
};
|
||||
});
|
||||
|
||||
const showPlaceholderToast = (title) => {
|
||||
uni.showToast({
|
||||
|
||||
Reference in New Issue
Block a user