makeDetail.vue 27 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971
  1. <template>
  2. <view class="page">
  3. <!-- 引入FontAwesome -->
  4. <view>
  5. <link rel="stylesheet"
  6. href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/4.7.0/css/font-awesome.min.css">
  7. </view>
  8. <!-- 顶部导航栏 -->
  9. <view class="custom-navbar">
  10. <view class="navbar-left" @click="goBack">
  11. <text class="fa fa-angle-left"></text>
  12. </view>
  13. <view class="navbar-center">
  14. <view class="navbar-title">
  15. <image class="navbar-avatar" :src="myinfo.avator" mode="aspectFill"></image>
  16. <text class="navbar-text">{{ myinfo.nickname }}</text>
  17. <text class="navbar-badge" v-if="myinfo.is_vip > 0">VIP</text>
  18. <!-- <image style=" width: 34rpx; height: 34rpx;" v-if="myinfo.is_vip > 0" src="@/static/me/icon-vip1.png" mode=""></image> -->
  19. </view>
  20. </view>
  21. <view class="navbar-right" @click="showActionSheet">
  22. <text class="fa fa-ellipsis-h"></text>
  23. </view>
  24. </view>
  25. <!-- 灵感 -->
  26. <template v-if="queueDetail.task_type == 1">
  27. <view class="inspiration-content">
  28. <image src="../../static/makedetail/cz_img_zhanshi.png" mode="widthFix"></image>
  29. <image :src="home_image" class="inspirationPictures" mode="widthFix"></image>
  30. </view>
  31. <!-- 内容头图区域 -->
  32. <view class="topUser" ref="ImageBox" v-if="false">
  33. <image :src="home_image" class="home_image" mode="aspectFill"></image>
  34. </view>
  35. <view class="body" v-if="false">
  36. <view class="article-header">
  37. <text class="title">{{ queueDetail.title }}</text>
  38. <!-- 显示第一个像素的颜色 -->
  39. <view class="pixel-color" v-if="pixelColor">
  40. <view class="color-box"
  41. :style="{ backgroundColor: `rgb(${pixelColor.r}, ${pixelColor.g}, ${pixelColor.b})` }">
  42. </view>
  43. <view class="color-info">
  44. <text class="color-text">左上角像素RGB值:</text>
  45. <text class="color-value">R:{{ pixelColor.r }} G:{{ pixelColor.g }} B:{{ pixelColor.b
  46. }}</text>
  47. <text class="color-hex">HEX: {{ rgbToHex(pixelColor.r, pixelColor.g, pixelColor.b) }}</text>
  48. </view>
  49. </view>
  50. <!-- 颜色加载中状态 -->
  51. <view class="pixel-color loading"
  52. v-else-if="home_image && home_image !== '../../static/home/avator.png'">
  53. <view class="color-box loading"></view>
  54. <!-- <text class="color-text">正在获取像素颜色...</text> -->
  55. </view>
  56. <view class="meta-info">
  57. <view class="meta-item">
  58. <text class="fa fa-clock-o"></text>
  59. <text class="meta-text">{{ queueDetail.create_time }}</text>
  60. </view>
  61. <view class="meta-item">
  62. <text class="fa fa-tag"></text>
  63. <text class="meta-text">{{ queueDetail.task_type == 1 ? '灵感创作' : '音乐创作' }}</text>
  64. </view>
  65. <view class="meta-item">
  66. <text class="fa fa-circle" :style="getStatusStyle(queueDetail.status)"></text>
  67. <text class="meta-text">{{ getStatusText(queueDetail.status) }}</text>
  68. </view>
  69. </view>
  70. </view>
  71. <view class="divider"></view>
  72. <view class="article-content">
  73. <!-- 灵感创作显示description -->
  74. <view v-if="queueDetail.task_type == 1">
  75. <text class="content">{{ queueDetail.description }}</text>
  76. <!-- 显示创作详情 -->
  77. <view class="creation-details">
  78. <view class="detail-item" v-if="queueDetail.action">
  79. <text class="detail-label">行为动作:</text>
  80. <text class="detail-value">{{ queueDetail.action }}</text>
  81. </view>
  82. <view class="detail-item" v-if="queueDetail.environment">
  83. <text class="detail-label">主体环境:</text>
  84. <text class="detail-value">{{ queueDetail.environment }}</text>
  85. </view>
  86. <view class="detail-item" v-if="queueDetail.subject">
  87. <text class="detail-label">主体形象:</text>
  88. <text class="detail-value">{{ queueDetail.subject }}</text>
  89. </view>
  90. <view class="detail-item" v-if="queueDetail.style">
  91. <text class="detail-label">参考风格:</text>
  92. <text class="detail-value">{{ queueDetail.style }}</text>
  93. </view>
  94. </view>
  95. </view>
  96. <!-- 音乐创作显示lyrics -->
  97. <view v-else-if="queueDetail.task_type == 2">
  98. <text class="content">{{ queueDetail.lyrics }}</text>
  99. <!-- 音乐创作显示歌曲名称 -->
  100. <view class="creation-details">
  101. <view class="detail-item" v-if="queueDetail.song_name">
  102. <text class="detail-label">歌曲名称:</text>
  103. <text class="detail-value">{{ queueDetail.song_name }}</text>
  104. </view>
  105. </view>
  106. </view>
  107. <!-- 显示状态信息 -->
  108. <view class="status-info" v-if="queueDetail.status < 4">
  109. <view class="queue-info">
  110. <text class="queue-text">队列位置:
  111. {{ queueDetail.queue_position }}/{{ queueDetail.all_position }}</text>
  112. <view class="progress-bar">
  113. <view class="progress-fill" :style="{ width: getProgressWidth() }"></view>
  114. </view>
  115. </view>
  116. </view>
  117. <!-- 显示错误信息 -->
  118. <view class="error-message" v-if="queueDetail.status == 3">
  119. <text class="error-text">{{ queueDetail.error_msg }}</text>
  120. </view>
  121. </view>
  122. </view>
  123. </template>
  124. <!-- 音乐 -->
  125. <template v-else-if="queueDetail.task_type == 2">
  126. <!-- 内容头图区域 -->
  127. <view class="topUser" ref="ImageBox">
  128. <image :src="home_image" class="home_image" mode="aspectFill"></image>
  129. <!-- 图片指示器 -->
  130. <!-- <view class="image-indicator" v-if="image_list.length > 1">
  131. <text>{{ selImg + 1 }}/{{ image_list.length }}</text>
  132. </view> -->
  133. <!-- 音乐类型时显示歌词 -->
  134. <view class="lyrics-overlay" v-if="queueDetail.task_type == 2" @mousedown="startDrag"
  135. @mouseup="stopDrag" @mousemove="drag">
  136. <text class="lyrics-text" ref="lyricsText" :style="{ transform: `translateY(${offsetY}px)` }">{{
  137. queueDetail.description }}</text>
  138. </view>
  139. <!-- 音乐类型且状态为9时显示播放按钮 -->
  140. <view class="play-button" v-if="queueDetail.task_type == 2 && queueDetail.status >= 9"
  141. @click="toggleAudio">
  142. <text class="fa" :class="isPlaying ? 'fa-pause' : 'fa-play'"></text>
  143. </view>
  144. </view>
  145. <view class="body">
  146. <view class="article-header">
  147. <text class="title">{{ queueDetail.title }}</text>
  148. <!-- 显示第一个像素的颜色 -->
  149. <view class="pixel-color" v-if="pixelColor">
  150. <view class="color-box"
  151. :style="{ backgroundColor: `rgb(${pixelColor.r}, ${pixelColor.g}, ${pixelColor.b})` }">
  152. </view>
  153. <view class="color-info">
  154. <text class="color-text">左上角像素RGB值:</text>
  155. <text class="color-value">R:{{ pixelColor.r }} G:{{ pixelColor.g }} B:{{ pixelColor.b
  156. }}</text>
  157. <text class="color-hex">HEX: {{ rgbToHex(pixelColor.r, pixelColor.g, pixelColor.b) }}</text>
  158. </view>
  159. </view>
  160. <!-- 颜色加载中状态 -->
  161. <view class="pixel-color loading"
  162. v-else-if="home_image && home_image !== '../../static/home/avator.png'">
  163. <view class="color-box loading"></view>
  164. <!-- <text class="color-text">正在获取像素颜色...</text> -->
  165. </view>
  166. <view class="meta-info">
  167. <view class="meta-item">
  168. <text class="fa fa-clock-o"></text>
  169. <text class="meta-text">{{ queueDetail.create_time }}</text>
  170. </view>
  171. <view class="meta-item">
  172. <text class="fa fa-tag"></text>
  173. <text class="meta-text">{{ queueDetail.task_type == 1 ? '灵感创作' : '音乐创作' }}</text>
  174. </view>
  175. <view class="meta-item">
  176. <text class="fa fa-circle" :style="getStatusStyle(queueDetail.status)"></text>
  177. <text class="meta-text">{{ getStatusText(queueDetail.status) }}</text>
  178. </view>
  179. </view>
  180. </view>
  181. <view class="divider"></view>
  182. <view class="article-content">
  183. <!-- 灵感创作显示description -->
  184. <view v-if="queueDetail.task_type == 1">
  185. <text class="content">{{ queueDetail.description }}</text>
  186. <!-- 显示创作详情 -->
  187. <view class="creation-details">
  188. <view class="detail-item" v-if="queueDetail.action">
  189. <text class="detail-label">行为动作:</text>
  190. <text class="detail-value">{{ queueDetail.action }}</text>
  191. </view>
  192. <view class="detail-item" v-if="queueDetail.environment">
  193. <text class="detail-label">主体环境:</text>
  194. <text class="detail-value">{{ queueDetail.environment }}</text>
  195. </view>
  196. <view class="detail-item" v-if="queueDetail.subject">
  197. <text class="detail-label">主体形象:</text>
  198. <text class="detail-value">{{ queueDetail.subject }}</text>
  199. </view>
  200. <view class="detail-item" v-if="queueDetail.style">
  201. <text class="detail-label">参考风格:</text>
  202. <text class="detail-value">{{ queueDetail.style }}</text>
  203. </view>
  204. </view>
  205. </view>
  206. <!-- 音乐创作显示lyrics -->
  207. <view v-else-if="queueDetail.task_type == 2">
  208. <text class="content">{{ queueDetail.lyrics }}</text>
  209. <!-- 音乐创作显示歌曲名称 -->
  210. <view class="creation-details">
  211. <view class="detail-item" v-if="queueDetail.song_name">
  212. <text class="detail-label">歌曲名称:</text>
  213. <text class="detail-value">{{ queueDetail.song_name }}</text>
  214. </view>
  215. </view>
  216. </view>
  217. <!-- 显示状态信息 -->
  218. <view class="status-info" v-if="queueDetail.status < 4">
  219. <view class="queue-info">
  220. <text class="queue-text">队列位置:
  221. {{ queueDetail.queue_position }}/{{ queueDetail.all_position }}</text>
  222. <view class="progress-bar">
  223. <view class="progress-fill" :style="{ width: getProgressWidth() }"></view>
  224. </view>
  225. </view>
  226. </view>
  227. <!-- 显示错误信息 -->
  228. <view class="error-message" v-if="queueDetail.status == 3">
  229. <text class="error-text">{{ queueDetail.error_msg }}</text>
  230. </view>
  231. </view>
  232. </view>
  233. </template>
  234. <!-- 作品描述 -->
  235. <view class="workDescription">
  236. <view class="workDescription-title">
  237. <view>创作描述 </view>
  238. <image class="pen" src="@/static/icon/wd_icon_bianji.png"></image>
  239. </view>
  240. <view class="workDescription-content">
  241. {{ queueDetail.lyrics ||queueDetail.description}}
  242. </view>
  243. </view>
  244. <!-- 作品描述 -->
  245. <view class="workDescription" v-if="queueDetail.content">
  246. <view class="workDescription-title">
  247. <view>创作描述 </view>
  248. <image class="pen" src="@/static/icon/wd_icon_bianji.png"></image>
  249. </view>
  250. <view class="workDescription-content">
  251. {{ noteContent}}
  252. </view>
  253. </view>
  254. <view class="thread2"></view>
  255. <!-- 音频元素 -->
  256. <audio id="audioPlayer" :src="queueDetail.result_audio" style="display:none;"></audio>
  257. <!-- 用于处理图片像素的隐藏canvas -->
  258. <canvas canvas-id="pixelCanvas"
  259. style="width: 10px; height: 10px; position: absolute; left: -100px; top: -100px;"></canvas>
  260. <!-- 底部漂浮栏 -->
  261. <view class="floating-bar" v-if="queueDetail.status == 9">
  262. <view class="floating-bar-content">
  263. <view class="add-note-btn" @click="openContentPopUpWindow">
  264. <text>添加说明</text>
  265. </view>
  266. <view class="publish-btn" @click="publishWork">
  267. <text>公布作品</text>
  268. </view>
  269. </view>
  270. </view>
  271. <!-- 添加说明弹窗 -->
  272. <!-- <view class="popup-mask" v-if="showNotePopup" @click="closeAddNotePopup"></view>
  273. <view class="note-popup" v-if="showNotePopup">
  274. <view class="popup-header">
  275. <text class="popup-title">添加说明</text>
  276. </view>
  277. <view class="popup-content">
  278. <textarea class="note-textarea" v-model="noteContent" placeholder="请描述你想添加的内容。"
  279. maxlength="500"></textarea>
  280. <view class="word-count">{{ noteContent.length }}/500</view>
  281. </view>
  282. <view class="popup-footer">
  283. <view class="cancel-btn" @click="closeAddNotePopup">
  284. <text>取消</text>
  285. </view>
  286. <view class="confirm-btn" @click="confirmAddNote">
  287. <text>确认</text>
  288. </view>
  289. </view>
  290. </view> -->
  291. <NicknamePopup title="添加说明" subtitle="" class="openContentPopUpWindow"
  292. ref="openContentPopUpWindow">
  293. <template slot="content">
  294. <uv-textarea v-model="noteContent" maxlength="500" count placeholder="请描述你添加的内容"></uv-textarea>
  295. <view class="btn-box" @click="confirmAddNote">确认</view>
  296. </template>
  297. </NicknamePopup>
  298. </view>
  299. </template>
  300. <script>
  301. import previewImage from '@/components/kxj-previewImage/kxj-previewImage.vue'; //引用插件
  302. import NicknamePopup from '@/components/NicknamePopup/NicknamePopup.vue';
  303. export default {
  304. components: {
  305. previewImage,
  306. NicknamePopup
  307. },
  308. data() {
  309. return {
  310. title: '',
  311. arcID: 0,
  312. selImg: 0,
  313. home_image: '',
  314. myinfo: {},
  315. tag_list: [],
  316. image_list: [],
  317. imgs: [],
  318. descs: [],
  319. isPlaying: false,
  320. audioPlayer: null,
  321. showNotePopup: false,
  322. noteContent: '',
  323. pixelColor: null, // 存储像素颜色值
  324. // 队列详情数据
  325. queueDetail: {
  326. id: 0,
  327. sso_id: 0,
  328. task_type: 1,
  329. title: '',
  330. description: '',
  331. action: '',
  332. environment: '',
  333. subject: '',
  334. style: '',
  335. song_name: '',
  336. lyrics: '',
  337. generate_uuid: '',
  338. result_images: '',
  339. result_audio: '',
  340. queue_position: 0,
  341. status: 1,
  342. generate_status: 1,
  343. points_cost: 0,
  344. error_msg: '',
  345. create_time: '',
  346. update_time: '',
  347. all_position: 0
  348. },
  349. myinfo: {},
  350. offsetY: 0,
  351. isDragging: false,
  352. startY: 0,
  353. initialOffsetY: 0
  354. }
  355. },
  356. onLoad(parms) {
  357. let self = this;
  358. this.arcID = parms.id || 9;
  359. this.getMyInfo();
  360. },
  361. onShow() {
  362. this.loadData();
  363. },
  364. onReady() {
  365. // 获取音频元素
  366. this.audioPlayer = uni.createInnerAudioContext();
  367. this.audioPlayer.onEnded(() => {
  368. this.isPlaying = false;
  369. });
  370. },
  371. onUnload() {
  372. // 页面卸载时停止音频播放
  373. if (this.audioPlayer) {
  374. this.audioPlayer.stop();
  375. this.audioPlayer.destroy();
  376. }
  377. },
  378. mounted() {
  379. },
  380. methods: {
  381. openContentPopUpWindow() {
  382. this.$refs.openContentPopUpWindow.open();
  383. },
  384. closeContentPopUpWindow() {
  385. this.$refs.openContentPopUpWindow.close();
  386. },
  387. // 获取图片第一个像素的RGB值
  388. getImagePixelColor() {
  389. console.log("图片加载完成,准备获取像素颜色");
  390. // 清空之前的颜色值,进入加载状态
  391. this.pixelColor = null;
  392. // 如果是默认图片或空图片,则直接返回
  393. if (!this.home_image || this.home_image === '../../static/home/avator.png') {
  394. console.log("无有效图片,不获取像素颜色");
  395. return;
  396. }
  397. // 使用uni.getImageInfo获取图片信息
  398. uni.getImageInfo({
  399. src: this.home_image,
  400. success: (res) => {
  401. console.log("图片信息:", res);
  402. // 创建临时canvas绘制上下文
  403. const ctx = uni.createCanvasContext('pixelCanvas', this);
  404. // 修改绘制参数,确保只绘制图片左上角的一小块区域
  405. // drawImage(图片路径, 源图片裁剪x, 源图片裁剪y, 源图片裁剪宽度, 源图片裁剪高度, canvas目标x, canvas目标y, canvas目标宽度, canvas目标高度)
  406. // 这里我们只从源图片左上角裁剪10x10的区域,绘制到canvas的左上角
  407. ctx.drawImage(res.path, 0, 0, 10, 10, 0, 0, 10, 10);
  408. ctx.draw(false, () => {
  409. // 绘制完成后,获取像素数据
  410. setTimeout(() => { // 添加短暂延迟确保绘制完成
  411. uni.canvasGetImageData({
  412. canvasId: 'pixelCanvas',
  413. x: 0, // 获取(0,0)位置的像素
  414. y: 0,
  415. width: 1,
  416. height: 1,
  417. success: (res) => {
  418. // 获取像素RGB值
  419. this.pixelColor = {
  420. r: res.data[0],
  421. g: res.data[1],
  422. b: res.data[2],
  423. a: res.data[3]
  424. };
  425. console.log("第一个像素的RGB值:", this
  426. .pixelColor);
  427. },
  428. fail: (err) => {
  429. console.error("获取像素数据失败:", err);
  430. // 显示错误提示
  431. uni.showToast({
  432. title: '获取颜色失败',
  433. icon: 'none',
  434. duration: 2000
  435. });
  436. }
  437. });
  438. }, 100);
  439. });
  440. },
  441. fail: (err) => {
  442. console.error("获取图片信息失败:", err);
  443. // 显示错误提示
  444. uni.showToast({
  445. title: '图片加载失败',
  446. icon: 'none',
  447. duration: 2000
  448. });
  449. }
  450. });
  451. },
  452. // 返回上一页
  453. goBack() {
  454. uni.navigateBack({
  455. delta: 1
  456. });
  457. },
  458. getMyInfo() {
  459. uni.request({
  460. url: this.$apiHost + '/My/getnum',
  461. method: 'GET',
  462. header: {
  463. 'content-type': 'application/json',
  464. 'sign': getApp().globalData.headerSign
  465. },
  466. data: {
  467. uuid: getApp().globalData.uuid
  468. },
  469. success: (res) => {
  470. console.log("获取用户信息:", res.data);
  471. this.myinfo = res.data
  472. }
  473. })
  474. },
  475. selPhoto(item, sel) {
  476. this.selImg = sel;
  477. this.home_image = this.image_list[sel];
  478. },
  479. toArr(imgs) {
  480. let arr = imgs.split("|");
  481. return arr;
  482. },
  483. previewOpen(imgs1, index) {
  484. this.imgs = imgs1.split("|");
  485. setTimeout(() => this.$refs.previewImage.open(index), 0)
  486. // 传入当前选中的图片地址或序号
  487. return; //如需测试和uni原生预览差别可注释这两行
  488. },
  489. // 切换音频播放状态
  490. toggleAudio() {
  491. if (!this.queueDetail.result_audio) return;
  492. if (this.isPlaying) {
  493. this.audioPlayer.pause();
  494. this.isPlaying = false;
  495. } else {
  496. this.audioPlayer.src = this.queueDetail.result_audio;
  497. this.audioPlayer.play();
  498. this.isPlaying = true;
  499. }
  500. },
  501. // 获取状态文本
  502. getStatusText(status) {
  503. const statusMap = {
  504. 1: '排队中',
  505. 2: '生成中',
  506. 3: '生成失败',
  507. 4: '已完成',
  508. 9: '已完成'
  509. };
  510. return statusMap[status] || '未知状态';
  511. },
  512. // 获取状态样式
  513. getStatusStyle(status) {
  514. const colorMap = {
  515. 1: '#ffa500', // 橙色 - 排队中
  516. 2: '#2979ff', // 蓝色 - 生成中
  517. 3: '#ff5151', // 红色 - 生成失败
  518. 4: '#4caf50', // 绿色 - 已完成
  519. 9: '#4caf50' // 绿色 - 已完成
  520. };
  521. return `color: ${colorMap[status] || '#999'}`;
  522. },
  523. // 获取进度条宽度
  524. getProgressWidth() {
  525. if (this.queueDetail.all_position === 0) return '0%';
  526. const progress = (1 - (this.queueDetail.queue_position / this.queueDetail.all_position)) * 100;
  527. return `${progress}%`;
  528. },
  529. // 加载数据
  530. loadData() {
  531. uni.showLoading({
  532. title: '加载中...'
  533. });
  534. let that = this;
  535. uni.request({
  536. url: this.$apiHost + '/WorkAI/getQueueDetail',
  537. data: {
  538. uuid: getApp().globalData.uuid,
  539. id: this.arcID
  540. },
  541. header: {
  542. "content-type": "application/json",
  543. 'sign': getApp().globalData.headerSign
  544. },
  545. success: (res) => {
  546. console.log("队列详情:", res.data);
  547. if (res.data.success === "yes") {
  548. // 更新队列详情
  549. this.queueDetail = res.data.data;
  550. this.noteContent = res.data.data.content;
  551. // 更新图片列表
  552. if (this.queueDetail.result_images && this.queueDetail.result_images !== "") {
  553. this.image_list = this.queueDetail.result_images.split(",");
  554. this.home_image = this.image_list[0];
  555. // 当图片更新后,手动触发获取像素颜色(因为图片可能从缓存加载,不会触发@load事件)
  556. // setTimeout(() => {
  557. // that.getImagePixelColor();
  558. // }, 500);
  559. } else {
  560. this.home_image = "../../static/home/avator.png";
  561. }
  562. // 如果是音频类型,设置音频源
  563. if (this.queueDetail.task_type == 2 && this.queueDetail.result_audio) {
  564. this.audioPlayer.src = this.queueDetail.result_audio;
  565. }
  566. } else {
  567. uni.showToast({
  568. title: '获取详情失败',
  569. icon: 'none'
  570. });
  571. }
  572. },
  573. complete: () => {
  574. uni.hideLoading();
  575. },
  576. fail: (e) => {
  577. console.log("请求失败:", e);
  578. uni.showToast({
  579. title: '网络请求失败',
  580. icon: 'none'
  581. });
  582. }
  583. });
  584. },
  585. showActionSheet() {
  586. // 显示操作列表
  587. uni.showActionSheet({
  588. itemList: ['修改封面', '删除作品'],
  589. success: (res) => {
  590. switch (res.tapIndex) {
  591. case 0:
  592. // 修改封面
  593. this.editCover();
  594. break;
  595. case 1:
  596. // 删除作品
  597. this.deleteWork();
  598. break;
  599. }
  600. },
  601. fail: (res) => {
  602. console.log(res.errMsg);
  603. }
  604. });
  605. },
  606. // 修改封面
  607. editCover() {
  608. var _self = this;
  609. uni.chooseImage({
  610. count: 1,
  611. sizeType: ['compressed'],
  612. sourceType: ['album', 'camera'],
  613. success: function (res) {
  614. console.log('res:', res)
  615. if (res.tempFilePaths.length > 0) {
  616. _self.imglocal = res.tempFilePaths[0]
  617. const tempFilePaths = res.tempFilePaths[0];
  618. console.log('tempFilePaths:', tempFilePaths);
  619. const uploadTask = uni.uploadFile({
  620. url: _self.$apiHost + '/Xweb/upload_img?skey=' + _self.skey,
  621. filePath: res.tempFilePaths[0],
  622. name: 'file',
  623. success: function (uploadFileRes) {
  624. let resdata = JSON.parse(uploadFileRes.data)
  625. console.log('Success11:', uploadFileRes);
  626. console.log('Success21:', resdata);
  627. if (resdata.success == 'yes') {
  628. _self.home_image = resdata.url;
  629. // 调用修改封面接口
  630. uni.request({
  631. url: _self.$apiHost + '/WorkAI/queueAction',
  632. method: 'GET',
  633. data: {
  634. uuid: getApp().globalData.uuid,
  635. act: 'editImg',
  636. result_images: resdata.url,
  637. id: _self.arcID
  638. },
  639. header: {
  640. 'content-type': 'application/json',
  641. 'sign': getApp().globalData.headerSign
  642. },
  643. success: (res) => {
  644. if (res.data.success === "yes") {
  645. uni.showToast({
  646. title: '修改封面成功',
  647. icon: 'success'
  648. });
  649. } else {
  650. uni.showToast({
  651. title: '修改封面失败',
  652. icon: 'none'
  653. });
  654. }
  655. },
  656. fail: () => {
  657. uni.showToast({
  658. title: '修改封面失败',
  659. icon: 'none'
  660. });
  661. }
  662. });
  663. }
  664. },
  665. fail: function (uploadFileFail) {
  666. console.log('Error:', uploadFileFail.data);
  667. uni.showToast({
  668. title: '图片上传失败',
  669. icon: 'none'
  670. });
  671. }
  672. });
  673. }
  674. },
  675. error: function (e) {
  676. console.log(e);
  677. uni.showToast({
  678. title: '选择图片失败',
  679. icon: 'none'
  680. });
  681. }
  682. });
  683. },
  684. // 删除作品
  685. deleteWork() {
  686. // 显示确认对话框
  687. uni.showModal({
  688. title: '确认删除',
  689. content: '确定要删除这个作品吗?',
  690. confirmColor: '#ff5151',
  691. success: (res) => {
  692. if (res.confirm) {
  693. // 用户点击确定,执行删除操作
  694. this.confirmDelete();
  695. }
  696. }
  697. });
  698. },
  699. // 确认删除
  700. confirmDelete() {
  701. uni.showLoading({
  702. title: '删除中...'
  703. });
  704. uni.request({
  705. url: this.$apiHost + '/WorkAI/queueAction',
  706. method: 'GET',
  707. data: {
  708. uuid: getApp().globalData.uuid,
  709. act: 'del',
  710. id: this.arcID
  711. },
  712. header: {
  713. 'content-type': 'application/json',
  714. 'sign': getApp().globalData.headerSign
  715. },
  716. success: (res) => {
  717. uni.hideLoading();
  718. if (res.data.success === "yes") {
  719. uni.showToast({
  720. title: '删除成功',
  721. icon: 'success'
  722. });
  723. // 删除成功后返回上一页
  724. setTimeout(() => {
  725. uni.navigateBack({
  726. delta: 1
  727. });
  728. }, 1500);
  729. } else {
  730. uni.showToast({
  731. title: '删除失败',
  732. icon: 'none'
  733. });
  734. }
  735. },
  736. fail: () => {
  737. uni.hideLoading();
  738. uni.showToast({
  739. title: '删除失败',
  740. icon: 'none'
  741. });
  742. }
  743. });
  744. },
  745. // 显示添加说明弹窗
  746. showAddNotePopup() {
  747. this.showNotePopup = true;
  748. },
  749. // 关闭添加说明弹窗
  750. closeAddNotePopup() {
  751. this.showNotePopup = false;
  752. },
  753. // 确认添加说明
  754. confirmAddNote() {
  755. if (!this.noteContent.trim()) {
  756. uni.showToast({
  757. title: '请输入说明内容',
  758. icon: 'none'
  759. });
  760. return;
  761. }
  762. uni.showLoading({
  763. title: '保存中...'
  764. });
  765. uni.request({
  766. url: this.$apiHost + '/WorkAI/queueAction',
  767. method: 'GET',
  768. data: {
  769. uuid: getApp().globalData.uuid,
  770. act: 'editContent',
  771. content: this.noteContent,
  772. id: this.arcID
  773. },
  774. header: {
  775. 'content-type': 'application/json',
  776. 'sign': getApp().globalData.headerSign
  777. },
  778. success: (res) => {
  779. uni.hideLoading();
  780. if (res.data.success === "yes") {
  781. uni.showToast({
  782. title: '添加说明成功',
  783. icon: 'success'
  784. });
  785. this.noteContent = '';
  786. this.closeContentPopUpWindow();
  787. // 重新加载数据
  788. this.loadData();
  789. } else {
  790. uni.showToast({
  791. title: '添加说明失败',
  792. icon: 'none'
  793. });
  794. }
  795. },
  796. fail: () => {
  797. uni.hideLoading();
  798. uni.showToast({
  799. title: '添加说明失败',
  800. icon: 'none'
  801. });
  802. }
  803. });
  804. },
  805. // 发布作品
  806. publishWork() {
  807. uni.showLoading({
  808. title: '发布中...'
  809. });
  810. uni.request({
  811. url: this.$apiHost + '/WorkAI/queueAction',
  812. method: 'GET',
  813. data: {
  814. uuid: getApp().globalData.uuid,
  815. act: 'fabu',
  816. id: this.arcID
  817. },
  818. header: {
  819. 'content-type': 'application/json',
  820. 'sign': getApp().globalData.headerSign
  821. },
  822. success: (res) => {
  823. console.log("resddd", res.data);
  824. uni.hideLoading();
  825. if (res.data.success === "yes") {
  826. uni.showToast({
  827. title: '发布成功',
  828. icon: 'success'
  829. });
  830. // 重新加载数据
  831. // this.loadData();
  832. } else {
  833. uni.showToast({
  834. title: res.data.str || '发布失败',
  835. icon: 'none'
  836. });
  837. }
  838. },
  839. fail: () => {
  840. uni.hideLoading();
  841. uni.showToast({
  842. title: '发布失败',
  843. icon: 'none'
  844. });
  845. }
  846. });
  847. },
  848. startDrag(event) {
  849. this.isDragging = true;
  850. this.startY = event.clientY;
  851. this.initialOffsetY = this.offsetY || 0;
  852. },
  853. stopDrag() {
  854. this.isDragging = false;
  855. },
  856. drag(event) {
  857. if (this.isDragging) {
  858. const deltaY = event.clientY - this.startY;
  859. const newOffsetY = this.initialOffsetY + deltaY;
  860. // Get the height of the lyrics text
  861. const lyricsTextHeight = this.$refs.lyricsText ? this.$refs.lyricsText.$el.clientHeight : 0;
  862. const imageBoxHeight = this.$refs.ImageBox ? this.$refs.ImageBox.$el.clientHeight : 0;
  863. // Define the threshold limits based on the height of the lyrics text
  864. const minY = -lyricsTextHeight + 50 + imageBoxHeight; // Allow some space above
  865. const maxY = lyricsTextHeight / 2; // Allow some space below
  866. // Apply the limits
  867. this.offsetY = Math.min(Math.max(newOffsetY, minY), maxY);
  868. // Log the height and current offset
  869. console.log('Lyrics Text Height:', lyricsTextHeight);
  870. console.log('Current Offset Y:', this.offsetY);
  871. console.log(this);
  872. }
  873. },
  874. rgbToHex(r, g, b) {
  875. return '#' + ((1 << 24) + (r << 16) + (g << 8) + b).toString(16).slice(1);
  876. }
  877. }
  878. }
  879. </script>
  880. <style scoped lang="scss">
  881. @import 'makeDetail.scss';
  882. .openContentPopUpWindow {
  883. ::v-deep.uv-textarea {
  884. width: 694rpx !important;
  885. border-radius: 20rpx !important;
  886. border: 1rpx solid #000000 !important;
  887. margin: 0 auto;
  888. margin-bottom: 44rpx;
  889. min-height: 300rpx;
  890. }
  891. }
  892. </style>