createImgHandle.js 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407
  1. import {
  2. MessageBox
  3. } from 'mint-ui';
  4. import {
  5. Toast
  6. } from 'mint-ui';
  7. export default {
  8. data() {
  9. return {
  10. timeOut: 50000, //超时时间
  11. subType: 0, //0 首次 1 再次
  12. aiPicId: "", // 图生图任务ID
  13. count: 0, //轮询次数
  14. randomTimer: null,
  15. timer: null,
  16. currentImg: null, //当次生成图的结果
  17. startCreate:false, //是否开始生成AI图了
  18. // myloading: false, //加载中
  19. loadingMsg: '', //加载中的话术
  20. reqList: [{
  21. model: 'batouresearch/sdxl-controlnet-lora',
  22. level: '5',
  23. aiPicId: '',
  24. resultImg: '',
  25. }],
  26. reqListReset: [{
  27. model: 'deployments/elabgroup/elab-sdxl-controlnet-lora',
  28. level: '3',
  29. aiPicId: '',
  30. resultImg: '',
  31. }, {
  32. model: 'batouresearch/sdxl-controlnet-lora',
  33. level: '5',
  34. aiPicId: '',
  35. resultImg: '',
  36. }],
  37. createTabIndex:0, //生成AI图时记录下当前AI图的类型序号
  38. createOptionIndex:0,//生成AI图时记录下当前AI图的选项序号
  39. paramObj:null, //启动参数-外界传进来的
  40. }
  41. },
  42. methods: {
  43. //前置逻辑
  44. async prevHandle(parmas) {
  45. //不是首次请求,则无需前置判断 用户上传的也不需要前置处理
  46. if (this.subType != 0) {
  47. return '';
  48. }
  49. return new Promise(async (resolve, reject) => {
  50. let _data = JSON.parse(JSON.stringify(parmas))
  51. _data.keyword = "zhiqite";
  52. _data.model = "controlnet";
  53. delete _data.webhook;
  54. let res = await requestConfig("img2img_local", _data);
  55. if (res.success) {
  56. if (res.success && res.single) {
  57. let resultImg = res.single;
  58. resolve(resultImg);
  59. } else {
  60. resolve('');
  61. }
  62. } else {
  63. resolve('');
  64. }
  65. })
  66. },
  67. //随机处理
  68. randomHandle(resultImg) {
  69. if (this.timer || !resultImg) {
  70. return false;
  71. }
  72. let self = this;
  73. var count = 1;
  74. var process = 0; //进度
  75. var randomNum = Math.floor(Math.random() * 4 + 5); //5-8随机数
  76. this.randomTimer = setInterval(function() {
  77. process = parseInt(count * 100 / (randomNum));
  78. if (process >= 100) {
  79. process = 99;
  80. }
  81. if (count < randomNum) { //没有到上限
  82. // self.myloading = true;
  83. self.loadingMsg = '生成中…' + process + '%';
  84. } else {
  85. // self.myloading = false;
  86. this.loadingMsg = '生成中…100%';
  87. self.resultHandle(resultImg);
  88. }
  89. count = count + 1;
  90. }, 1000);
  91. },
  92. //开始图生图流程
  93. async startServer(obj) {
  94. if (!obj || !obj.imgUrl || !obj.prompt || !obj.negativePrompt) {
  95. Toast({
  96. message: '数据不全',
  97. });
  98. return false
  99. }
  100. // if(this.$parent.pvCurPageName!="room_show"){//说明用户切换页面了
  101. // console.warn("***用户已经退出页面***")
  102. // return false;
  103. // }
  104. let imgUrl = obj.imgUrl;
  105. let subType = this.subType;
  106. let session_hash = Date.now();
  107. let prompt = obj.prompt;
  108. let noPromot = obj.negativePrompt;
  109. // let unit = 768 / this.screenWidth;
  110. // this.imageWidth = parseInt((this.screenWidth * unit).toFixed());
  111. // this.imageHeight = parseInt((this.$parent.canvasHeight * unit).toFixed());
  112. if(this.startCreate){
  113. return false
  114. }
  115. this.startCreate = true;
  116. this.paramObj = obj;
  117. this.loadingMsg = '启动中';
  118. this.createTabIndex = obj.tabIndex;
  119. this.createOptionIndex = obj.optionIndex;
  120. var parmas = {
  121. negativePrompt: noPromot,
  122. prompt: prompt,
  123. "batchSize": 1,
  124. brandId: $config.brandId,
  125. height: 512,
  126. width: 768,
  127. "moduleType": "AI_Biography",
  128. "steps": 20,
  129. "sampler": "DDIM",
  130. "controlNetSessionHash": session_hash,
  131. "cfgScale": 12,
  132. "denoising": 0.9,
  133. image: imgUrl,
  134. // styleImage:imgUrl,
  135. // keyword: "zhiqite",
  136. // model: 'controlnet',
  137. keyword: "replicate",
  138. model: 'lucataco/ssd-1b',
  139. };
  140. let result = await this.prevHandle(parmas);
  141. console.warn("***prevHandle***", result)
  142. if (result && result.length > 0) { //匹配到了,则随机处理
  143. this.randomHandle(result)
  144. return false;
  145. } else {
  146. this.otherHandle(parmas); //发送其他AI请求
  147. let res = await requestConfig("generateTaskImgToImgForAliyun", parmas);
  148. console.log("图生图结果:", res);
  149. let that = this;
  150. if (res.success && res.single) {
  151. this.aiPicId = res.single;
  152. if (subType == 0) { //首次
  153. this.reqList[0].aiPicId = this.aiPicId;
  154. } else { //重试
  155. this.reqListReset[0].aiPicId = this.aiPicId;
  156. }
  157. if (this.aiPicId) {
  158. this.startInterval(); //开始轮询AI生成图的结果
  159. } else {
  160. this.stopInterval()
  161. }
  162. } else {
  163. this.stopInterval()
  164. // this.showToast("渲染失败,请重试")
  165. }
  166. }
  167. },
  168. stopInterval() {
  169. if (this.randomTimer) {
  170. clearInterval(this.randomTimer);
  171. this.randomTimer = null;
  172. }
  173. if (this.timer) {
  174. // clearInterval(this.timer);
  175. this.timer = null;
  176. }
  177. if (this.outTimer) {
  178. clearTimeout(this.outTimer)
  179. this.outTimer = null
  180. }
  181. this.subType = 0;
  182. this.reqList.forEach(it => {
  183. it.aiPicId = '';
  184. it.resultImg = '';
  185. })
  186. this.reqListReset.forEach(it => {
  187. it.aiPicId = '';
  188. it.resultImg = '';
  189. })
  190. // this.myloading = false;
  191. // this.aiFlag = false;
  192. this.startCreate = false;//释放标志
  193. },
  194. //从请求接口队列里面挨个发出请求
  195. otherHandle(parmas) {
  196. let reqList = [];
  197. if (this.subType == 0) { //首次
  198. reqList = this.reqList;
  199. } else { //重试
  200. reqList = this.reqListReset;
  201. }
  202. reqList.forEach(async (it, index) => {
  203. let _data = JSON.parse(JSON.stringify(parmas));
  204. if (index > 0) {
  205. _data.model = it.model;
  206. let res = await requestConfig("generateTaskImgToImgForAliyun", _data);
  207. if (res.success) {
  208. console.log('生成结果123:', res);
  209. it.aiPicId = res.single || '';
  210. }
  211. }
  212. })
  213. },
  214. //开始生成AI图的轮询,每隔1s轮询一次
  215. startInterval() {
  216. if (this.timer) {
  217. return false;
  218. }
  219. let self = this;
  220. this.count = 1; //轮询次数
  221. var random = 0;
  222. this.currentImg = false; //当次生成图还没有结果
  223. this.timer = 1; //标志进入了轮询流程
  224. this.getOutPicture(); //不在轮询,而是等结果
  225. this.setOutTimer(); //设置超时逻辑
  226. },
  227. //设置一个超时逻辑,到底指定时间后停止轮询,当前是90s
  228. setOutTimer() {
  229. if (this.outTimer) {
  230. clearTimeout(this.outTimer)
  231. this.outTimer = null
  232. }
  233. var self = this;
  234. this.outTimer = setTimeout(function() {
  235. if (self.timer) {
  236. let hasResult = false;
  237. let reqList = [];
  238. if (self.subType == 0) { //首次
  239. reqList = self.reqList;
  240. } else { //重试
  241. reqList = self.reqListReset;
  242. }
  243. reqList.some((item, index) => {
  244. if (item.resultImg) {
  245. hasResult = true;
  246. self.resultHandle(item.resultImg)
  247. }
  248. });
  249. console.warn("***hasResult***", hasResult)
  250. if (!hasResult) { //没有结果
  251. self.stopInterval(); //停止轮询
  252. MessageBox.confirm('', {
  253. title: '提示',
  254. message: '当前AI使用火爆,请继续尝试?',
  255. showCancelButton: true,
  256. confirmButtonText: '继续尝试',
  257. cancelButtonText: '取消等待',
  258. }).then(action => {
  259. console.warn("***MessageBox-action***", action)
  260. if (action == 'confirm') {
  261. self.confirmHandle(1);
  262. }
  263. }).catch(err => {
  264. console.warn("***MessageBox-err***", err)
  265. if (err == 'cancel') {
  266. self.cancelHandle();
  267. }
  268. });
  269. }
  270. }
  271. clearTimeout(self.outTimer);
  272. self.outTimer = null
  273. }, this.timeOut);
  274. },
  275. confirmHandle(type) {
  276. this.subType = type || 0;
  277. this.startServer(this.paramObj);
  278. },
  279. cancelHandle() {
  280. this.subType = 0;
  281. },
  282. //获取生成图结果
  283. getOutPicture() {
  284. if (this.timer == null) {
  285. console.warn("***当前轮询已经结束了1***")
  286. return false;
  287. }
  288. let reqList = [];
  289. if (this.subType == 0) { //首次
  290. reqList = this.reqList;
  291. } else { //重试
  292. reqList = this.reqListReset;
  293. }
  294. reqList.forEach((item, index) => {
  295. this.singleHandle(item)
  296. });
  297. },
  298. //发出获取结果请求获取AI生成结果
  299. async singleHandle(model) {
  300. if (!model || !model.aiPicId) {
  301. return false;
  302. }
  303. var parmas = {
  304. id: model.aiPicId,
  305. };
  306. let res = await requestConfig("getPredictions", parmas);
  307. if (res.success && res.single) {
  308. if (this.currentImg) { //当前已经有生成图了
  309. console.warn("***当前已经有最高级生成图了***")
  310. return false;
  311. }
  312. if (this.timer == null) {
  313. console.warn("***当前轮询已经结束了***")
  314. return false;
  315. }
  316. if (res.single.status == 'succeeded' && res.single.output) {
  317. model.resultImg = res.single.output; //把生成图结果记录到请求接口对象里面
  318. if (model.level == '5') { //最高级的生成图,可以直接用
  319. this.currentImg = true;
  320. setTimeout(() => {
  321. this.resultHandle(res.single.output)
  322. }, 1500)
  323. }
  324. console.warn("***有生成图了***", model)
  325. }
  326. if (model.level == '5') { //最高优先级的接口返回的结果
  327. this.processHandle(res.single);
  328. }
  329. } else if (!res.success && model.level == '5') { //最高优先级的接口返回失败
  330. this.stopInterval(); //停止轮询
  331. // this.showToast("渲染失败,请重试")
  332. }
  333. },
  334. //进度处理
  335. processHandle(single) {
  336. console.warn("***single***", single.status, single.progress, this.count, single);
  337. let self = this;
  338. if (single.status == 'starting') { //启动中的逻辑
  339. if (this.count >= 20) {
  340. this.stopInterval(); //停止轮询
  341. MessageBox.confirm('', {
  342. title: '提示',
  343. message: 'AI开了小差,是否重新生成?',
  344. showCancelButton: true,
  345. confirmButtonText: '继续生成',
  346. cancelButtonText: '放弃生成',
  347. }).then(action => {
  348. console.warn("***MessageBox-action***", action)
  349. if (action == 'confirm') { //继续生成
  350. this.confirmHandle(0);
  351. }
  352. }).catch(err => {
  353. if (err == 'cancel') {
  354. this.cancelHandle();
  355. }
  356. });
  357. } else {
  358. // this.myloading = true;
  359. this.loadingMsg = '启动中';
  360. }
  361. this.count = this.count + 1;
  362. setTimeout(()=>{
  363. this.getOutPicture();
  364. },10000)
  365. } else if (single.status == 'processing') {
  366. let random = single.progress || 0;
  367. if (random >= 100) {
  368. random = 99;
  369. }
  370. // this.myloading = true;
  371. this.loadingMsg = '生成中…' + parseInt(random) + '%';
  372. setTimeout(()=>{
  373. this.getOutPicture();
  374. },10000)
  375. } else if (single.status == 'succeeded') {
  376. // this.myloading = true;
  377. this.loadingMsg = '生成中…100%';
  378. }
  379. },
  380. //返回结果处理
  381. resultHandle(resultImg) {
  382. this.currentImg = true;
  383. this.aiImage = resultImg;
  384. this.stopInterval();
  385. let newImage = resultImg;
  386. // let aiStyleName = this.styleList[this.curStyleIndex].styleName;
  387. let _data = {
  388. imageUrl: newImage,
  389. checked: false,
  390. type:'AI',//表示AI生成的
  391. }
  392. // this.aiImagesList.push(_data);
  393. this.paramObj = null;//生成成功后,清楚外界传入参数
  394. // this.tabData[this.createTabIndex].options[this.createOptionIndex].hardboundEffect.push(_data);
  395. if (this.createTabIndex == this.tabIndex) {
  396. let len = this.aiImagesList.length;
  397. this.aiImagesList.push(_data);
  398. setTimeout(() => {
  399. this.$refs.carousel.setActiveItem(len); //切换到最后一张
  400. }, 200);
  401. }else{
  402. this.tabData[this.createTabIndex].options[this.createOptionIndex].hardboundEffect.push(_data);
  403. }
  404. // this.subDataList[this.tabIndex].hardboundEffect.push(_data);//把数据同步到对应的待提交对象中
  405. },
  406. }
  407. }