Compare commits
3 Commits
23f8453868
...
99151bca58
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
99151bca58 | ||
|
|
67b1b78f1f | ||
|
|
dcf67dedfc |
@@ -4,7 +4,10 @@
|
|||||||
{{ saving ? "保存中..." : "保存图片" }}
|
{{ saving ? "保存中..." : "保存图片" }}
|
||||||
</view>
|
</view>
|
||||||
|
|
||||||
<button class="result-action is-secondary" open-type="share" hover-class="none">分享好友</button>
|
<button class="result-action is-secondary" :class="{ 'is-disabled': sharePreparing }"
|
||||||
|
:open-type="shareReady ? 'share' : undefined" hover-class="none" @tap="handleShare">
|
||||||
|
{{ sharePreparing ? "准备分享..." : "分享好友" }}
|
||||||
|
</button>
|
||||||
</view>
|
</view>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
@@ -14,15 +17,29 @@ const props = defineProps({
|
|||||||
type: Boolean,
|
type: Boolean,
|
||||||
default: false,
|
default: false,
|
||||||
},
|
},
|
||||||
|
shareReady: {
|
||||||
|
type: Boolean,
|
||||||
|
default: false,
|
||||||
|
},
|
||||||
|
sharePreparing: {
|
||||||
|
type: Boolean,
|
||||||
|
default: false,
|
||||||
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
const emit = defineEmits(["save"]);
|
const emit = defineEmits(["save", "prepare-share"]);
|
||||||
|
|
||||||
const handleSave = () => {
|
const handleSave = () => {
|
||||||
if (!props.saving) {
|
if (!props.saving) {
|
||||||
emit("save");
|
emit("save");
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const handleShare = () => {
|
||||||
|
if (!props.shareReady && !props.sharePreparing) {
|
||||||
|
emit("prepare-share");
|
||||||
|
}
|
||||||
|
};
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style scoped lang="scss">
|
<style scoped lang="scss">
|
||||||
|
|||||||
@@ -6,7 +6,8 @@
|
|||||||
<template v-if="taskDetail">
|
<template v-if="taskDetail">
|
||||||
<ResultPreview v-if="result.cover" :result="result" />
|
<ResultPreview v-if="result.cover" :result="result" />
|
||||||
<ResultMeta :items="metaItems" />
|
<ResultMeta :items="metaItems" />
|
||||||
<ResultActions :saving="isSaving" @save="handleSave" />
|
<ResultActions :saving="isSaving" :share-ready="Boolean(shareKey)" :share-preparing="isPreparingShare"
|
||||||
|
@save="handleSave" @prepare-share="handlePrepareShare" />
|
||||||
|
|
||||||
<view class="aigc-detail-text-actions">
|
<view class="aigc-detail-text-actions">
|
||||||
<view class="aigc-detail-text-action" @tap="handleRegenerate">再生成一版</view>
|
<view class="aigc-detail-text-action" @tap="handleRegenerate">再生成一版</view>
|
||||||
@@ -15,6 +16,7 @@
|
|||||||
</view>
|
</view>
|
||||||
</template>
|
</template>
|
||||||
</view>
|
</view>
|
||||||
|
|
||||||
</view>
|
</view>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
@@ -23,7 +25,10 @@ import { computed, ref } from "vue";
|
|||||||
import { onLoad, onShareAppMessage, onShow } from "@dcloudio/uni-app";
|
import { onLoad, onShareAppMessage, onShow } from "@dcloudio/uni-app";
|
||||||
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 { getAigcGeneratorTaskDetail } from "@/request/api/AigcApi.js";
|
import {
|
||||||
|
createAigcGeneratorTaskShare,
|
||||||
|
getAigcGeneratorTaskDetail,
|
||||||
|
} from "@/request/api/AigcApi.js";
|
||||||
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";
|
||||||
import ResultPreview from "./components/ResultPreview/index.vue";
|
import ResultPreview from "./components/ResultPreview/index.vue";
|
||||||
@@ -32,6 +37,8 @@ const { pointBalance, fetchCurrentCredit } = useCurrentCredit();
|
|||||||
const taskId = ref("");
|
const taskId = ref("");
|
||||||
const taskDetail = ref(null);
|
const taskDetail = ref(null);
|
||||||
const isSaving = ref(false);
|
const isSaving = ref(false);
|
||||||
|
const isPreparingShare = ref(false);
|
||||||
|
const shareKey = ref("");
|
||||||
|
|
||||||
const GENERATOR_TYPE_TEXT = {
|
const GENERATOR_TYPE_TEXT = {
|
||||||
0: "图片版",
|
0: "图片版",
|
||||||
@@ -102,6 +109,8 @@ const metaItems = computed(() => {
|
|||||||
];
|
];
|
||||||
});
|
});
|
||||||
|
|
||||||
|
const sharePreviewImage = computed(() => taskDetail.value?.imageResultUrl || "");
|
||||||
|
|
||||||
const showPlaceholderToast = (title) => {
|
const showPlaceholderToast = (title) => {
|
||||||
uni.showToast({
|
uni.showToast({
|
||||||
title,
|
title,
|
||||||
@@ -119,6 +128,7 @@ const fetchTaskDetail = async () => {
|
|||||||
const res = await getAigcGeneratorTaskDetail({ taskId: taskId.value });
|
const res = await getAigcGeneratorTaskDetail({ taskId: taskId.value });
|
||||||
if (res?.code === 0 && res.data && typeof res.data === "object" && !Array.isArray(res.data)) {
|
if (res?.code === 0 && res.data && typeof res.data === "object" && !Array.isArray(res.data)) {
|
||||||
taskDetail.value = res.data;
|
taskDetail.value = res.data;
|
||||||
|
prepareShareKey();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -147,15 +157,14 @@ onShow(() => {
|
|||||||
fetchCurrentCredit();
|
fetchCurrentCredit();
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
||||||
onShareAppMessage(() => {
|
onShareAppMessage(() => {
|
||||||
const shareInfo = {
|
const shareInfo = {
|
||||||
title: taskDetail.value?.itemTitle,
|
title: taskDetail.value?.itemTitle || "分享旅行作品",
|
||||||
path: taskId.value
|
path: shareKey.value
|
||||||
? `/pages-aigc/detail/detail?taskId=${encodeURIComponent(taskId.value)}`
|
? `/pages-aigc/sharedWork/sharedWork?shareKey=${encodeURIComponent(shareKey.value)}`
|
||||||
: "/pages-aigc/home/home",
|
: "/pages/index/index",
|
||||||
};
|
};
|
||||||
const imageUrl = taskDetail.value?.imageResultUrl || "";
|
const imageUrl = sharePreviewImage.value;
|
||||||
|
|
||||||
if (imageUrl) {
|
if (imageUrl) {
|
||||||
shareInfo.imageUrl = imageUrl;
|
shareInfo.imageUrl = imageUrl;
|
||||||
@@ -164,6 +173,39 @@ onShareAppMessage(() => {
|
|||||||
return shareInfo;
|
return shareInfo;
|
||||||
});
|
});
|
||||||
|
|
||||||
|
const prepareShareKey = async (showFeedback = false) => {
|
||||||
|
if (isPreparingShare.value || !taskId.value) return;
|
||||||
|
if (shareKey.value) return;
|
||||||
|
|
||||||
|
isPreparingShare.value = true;
|
||||||
|
|
||||||
|
try {
|
||||||
|
const res = await createAigcGeneratorTaskShare({ taskId: taskId.value });
|
||||||
|
const nextShareKey = String(res?.data?.shareKey || "").trim();
|
||||||
|
if (res?.code === 0 && nextShareKey) {
|
||||||
|
shareKey.value = nextShareKey;
|
||||||
|
if (showFeedback) {
|
||||||
|
showPlaceholderToast("分享已准备,请再次点击");
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (showFeedback) {
|
||||||
|
showPlaceholderToast(res?.msg || "创建分享失败");
|
||||||
|
}
|
||||||
|
} catch (error) {
|
||||||
|
console.error("创建AIGC任务分享失败", error);
|
||||||
|
if (showFeedback) {
|
||||||
|
showPlaceholderToast("创建分享失败");
|
||||||
|
}
|
||||||
|
} finally {
|
||||||
|
isPreparingShare.value = false;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
const handlePrepareShare = () => {
|
||||||
|
prepareShareKey(true);
|
||||||
|
};
|
||||||
|
|
||||||
const handleBack = () => {
|
const handleBack = () => {
|
||||||
const pages = getCurrentPages();
|
const pages = getCurrentPages();
|
||||||
|
|||||||
@@ -1,21 +1,31 @@
|
|||||||
<template>
|
<template>
|
||||||
<view class="recharge-footer">
|
<view class="recharge-footer">
|
||||||
<text class="recharge-gain">
|
<view class="recharge-agreement" :class="{ 'is-disabled': !agreementReady }">
|
||||||
支付金额 <text class="recharge-gain-value">¥{{ formattedPrice }}</text>
|
<CheckBox :model-value="agreed" @update:model-value="handleAgreementChange">
|
||||||
</text>
|
<text class="recharge-agreement-text">我已阅读并同意</text>
|
||||||
|
<text class="recharge-agreement-link" @tap.stop="handleViewAgreement">《积分充值协议》</text>
|
||||||
|
</CheckBox>
|
||||||
|
</view>
|
||||||
|
|
||||||
<view
|
<view class="recharge-payment-row">
|
||||||
class="recharge-pay-button"
|
<text class="recharge-gain">
|
||||||
:class="{ 'is-disabled': loading || price <= 0 }"
|
支付金额 <text class="recharge-gain-value">¥{{ formattedPrice }}</text>
|
||||||
@tap="emit('pay')"
|
</text>
|
||||||
>
|
|
||||||
{{ loading ? "支付中..." : "立即支付" }}
|
<view
|
||||||
|
class="recharge-pay-button"
|
||||||
|
:class="{ 'is-disabled': payDisabled }"
|
||||||
|
@tap="handlePay"
|
||||||
|
>
|
||||||
|
{{ loading ? "支付中..." : "立即支付" }}
|
||||||
|
</view>
|
||||||
</view>
|
</view>
|
||||||
</view>
|
</view>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup>
|
<script setup>
|
||||||
import { computed } from "vue";
|
import { computed } from "vue";
|
||||||
|
import CheckBox from "@/components/CheckBox/index.vue";
|
||||||
|
|
||||||
const props = defineProps({
|
const props = defineProps({
|
||||||
price: {
|
price: {
|
||||||
@@ -26,11 +36,40 @@ const props = defineProps({
|
|||||||
type: Boolean,
|
type: Boolean,
|
||||||
default: false,
|
default: false,
|
||||||
},
|
},
|
||||||
|
agreed: {
|
||||||
|
type: Boolean,
|
||||||
|
default: false,
|
||||||
|
},
|
||||||
|
agreementReady: {
|
||||||
|
type: Boolean,
|
||||||
|
default: false,
|
||||||
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
const emit = defineEmits(["pay"]);
|
const emit = defineEmits(["pay", "update:agreed", "view-agreement"]);
|
||||||
|
|
||||||
const formattedPrice = computed(() => Number(props.price).toLocaleString("zh-CN"));
|
const formattedPrice = computed(() => Number(props.price).toLocaleString("zh-CN"));
|
||||||
|
const payDisabled = computed(() => {
|
||||||
|
return props.loading || props.price <= 0 || !props.agreed || !props.agreementReady;
|
||||||
|
});
|
||||||
|
|
||||||
|
const handleAgreementChange = (value) => {
|
||||||
|
if (!props.agreementReady) {
|
||||||
|
emit("view-agreement");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
emit("update:agreed", value);
|
||||||
|
};
|
||||||
|
|
||||||
|
const handleViewAgreement = () => {
|
||||||
|
emit("view-agreement");
|
||||||
|
};
|
||||||
|
|
||||||
|
const handlePay = () => {
|
||||||
|
if (props.loading || props.price <= 0) return;
|
||||||
|
emit("pay");
|
||||||
|
};
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style scoped lang="scss">
|
<style scoped lang="scss">
|
||||||
|
|||||||
@@ -1,10 +1,9 @@
|
|||||||
.recharge-footer {
|
.recharge-footer {
|
||||||
position: sticky;
|
position: sticky;
|
||||||
bottom: 12px;
|
bottom: 12px;
|
||||||
display: grid;
|
display: flex;
|
||||||
grid-template-columns: 1fr 142px;
|
flex-direction: column;
|
||||||
align-items: center;
|
gap: 12px;
|
||||||
gap: 10px;
|
|
||||||
margin-top: 16px;
|
margin-top: 16px;
|
||||||
padding: 12px;
|
padding: 12px;
|
||||||
border-radius: 20px;
|
border-radius: 20px;
|
||||||
@@ -13,6 +12,38 @@
|
|||||||
box-sizing: border-box;
|
box-sizing: border-box;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.recharge-agreement {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
box-sizing: border-box;
|
||||||
|
}
|
||||||
|
|
||||||
|
.recharge-agreement.is-disabled {
|
||||||
|
opacity: 0.56;
|
||||||
|
}
|
||||||
|
|
||||||
|
.recharge-agreement-text,
|
||||||
|
.recharge-agreement-link {
|
||||||
|
font-size: 14px;
|
||||||
|
line-height: 24px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.recharge-agreement-text {
|
||||||
|
color: #667386;
|
||||||
|
}
|
||||||
|
|
||||||
|
.recharge-agreement-link {
|
||||||
|
color: $theme-color-600;
|
||||||
|
font-weight: 700;
|
||||||
|
}
|
||||||
|
|
||||||
|
.recharge-payment-row {
|
||||||
|
display: grid;
|
||||||
|
grid-template-columns: minmax(0, 1fr) 142px;
|
||||||
|
align-items: center;
|
||||||
|
gap: 10px;
|
||||||
|
}
|
||||||
|
|
||||||
.recharge-gain {
|
.recharge-gain {
|
||||||
min-width: 0;
|
min-width: 0;
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
|
|||||||
@@ -32,9 +32,20 @@
|
|||||||
<RechargeFooter
|
<RechargeFooter
|
||||||
:price="payPrice"
|
:price="payPrice"
|
||||||
:loading="paying"
|
:loading="paying"
|
||||||
|
:agreed="agreementAccepted"
|
||||||
|
:agreement-ready="agreementReady"
|
||||||
|
@update:agreed="agreementAccepted = $event"
|
||||||
|
@view-agreement="handleViewAgreement"
|
||||||
@pay="handlePay"
|
@pay="handlePay"
|
||||||
/>
|
/>
|
||||||
</view>
|
</view>
|
||||||
|
|
||||||
|
<AgreePopup
|
||||||
|
:visible="agreementVisible"
|
||||||
|
title="积分充值协议"
|
||||||
|
:agreement="agreementContent"
|
||||||
|
@close="agreementVisible = false"
|
||||||
|
/>
|
||||||
</view>
|
</view>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
@@ -43,7 +54,12 @@ import { computed, ref } from "vue";
|
|||||||
import { onLoad, onShow } from "@dcloudio/uni-app";
|
import { onLoad, onShow } from "@dcloudio/uni-app";
|
||||||
import TopNavBar from "@/components/TopNavBar/index.vue";
|
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 {
|
||||||
|
getPointsTopUpAgreement,
|
||||||
|
getRechargeOptions,
|
||||||
|
rechargeCredit,
|
||||||
|
} from "@/request/api/AigcApi.js";
|
||||||
|
import AgreePopup from "@/pages/login/components/AgreePopup/index.vue";
|
||||||
import BalanceCard from "./components/BalanceCard/index.vue";
|
import BalanceCard from "./components/BalanceCard/index.vue";
|
||||||
import CustomAmountCard from "./components/CustomAmountCard/index.vue";
|
import CustomAmountCard from "./components/CustomAmountCard/index.vue";
|
||||||
import RechargeFooter from "./components/RechargeFooter/index.vue";
|
import RechargeFooter from "./components/RechargeFooter/index.vue";
|
||||||
@@ -55,6 +71,12 @@ const selectedRechargeOption = ref(null);
|
|||||||
const customAmount = ref("");
|
const customAmount = ref("");
|
||||||
const rechargeMode = ref("package");
|
const rechargeMode = ref("package");
|
||||||
const paying = ref(false);
|
const paying = ref(false);
|
||||||
|
const agreementAccepted = ref(false);
|
||||||
|
const agreementContent = ref("");
|
||||||
|
const agreementLoading = ref(false);
|
||||||
|
const agreementVisible = ref(false);
|
||||||
|
|
||||||
|
const agreementReady = computed(() => Boolean(agreementContent.value.trim()));
|
||||||
|
|
||||||
const getRechargeOptionKey = (option) => {
|
const getRechargeOptionKey = (option) => {
|
||||||
if (!option) return "";
|
if (!option) return "";
|
||||||
@@ -97,8 +119,41 @@ const fetchRechargeOptions = async () => {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const fetchPointsTopUpAgreement = async (showError = false) => {
|
||||||
|
if (agreementLoading.value) return false;
|
||||||
|
|
||||||
|
agreementLoading.value = true;
|
||||||
|
try {
|
||||||
|
const res = await getPointsTopUpAgreement();
|
||||||
|
const content = typeof res?.data === "string" ? res.data.trim() : "";
|
||||||
|
if (res?.code === 0 && content) {
|
||||||
|
agreementContent.value = content;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
agreementContent.value = "";
|
||||||
|
agreementAccepted.value = false;
|
||||||
|
if (showError) {
|
||||||
|
showToast(res?.msg || "协议加载失败,请重试");
|
||||||
|
}
|
||||||
|
} catch (error) {
|
||||||
|
console.error("获取积分充值协议失败", error);
|
||||||
|
agreementContent.value = "";
|
||||||
|
agreementAccepted.value = false;
|
||||||
|
if (showError) {
|
||||||
|
showToast("协议加载失败,请重试");
|
||||||
|
}
|
||||||
|
} finally {
|
||||||
|
agreementLoading.value = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
};
|
||||||
|
|
||||||
onLoad(() => {
|
onLoad(() => {
|
||||||
|
agreementAccepted.value = false;
|
||||||
fetchRechargeOptions();
|
fetchRechargeOptions();
|
||||||
|
fetchPointsTopUpAgreement();
|
||||||
});
|
});
|
||||||
|
|
||||||
onShow(() => {
|
onShow(() => {
|
||||||
@@ -129,6 +184,23 @@ const handleSelectCustomAmount = () => {
|
|||||||
selectedRechargeOption.value = null;
|
selectedRechargeOption.value = null;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const handleViewAgreement = async () => {
|
||||||
|
if (agreementReady.value) {
|
||||||
|
agreementVisible.value = true;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (agreementLoading.value) {
|
||||||
|
showToast("协议加载中,请稍候");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const loaded = await fetchPointsTopUpAgreement(true);
|
||||||
|
if (loaded) {
|
||||||
|
agreementVisible.value = true;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
const requestWechatPay = (payData) => {
|
const requestWechatPay = (payData) => {
|
||||||
const { nonceStr, packageVal, paySign, signType, timeStamp } = payData || {};
|
const { nonceStr, packageVal, paySign, signType, timeStamp } = payData || {};
|
||||||
|
|
||||||
@@ -174,6 +246,21 @@ const handlePay = async () => {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (agreementLoading.value) {
|
||||||
|
showToast("协议加载中,请稍候");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!agreementReady.value) {
|
||||||
|
showToast("协议加载失败,请重试");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!agreementAccepted.value) {
|
||||||
|
showToast("请先阅读并同意积分充值协议");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
paying.value = true;
|
paying.value = true;
|
||||||
uni.showLoading({ title: "正在发起支付..." });
|
uni.showLoading({ title: "正在发起支付..." });
|
||||||
|
|
||||||
|
|||||||
118
src/pages-aigc/sharedWork/sharedWork.vue
Normal file
118
src/pages-aigc/sharedWork/sharedWork.vue
Normal file
@@ -0,0 +1,118 @@
|
|||||||
|
<template>
|
||||||
|
<view class="shared-work-page">
|
||||||
|
<view class="shared-work-nav">
|
||||||
|
<TopNavBar title="旅行作品" background="transparent" title-color="#173a5f" back-icon-color="#173a5f"
|
||||||
|
:align-with-menu-button="true" :z-index="3" @back="handleBack" />
|
||||||
|
</view>
|
||||||
|
|
||||||
|
<view class="shared-work-scroll" scroll-y>
|
||||||
|
<template v-if="shareDetail">
|
||||||
|
<video v-if="isVideo" class="shared-work-media is-video" :src="shareDetail.videoUrl"
|
||||||
|
:poster="shareDetail.imageUrl" controls object-fit="cover" />
|
||||||
|
<image v-else-if="shareDetail.imageUrl" class="shared-work-media" :src="shareDetail.imageUrl" mode="widthFix" />
|
||||||
|
|
||||||
|
<view class="shared-work-meta">
|
||||||
|
<text class="shared-work-title">{{ shareDetail.templateName || "旅行作品" }}</text>
|
||||||
|
<text class="shared-work-type">{{ generatorTypeText }}</text>
|
||||||
|
</view>
|
||||||
|
</template>
|
||||||
|
</view>
|
||||||
|
|
||||||
|
<view class="shared-work-cta-wrap">
|
||||||
|
<button class="shared-work-cta" hover-class="is-pressed" @tap="handleCreateOwn">
|
||||||
|
我也生成一个
|
||||||
|
</button>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script setup>
|
||||||
|
import { computed, ref } from "vue";
|
||||||
|
import { onLoad } from "@dcloudio/uni-app";
|
||||||
|
import TopNavBar from "@/components/TopNavBar/index.vue";
|
||||||
|
import { checkToken } from "@/hooks/useGoLogin.js";
|
||||||
|
import { getAigcGeneratorTaskShareDetail } from "@/request/api/AigcApi.js";
|
||||||
|
|
||||||
|
const shareKey = ref("");
|
||||||
|
const shareDetail = ref(null);
|
||||||
|
|
||||||
|
const isVideo = computed(() => {
|
||||||
|
return Number(shareDetail.value?.generatorType) === 1 && Boolean(shareDetail.value?.videoUrl);
|
||||||
|
});
|
||||||
|
|
||||||
|
const generatorTypeText = computed(() => {
|
||||||
|
const generatorType = shareDetail.value?.generatorType;
|
||||||
|
if (Number(generatorType) === 0) return "图片版";
|
||||||
|
if (Number(generatorType) === 1) return "视频版";
|
||||||
|
return generatorType === undefined || generatorType === null || generatorType === ""
|
||||||
|
? "生成作品"
|
||||||
|
: `类型${generatorType}`;
|
||||||
|
});
|
||||||
|
|
||||||
|
const showToast = (title) => {
|
||||||
|
uni.showToast({
|
||||||
|
title,
|
||||||
|
icon: "none",
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
const fetchShareDetail = async () => {
|
||||||
|
uni.showLoading({
|
||||||
|
title: "加载中",
|
||||||
|
mask: true,
|
||||||
|
});
|
||||||
|
|
||||||
|
try {
|
||||||
|
const res = await getAigcGeneratorTaskShareDetail({ shareKey: shareKey.value });
|
||||||
|
if (res?.code === 0 && res.data && typeof res.data === "object" && !Array.isArray(res.data)) {
|
||||||
|
shareDetail.value = res.data;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
shareDetail.value = null;
|
||||||
|
showToast(res?.msg || "获取分享作品失败");
|
||||||
|
} catch (error) {
|
||||||
|
console.error("获取AIGC分享作品失败", error);
|
||||||
|
shareDetail.value = null;
|
||||||
|
showToast("获取分享作品失败");
|
||||||
|
} finally {
|
||||||
|
uni.hideLoading();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
onLoad((query = {}) => {
|
||||||
|
shareKey.value = String(query.shareKey || "").trim();
|
||||||
|
if (!shareKey.value) {
|
||||||
|
showToast("缺少分享标识");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
fetchShareDetail();
|
||||||
|
});
|
||||||
|
|
||||||
|
const openAigcHome = () => {
|
||||||
|
uni.reLaunch({
|
||||||
|
url: "/pages-aigc/home/home",
|
||||||
|
fail: () => showToast("打开模板列表失败"),
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
const handleBack = () => {
|
||||||
|
const pages = getCurrentPages();
|
||||||
|
if (pages.length > 1) {
|
||||||
|
uni.navigateBack();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
openAigcHome();
|
||||||
|
};
|
||||||
|
|
||||||
|
const handleCreateOwn = async () => {
|
||||||
|
await checkToken();
|
||||||
|
openAigcHome();
|
||||||
|
};
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style scoped lang="scss">
|
||||||
|
@import "./styles/index.scss";
|
||||||
|
</style>
|
||||||
116
src/pages-aigc/sharedWork/styles/index.scss
Normal file
116
src/pages-aigc/sharedWork/styles/index.scss
Normal file
@@ -0,0 +1,116 @@
|
|||||||
|
.shared-work-page {
|
||||||
|
position: relative;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
width: 100vw;
|
||||||
|
height: 100vh;
|
||||||
|
overflow: hidden;
|
||||||
|
color: #173a5f;
|
||||||
|
background: #c5e5f8;
|
||||||
|
box-sizing: border-box;
|
||||||
|
}
|
||||||
|
|
||||||
|
.shared-work-nav {
|
||||||
|
position: relative;
|
||||||
|
z-index: 3;
|
||||||
|
flex: 0 0 auto;
|
||||||
|
background: rgba(197, 229, 248, 0.96);
|
||||||
|
}
|
||||||
|
|
||||||
|
.shared-work-nav :deep(.top-nav-bar > .flex) {
|
||||||
|
padding-right: 12px;
|
||||||
|
padding-left: 12px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.shared-work-nav :deep(.nav-bar-center text) {
|
||||||
|
font-size: 17px;
|
||||||
|
line-height: 23px;
|
||||||
|
font-weight: 900;
|
||||||
|
}
|
||||||
|
|
||||||
|
.shared-work-scroll {
|
||||||
|
flex: 1 1 0;
|
||||||
|
width: 100%;
|
||||||
|
height: 0;
|
||||||
|
min-height: 0;
|
||||||
|
padding-bottom: 104px;
|
||||||
|
box-sizing: border-box;
|
||||||
|
}
|
||||||
|
|
||||||
|
.shared-work-media {
|
||||||
|
width: 100%;
|
||||||
|
display: block;
|
||||||
|
background: #b8dced;
|
||||||
|
}
|
||||||
|
|
||||||
|
.shared-work-media.is-video {
|
||||||
|
height: min(500px, 66vh);
|
||||||
|
}
|
||||||
|
|
||||||
|
.shared-work-meta {
|
||||||
|
padding: 18px 18px 118px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.shared-work-title,
|
||||||
|
.shared-work-type {
|
||||||
|
display: block;
|
||||||
|
}
|
||||||
|
|
||||||
|
.shared-work-title {
|
||||||
|
overflow: hidden;
|
||||||
|
color: #173a5f;
|
||||||
|
font-size: 20px;
|
||||||
|
line-height: 27px;
|
||||||
|
font-weight: 900;
|
||||||
|
text-overflow: ellipsis;
|
||||||
|
white-space: nowrap;
|
||||||
|
}
|
||||||
|
|
||||||
|
.shared-work-type {
|
||||||
|
margin-top: 4px;
|
||||||
|
color: #0b7b60;
|
||||||
|
font-size: 12px;
|
||||||
|
line-height: 17px;
|
||||||
|
font-weight: 800;
|
||||||
|
}
|
||||||
|
|
||||||
|
.shared-work-empty {
|
||||||
|
min-height: 420px;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.shared-work-cta-wrap {
|
||||||
|
position: fixed;
|
||||||
|
z-index: 4;
|
||||||
|
right: 0;
|
||||||
|
bottom: 0;
|
||||||
|
left: 0;
|
||||||
|
padding: 18px 16px calc(14px + env(safe-area-inset-bottom));
|
||||||
|
background: linear-gradient(180deg, rgba(197, 229, 248, 0) 0%, #c5e5f8 34%);
|
||||||
|
box-sizing: border-box;
|
||||||
|
}
|
||||||
|
|
||||||
|
.shared-work-cta {
|
||||||
|
width: 100%;
|
||||||
|
height: 54px;
|
||||||
|
margin: 0;
|
||||||
|
padding: 0;
|
||||||
|
border: 0;
|
||||||
|
border-radius: 8px;
|
||||||
|
background: #20c99a;
|
||||||
|
color: #173a5f;
|
||||||
|
font-size: 16px;
|
||||||
|
line-height: 54px;
|
||||||
|
font-weight: 900;
|
||||||
|
box-shadow: 0 10px 22px rgba(32, 201, 154, 0.2);
|
||||||
|
}
|
||||||
|
|
||||||
|
.shared-work-cta::after {
|
||||||
|
border: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.shared-work-cta.is-pressed {
|
||||||
|
opacity: 0.84;
|
||||||
|
}
|
||||||
@@ -182,6 +182,12 @@
|
|||||||
"navigationStyle": "custom"
|
"navigationStyle": "custom"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"path": "sharedWork/sharedWork",
|
||||||
|
"style": {
|
||||||
|
"navigationStyle": "custom"
|
||||||
|
}
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"path": "recharge/recharge",
|
"path": "recharge/recharge",
|
||||||
"style": {
|
"style": {
|
||||||
|
|||||||
@@ -36,6 +36,18 @@ function getCreditLedgerPage(args) {
|
|||||||
return request.post("/hotelBiz/credit/ledger/page", args);
|
return request.post("/hotelBiz/credit/ledger/page", args);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function getPointsTopUpAgreement() {
|
||||||
|
return request.get("/hotelBiz/mainScene/pointsTopUpAgreement", {});
|
||||||
|
}
|
||||||
|
|
||||||
|
function createAigcGeneratorTaskShare(args) {
|
||||||
|
return request.post("/hotelBiz/aigcGeneratorTask/share/create", args);
|
||||||
|
}
|
||||||
|
|
||||||
|
function getAigcGeneratorTaskShareDetail(args) {
|
||||||
|
return request.post("/hotelBiz/aigcGeneratorTask/share/detail", args, { noToken: true });
|
||||||
|
}
|
||||||
|
|
||||||
export {
|
export {
|
||||||
getAigcTemplateList,
|
getAigcTemplateList,
|
||||||
getAigcTemplateItemList,
|
getAigcTemplateItemList,
|
||||||
@@ -46,4 +58,7 @@ export {
|
|||||||
getRechargeOptions,
|
getRechargeOptions,
|
||||||
rechargeCredit,
|
rechargeCredit,
|
||||||
getCreditLedgerPage,
|
getCreditLedgerPage,
|
||||||
|
getPointsTopUpAgreement,
|
||||||
|
createAigcGeneratorTaskShare,
|
||||||
|
getAigcGeneratorTaskShareDetail,
|
||||||
};
|
};
|
||||||
|
|||||||
Reference in New Issue
Block a user