fix: nanobanana 优化请求体

This commit is contained in:
old burden 2026-04-23 17:55:13 +08:00
parent bf9e320817
commit 5d4b6d45e8
5 changed files with 67 additions and 71 deletions

View File

@ -218,7 +218,7 @@ export default {
method: 'POST',
data: {
text: this.text || this.textPlaceholder,
firstUrl: [this.firstUrl.url, this.secondUrl.url],
imageUrls: [this.firstUrl.url, this.secondUrl.url],
functionType: '13',
tags: tags.join(',')
}

View File

@ -22,6 +22,8 @@
<mf-image-upload
listType="draggable"
uploadHeight="200px"
:multiple="true"
:limit="9"
:show-file-list="false"
:content="$t('common.uploadPlaceholder')"
v-model="firstUrl" />
@ -73,23 +75,22 @@
<div class="nano-label">{{ $t('common.aspectRatioLabel') }}</div>
<a-select
v-model="aspectRatio"
popup-class-name="image-select-popup"
style="width: 100%">
<a-select-option value="auto">auto</a-select-option>
<a-select-option value="1:1">1:1</a-select-option>
<a-select-option value="1:4">1:4</a-select-option>
<a-select-option value="1:8">1:8</a-select-option>
<a-select-option value="2:3">2:3</a-select-option>
<a-select-option value="3:2">3:2</a-select-option>
<a-select-option value="3:4">3:4</a-select-option>
<a-select-option value="4:1">4:1</a-select-option>
<a-select-option value="4:3">4:3</a-select-option>
<a-select-option value="4:5">4:5</a-select-option>
<a-select-option value="5:4">5:4</a-select-option>
<a-select-option value="8:1">8:1</a-select-option>
<a-select-option value="9:16">9:16</a-select-option>
<a-select-option value="16:9">16:9</a-select-option>
<a-select-option value="21:9">21:9</a-select-option>
<a-option value="auto">auto</a-option>
<a-option value="1:1">1:1</a-option>
<a-option value="1:4">1:4</a-option>
<a-option value="1:8">1:8</a-option>
<a-option value="2:3">2:3</a-option>
<a-option value="3:2">3:2</a-option>
<a-option value="3:4">3:4</a-option>
<a-option value="4:1">4:1</a-option>
<a-option value="4:3">4:3</a-option>
<a-option value="4:5">4:5</a-option>
<a-option value="5:4">5:4</a-option>
<a-option value="8:1">8:1</a-option>
<a-option value="9:16">9:16</a-option>
<a-option value="16:9">16:9</a-option>
<a-option value="21:9">21:9</a-option>
</a-select>
</div>
<div class="nano-row">
@ -99,21 +100,21 @@
</div>
<a-select
v-model="resolution"
popup-class-name="image-select-popup"
style="width: 100%">
<a-select-option value="1K">1K</a-select-option>
<a-select-option value="2K">2K</a-select-option>
<a-select-option value="4K">4K</a-select-option>
<a-option value="1K">1K</a-option>
<a-option value="2K">2K</a-option>
<a-option value="4K">4K</a-option>
</a-select>
</div>
<div class="nano-row">
<div
class="nano-row"
v-if="current !== 2">
<div class="nano-label">输出格式</div>
<a-select
v-model="outputFormat"
popup-class-name="image-select-popup"
style="width: 100%">
<a-select-option value="png">png</a-select-option>
<a-select-option value="jpg">jpg</a-select-option>
<a-option value="png">png</a-option>
<a-option value="jpg">jpg</a-option>
</a-select>
</div>
</div>
@ -208,7 +209,7 @@ export default {
data() {
return {
prefixCls: 'image',
firstUrl: '',
firstUrl: [],
text: '',
current: 1,
generateLoading: false,
@ -318,11 +319,27 @@ export default {
if (this.uploadType === 'upload') {
this.selectedTemplatePreview = ''
this.selectedTemplate = null
this.firstUrl = ''
this.firstUrl = []
} else {
this.firstUrl = ''
this.firstUrl = []
}
},
getImageUrls() {
if (this.$datas.isEmpty(this.firstUrl)) return []
if (Array.isArray(this.firstUrl)) {
return this.firstUrl
.map((item) => item?.serverUrl || item?.url || '')
.filter((url) => !!url)
}
if (typeof this.firstUrl === 'object') {
const url = this.firstUrl.serverUrl || this.firstUrl.url
return url ? [url] : []
}
if (typeof this.firstUrl === 'string') {
return this.firstUrl ? [this.firstUrl] : []
}
return []
},
//
openTemplateDialog() {
this.templateDialogVisible = true
@ -430,10 +447,7 @@ export default {
}
},
generateImage() {
if (!this.firstUrl || !this.firstUrl.url) {
this.$message.error(this.$t('common.uploadImageError'))
return
}
const imageUrls = this.getImageUrls()
// image-to-image2 (current=2)
if (this.current === 2 && !this.resolution) {
this.$message.warning(this.$t('common.proResolutionRequired'))
@ -463,16 +477,19 @@ export default {
})
this.generateLoading = true
this.taskIdHint = ''
nanoBananaImgToImg({
const requestData = {
functionType: this.current == 1 ? '11' : '12',
imageUrl: this.firstUrl.url,
imageUrls,
text: this.text,
tags: tags.join(','),
aspectRatio: this.aspectRatio,
resolution: this.resolution,
outputFormat: this.outputFormat,
numImages: 1
})
}
if (this.current !== 2) {
requestData.outputFormat = this.outputFormat
}
nanoBananaImgToImg(requestData)
.then((res) => {
this.generateLoading = false
if (res.code == 200) {
@ -887,22 +904,3 @@ export default {
}
}
</style>
<style lang="less">
.image-select-popup {
.arco-select-dropdown-list {
display: block !important;
}
.arco-select-option {
display: flex !important;
width: 100%;
}
.arco-select-option-content {
display: block;
width: 100%;
white-space: normal;
}
}
</style>

View File

@ -164,9 +164,6 @@ public class ByteApiController extends BaseController {
} else if (StringUtils.isNotEmpty(request.getImageUrl())) {
imageUrls.add(request.getImageUrl().trim());
}
if (imageUrls.isEmpty()) {
return AjaxResult.error("请提供 imageUrl 或 imageUrls");
}
AiManager aiManager = managerService.selectAiManagerByType(functionType);
if (aiManager == null) {
@ -196,7 +193,7 @@ public class ByteApiController extends BaseController {
return AjaxResult.error(-1, "You have a low balance, please recharge");
}
aiOrder.setText(text);
aiOrder.setImg1(imageUrls.get(0));
aiOrder.setImg1(imageUrls.isEmpty() ? null : imageUrls.get(0));
NanoBananaRequest nanoRequest = NanoBananaRequest.forImageToImage(
text,
@ -347,9 +344,13 @@ public class ByteApiController extends BaseController {
return AjaxResult.error("text is null");
}
Object firstUrl = request.getFirstUrl();
if (null == firstUrl) {
return AjaxResult.error("firstUrl is null");
List<String> imageUrls = new ArrayList<>();
if (request.getImageUrls() != null && !request.getImageUrls().isEmpty()) {
for (String u : request.getImageUrls()) {
if (StringUtils.isNotEmpty(u)) {
imageUrls.add(u.trim());
}
}
}
String resolution = StringUtils.isNotBlank(request.getResolution())
@ -363,13 +364,7 @@ public class ByteApiController extends BaseController {
}
aiOrder.setText(text);
aiOrder.setImg1(firstUrl.toString());
// 4. 组装NanoBanana接口参数 - 图生图
List<String> imageUrls = new ArrayList<>();
if (firstUrl != null) {
imageUrls.add(firstUrl.toString());
}
aiOrder.setImg1(imageUrls.isEmpty() ? null : imageUrls.get(0));
NanoBananaRequest nanoRequest = NanoBananaRequest.forImageToImage(
text,

View File

@ -37,6 +37,9 @@ public class ByteApiRequest {
@ApiModelProperty(name = "分辨率 1K/2K/4K")
private String resolution;
@ApiModelProperty(name = "图生图参考图列表,可为空")
private List<String> imageUrls;
/**
* NanoBanana 接口版本v1(/generate)v2(/generate-2)pro(/generate-pro)默认 v2 兼容旧逻辑
*/

View File

@ -35,10 +35,10 @@ public class NanoBananaPortalImgRequest {
@ApiModelProperty("标签字符串")
private String tags;
@ApiModelProperty("单张参考图 URL与 imageUrls 二选一")
@ApiModelProperty("单张参考图 URL兼容字段,可为空")
private String imageUrl;
@ApiModelProperty("多张参考图 URL优先于 imageUrl")
@ApiModelProperty("多张参考图 URL优先于 imageUrl,可为空数组")
private List<String> imageUrls;
@ApiModelProperty("输出格式png / jpg")