用途介紹
Midjourney是一個(gè)目前優(yōu)秀的AI畫圖工具,不掛梯無法直接訪問
本代碼主要用于搭建鏡像站使用
適合人群
本代碼不適合新手,建議使用過okhttp、且具有二開能力的同學(xué)使用~
實(shí)現(xiàn)原理
通過調(diào)用發(fā)送信息接口發(fā)送請求,通過輪詢房間消息接口判斷是否作圖完成
發(fā)送的時(shí)候帶上我們存儲好的cookie信息即可
輪詢房間消息接口是為了避免模擬網(wǎng)頁實(shí)際的websocket連接,那玩意解密沒解出來...
準(zhǔn)備
1. 開通Midjourney會員的Discord賬號
2. 新建很多房間(因?yàn)榉块g消息接口默認(rèn)就50條數(shù)據(jù),也就是說每個(gè)房間最多并行50個(gè)圖片生成任務(wù))
功能預(yù)覽
上代碼
代碼功能:
1. 調(diào)用Midjourney生成并將生成好的內(nèi)容發(fā)送微信消息給用戶(這個(gè)是在微信公眾號平臺做的,大家做網(wǎng)頁版的話自己改下輸出到網(wǎng)頁就可以)
2. 進(jìn)行合規(guī)性檢測(生成點(diǎn)不得了的東西后果你懂得,這里用的是百度的文本審核服務(wù),5萬次以下免費(fèi))
3. 如果用戶輸入是中文,就翻譯為英文再發(fā)送
midjourneyLog
midjourney_log表字段如下代碼所示
需要使用通用mapper哦~
package com.example.midjourney.bean.pojo;
import lombok.Data;
import tk.mybatis.mapper.annotation.NameStyle;
import tk.mybatis.mapper.code.Style;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.Table;
import java.util.Date;
@Data
@NameStyle(Style.camelhump)
@Table(name = "midjourney_log")
public class MidjourneyLog {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
private Integer memberId;
private String channel;
private String prompt;
private Integer type;
private Integer status;
private String imgFile;
private Integer roomId;
private String uuid;
private Date createTime;
}
MidJourneyBiz
請求唯一id沒啥規(guī)律,一段時(shí)間內(nèi)不一致就行,試了沒啥校驗(yàn)
另外請求頭除了cookie需要保證和 authorization、x-super-properties對應(yīng)上,三者對應(yīng)上實(shí)測2個(gè)月都不會掉線!
package com.example.midjourney.biz;
import cn.hutool.core.img.ImgUtil;
import cn.hutool.core.io.FileUtil;
import com.alibaba.fastjson.JSON;
import com.example.midjourney.bean.BaiduTextCensor;
import com.example.midjourney.bean.BaiduTextCensorData;
import com.example.midjourney.bean.MidMsg;
import com.example.midjourney.bean.pojo.Discord;
import com.example.midjourney.bean.pojo.MidjourneyLog;
import com.example.midjourney.bean.pojo.RoomInfo;
import com.example.midjourney.contant.Constant;
import com.example.midjourney.enums.MedjourneyLogType;
import com.example.midjourney.service.DiscordService;
import com.example.midjourney.service.MidjourneyLogService;
import com.example.midjourney.service.MemberService;
import com.example.midjourney.service.RoomInfoService;
import com.example.midjourney.util.*;
import com.google.common.base.Joiner;
import com.google.common.base.Splitter;
import com.google.common.collect.Lists;
import lombok.SneakyThrows;
import lombok.extern.slf4j.Slf4j;
import okhttp3.*;
import org.apache.logging.log4j.util.Strings;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Service;
import javax.annotation.Resource;
import javax.imageio.ImageIO;
import java.awt.*;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.math.BigDecimal;
import java.net.InetSocketAddress;
import java.net.Proxy;
import java.util.List;
import java.util.Objects;
import java.util.Set;
import java.util.UUID;
import java.util.stream.Collectors;
import static com.example.midjourney.contant.Constant.*;
/**
* 啟動就運(yùn)行,不停刷新消息列表
*/
@Slf4j
@Service
public class MidJourneyBiz {
private static BigDecimal bigDecimal = new BigDecimal("1099765990370980513")
.add(new BigDecimal(System.currentTimeMillis()));
@Resource
private WeChatBiz weChatBiz;
@Resource
private TranslateBiz translateBiz;
@Resource
private MidjourneyLogService midjourneyLogService;
@Resource
private MemberService memberService;
@Resource
private RoomInfoService roomInfoService;
@Resource
private DiscordService discordService;
public void buildImg(Long id) {
MidjourneyLog midjourneyLog = midjourneyLogService.findById(id);
try {
if (midjourneyLog.getStatus() != 0) {
return;
}
if (isFailMsg(midjourneyLog.getChannel(), midjourneyLog)) {
log.info("[失敗提示] 消息校驗(yàn)不通過 log:{}", midjourneyLog);
sendBuildFail(midjourneyLog);
return;
}
String prompt = midjourneyLog.getPrompt();
if (midjourneyLog.getType() == MedjourneyLogType.BIG_IMG.getCode()) {
downImg(midjourneyLog);
return;
}
BaiduTextCensor censor = null;
if (TextUtil.isHaveChinese(prompt)) {
censor = BaiduUtil.textCensor(prompt);
}
prompt = cleanMsg(prompt);
if (isBlackWord(prompt)) {
sendSensitive(midjourneyLog);
return;
}
if (Objects.isNull(censor)) {
censor = BaiduUtil.textCensor(prompt);
}
midjourneyLogService.updatePrompt(midjourneyLog, prompt);
if (censor.getConclusionType() == 2 || censor.getConclusionType() == 3) {
sendSensitive(midjourneyLog, censor);
return;
}
if (midjourneyLog.getType() == MedjourneyLogType.ITERATIVE.getCode()) {
//暫不支持
sendBuildFail(midjourneyLog);
return;
}
RoomInfo roomInfo = roomInfoService.findIdleRoom();
if (Objects.isNull(roomInfo)) {
log.error("[并發(fā)超出警報(bào)] 當(dāng)前并發(fā)次數(shù)已經(jīng)無法滿足?。?!");
sendBuildFail(midjourneyLog);
return;
}
if (sendMsg(prompt, roomInfo)) {
midjourneyLogService.updateRoom(midjourneyLog, roomInfo);
} else {
log.error("[發(fā)送失敗] 發(fā)送信息失敗,請檢查");
sendBuildFail(midjourneyLog);
}
} catch (Throwable t) {
sendBuildFail(midjourneyLog);
}
}
@SneakyThrows
private void downImg(MidjourneyLog midjourneyLog) {
MidjourneyLog lastLog = midjourneyLogService.findLastNormalLog(midjourneyLog.getMemberId());
log.info("[下載圖片] {}", lastLog);
if (Objects.isNull(lastLog)) {
log.info("[失敗提示] 找不到上一次的圖片 log:{}", midjourneyLog);
sendBuildFail(midjourneyLog);
return;
}
String imgFile = lastLog.getImgFile();
File file = new File(imgFile);
if (!file.exists()) {
log.info("[失敗提示] 上一次圖片不存在 log:{}", lastLog);
sendBuildFail(midjourneyLog);
return;
}
cutAndSendImg(midjourneyLog, file);
}
private void cutAndSendImg(MidjourneyLog midjourneyLog, File oldFile) throws IOException {
BufferedImage bufferedImage = ImageIO.read(new FileInputStream(oldFile));
int width = bufferedImage.getWidth();
int height = bufferedImage.getHeight();
String msg = midjourneyLog.getPrompt().trim();
String newFileName;
if (msg.equalsIgnoreCase("u1")) {
newFileName = oldFile.getPath() + "_u1.png";
ImgUtil.cut(oldFile, FileUtil.file(newFileName),
new Rectangle(0, 0, width / 2, height / 2)
);
} else if (msg.equalsIgnoreCase("u2")) {
newFileName = oldFile.getPath() + "_u2.png";
ImgUtil.cut(oldFile, FileUtil.file(newFileName),
new Rectangle(width / 2, 0, width / 2, height / 2)
);
} else if (msg.equalsIgnoreCase("u3")) {
newFileName = oldFile.getPath() + "_u3.png";
ImgUtil.cut(oldFile, FileUtil.file(newFileName),
new Rectangle(0, height / 2, width / 2, height / 2)
);
} else if (msg.equalsIgnoreCase("u4")) {
newFileName = oldFile.getPath() + "_u4.png";
ImgUtil.cut(oldFile, FileUtil.file(newFileName),
new Rectangle(width / 2, height / 2, width / 2, height / 2)
);
} else {
sendBuildFail(midjourneyLog);
return;
}
String mediaId = weChatBiz.sendImg(newFileName, midjourneyLog.getChannel());
log.info("[mediaId] {}", mediaId);
if (Strings.isNotEmpty(mediaId)) {
String wxId = memberService.selectWxidById(midjourneyLog.getMemberId());
if (Strings.isEmpty(wxId)) {
sendBuildFail(midjourneyLog);
return;
}
midjourneyLogService.updateFinish(midjourneyLog);
weChatBiz.sendImgMsg(wxId, mediaId, midjourneyLog.getChannel());
}
}
private boolean isFailMsg(String channel, MidjourneyLog midjourneyLog) {
return Objects.isNull(midjourneyLog) || Strings.isEmpty(midjourneyLog.getPrompt()) || Strings.isEmpty(channel)
|| Objects.isNull(midjourneyLog.getMemberId()) || checkNotRunMsg(midjourneyLog);
}
public boolean checkNotRunMsg(MidjourneyLog midjourneyLog) {
String prompt = midjourneyLog.getPrompt();
if (midjourneyLog.getType() == MedjourneyLogType.BIG_IMG.getCode()) {
return !(prompt.equalsIgnoreCase("u1") || prompt.equalsIgnoreCase("u2")
|| prompt.equalsIgnoreCase("u3") || prompt.equalsIgnoreCase("u4"));
} else if (midjourneyLog.getType() == MedjourneyLogType.ITERATIVE.getCode()) {
return !(prompt.equalsIgnoreCase("v1") || prompt.equalsIgnoreCase("v2")
|| prompt.equalsIgnoreCase("v3") || prompt.equalsIgnoreCase("v4"));
} else {
return false;
}
}
private String cleanMsg(String msg) {
msg = msg.replace("—", "--")
.replace("-- ", "--")
.replace("-- ", "--")
.replace("-- ", "--")
.replace(",", ",")
.replace("/", "")
.replace("--v", " --v ")
.replace("--niji", " --niji ")
.replace("--ar", " --ar ")
.replace("--aspect", " --ar ")
.replace("--chaos", " --chaos ")
.replace("--c", " --c ")
.replace("--no", " --no ")
.replace("--quality", " --quality ")
.replace("--q", " --q ")
.replace("--repeat", " --repeat ")
.replace("--s", " --s ")
.replace("--upbeta", " --upbeta ")
.trim();
if (TextUtil.isHaveChinese(msg)) {
msg = translateBiz.translate(msg);
}
msg = msg.replace(",", ",")
.replace("/", "")
.replace("--v5", " --v 5 ")
.replace("--niji5", " --niji 5 ")
.trim();
if (!msg.contains("--niji") && !msg.contains("--v") && msg.length() > 3) {
msg = msg + " --v 5";
}
return msg;
}
public void sendBuildFail(MidjourneyLog midjourneyLog) {
String wxId = memberService.selectWxidById(midjourneyLog.getMemberId());
CallBackUtil.failCallBack(midjourneyLog.getChannel(), MIDJOURNEY, midjourneyLog.getId());
midjourneyLogService.updateFail(midjourneyLog);
weChatBiz.sendTextMsg(wxId, "抱歉,您的消息【" + midjourneyLog.getPrompt() + "】處理失敗,已為您退換對應(yīng)電量",
midjourneyLog.getChannel());
}
@Scheduled(cron = "34 * * * * ? ")
public void checkImg() {
//房間號清理
cleanRoomNumber();
//查詢所有進(jìn)行中的任務(wù)
List<MidjourneyLog> logs = midjourneyLogService.selectAllDoing().stream()
.filter(log -> Objects.nonNull(log.getRoomId())).collect(Collectors.toList());
//找到超時(shí)任務(wù)進(jìn)行關(guān)閉
List<MidjourneyLog> failLogs = logs.stream()
.filter(log -> System.currentTimeMillis() - log.getCreateTime().getTime() > MAX_WAIT_TIME)
.collect(Collectors.toList());
failLogs.forEach(this::sendBuildFail);
//剩余任務(wù)整理出來房間號
logs.removeAll(failLogs);
Set<Integer> roomSet = logs.stream().map(MidjourneyLog::getRoomId).collect(Collectors.toSet());
//輪詢當(dāng)前進(jìn)度
for (Integer roomId : roomSet) {
RoomInfo roomInfo = roomInfoService.findById(roomId);
if (Objects.isNull(roomInfo)) {
log.error("[room沒找到] roomId:{} 沒找到對應(yīng)房間,看一下是不是掛了", roomId);
continue;
}
Discord discord = discordService.findById(roomInfo.getDiscordId());
List<MidMsg> midMsgs = readNowList(roomInfo, discord);
log.info("[消息列表] {}", midMsgs);
checkAndSendMsg(midMsgs, logs, roomInfo);
}
}
private void cleanRoomNumber() {
List<RoomInfo> roomInfos = roomInfoService.findAll();
for (RoomInfo roomInfo : roomInfos) {
int count = midjourneyLogService.selectRoomOnUse(roomInfo.getId());
roomInfo.setNowNumber(count);
roomInfoService.update(roomInfo);
}
}
private void checkAndSendMsg(List<MidMsg> midMsgs, List<MidjourneyLog> logs, RoomInfo roomInfo) {
List<MidjourneyLog> roomLogs = logs.stream()
.filter(log -> log.getRoomId().equals(roomInfo.getId()))
.collect(Collectors.toList());
midMsgs.stream()
.filter(this::isPrintOk)
.forEach(m -> roomLogs.forEach(midjourey -> {
if (m.getContent().startsWith(MID_JOURNEY_HEAD + filterHead(midjourey.getPrompt()))) {
log.info("[Midjourney 配對] msg:{} key:{}", m, midjourey.getPrompt());
String wxid = memberService.selectWxidById(midjourey.getMemberId());
String url = m.getAttachments().get(0).getUrl();
String localPath = Constant.FILE_PATH + UUID.randomUUID() + "." + FileUtil.getSuffix(url);
ImgDownUtil.getImage(url.replace("https://", "http://"), localPath);
localPath = localPath.replace("\\", "/");
if ("webp".equals(FileUtil.getSuffix(localPath))) {
com.example.midjourney.util.ImgUtil.webpToPng(localPath, localPath + ".png");
localPath = localPath + ".png";
}
String mediaId = weChatBiz.sendImg(localPath, midjourey.getChannel());
log.info("[mediaId] {}", mediaId);
if (Strings.isNotEmpty(mediaId)) {
weChatBiz.sendImgMsg(wxid, mediaId, midjourey.getChannel());
weChatBiz.sendTextMsg(wxid, "下載高清大圖口令:\n\n☆左上圖回復(fù):U1\n\n☆右上圖回復(fù):U2" +
"\n\n☆左下圖回復(fù):U3\n\n☆右下圖回復(fù):U4\n\n下載大圖也會扣電量哦~", midjourey.getChannel());
midjourey.setImgFile(localPath);
midjourneyLogService.updateFinish(midjourey);
}
}
}));
}
private String filterHead(String prompt) {
return Lists.newArrayList(Splitter.on("--").split(prompt)).stream().findFirst().orElse("").trim();
}
private boolean isPrintOk(MidMsg midMsg) {
if (Objects.isNull(midMsg)
|| Strings.isEmpty(midMsg.getContent())
|| !midMsg.getContent().contains(MID_FIND_LEFT)) {
return false;
}
String str = midMsg.getContent().substring(midMsg.getContent().indexOf(MID_FIND_LEFT));
return !str.contains("%") && !str.contains("Waiting");
}
private boolean isBlackWord(String msg) {
msg = msg.toLowerCase();
for (String s : Constant.MidjourneyBlackWord) {
if (msg.contains(s.toLowerCase())) {
return true;
}
}
return false;
}
private void sendSensitive(MidjourneyLog midjourneyLog) {
String wxid = memberService.selectWxidById(midjourneyLog.getMemberId());
midjourneyLogService.updateSensitive(midjourneyLog);
weChatBiz.sendTextMsg(wxid, "【違規(guī)提示】輸入內(nèi)容包含違禁詞,依法進(jìn)行屏蔽。", midjourneyLog.getChannel());
}
/**
* 審核不通過通知用戶
*/
private void sendSensitive(MidjourneyLog midjourneyLog, BaiduTextCensor censor) {
String reason = Joiner.on("、")
.join(Safes.of(censor.getData()).stream()
.map(BaiduTextCensorData::getMsg)
.collect(Collectors.toList()));
reason = Strings.isEmpty(reason) ? "包含敏感信息" : reason;
String fullText = "【違規(guī)提示】輸入內(nèi)容因 " + reason + " ,依法進(jìn)行屏蔽。(百度提供審核能力)";
String wxid = memberService.selectWxidById(midjourneyLog.getMemberId());
midjourneyLogService.updateSensitive(midjourneyLog);
weChatBiz.sendTextMsg(wxid, fullText, midjourneyLog.getChannel());
}
public List<MidMsg> readNowList(RoomInfo roomInfo, Discord discord) {
OkHttpClient client = new OkHttpClient().newBuilder()
.build();
Request request = new Request.Builder()
.url("https://discord.com/api/v9/channels/" + roomInfo.getDiscordChannelId() + "/messages?limit=50")
.get()
.addHeader("authority", "discord.com")
.addHeader("accept", "*/*")
.addHeader("accept-language", "zh-CN,zh;q=0.9,en;q=0.8,en-GB;q=0.7,en-US;q=0.6")
.addHeader("authorization", discord.getAuthorization())
.addHeader("cache-control", "no-cache")
.addHeader("cookie", discord.getCookie())
.addHeader("pragma", "no-cache")
.addHeader("referer", "https://discord.com/channels/" + roomInfo.getDiscordGuildId() +
"/" + roomInfo.getDiscordChannelId())
.addHeader("sec-ch-ua", "\"Not_A Brand\";v=\"99\", \"Microsoft Edge\";v=\"109\", \"Chromium\";v=\"109\"")
.addHeader("sec-ch-ua-mobile", "?0")
.addHeader("sec-ch-ua-platform", "\"Windows\"")
.addHeader("sec-fetch-dest", "empty")
.addHeader("sec-fetch-mode", "cors")
.addHeader("sec-fetch-site", "same-origin")
.addHeader("user-agent", "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/109.0.0.0 Safari/537.36 Edg/109.0.1518.70")
.addHeader("x-debug-options", "bugReporterEnabled")
.addHeader("x-discord-locale", "zh-CN")
.addHeader("x-super-properties", discord.getSuperProperties())
.build();
try {
Response response = client.newCall(request).execute();
String string = Objects.requireNonNull(response.body()).string();
response.close();
return JSON.parseArray(string, MidMsg.class);
} catch (Throwable t) {
log.error("[發(fā)生意外 讀取消息失敗] room: {}", roomInfo);
}
return Lists.newArrayList();
}
@SneakyThrows
public boolean sendMsg(String msg, RoomInfo roomInfo) {
Discord discord = discordService.findById(roomInfo.getDiscordId());
bigDecimal = bigDecimal.add(new BigDecimal(1000));
OkHttpClient client = new OkHttpClient().newBuilder()
.build();
RequestBody body = new MultipartBody.Builder().setType(MultipartBody.FORM)
.addFormDataPart("payload_json", "{\"type\":2,\"application_id\":\"936929561302675456\"," +
"\"guild_id\":\"" + roomInfo.getDiscordGuildId() + "\"," +
"\"channel_id\":\"" + roomInfo.getDiscordChannelId() + "\"," +
"\"session_id\":\"" + discord.getSessionId() + "\"," +
"\"data\":{\"version\":\"1077969938624553050\"," +
"\"id\":\"938956540159881230\"," +
"\"name\":\"imagine\"," +
"\"type\":1,\"options\":[" +
"{\"type\":3,\"name\":\"prompt\"," +
"\"value\":\"" + TextUtil.cleanString(msg) + "\"}]," +
"\"application_command\":" +
"{\"id\":\"938956540159881230\",\"application_id\":\"936929561302675456\",\"version\":" +
"\"1077969938624553050\",\"default_member_permissions\":null,\"type\":1,\"nsfw\":false," +
"\"name\":\"imagine\",\"description\":\"Create images with Midjourney\",\"dm_permission\":true," +
"\"contexts\":null,\"options\":[{\"type\":3,\"name\":\"prompt\"," +
"\"description\":\"The prompt to imagine\",\"required\":true}]}," +
"\"attachments\":[]},\"nonce\":\"" + bigDecimal.toString() + "\"} ")
.build();
Request request = new Request.Builder()
.url("https://discord.com/api/v9/interactions")
.method("POST", body)
.addHeader("authority", "discord.com")
.addHeader("accept", "*/*")
.addHeader("accept-language", "zh-CN,zh;q=0.9,en;q=0.8,en-GB;q=0.7,en-US;q=0.6")
.addHeader("authorization", discord.getAuthorization())
.addHeader("cache-control", "no-cache")
.addHeader("cookie", discord.getCookie())
.addHeader("origin", "https://discord.com")
.addHeader("pragma", "no-cache")
.addHeader("referer", "https://discord.com/channels/" + roomInfo.getDiscordGuildId() +
"/" + roomInfo.getDiscordChannelId())
.addHeader("sec-ch-ua", "\"Not_A Brand\";v=\"99\", \"Microsoft Edge\";v=\"109\", \"Chromium\";v=\"109\"")
.addHeader("sec-ch-ua-mobile", "?0")
.addHeader("sec-ch-ua-platform", "\"Windows\"")
.addHeader("sec-fetch-dest", "empty")
.addHeader("sec-fetch-mode", "cors")
.addHeader("sec-fetch-site", "same-origin")
.addHeader("user-agent", "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/109.0.0.0 Safari/537.36 Edg/109.0.1518.70")
.addHeader("x-debug-options", "bugReporterEnabled")
.addHeader("x-discord-locale", "zh-CN")
.addHeader("x-super-properties", discord.getSuperProperties())
.build();
Response response = client.newCall(request).execute();
if (response.code() == 204) {
roomInfoService.addOnce(roomInfo);
response.close();
return true;
}
response.close();
log.info("[midjourney發(fā)消息失敗] {}", response.code());
return false;
}
}
MidjourneyLogService
package com.example.midjourney.service;
import com.example.midjourney.bean.pojo.MidjourneyLog;
import com.example.midjourney.bean.pojo.RoomInfo;
import java.util.List;
public interface MidjourneyLogService {
MidjourneyLog findById(Long id);
MidjourneyLog findLastNormalLog(Integer memberId);
MidjourneyLog findLastNormalOrIterative(Integer memberId);
void updateRoom(MidjourneyLog midjourneyLog, RoomInfo roomInfo);
List<MidjourneyLog> selectAllDoing();
void updateFail(MidjourneyLog midjourneyLog);
void updateSensitive(MidjourneyLog midjourneyLog);
void updatePrompt(MidjourneyLog midjourneyLog, String prompt);
void updateFinish(MidjourneyLog midjourey);
int selectRoomOnUse(Integer id);
}
MidjourneyLogServiceImpl
package com.example.midjourney.service.impl;
import com.example.midjourney.bean.pojo.MidjourneyLog;
import com.example.midjourney.bean.pojo.RoomInfo;
import com.example.midjourney.mapper.MidjourneyLogMapper;
import com.example.midjourney.service.MidjourneyLogService;
import com.example.midjourney.util.Safes;
import org.springframework.stereotype.Service;
import javax.annotation.Resource;
import java.util.List;
@Service
public class MidjourneyLogServiceImpl implements MidjourneyLogService {
@Resource
private MidjourneyLogMapper midjourneyLogMapper;
@Override
public MidjourneyLog findById(Long id) {
return midjourneyLogMapper.selectByPrimaryKey(id);
}
@Override
public MidjourneyLog findLastNormalLog(Integer memberId) {
return midjourneyLogMapper.findLastNormalLog(memberId);
}
@Override
public MidjourneyLog findLastNormalOrIterative(Integer memberId) {
return midjourneyLogMapper.findLastNormalOrIterative(memberId);
}
@Override
public void updateRoom(MidjourneyLog midjourneyLog, RoomInfo roomInfo) {
midjourneyLog.setRoomId(roomInfo.getId());
midjourneyLogMapper.updateByPrimaryKeySelective(midjourneyLog);
}
@Override
public List<MidjourneyLog> selectAllDoing() {
MidjourneyLog midjourneyLog = new MidjourneyLog();
midjourneyLog.setStatus(0);
return Safes.of(midjourneyLogMapper.select(midjourneyLog));
}
@Override
public void updateFail(MidjourneyLog midjourneyLog) {
midjourneyLog.setStatus(500);
midjourneyLogMapper.updateByPrimaryKeySelective(midjourneyLog);
}
@Override
public void updateSensitive(MidjourneyLog midjourneyLog) {
midjourneyLog.setStatus(-1);
midjourneyLogMapper.updateByPrimaryKeySelective(midjourneyLog);
}
@Override
public void updatePrompt(MidjourneyLog midjourneyLog, String prompt) {
midjourneyLog.setPrompt(prompt);
midjourneyLogMapper.updateByPrimaryKeySelective(midjourneyLog);
}
@Override
public void updateFinish(MidjourneyLog midjourey) {
midjourey.setStatus(1);
midjourneyLogMapper.updateByPrimaryKeySelective(midjourey);
}
@Override
public int selectRoomOnUse(Integer id) {
return midjourneyLogMapper.selectRoomOnUse(id);
}
}
MidjourneyLogMapper?
這里用了通用mapper插件
package com.example.midjourney.mapper;
import com.example.midjourney.bean.pojo.MidjourneyLog;
import org.apache.ibatis.annotations.Param;
import org.apache.ibatis.annotations.Select;
import tk.mybatis.mapper.common.Mapper;
public interface MidjourneyLogMapper extends Mapper<MidjourneyLog> {
String COLUMN = " id, member_id AS memberId, prompt, channel, type, " +
"status, img_file AS imgFile, room_id AS roomId ";
@Select("SELECT " + COLUMN + " FROM midjourney_log WHERE member_id = #{memberId} AND type = 0 ORDER BY id DESC LIMIT 1")
MidjourneyLog findLastNormalLog(@Param("memberId") Integer memberId);
@Select("SELECT " + COLUMN + " FROM midjourney_log WHERE member_id = #{memberId} AND (type = 0 OR type = 2)" +
" ORDER BY id DESC LIMIT 1")
MidjourneyLog findLastNormalOrIterative(Integer memberId);
@Select("SELECT COUNT(*) AS count FROM midjourney_log WHERE room_id = #{id} AND status = 0")
Integer selectRoomOnUse(@Param("id") Integer id);
}
Constant
常量類可以根據(jù)需要自定調(diào)整敏感詞
敏感詞寫上審核不過,大家自己想想腦補(bǔ)下吧,各種不好的詞都往那個(gè)敏感詞List里面自己加吧!文章來源:http://www.zghlxwxcb.cn/news/detail-488541.html
文章來源地址http://www.zghlxwxcb.cn/news/detail-488541.html
package com.example.midjourney.contant;
import com.example.midjourney.bean.UserInfo;
import com.example.midjourney.biz.WeChatBiz;
import com.example.midjourney.util.BaiduUtil;
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
public class Constant {
public static ExecutorService threadPool = Executors.newFixedThreadPool(20);
public static Map<String, UserInfo> imgWordUserMap = Maps.newConcurrentMap();
public static String MID_JOURNEY_HEAD = "**";
public static String MID_FIND_LEFT = "** - <";
public static String FILE_PATH = "D:\\000img\\";
public static String CHATGPT = "chatgpt";
public static String MIDJOURNEY = "midjourney";
public static final String INSUFFICIENT = "insufficient_quota";
public static Map<String, String> WX_TOKEN_CHANNEL = Maps.newHashMap();
public static Map<String, String> WX_TOKEN_MAP = Maps.newHashMap();
public static String BAIDU_TOKEN = BaiduUtil.queryBaiduToken();
public static Map<String, String> CHANNEL_CALL_BACK = Maps.newHashMap();
/**
* 最大等待時(shí)間15分鐘
*/
public static long MAX_WAIT_TIME = 1000 * 60 * 15;
public static List<String> MidjourneyBlackWord = Lists.newArrayList("寫了審核不過,大家自己發(fā)揮想象吧...");
}
到了這里,關(guān)于Java調(diào)用Midjourney進(jìn)行AI畫圖原生版抓包實(shí)現(xiàn)支持中文的文章就介紹完了。如果您還想了解更多內(nèi)容,請?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!