641 lines
15 KiB
JavaScript
641 lines
15 KiB
JavaScript
//index.js
|
||
const app = getApp()
|
||
import TextDecoder from '../../utils/miniprogram-text-decoder'
|
||
Page({
|
||
data: {
|
||
currentTab: 'ToText', // 初始选择文生视频
|
||
uploadedImage: '',
|
||
userInfo: {},
|
||
videoUrl: '',
|
||
uuid: '',
|
||
inputValue: '',
|
||
charCount: 0,
|
||
picInputValue: '',
|
||
picCharCount: 0,
|
||
sizes: [{
|
||
ratio: '1:1',
|
||
width: 1080,
|
||
height: 1080
|
||
},
|
||
{
|
||
ratio: '16:9',
|
||
width: 1920,
|
||
height: 1080
|
||
},
|
||
{
|
||
ratio: '9:16',
|
||
width: 1080,
|
||
height: 1920
|
||
},
|
||
{
|
||
ratio: '4:3',
|
||
width: 1440,
|
||
height: 1080
|
||
},
|
||
{
|
||
ratio: '3:4',
|
||
width: 1080,
|
||
height: 1440
|
||
}
|
||
],
|
||
selectedSize: '9:16',
|
||
selectedWidth: 1080,
|
||
selectedHeight: 1920,
|
||
styles: {
|
||
abandoned: '废弃',
|
||
abstract_sculpture: '抽象',
|
||
advertising: '广告',
|
||
anime: '动漫',
|
||
cine_lens: '电影镜头',
|
||
cinematic: '电影',
|
||
concept_art: '艺术',
|
||
forestpunk: '赛博朋克',
|
||
frost: '雪',
|
||
graphite: '石墨',
|
||
macro_photography: '宏观',
|
||
pixel_art: '像素艺术',
|
||
retro_photography: '复古',
|
||
sci_fi_art: '科幻',
|
||
thriller: '惊悚',
|
||
'35mm': '35mm',
|
||
vector: '矢量',
|
||
watercolor: '水彩'
|
||
},
|
||
selectedStyle: '',
|
||
enhanceValue: 5, // 初始值设置为5
|
||
picEnhanceValue: 5,
|
||
|
||
ShowPicUrl: '',
|
||
tempImg: null, // 图片
|
||
messages: {},
|
||
messagesTemp: {
|
||
is_response: true,
|
||
content: '您好,我是智能AI助手,请问有什么可以帮助您的?'
|
||
},
|
||
inputMessage: "",
|
||
toView: 'toBottom1',
|
||
showRoleDropdown: false,
|
||
currentRole: 9, // 默认角色
|
||
currentRoleText: '选择角色',
|
||
roles: []
|
||
|
||
},
|
||
|
||
|
||
// 文生视频提交
|
||
textGenerateSubmit() {
|
||
if (this.data.inputValue === "") {
|
||
wx.showToast({
|
||
title: '请输入视频描述',
|
||
icon: 'error'
|
||
})
|
||
return
|
||
}
|
||
|
||
let userId = wx.getStorageSync('userId')
|
||
const data = {
|
||
user_id: userId,
|
||
text_prompt: this.data.inputValue,
|
||
width: this.data.selectedWidth,
|
||
height: this.data.selectedHeight,
|
||
motion_score: this.data.enhanceValue,
|
||
style: this.data.selectedStyle
|
||
}
|
||
wx.showLoading({
|
||
title: '任务提交中',
|
||
})
|
||
app.apiRequest({
|
||
url: "/myapp/generate_video/",
|
||
method: "POST",
|
||
data,
|
||
success: res => {
|
||
console.log('res', res);
|
||
if (res.data.success === false) {
|
||
wx.showModal({
|
||
title: "文生视频",
|
||
content: "哎呀!创意点数不足, 请充值",
|
||
confirmColor: "#00B269",
|
||
cancelColor: "#858585",
|
||
success: function (e) {
|
||
e.confirm ? (console.log("确定"), wx.navigateTo({
|
||
url: "../vip_recharge/vip_recharge?show=true"
|
||
})) : e.cancel && console.log("取消");
|
||
}
|
||
})
|
||
} else {
|
||
wx.navigateTo({
|
||
url: '/pages/tips/tips',
|
||
})
|
||
}
|
||
},
|
||
fail: err => {
|
||
console.log('err', err);
|
||
},
|
||
complete: () => {
|
||
wx.hideLoading()
|
||
}
|
||
})
|
||
},
|
||
// 图生视频提交
|
||
async picGenerateSubmit() {
|
||
if (this.data.ShowPicUrl === "") {
|
||
wx.showToast({
|
||
title: '请上传图片',
|
||
icon: 'error'
|
||
})
|
||
return
|
||
}
|
||
if (this.data.picInputValue === "") {
|
||
wx.showToast({
|
||
title: '请输入视频描述',
|
||
icon: 'error'
|
||
})
|
||
return
|
||
}
|
||
|
||
let imageUrl = ''
|
||
wx.showLoading({
|
||
title: '任务提交中',
|
||
})
|
||
try {
|
||
let res = await app.uploadFile(this.data.ShowPicUrl)
|
||
imageUrl = app.globalData.apiDomain + JSON.parse(res).file_url
|
||
} catch (error) {
|
||
console.log('error', error);
|
||
wx.hideLoading()
|
||
wx.showToast({
|
||
title: '图片上传失败,请稍后重试~',
|
||
icon: 'error'
|
||
});
|
||
return
|
||
}
|
||
let userId = wx.getStorageSync('userId')
|
||
const data = {
|
||
user_id: userId,
|
||
image_url: imageUrl,
|
||
text_prompt: this.data.picInputValue,
|
||
motion_score: this.data.picEnhanceValue
|
||
}
|
||
app.apiRequest({
|
||
url: "/myapp/generate_image_video/",
|
||
method: "POST",
|
||
data,
|
||
success: res => {
|
||
console.log('res', res);
|
||
if (res.data.success === false) {
|
||
wx.showModal({
|
||
title: "图生视频",
|
||
content: "哎呀!创意点数不足, 请充值",
|
||
confirmColor: "#00B269",
|
||
cancelColor: "#858585",
|
||
success: function (e) {
|
||
e.confirm ? (console.log("确定"), wx.navigateTo({
|
||
url: "../vip_recharge/vip_recharge?show=true"
|
||
})) : e.cancel && console.log("取消");
|
||
}
|
||
})
|
||
} else {
|
||
wx.navigateTo({
|
||
url: '/pages/tips/tips',
|
||
})
|
||
|
||
}
|
||
},
|
||
fail: err => {
|
||
console.log('err', err);
|
||
},
|
||
complete: () => {
|
||
wx.hideLoading()
|
||
}
|
||
})
|
||
},
|
||
// 点击上传图片
|
||
uploadImage() {
|
||
let that = this
|
||
wx.chooseMedia({
|
||
count: 1,
|
||
mediaType: ['image'],
|
||
sourceType: ['album'],
|
||
success(res) {
|
||
console.log(res)
|
||
let tempImg = res.tempFiles[0]
|
||
let pictureSize = tempImg.size
|
||
let ShowPicUrl = tempImg.tempFilePath
|
||
if (pictureSize > 1024 * 1024 * 10) {
|
||
wx.showToast({
|
||
title: '图片大小不能超过10MB',
|
||
icon: 'error'
|
||
})
|
||
return
|
||
}
|
||
that.setData({
|
||
tempImg,
|
||
ShowPicUrl
|
||
})
|
||
}
|
||
})
|
||
},
|
||
switchNav(e) {
|
||
const nav = e.currentTarget.dataset.nav;
|
||
console.log(nav)
|
||
this.setData({
|
||
currentTab: nav
|
||
});
|
||
},
|
||
// 文生视频输入
|
||
onInput(e) {
|
||
const value = e.detail.value;
|
||
this.setData({
|
||
inputValue: value,
|
||
charCount: value.length
|
||
});
|
||
},
|
||
// 图生视频输入
|
||
onPicInput(e) {
|
||
const value = e.detail.value;
|
||
this.setData({
|
||
picInputValue: value,
|
||
picCharCount: value.length
|
||
});
|
||
},
|
||
optimizePrompt() {
|
||
// 优化提示词的逻辑
|
||
console.log("优化提示词按钮被点击");
|
||
// 可以在这里实现优化提示词的功能
|
||
},
|
||
// 文生视频运动增强
|
||
onSliderChange(e) {
|
||
const value = e.detail.value;
|
||
this.setData({
|
||
enhanceValue: value
|
||
});
|
||
},
|
||
// 图生视频运动增强
|
||
onPicSliderChange(e) {
|
||
const value = e.detail.value;
|
||
this.setData({
|
||
picEnhanceValue: value
|
||
});
|
||
},
|
||
selectStyle(e) {
|
||
const {
|
||
key
|
||
} = e.currentTarget.dataset;
|
||
this.setData({
|
||
selectedStyle: key
|
||
});
|
||
},
|
||
selectSize(e) {
|
||
const {
|
||
ratio,
|
||
width,
|
||
height
|
||
} = e.currentTarget.dataset;
|
||
this.setData({
|
||
selectedSize: ratio,
|
||
selectedWidth: width,
|
||
selectedHeight: height
|
||
});
|
||
},
|
||
onSliderChange(e) {
|
||
const value = e.detail.value;
|
||
this.setData({
|
||
enhanceValue: value
|
||
});
|
||
},
|
||
onLoad: function (options) {
|
||
let uuid = options.uuid || ''
|
||
this.setData({
|
||
uuid: uuid
|
||
})
|
||
wx.showShareMenu({
|
||
withShareTicket: true,
|
||
menus: ['shareAppMessage', 'shareTimeline']
|
||
})
|
||
|
||
// 获取角色列表
|
||
this.getRoles()
|
||
// 获取聊天记录
|
||
this.getChatRecords()
|
||
},
|
||
// 获取角色列表
|
||
getRoles() {
|
||
let that = this
|
||
wx.showLoading({
|
||
title: '加载中',
|
||
})
|
||
app.chatApiRequest({
|
||
url: "/chat/getRoles",
|
||
method: "GET",
|
||
success: res => {
|
||
console.log('res', res)
|
||
this.setData({
|
||
roles: res.data.roles,
|
||
currentRole: 9 // 默认9 AI助手
|
||
})
|
||
},
|
||
fail: err => {
|
||
console.log('err', err)
|
||
},
|
||
complete: () => {
|
||
|
||
}
|
||
})
|
||
},
|
||
// 获取聊天记录
|
||
getChatRecords() {
|
||
let that = this
|
||
let userId = wx.getStorageSync('userId')
|
||
let openId = wx.getStorageSync('openid')
|
||
wx.showLoading({
|
||
title: '加载中',
|
||
})
|
||
app.chatApiRequest({
|
||
url: '/chat/getRecord',
|
||
method: 'POST',
|
||
data: {
|
||
nickname: userId,
|
||
openid: openId,
|
||
role_id: this.data.currentRole
|
||
},
|
||
success: (res) => {
|
||
let messages = this.data.messages
|
||
messages[that.data.currentRole] = res.data.records
|
||
that.setData({
|
||
messages
|
||
})
|
||
that.scrollToBottom()
|
||
},
|
||
fail: (err) => {
|
||
console.log('err', err)
|
||
},
|
||
complete: () => {
|
||
wx.hideLoading()
|
||
}
|
||
})
|
||
},
|
||
bindInput(e) {
|
||
this.setData({
|
||
inputMessage: e.detail.value
|
||
});
|
||
},
|
||
|
||
// 滚动条置底
|
||
scrollToBottom() {
|
||
this.setData({
|
||
toView: this.data.toView === 'toBottom1' ? 'toBottom2' : 'toBottom1'
|
||
});
|
||
},
|
||
|
||
// 发送
|
||
sendMessage() {
|
||
let that = this
|
||
let inputMessage = this.data.inputMessage
|
||
if (inputMessage === '') {
|
||
wx.showToast({
|
||
title: '请输入消息',
|
||
icon: 'none'
|
||
})
|
||
return false
|
||
}
|
||
|
||
let messages = that.data.messages
|
||
// 获取会话session_id
|
||
let sessionID
|
||
if (messages[this.data.currentRole].length !== 0) {
|
||
sessionID = messages[this.data.currentRole][messages[this.data.currentRole].length - 1].session_id
|
||
}
|
||
messages[this.data.currentRole].push({
|
||
is_response: false,
|
||
message_content: inputMessage
|
||
})
|
||
this.setData({
|
||
inputMessage: ''
|
||
})
|
||
|
||
messages[this.data.currentRole].push({
|
||
is_response: true,
|
||
message_content: '',
|
||
isGenerating: true
|
||
})
|
||
that.setData({
|
||
messages: messages,
|
||
})
|
||
this.scrollToBottom()
|
||
let userId = wx.getStorageSync('userId')
|
||
let openid = wx.getStorageSync('openid')
|
||
let role = this.data.currentRole
|
||
|
||
|
||
let reqTask = app.chatApiRequest({
|
||
url: '/chat/send',
|
||
method: 'POST',
|
||
enableChunked: true,
|
||
data: {
|
||
openid,
|
||
userid: userId,
|
||
prompt: inputMessage,
|
||
role_id: role,
|
||
session_id: sessionID
|
||
},
|
||
success: (res) => {
|
||
// console.log('res', res)
|
||
},
|
||
fail: (err) => {
|
||
console.log('err', err)
|
||
}
|
||
})
|
||
let newMessages = this.data.messages
|
||
let currentMessages = newMessages[this.data.currentRole]
|
||
let lastMessages = currentMessages[currentMessages.length - 1]
|
||
reqTask.onChunkReceived(r => {
|
||
let decoder = new TextDecoder('utf-8');
|
||
let str = decoder.decode(r.data);
|
||
let lines = str.split('\n\n')
|
||
lines.pop()
|
||
for (let i of lines) {
|
||
let jsonStr = i
|
||
if (i.startsWith("data:")) {
|
||
jsonStr = jsonStr.substring(5);
|
||
}
|
||
let messageObject = JSON.parse(jsonStr)
|
||
lastMessages.isGenerating = false
|
||
lastMessages.message_content += messageObject.output.text
|
||
lastMessages.session_id = messageObject.output.session_id
|
||
this.setData({
|
||
messages: newMessages
|
||
})
|
||
}
|
||
|
||
that.scrollToBottom()
|
||
})
|
||
},
|
||
|
||
utf8ArrayToStr(array) {
|
||
var out, i, len, c;
|
||
var char2, char3;
|
||
|
||
out = "";
|
||
len = array.length;
|
||
i = 0;
|
||
while (i < len) {
|
||
c = array[i++];
|
||
switch (c >> 4) {
|
||
case 0:
|
||
case 1:
|
||
case 2:
|
||
case 3:
|
||
case 4:
|
||
case 5:
|
||
case 6:
|
||
case 7:
|
||
// 0xxxxxxx
|
||
out += String.fromCharCode(c);
|
||
break;
|
||
case 12:
|
||
case 13:
|
||
// 110x xxxx 10xx xxxx
|
||
char2 = array[i++];
|
||
out += String.fromCharCode(((c & 0x1F) << 6) | (char2 & 0x3F));
|
||
break;
|
||
case 14:
|
||
// 1110 xxxx 10xx xxxx 10xx xxxx
|
||
char2 = array[i++];
|
||
char3 = array[i++];
|
||
out += String.fromCharCode(((c & 0x0F) << 12) |
|
||
((char2 & 0x3F) << 6) |
|
||
((char3 & 0x3F) << 0));
|
||
break;
|
||
}
|
||
}
|
||
|
||
return out;
|
||
},
|
||
|
||
|
||
toggleRoleDropdown() {
|
||
this.setData({
|
||
showRoleDropdown: !this.data.showRoleDropdown,
|
||
});
|
||
},
|
||
switchRole(event) {
|
||
const roleIndex = event.currentTarget.dataset.role;
|
||
this.setData({
|
||
currentRole: this.data.roles[roleIndex].id,
|
||
currentRoleText: this.data.roles[roleIndex].name,
|
||
showRoleDropdown: false,
|
||
});
|
||
this.getChatRecords()
|
||
// 在这里你可以根据需要添加更多逻辑,比如切换到不同的AI模型
|
||
},
|
||
|
||
// 判断邀请用户
|
||
sendReward_invitation: function (uuid) {
|
||
app.apiRequest({
|
||
url: '/myapp/reward_invitation', // 后端接口URL
|
||
method: 'POST',
|
||
data: {
|
||
openid: wx.getStorageSync('openid'),
|
||
uuid: uuid,
|
||
},
|
||
success(res) {
|
||
console.log(res);
|
||
if (res.data.success == true) {
|
||
wx.setStorageSync('defaultDailyFreeParseNum', wx.getStorageSync('defaultDailyFreeParseNum') + 10);
|
||
}
|
||
},
|
||
fail(err) {
|
||
console.error(err);
|
||
// 错误处理
|
||
}
|
||
});
|
||
|
||
},
|
||
|
||
|
||
onShow() {
|
||
app.getCurrentTabbar(1, this);
|
||
app.checkUpdateVersion()
|
||
wx.showLoading()
|
||
app.getUserInfo().then(() => {
|
||
if (this.data.uuid != '' && wx.getStorageSync('openid') != '' && wx.getStorageSync('uuid') != this.data.uuid) {
|
||
this.sendReward_invitation(this.data.uuid);
|
||
}
|
||
}).catch(error => {
|
||
console.error('获取用户信息失败:', error);
|
||
}).finally(() => {
|
||
console.log('getUserInfo调用完成');
|
||
});
|
||
},
|
||
|
||
// 清空输入框
|
||
inputClear: function () {
|
||
this.setData({
|
||
videoUrl: ''
|
||
})
|
||
},
|
||
|
||
copyContent(e) {
|
||
console.log(e)
|
||
const content = e.target.dataset.content;
|
||
wx.setClipboardData({
|
||
data: content,
|
||
success() {
|
||
wx.showToast({
|
||
title: '内容已复制',
|
||
icon: 'none',
|
||
});
|
||
},
|
||
fail(err) {
|
||
wx.showToast({
|
||
title: '复制失败',
|
||
icon: 'none',
|
||
});
|
||
console.error('复制失败', err);
|
||
}
|
||
});
|
||
},
|
||
|
||
onShareAppMessage: function () {
|
||
return {
|
||
title: '推荐一款免费又超好用的AI视频文案创作工具,快来体验吧',
|
||
path: '/pages/index/index?uuid=' + wx.getStorageSync('uuid'),
|
||
imageUrl: '/images/index.jpg',
|
||
success: function (e) {
|
||
wx.showToast({
|
||
title: "分享成功",
|
||
icon: "success",
|
||
duration: 2e3
|
||
});
|
||
},
|
||
fail: function (e) {
|
||
wx.showToast({
|
||
title: "分享失败",
|
||
icon: "none",
|
||
duration: 2e3
|
||
});
|
||
}
|
||
}
|
||
},
|
||
onShareTimeline: function () {
|
||
return {
|
||
title: '推荐一款免费又超好用的AI视频文案创作工具,快来体验吧',
|
||
path: '/pages/index/index?uuid=' + wx.getStorageSync('uuid'),
|
||
imageUrl: '/images/index.jpg',
|
||
success: function (e) {
|
||
wx.showToast({
|
||
title: "分享成功",
|
||
icon: "success",
|
||
duration: 2e3
|
||
});
|
||
},
|
||
fail: function (e) {
|
||
wx.showToast({
|
||
title: "分享失败",
|
||
icon: "none",
|
||
duration: 2e3
|
||
});
|
||
}
|
||
}
|
||
},
|
||
}) |