Feat(送礼):支持AI的文生图-5

This commit is contained in:
lifizer
2026-09-15 16:39:32 +08:00
parent 46d8fe8b70
commit bc5a59c104
3 changed files with 364 additions and 55 deletions
+188 -55
View File
@@ -36,49 +36,96 @@
>
<view class="ai-cover-body">
<view class="ai-cover-container">
<view v-if="showGenerateBtn" class="prompt">
<textarea
v-model.trim="aiCoverDesc"
:maxlength="300"
placeholder="请描述你想生成的图片"
class="prompt-textarea"
/>
<p class="prompt-tips">{{ aiCoverDesc.length }}/300</p>
</view>
<view v-else class="imgs-list-wrap">
<view class="img-item" v-for="(item, index) in aiCoverImgsList" :key="index">
<image
:src="item.cover"
:class="{
'active': item.id === selectedAiCoverImage.id
}"
mode="heightFix"
class="img-image"
@click="handleSelectAiCover(item)"
<view v-if="!showAiImgHistoryListSelect">
<view v-if="showGenerateBtn" class="prompt">
<textarea
v-model.trim="aiCoverDesc"
:maxlength="300"
placeholder="请描述你想生成的图片"
class="prompt-textarea"
/>
<p class="prompt-tips">{{ aiCoverDesc.length }}/300</p>
</view>
<view v-else class="imgs-list-wrap">
<view
v-for="(item, index) in aiCoverImgsList"
:key="index"
class="img-item"
>
<image
:src="item.cover"
:class="{
'active': item.id === selectedAiCoverImage.id
}"
mode="heightFix"
class="img-image"
@click="handleSelectAiCover(item)"
/>
</view>
</view>
</view>
<view v-else>
<view
:class="{'scrollable': aiHistoryCoverImgsList.length > 3}"
class="imgs-list-wrap"
>
<view
v-for="(item, index) in aiHistoryCoverImgsList"
:key="index"
class="img-item"
>
<image
:src="item.cover"
:class="{
'active': item.id === selectedAiCoverImage.id
}"
mode="heightFix"
class="img-image"
@click="handleSelectAiHistoryCover(item)"
/>
</view>
</view>
</view>
</view>
<view class="ai-cover-bottom">
<view v-if="showGenerateBtn" class="btn-wrap">
<view class="btn" @click="handleGenerateAiCover">
{{ aiCoverGenerateLoading ? '礼包封面生成中...' : 'AI生成礼包封面' }}
<image v-if="!aiCoverGenerateLoading" :src="webUrl + '/page/gift/gift-tab-icon01.png'" class="icon"></image>
<block v-if="!showAiImgHistoryListSelect">
<view v-if="showGenerateBtn" class="btn-wrap">
<view
v-if="!aiCoverGenerateLoading && aiHistoryCoverImgsList.length > 0"
class="btn btn2"
@click="toggleShowAiImgHistoryListSelect(true)"
>
历史图片
</view>
<view class="btn" @click="handleGenerateAiCover">
{{ aiCoverGenerateLoading ? '礼包封面生成中...' : 'AI生成礼包封面' }}
<image v-if="!aiCoverGenerateLoading" :src="webUrl + '/page/gift/gift-tab-icon01.png'" class="icon"></image>
</view>
<image
v-if="aiCoverGenerateLoading && settingInfo.giftCardT2ILoadingGif"
:src="settingInfo.giftCardT2ILoadingGif"
class="loading-img"
/>
</view>
<image
v-if="aiCoverGenerateLoading && settingInfo.giftCardT2ILoadingGif"
:src="settingInfo.giftCardT2ILoadingGif"
class="loading-img"
/>
</view>
<view v-else class="btn-wrap">
<view class="btn" @click="handleShowAiCover">
预览
<view v-else class="btn-wrap">
<view class="btn" @click="handleShowAiCover">
预览
</view>
<view class="btn btn2" @click="handleGenerateAgain">
重新生成
</view>
</view>
<view class="btn btn2" @click="handleGenerateAgain">
重新生成
</block>
<block v-else>
<view class="btn-wrap">
<view class="btn" @click="handleShowAiHistoryCoverPicker">
预览
</view>
<view class="btn btn2" @click="toggleShowAiImgHistoryListSelect(false)">
使用AI生成
</view>
</view>
</view>
</block>
</view>
</view>
</view>
@@ -232,6 +279,12 @@
:index="aiDefaultIndex"
@confirm="onAiCoverConfirm"
/>
<AiHistoryCoverPicker
:show.sync="showAiHistoryCoverPicker"
:list="aiHistoryCoverImgsList"
:index="aiHistoryDefaultIndex"
@confirm="onAiHistoryCoverConfirm"
/>
<passkeyborad
ref='payPwdPop'
showMoney
@@ -302,7 +355,8 @@ import {
fetchSojoumGroupBuyGiftCarousel,
computedSojoumGroupBuyGiftOrderPrice,
aiGiftImageGenerate,
aiGiftImageStatus
aiGiftImageStatus,
aiGiftImageHistory
} from '@/api/gift'
import {
getAiSystemInfoSetting
@@ -312,6 +366,7 @@ import {mapGetters} from "vuex";
import giftTips from './components/giftTips.vue'
import CoverPicker from './components/CoverPicker.vue'
import AiCoverPicker from './components/AiCoverPicker.vue'
import AiHistoryCoverPicker from './components/AiHistoryCoverPicker.vue'
import PayPicker from './components/PayPicker.vue';
import CouponsPopup from "@/components/CouponsPopup.vue"
export default {
@@ -319,6 +374,7 @@ export default {
giftTips,
CoverPicker,
AiCoverPicker,
AiHistoryCoverPicker,
PayPicker,
passkeyborad,
CouponsPopup
@@ -361,6 +417,7 @@ export default {
defaultIndex:0,
discount: null,
computedResult: {},
skipCouponIdWatch: false,
couponList: {
unusable: [],
usable: []
@@ -406,11 +463,19 @@ export default {
selectedAiCoverImage: {},
showAiCoverPicker: false,
pollInterval: null,
aiDefaultIndex: 0
aiDefaultIndex: 0,
aiHistoryDefaultIndex: 0,
showAiHistoryCoverPicker: false,
aiHistoryCoverImgsList: [],
showAiImgHistoryListSelect: false
}
},
watch: {
async couponId(value) {
if (this.skipCouponIdWatch) {
this.skipCouponIdWatch = false
return
}
if (this.isCountyLotteryGift) {
this.couponTitle = ''
if (Number(value || 0) !== 0) {
@@ -472,11 +537,27 @@ export default {
}
},
methods: {
// 將面切换
// 封面类型切换
toggleSelectCoverType(type) {
if (this.selectCoverType === type) return
this.selectCoverType = type
},
// 获取商品以前使用过的AI礼品卡图片
aiGiftImageHistoryReq() {
aiGiftImageHistory({
productId: this.goodsInfo.productId
}).then(res => {
const { success, data } = res
if (success && data) {
this.aiHistoryCoverImgsList = data || []
this.aiHistoryCoverImgsList.map(historyItem => {
historyItem.cover = historyItem.coverUrl,
historyItem.image = historyItem.shareUrl,
historyItem.name = historyItem.name || ''
})
}
})
},
handleGenerateAiCover() {
if (!this.aiCoverDesc || !this.aiCoverDesc.trim()) {
uni.showToast({
@@ -577,6 +658,11 @@ export default {
if (this.isCountyLotteryGift) return 0
return this.couponId || 0
},
setCouponIdSilently(value) {
if (this.couponId === value) return
this.skipCouponIdWatch = true
this.couponId = value
},
isCountyLotteryCartItem(item) {
return Number(
(item && item.drawActivityId) ||
@@ -591,7 +677,7 @@ export default {
if (!this.isCountyLotteryGift) return
this.couponTitle = ''
if (Number(this.couponId || 0) !== 0) {
this.couponId = 0
this.setCouponIdSilently(0)
}
},
adjustCoverListForProductStory(coverList, productInfo, defaultTemplate) {
@@ -636,10 +722,10 @@ export default {
if (this.isCountyLotteryGift) {
this.couponTitle = ''
if (this.couponId !== 0) {
this.couponId = 0
this.setCouponIdSilently(0)
}
} else if(useDefaultCouponId) {
this.couponId = res.data.result.defaultCouponId || 0
this.setCouponIdSilently(res.data.result.defaultCouponId || 0)
}
})
},
@@ -649,6 +735,27 @@ export default {
handleShowAiCover() {
this.showAiCoverPicker = true
},
handleShowAiHistoryCoverPicker() {
this.showAiHistoryCoverPicker = true
},
toggleShowAiImgHistoryListSelect(show) {
this.showAiImgHistoryListSelect = show
this.selectedAiCoverImage = {}
this.selectedCover = ''
this.giftImage = ''
this.templateId = ''
this.aiHistoryDefaultIndex = 0
this.aiDefaultIndex = 0
if (show) {
if (this.aiHistoryCoverImgsList.length > 0 && this.aiHistoryDefaultIndex === 0) {
const index = this.aiHistoryCoverImgsList.findIndex(item => item.isLastSelected)
if (index !== -1) {
this.aiHistoryDefaultIndex = index
}
this.handleSelectAiHistoryCover(this.aiHistoryCoverImgsList[this.aiHistoryDefaultIndex])
}
}
},
showCouponsPopup() {
if (this.isCountyLotteryGift) return
if (this.couponList.usable && this.couponList.usable.length === 0) return
@@ -664,7 +771,7 @@ export default {
if (this.couponList.usable && this.couponList.usable.length === 0) return
this.showPopup = !this.showPopup
if(!item.id) {
this.couponId = 0
this.setCouponIdSilently(0)
this.couponTitle = ''
if(this.isGroupBuy) {
this.computedTravelGroupPrice(false)
@@ -673,7 +780,7 @@ export default {
}
return
}
this.couponId = item.id
this.setCouponIdSilently(item.id)
this.couponTitle = item.couponTitle
if(this.isGroupBuy) {
this.computedTravelGroupPrice(false)
@@ -708,7 +815,7 @@ export default {
this.giftImage = this.selectedAiCoverImage.image
this.templateId = this.selectedAiCoverImage.id
}
this.couponId = ''
this.setCouponIdSilently('')
this.computedPrice(this.goodsInfo.cartNum)
})
},
@@ -745,10 +852,10 @@ export default {
if (this.isCountyLotteryGift) {
this.couponTitle = ''
if (this.couponId !== 0) {
this.couponId = 0
this.setCouponIdSilently(0)
}
} else if(!f) {
this.couponId = res.data.result.defaultCouponId || 0
this.setCouponIdSilently(res.data.result.defaultCouponId || 0)
this.$forceUpdate()
}
this.payPrice = res.data.result.payPrice
@@ -800,6 +907,16 @@ export default {
this.aiDefaultIndex = this.aiCoverImgsList.findIndex(item => item.id === cover.id)
}
},
onAiHistoryCoverConfirm(cover) {
// 封面图片
this.selectedCover = cover.cover
// 分享对话图片
this.giftImage = cover.image
if (this.selectCoverType === 'ai') {
this.selectedAiCoverImage = cover
this.aiHistoryDefaultIndex = this.aiHistoryCoverImgsList.findIndex(item => item.id === cover.id)
}
},
handleSelectAiCover(cover) {
this.selectedAiCoverImage = cover
this.aiDefaultIndex = this.aiCoverImgsList.findIndex(item => item.id === cover.id)
@@ -807,6 +924,13 @@ export default {
this.giftImage = cover.image
this.templateId = cover.id
},
handleSelectAiHistoryCover(cover) {
this.selectedAiCoverImage = cover
this.aiHistoryDefaultIndex = this.aiHistoryCoverImgsList.findIndex(item => item.id === cover.id)
this.selectedCover = cover.cover
this.giftImage = cover.image
this.templateId = cover.id
},
showTips() {
this.$refs.giftTips.showTips = true
},
@@ -817,25 +941,27 @@ export default {
}
this.loading = true
getGiftCardSendOrderConfirm(params).then(res => {
const temp = this.isGroupBuy ? res.data.giftCardTemplates : res.data.giftCardTemplates.filter(e => e.isTravelGroup === 0)
const hasSpecial = res.data.giftCardTemplates.map(e => e.id).includes(res.data.specialGiftCardTemplate.id)
const initialCoverList = hasSpecial ? [...temp] : [...temp, res.data.specialGiftCardTemplate]
const goodsInfo = res.data.cartInfo[0]
const { coverList, template } = this.adjustCoverListForProductStory(initialCoverList, goodsInfo && goodsInfo.productInfo, res.data.specialGiftCardTemplate)
const data = res.data
const temp = this.isGroupBuy ? data.giftCardTemplates : data.giftCardTemplates.filter(e => e.isTravelGroup === 0)
const hasSpecial = data.giftCardTemplates.map(e => e.id).includes(data.specialGiftCardTemplate.id)
const initialCoverList = hasSpecial ? [...temp] : [...temp, data.specialGiftCardTemplate]
const goodsInfo = data.cartInfo[0]
const { coverList, template } = this.adjustCoverListForProductStory(initialCoverList, goodsInfo && goodsInfo.productInfo, data.specialGiftCardTemplate)
this.coverList = coverList
this.giftNotice = res.data.giftCardGiftNotice
this.orderKey = res.data.orderKey
this.giftNotice = data.giftCardGiftNotice
this.orderKey = data.orderKey
this.goodsInfo = goodsInfo
this.syncCountyLotteryGiftFlag(goodsInfo)
this.templateId = template.id
this.selectedCover = template.cover
this.giftImage = template.image
this.blindImage = res.data.giftCardBlindBoxShareImage
this.blindImage = data.giftCardBlindBoxShareImage
this.defaultIndex = this.coverList.findIndex(item => item.id === this.templateId)
// if(!this.couponId) {
// this.couponId = res.data.couponList.usable[0] && res.data.couponList.usable[0].id || ''
// this.couponId = data.couponList.usable[0] && data.couponList.usable[0].id || ''
// }
this.computedPrice(this.goodsInfo.cartNum)
this.aiGiftImageHistoryReq()
this.isLoad = true
}).finally(() => {
this.loading = false
@@ -854,6 +980,7 @@ export default {
if (this.isCountyLotteryGift && this.isEligibleForDraw) {
this.showLotteryGiftPopup = true
}
this.aiGiftImageHistoryReq()
},
closeLotteryGiftPopup() {
this.showLotteryGiftPopup = false
@@ -1338,10 +1465,16 @@ export default {
gap: 24rpx;
padding: 20rpx 0;
box-sizing: border-box;
&.scrollable {
justify-content: flex-start;
flex-wrap: nowrap;
overflow-x: auto;
}
}
.img-image {
display: block;
height: 176rpx;
flex-shrink: 0;
&.active {
transform: scale(1.2);
}