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:
@@ -1,6 +1,13 @@
|
|||||||
<template>
|
<template>
|
||||||
<view class="result-preview" :style="{ '--result-accent': result.accent }">
|
<view class="result-preview" :style="{ '--result-accent': result.accent }">
|
||||||
<image class="result-preview-image" :src="result.cover" mode="aspectFill" />
|
<video
|
||||||
|
v-if="result.mediaType === 'video'"
|
||||||
|
class="result-preview-image"
|
||||||
|
:src="result.cover"
|
||||||
|
controls
|
||||||
|
object-fit="cover"
|
||||||
|
/>
|
||||||
|
<image v-else class="result-preview-image" :src="result.cover" mode="aspectFill" />
|
||||||
<view class="result-preview-shade" />
|
<view class="result-preview-shade" />
|
||||||
|
|
||||||
<view class="result-preview-caption">
|
<view class="result-preview-caption">
|
||||||
|
|||||||
@@ -5,7 +5,7 @@
|
|||||||
<view class="aigc-detail-content">
|
<view class="aigc-detail-content">
|
||||||
<ResultPreview :result="result" />
|
<ResultPreview :result="result" />
|
||||||
<ResultMeta :items="metaItems" />
|
<ResultMeta :items="metaItems" />
|
||||||
<ContinuationCard :info="continuationInfo" @upgrade="handleUpgradeToVideo" />
|
<ContinuationCard v-if="continuationInfo" :info="continuationInfo" @upgrade="handleUpgradeToVideo" />
|
||||||
<ResultActions @save="handleSave" @share="handleShare" />
|
<ResultActions @save="handleSave" @share="handleShare" />
|
||||||
|
|
||||||
<view class="aigc-detail-text-actions">
|
<view class="aigc-detail-text-actions">
|
||||||
@@ -20,8 +20,10 @@
|
|||||||
<script setup>
|
<script setup>
|
||||||
import { computed } from "vue";
|
import { computed } from "vue";
|
||||||
import { onShow } from "@dcloudio/uni-app";
|
import { onShow } from "@dcloudio/uni-app";
|
||||||
|
import { storeToRefs } from "pinia";
|
||||||
import AigcTopBar from "@/pages-aigc/components/AigcTopBar/index.vue";
|
import AigcTopBar from "@/pages-aigc/components/AigcTopBar/index.vue";
|
||||||
import { useCurrentCredit } from "@/pages-aigc/hooks/useCurrentCredit.js";
|
import { useCurrentCredit } from "@/pages-aigc/hooks/useCurrentCredit.js";
|
||||||
|
import { useAigcRecordStore } from "@/store";
|
||||||
import ContinuationCard from "./components/ContinuationCard/index.vue";
|
import ContinuationCard from "./components/ContinuationCard/index.vue";
|
||||||
import ResultActions from "./components/ResultActions/index.vue";
|
import ResultActions from "./components/ResultActions/index.vue";
|
||||||
import ResultMeta from "./components/ResultMeta/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";
|
import { aigcDetailResult } from "./data/result.js";
|
||||||
|
|
||||||
const { pointBalance, fetchCurrentCredit } = useCurrentCredit();
|
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(() => {
|
onShow(() => {
|
||||||
fetchCurrentCredit();
|
fetchCurrentCredit();
|
||||||
});
|
});
|
||||||
|
|
||||||
const metaItems = computed(() => [
|
const metaItems = computed(() => {
|
||||||
{
|
if (currentRecord.value) {
|
||||||
label: "结果",
|
const record = currentRecord.value;
|
||||||
value: result.resultLabel,
|
const completeTime =
|
||||||
},
|
record.videoGeneratorCompleteTime || record.imageGeneratorCompleteTime || record.createTime || "-";
|
||||||
{
|
|
||||||
label: "已消耗",
|
|
||||||
value: result.consumedText,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
label: "余额",
|
|
||||||
value: `${pointBalance.value}积分`,
|
|
||||||
},
|
|
||||||
]);
|
|
||||||
|
|
||||||
const continuationInfo = computed(() => ({
|
return [
|
||||||
title: result.continuationTitle,
|
{
|
||||||
desc: result.continuationDesc,
|
label: "结果",
|
||||||
cost: result.continuationCost,
|
value: result.value.resultLabel,
|
||||||
buttonText: result.continuationButtonText,
|
},
|
||||||
}));
|
{
|
||||||
|
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) => {
|
const showPlaceholderToast = (title) => {
|
||||||
uni.showToast({
|
uni.showToast({
|
||||||
|
|||||||
@@ -5,38 +5,20 @@
|
|||||||
<text class="template-heading-title">选择模板</text>
|
<text class="template-heading-title">选择模板</text>
|
||||||
<text class="template-heading-subtitle">左右滑动预览效果</text>
|
<text class="template-heading-subtitle">左右滑动预览效果</text>
|
||||||
</view>
|
</view>
|
||||||
<text class="template-heading-badge">同源双版本</text>
|
|
||||||
</view>
|
</view>
|
||||||
|
|
||||||
<scroll-view
|
<scroll-view class="template-rail" scroll-x show-scrollbar="false" scroll-with-animation
|
||||||
class="template-rail"
|
:scroll-left="railScrollLeft" @scroll="handleScroll" @touchstart="handleTouchStart" @touchend="handleTouchEnd"
|
||||||
scroll-x
|
@touchcancel="handleTouchEnd">
|
||||||
show-scrollbar="false"
|
|
||||||
scroll-with-animation
|
|
||||||
:scroll-left="railScrollLeft"
|
|
||||||
@scroll="handleScroll"
|
|
||||||
@touchstart="handleTouchStart"
|
|
||||||
@touchend="handleTouchEnd"
|
|
||||||
@touchcancel="handleTouchEnd"
|
|
||||||
>
|
|
||||||
<view class="template-track">
|
<view class="template-track">
|
||||||
<TemplateCard
|
<TemplateCard v-for="(template, index) in templates" :key="template.templateId || index" :template="template"
|
||||||
v-for="(template, index) in templates"
|
:active="index === modelValue" @select="handleSelect(template, index)" />
|
||||||
:key="template.templateId || index"
|
|
||||||
:template="template"
|
|
||||||
:active="index === modelValue"
|
|
||||||
@select="handleSelect(template, index)"
|
|
||||||
/>
|
|
||||||
</view>
|
</view>
|
||||||
</scroll-view>
|
</scroll-view>
|
||||||
|
|
||||||
<view class="template-dots">
|
<view class="template-dots">
|
||||||
<view
|
<view v-for="(template, index) in templates" :key="`${template.templateId || index}-dot`" class="template-dot"
|
||||||
v-for="(template, index) in templates"
|
:class="{ 'is-active': index === modelValue }" />
|
||||||
:key="`${template.templateId || index}-dot`"
|
|
||||||
class="template-dot"
|
|
||||||
:class="{ 'is-active': index === modelValue }"
|
|
||||||
/>
|
|
||||||
</view>
|
</view>
|
||||||
</view>
|
</view>
|
||||||
</template>
|
</template>
|
||||||
|
|||||||
@@ -31,19 +31,6 @@
|
|||||||
font-weight: 800;
|
font-weight: 800;
|
||||||
}
|
}
|
||||||
|
|
||||||
.template-heading-badge {
|
|
||||||
height: 26px;
|
|
||||||
display: inline-flex;
|
|
||||||
align-items: center;
|
|
||||||
padding: 0 10px;
|
|
||||||
border-radius: 999px;
|
|
||||||
background: rgba(32, 207, 117, 0.12);
|
|
||||||
color: #10a765;
|
|
||||||
font-size: 11px;
|
|
||||||
line-height: 26px;
|
|
||||||
font-weight: 900;
|
|
||||||
}
|
|
||||||
|
|
||||||
.template-rail {
|
.template-rail {
|
||||||
max-width: 100vw;
|
max-width: 100vw;
|
||||||
height: var(--template-rail-height, 560px);
|
height: var(--template-rail-height, 560px);
|
||||||
@@ -61,7 +48,8 @@
|
|||||||
align-items: flex-start;
|
align-items: flex-start;
|
||||||
gap: var(--template-track-gap, 12px);
|
gap: var(--template-track-gap, 12px);
|
||||||
height: var(--template-rail-height, 560px);
|
height: var(--template-rail-height, 560px);
|
||||||
padding: 0 var(--template-track-end-padding, 41px) 0 var(--template-side-padding, 16px);
|
padding: 0 var(--template-track-end-padding, 41px) 0
|
||||||
|
var(--template-side-padding, 16px);
|
||||||
box-sizing: border-box;
|
box-sizing: border-box;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,13 +1,15 @@
|
|||||||
<template>
|
<template>
|
||||||
<view class="custom-card is-selected">
|
<view :class="['custom-card', { 'is-selected': selected }]" @tap="emit('select')">
|
||||||
<text class="custom-title">充值金额</text>
|
<text class="custom-title">自选金额</text>
|
||||||
|
|
||||||
<label class="custom-input-wrap">
|
<label class="custom-input-wrap">
|
||||||
<text class="custom-currency">¥</text>
|
<text class="custom-currency">¥</text>
|
||||||
<input
|
<input
|
||||||
class="custom-input"
|
class="custom-input"
|
||||||
type="number"
|
type="number"
|
||||||
|
:maxlength="4"
|
||||||
:value="modelValue"
|
:value="modelValue"
|
||||||
|
@focus="emit('select')"
|
||||||
@input="handleInput"
|
@input="handleInput"
|
||||||
/>
|
/>
|
||||||
</label>
|
</label>
|
||||||
@@ -24,13 +26,20 @@ defineProps({
|
|||||||
type: String,
|
type: String,
|
||||||
default: "",
|
default: "",
|
||||||
},
|
},
|
||||||
|
selected: {
|
||||||
|
type: Boolean,
|
||||||
|
default: false,
|
||||||
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
const emit = defineEmits(["update:modelValue"]);
|
const emit = defineEmits(["update:modelValue", "select"]);
|
||||||
|
const MAX_CUSTOM_AMOUNT = 9999;
|
||||||
|
|
||||||
const handleInput = (event) => {
|
const handleInput = (event) => {
|
||||||
const rawValue = event?.detail?.value ?? event?.target?.value ?? "";
|
const rawValue = event?.detail?.value ?? event?.target?.value ?? "";
|
||||||
const value = String(rawValue).replace(/\D/g, "");
|
const digits = String(rawValue).replace(/\D/g, "");
|
||||||
|
const value = digits ? String(Math.min(Number(digits), MAX_CUSTOM_AMOUNT)) : "";
|
||||||
|
emit("select");
|
||||||
emit("update:modelValue", value);
|
emit("update:modelValue", value);
|
||||||
};
|
};
|
||||||
</script>
|
</script>
|
||||||
|
|||||||
@@ -23,6 +23,12 @@
|
|||||||
@select="handleSelectRechargeOption"
|
@select="handleSelectRechargeOption"
|
||||||
/>
|
/>
|
||||||
|
|
||||||
|
<CustomAmountCard
|
||||||
|
v-model="customAmount"
|
||||||
|
:selected="rechargeMode === 'custom'"
|
||||||
|
@select="handleSelectCustomAmount"
|
||||||
|
/>
|
||||||
|
|
||||||
<RechargeFooter
|
<RechargeFooter
|
||||||
:price="payPrice"
|
:price="payPrice"
|
||||||
:loading="paying"
|
:loading="paying"
|
||||||
@@ -39,12 +45,15 @@ import TopNavBar from "@/components/TopNavBar/index.vue";
|
|||||||
import { useCurrentCredit } from "@/pages-aigc/hooks/useCurrentCredit.js";
|
import { useCurrentCredit } from "@/pages-aigc/hooks/useCurrentCredit.js";
|
||||||
import { getRechargeOptions, rechargeCredit } from "@/request/api/AigcApi.js";
|
import { getRechargeOptions, rechargeCredit } from "@/request/api/AigcApi.js";
|
||||||
import BalanceCard from "./components/BalanceCard/index.vue";
|
import BalanceCard from "./components/BalanceCard/index.vue";
|
||||||
|
import CustomAmountCard from "./components/CustomAmountCard/index.vue";
|
||||||
import RechargeFooter from "./components/RechargeFooter/index.vue";
|
import RechargeFooter from "./components/RechargeFooter/index.vue";
|
||||||
import RechargePackageList from "./components/RechargePackageList/index.vue";
|
import RechargePackageList from "./components/RechargePackageList/index.vue";
|
||||||
|
|
||||||
const { pointBalance: balancePoints, fetchCurrentCredit } = useCurrentCredit();
|
const { pointBalance: balancePoints, fetchCurrentCredit } = useCurrentCredit();
|
||||||
const rechargeOptions = ref([]);
|
const rechargeOptions = ref([]);
|
||||||
const selectedRechargeOption = ref(null);
|
const selectedRechargeOption = ref(null);
|
||||||
|
const customAmount = ref("");
|
||||||
|
const rechargeMode = ref("package");
|
||||||
const paying = ref(false);
|
const paying = ref(false);
|
||||||
|
|
||||||
const getRechargeOptionKey = (option) => {
|
const getRechargeOptionKey = (option) => {
|
||||||
@@ -53,10 +62,17 @@ const getRechargeOptionKey = (option) => {
|
|||||||
return `${option.rechargeAmount ?? ""}-${option.rechargePoints ?? ""}`;
|
return `${option.rechargeAmount ?? ""}-${option.rechargePoints ?? ""}`;
|
||||||
};
|
};
|
||||||
|
|
||||||
const selectedRechargeKey = computed(() => getRechargeOptionKey(selectedRechargeOption.value));
|
const selectedRechargeKey = computed(() => {
|
||||||
|
if (rechargeMode.value !== "package") return "";
|
||||||
|
|
||||||
|
return getRechargeOptionKey(selectedRechargeOption.value);
|
||||||
|
});
|
||||||
|
|
||||||
const payPrice = computed(() => {
|
const payPrice = computed(() => {
|
||||||
const amount = Number(selectedRechargeOption.value?.rechargeAmount);
|
const amount =
|
||||||
|
rechargeMode.value === "custom"
|
||||||
|
? Number.parseInt(customAmount.value || "0", 10)
|
||||||
|
: Number(selectedRechargeOption.value?.rechargeAmount);
|
||||||
return Number.isFinite(amount) ? amount : 0;
|
return Number.isFinite(amount) ? amount : 0;
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -72,7 +88,9 @@ const fetchRechargeOptions = async () => {
|
|||||||
const res = await getRechargeOptions();
|
const res = await getRechargeOptions();
|
||||||
if (res?.code === 0 && Array.isArray(res.data)) {
|
if (res?.code === 0 && Array.isArray(res.data)) {
|
||||||
rechargeOptions.value = res.data;
|
rechargeOptions.value = res.data;
|
||||||
selectedRechargeOption.value = res.data[0] || null;
|
if (rechargeMode.value === "package") {
|
||||||
|
selectedRechargeOption.value = res.data[0] || null;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error("获取积分充值档位失败", error);
|
console.error("获取积分充值档位失败", error);
|
||||||
@@ -102,9 +120,15 @@ const handleOpenLedger = () => {
|
|||||||
};
|
};
|
||||||
|
|
||||||
const handleSelectRechargeOption = (option) => {
|
const handleSelectRechargeOption = (option) => {
|
||||||
|
rechargeMode.value = "package";
|
||||||
selectedRechargeOption.value = option;
|
selectedRechargeOption.value = option;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const handleSelectCustomAmount = () => {
|
||||||
|
rechargeMode.value = "custom";
|
||||||
|
selectedRechargeOption.value = null;
|
||||||
|
};
|
||||||
|
|
||||||
const requestWechatPay = (payData) => {
|
const requestWechatPay = (payData) => {
|
||||||
const { nonceStr, packageVal, paySign, signType, timeStamp } = payData || {};
|
const { nonceStr, packageVal, paySign, signType, timeStamp } = payData || {};
|
||||||
|
|
||||||
@@ -138,14 +162,15 @@ const requestWechatPay = (payData) => {
|
|||||||
const handlePay = async () => {
|
const handlePay = async () => {
|
||||||
if (paying.value) return;
|
if (paying.value) return;
|
||||||
|
|
||||||
if (!selectedRechargeOption.value) {
|
if (rechargeMode.value === "package" && !selectedRechargeOption.value) {
|
||||||
showToast("请选择充值档位");
|
showToast("请选择充值档位");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
const rechargeAmount = payPrice.value;
|
const rechargeAmount = payPrice.value;
|
||||||
if (!Number.isInteger(rechargeAmount) || rechargeAmount <= 0) {
|
if (!Number.isInteger(rechargeAmount) || rechargeAmount <= 0) {
|
||||||
showToast("充值档位金额错误,请重试");
|
const message = rechargeMode.value === "custom" ? "请输入正确的充值金额" : "充值档位金额错误,请重试";
|
||||||
|
showToast(message);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,14 +1,7 @@
|
|||||||
<template>
|
<template>
|
||||||
<view class="record-card">
|
<view class="record-card">
|
||||||
<video
|
<video v-if="isVideoRecord" class="record-card-image" :src="mediaUrl" :controls="false" :show-play-btn="false"
|
||||||
v-if="isVideoRecord"
|
:show-center-play-btn="false" object-fit="cover" />
|
||||||
class="record-card-image"
|
|
||||||
:src="mediaUrl"
|
|
||||||
:controls="false"
|
|
||||||
:show-play-btn="false"
|
|
||||||
:show-center-play-btn="false"
|
|
||||||
object-fit="cover"
|
|
||||||
/>
|
|
||||||
<image v-else-if="mediaUrl" class="record-card-image" :src="mediaUrl" mode="aspectFill" />
|
<image v-else-if="mediaUrl" class="record-card-image" :src="mediaUrl" mode="aspectFill" />
|
||||||
<view v-else class="record-card-image record-card-media-placeholder" />
|
<view v-else class="record-card-image record-card-media-placeholder" />
|
||||||
|
|
||||||
@@ -18,7 +11,7 @@
|
|||||||
<text class="record-card-status ellipsis-1">{{ statusText }}</text>
|
<text class="record-card-status ellipsis-1">{{ statusText }}</text>
|
||||||
</view>
|
</view>
|
||||||
|
|
||||||
<view class="record-card-action" @tap="emit('view', record)">
|
<view v-if="record.taskStatus === 2" class="record-card-action" @tap="emit('view', record)">
|
||||||
查看
|
查看
|
||||||
</view>
|
</view>
|
||||||
</view>
|
</view>
|
||||||
|
|||||||
@@ -1,30 +1,14 @@
|
|||||||
<template>
|
<template>
|
||||||
<z-paging
|
<z-paging ref="paging" v-model="records" class="aigc-record-page" bg-color="#ffffff" safe-area-inset-bottom
|
||||||
ref="paging"
|
@query="queryList">
|
||||||
v-model="records"
|
|
||||||
class="aigc-record-page"
|
|
||||||
bg-color="#ffffff"
|
|
||||||
safe-area-inset-bottom
|
|
||||||
@query="queryList"
|
|
||||||
>
|
|
||||||
<template #top>
|
<template #top>
|
||||||
<view class="aigc-record-nav">
|
<view class="aigc-record-nav">
|
||||||
<TopNavBar
|
<TopNavBar title="最近任务" background="transparent" title-color="#162235" back-icon-color="#162235"
|
||||||
title="最近任务"
|
:align-with-menu-button="true" :z-index="1" @back="handleBack" />
|
||||||
background="transparent"
|
|
||||||
title-color="#162235"
|
|
||||||
back-icon-color="#162235"
|
|
||||||
:align-with-menu-button="true"
|
|
||||||
:z-index="1"
|
|
||||||
@back="handleBack"
|
|
||||||
/>
|
|
||||||
</view>
|
</view>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<RecordList
|
<RecordList :records="records" @view="handleViewRecord" />
|
||||||
:records="records"
|
|
||||||
@view="handleViewRecord"
|
|
||||||
/>
|
|
||||||
|
|
||||||
<template #empty>
|
<template #empty>
|
||||||
<CustomEmpty statusText="暂无生成记录" />
|
<CustomEmpty statusText="暂无生成记录" />
|
||||||
@@ -37,10 +21,12 @@ import { ref } from "vue";
|
|||||||
import TopNavBar from "@/components/TopNavBar/index.vue";
|
import TopNavBar from "@/components/TopNavBar/index.vue";
|
||||||
import CustomEmpty from "@/components/CustomEmpty/index.vue";
|
import CustomEmpty from "@/components/CustomEmpty/index.vue";
|
||||||
import { getAigcGeneratorTaskList } from "@/request/api/AigcApi.js";
|
import { getAigcGeneratorTaskList } from "@/request/api/AigcApi.js";
|
||||||
|
import { useAigcRecordStore } from "@/store";
|
||||||
import RecordList from "./components/RecordList/index.vue";
|
import RecordList from "./components/RecordList/index.vue";
|
||||||
|
|
||||||
const records = ref([]);
|
const records = ref([]);
|
||||||
const paging = ref(null);
|
const paging = ref(null);
|
||||||
|
const aigcRecordStore = useAigcRecordStore();
|
||||||
|
|
||||||
const queryList = async (pageNum, pageSize) => {
|
const queryList = async (pageNum, pageSize) => {
|
||||||
try {
|
try {
|
||||||
@@ -65,10 +51,13 @@ const handleBack = () => {
|
|||||||
};
|
};
|
||||||
|
|
||||||
const handleViewRecord = (record) => {
|
const handleViewRecord = (record) => {
|
||||||
uni.showToast({
|
if (record?.taskStatus === 2) {
|
||||||
title: record.itemTitle || record.taskId || "",
|
aigcRecordStore.setCurrentRecord(record);
|
||||||
icon: "none",
|
uni.navigateTo({
|
||||||
});
|
url: "/pages-aigc/detail/detail",
|
||||||
|
});
|
||||||
|
return;
|
||||||
|
}
|
||||||
};
|
};
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
|
|||||||
15
src/store/modules/aigcRecord.js
Normal file
15
src/store/modules/aigcRecord.js
Normal file
@@ -0,0 +1,15 @@
|
|||||||
|
import { defineStore } from "pinia";
|
||||||
|
|
||||||
|
export const useAigcRecordStore = defineStore("aigcRecord", {
|
||||||
|
state() {
|
||||||
|
return {
|
||||||
|
currentRecord: null,
|
||||||
|
};
|
||||||
|
},
|
||||||
|
|
||||||
|
actions: {
|
||||||
|
setCurrentRecord(record) {
|
||||||
|
this.currentRecord = record ? { ...record } : null;
|
||||||
|
},
|
||||||
|
},
|
||||||
|
});
|
||||||
@@ -1,6 +1,7 @@
|
|||||||
import { useAppStore } from "./app";
|
import { useAppStore } from "./app";
|
||||||
|
import { useAigcRecordStore } from "./aigcRecord";
|
||||||
import { useSelectedDateStore } from "./selectedDate";
|
import { useSelectedDateStore } from "./selectedDate";
|
||||||
import { usePictureStore } from "./picture";
|
import { usePictureStore } from "./picture";
|
||||||
import { useLocationStore } from "./location";
|
import { useLocationStore } from "./location";
|
||||||
|
|
||||||
export { useAppStore, useSelectedDateStore, usePictureStore, useLocationStore };
|
export { useAppStore, useAigcRecordStore, useSelectedDateStore, usePictureStore, useLocationStore };
|
||||||
|
|||||||
Reference in New Issue
Block a user