makeDetail copy.vue 28 KB

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