my.vue 27 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899
  1. <template>
  2. <view class="page">
  3. <!-- 用于计算主题色的隐藏Canvas -->
  4. <view style="position: absolute; top: -9999px; left: -9999px;">
  5. <canvas canvas-id="themeCanvas" id="themeCanvas" style="width: 100px; height: 100px;"></canvas>
  6. </view>
  7. <view class="topBody">
  8. <!-- <view class="header" :class="{ 'header-isvip': !isRecharge }"> -->
  9. <view class="header"
  10. :style="{ backgroundImage: `url(${bgImage || '../../static/me/theme3.jpg'})`, marginBottom: labelBoxHeight < 45 ? '-80rpx' : '-40rpx' }">
  11. <view class="header-box" :style="headerBoxStyle">
  12. <view class="reserveASeat"></view>
  13. <view class="benner-box">
  14. <view class="setUp-box">
  15. <view class="my-box">我的</view>
  16. <view class="settingBtn-box">
  17. <image @click="clickShare()" src="@/static/me/fenxiang.png" mode=""></image>
  18. <image src="@/static/me/shezhi.png" mode="" @click="navigateToSettings">
  19. </image>
  20. </view>
  21. </view>
  22. <view class="profilePicture-box">
  23. <CircleAvatar class="avator" @click="goPage('/pages/my/editInfo')" :src="myinfo.avator">
  24. </CircleAvatar>
  25. <view class="profilePicture-box-right" @click="goPage('/pages/my/creativeExpert')">
  26. <view class="one-omit">{{ myinfo.nickname }}</view>
  27. <image v-if="myinfo.my_level || myinfo.my_level == 0"
  28. :src="`../../static/icon/level_${myinfo.my_level}.png`" mode="widthFix"
  29. class="level-icon" />
  30. </view>
  31. </view>
  32. <view class="intro_row" @click="goPage('/pages/my/editInfo')">
  33. <block v-if="myinfo.content == ''">
  34. <text class="intro_text two-omit">添加简介</text>
  35. <image src="@/static/me/xiugai.png" mode="widthFix" class="add_icon">
  36. </image>
  37. </block>
  38. <uv-text color="#fff" v-else :text="formatText(myinfo.content)" class="intro_text two-omit">
  39. </uv-text>
  40. </view>
  41. <view class="label-box" id="labelBox">
  42. <view class="label-item sex-item">
  43. <image src="../../static/icon/wd_icon_nv.png" mode="widthFix" v-if="myinfo.sex_id == 2">
  44. </image>
  45. <image src="../../static/icon/wd_icon_nan.png" mode="widthFix" v-else></image>
  46. </view>
  47. <view class="label-item" v-for="(item, index) in aihao_tags" :key="index + item">
  48. {{ item }}
  49. </view>
  50. </view>
  51. <view class="follow_info" @click="navigateToFollow">
  52. <view class="follow-box">
  53. <view class="num">{{ scientificCounting(myinfo.num_attention) }}</view>
  54. <view class="label">关注</view>
  55. </view>
  56. <!-- <view class="separator"></view> -->
  57. <view class="follow-box">
  58. <view class="num">{{ scientificCounting(myinfo.num_fans) }}</view>
  59. <view class="label">粉丝</view>
  60. </view>
  61. <!-- <view class="separator"></view> -->
  62. <view class="follow-box">
  63. <view class="num">{{ scientificCounting(myinfo.num_like) }}</view>
  64. <view class="label">获赞</view>
  65. </view>
  66. </view>
  67. <view class="bom-box">
  68. <view class="bom-item bom-item1 scale-tap" @click="goPage('/pages/my/wallet')">
  69. <view class="bom-item-title">钱包</view>
  70. <view class="bom-item-subtitle">查看我的钱包</view>
  71. </view>
  72. <view class="bom-item bom-item2 scale-tap">
  73. <view class="bom-item-title" @click="initiateFundraising()">发起募集</view>
  74. <view class="bom-item-subtitle">查看我的众筹</view>
  75. </view>
  76. <view class="bom-item bom-item3 scale-tap" @click="goPage('/pages/crowdFunding/orderList')">
  77. <view class="bom-item-title">订单</view>
  78. <view class="bom-item-subtitle">查看我的订单</view>
  79. </view>
  80. </view>
  81. </view>
  82. <view class="card-box" v-if="false">
  83. <view class="card-top">
  84. <view class="top-box">
  85. 1
  86. </view>
  87. <view class="userinfo-box" @click="goPage('/pages/my/editInfo')">
  88. <view class="userinfo-left">
  89. <CircleAvatar class="avator" :src="myinfo.avator"></CircleAvatar>
  90. </view>
  91. <view class="userinfo-right">
  92. <view class="nickname">
  93. <text class="one-omit">{{ myinfo.nickname }}</text>
  94. <view class="level">Lv{{ myinfo.my_level }}</view>
  95. </view>
  96. <view class="label">
  97. </view>
  98. </view>
  99. </view>
  100. <view class="line"></view>
  101. <view class="bom">
  102. <view class="points-box">
  103. <view class="points" @click="isRecharge ? goPage('/pages/vip/M_purchase') : ''">
  104. <image src="@/static/icon/wd_icon_coin.png" mode=""></image>
  105. <text>{{ myinfo.num_gmm | formatNumberToK }}</text>
  106. <image class="money-add" v-if="isRecharge" src="/static/icon/coin_add.png"
  107. mode="aspectFit"></image>
  108. </view>
  109. <view class="points"
  110. @click="isRecharge ? goPage('/pages/my/job?type=recharge') : ''">
  111. <image src="@/static/icon/coin_cd.png" mode=""></image>
  112. <text>{{ myinfo.num_gmd | formatNumberToK }}</text>
  113. <image class="money-add" v-if="isRecharge" src="/static/icon/coin_add.png"
  114. mode="aspectFit"></image>
  115. </view>
  116. </view>
  117. </view>
  118. </view>
  119. <!-- <view class="card-bom" v-if="isRecharge" @click="goPage('/pages/vip/index')"> -->
  120. </view>
  121. </view>
  122. </view>
  123. <view class="myinfo">
  124. <view class="vip-box" @click="isRecharge ? goPage('/pages/vip/index') : ''">
  125. <view class="content-box">
  126. <image v-if="false" src="@/static/me/icon-vip2.png" mode=""></image>
  127. <image v-else-if="0" src="@/static/me/icon-vip1.png" mode=""></image>
  128. <image v-else src="@/static/me/icon-vip0.png" mode=""></image>
  129. <text v-if="myinfo.is_vip == 0">开启专属会员权益</text>
  130. <text v-else style="font-size: 28rpx;">会员权益生效中 <text
  131. style="font-size: 24rpx; color: rgba(172 ,249 ,52, .5);"> ({{ myinfo.vip_date }})
  132. </text>
  133. </text>
  134. </view>
  135. <!-- <view class=""> -->
  136. <!-- <image v-if="isRecharge" src="@/static/me/wd_icon_jiantou.png" mode="aspectFit"></image> -->
  137. <view class="vip-btn">
  138. 会员中心
  139. </view>
  140. <!-- </view> -->
  141. </view>
  142. <!-- <view class="line"></view> -->
  143. <view class="tablist">
  144. <view class="item" :class="{ active: firstLevelNavActive === 0 }"
  145. @click="firstLevelNavActiveSwitch(0)">我的作品
  146. <view class="indicator-triangle"> </view>
  147. </view>
  148. <view class="item" :class="{ active: firstLevelNavActive === 1 }"
  149. @click="firstLevelNavActiveSwitch(1)">我的帖子
  150. <view class="indicator-triangle"> </view>
  151. </view>
  152. </view>
  153. <!-- 作品列表 -->
  154. <template v-if="firstLevelNavActive == 0">
  155. <view class="line"></view>
  156. <view class="subtitle">
  157. <view class="item" :class="{ active: activeTab === 0 }" @click="switchTab(0)">
  158. 作品
  159. </view>
  160. <view class="item" :class="{ active: activeTab === 1 }" @click="switchTab(1)">
  161. 生成中
  162. </view>
  163. </view>
  164. <view class="numlist1" v-if="activeTab === 0" style="margin-top: 15rpx">
  165. <WorkItem v-for="(item, index) in worksList" :secrecy="true" :subtitle="true" :key="index"
  166. :item="item" @click="goWork(item)" />
  167. <!-- 修改空状态显示条件 -->
  168. <view v-if="isDataLoaded && worksList.length === 0" class="empty-state">
  169. <image src="@/static/icon/xx_img_zanwuxiaoxi.png" mode="aspectFit" class="empty-image">
  170. </image>
  171. <text class="empty-text">暂无作品</text>
  172. <text class="empty-subtext">快来创作你的第一个作品吧~</text>
  173. </view>
  174. </view>
  175. <view class="numlist2" v-if="activeTab === 1" style="margin-top: 15rpx">
  176. <view class="item" v-for="(item, index) in worksList" :key="index"
  177. style="margin-bottom: 28rpx;">
  178. <view class="num" @click="goWork(item)"
  179. :class="{ 'clickable': item.status !== 3 && item.status !== 4 }">
  180. <WorkItem :item="item" style="margin-bottom: 12rpx" />
  181. <image class="incomplete-bg" v-if="item.status != 9"
  182. src="@/static/me/wd_bg_zhizuozhong.png"></image>
  183. <view class="maskLayer"></view>
  184. <!-- 当activeTab为1时显示队列状态 -->
  185. <view class="queue-status">
  186. <!-- 排队中 -->
  187. <view v-if="item.status === 1" class="status-text">
  188. <image class="state-img" src="@/static/me/wd_icon_paiduizhong.png"></image>
  189. </view>
  190. <!-- 生成失败 -->
  191. <view v-if="item.status === 3 || item.status === 4" class="status-text">
  192. <image class="state-img" src="@/static/me/wd_icon_zhizuoshibai.png"></image>
  193. </view>
  194. <!-- 制作中 -->
  195. <view v-else-if="item.status < 9" class="status-text">
  196. <image class="state-img" src="@/static/me/wd_icon_zhizuozhong.png"></image>
  197. </view>
  198. <!-- 创作完成 -->
  199. <view v-else-if="item.status === 9" class="status-text">
  200. <image class="state-img" src="@/static/me/wd_icon_chuangzuowancheng.png">
  201. </image>
  202. </view>
  203. </view>
  204. <view class="name one-omit" style="
  205. font-family: 'PingFang SC-Medium';
  206. font-weight: 500;
  207. font-size: 28rpx;
  208. color: #1a4d2e;
  209. max-width: 40vw;
  210. ">
  211. {{ item.title || item.description || "作品" + index }}
  212. </view>
  213. <!-- 显示任务类型标签 -->
  214. <view class="task-type-tag" style="position: absolute; left: 14rpx;top: 14rpx;">
  215. <image style="width: 120rpx; height: 36rpx" v-if="item.task_type === 1"
  216. src="@/static/me/wd_icon_lingganchuangzuo.png"></image>
  217. <image style="width: 82rpx; height: 36rpx" v-else-if="item.task_type === 2"
  218. src="@/static/me/wd_icon_yinyue.png"></image>
  219. <!-- <text v-if="item.task_type === 1">灵感创作</text>
  220. <text v-else-if="item.task_type === 2">音乐</text> -->
  221. </view>
  222. </view>
  223. </view>
  224. <!-- 修改空状态显示条件 -->
  225. <view v-if="isDataLoaded && worksList.length === 0" class="empty-state">
  226. <image src="@/static/icon/xx_img_zanwuxiaoxi.png" mode="aspectFit" class="empty-image">
  227. </image>
  228. <text class="empty-text">暂无生成中的作品</text>
  229. <text class="empty-subtext">快去创作新作品吧~</text>
  230. </view>
  231. </view>
  232. </template>
  233. <template v-else>
  234. <view class="numlist2" style="margin-top: 30rpx">
  235. <view class="item" v-for="(item, index) in worksList" :key="index" style="margin-bottom: 15rpx">
  236. <view class="num" @click="goWork2(item)"
  237. :class="{ 'clickable': item.status !== 3 && item.status !== 4 }">
  238. <WorkItem :item="item" style="margin-bottom: 20rpx" />
  239. <view class="incomplete-bg" style="background: #f8f9fa"></view>
  240. <image class="incomplete-bg" v-if="item.status != 1"
  241. src="@/static/me/wd_bg_zhizuozhong.png"></image>
  242. <image class="incomplete-bg2" v-else-if="item.status == 1" :src="item.image"
  243. mode="aspectFill" style="max-height: 520rpx;"></image>
  244. <view class="maskLayer" v-if="item.status != 1"></view>
  245. <!-- 当activeTab为1时显示队列状态 -->
  246. <view class="queue-status">
  247. <!-- 已发布 -->
  248. <view v-if="item.status == 1" class="status-text">
  249. </view>
  250. <!-- 待审核 -->
  251. <view v-if="item.status == 2 || item.status === 4" class="status-text">
  252. <image class="state-img" src="@/static/me/wd_icon_shenhezhong.png"></image>
  253. </view>
  254. <!-- 审核失败 -->
  255. <view v-else-if="item.status == 3" class="status-text">
  256. <image class="state-img" src="@/static/me/wd_icon_fabushibai.png"></image>
  257. </view>
  258. </view>
  259. <view class="name one-omit" style="
  260. font-family: 'PingFang SC-Medium';
  261. font-weight: 500;
  262. font-size: 28rpx;
  263. color: #1a4d2e;
  264. max-width: 40vw;
  265. ">
  266. {{ item.title || item.description || "作品" + index }}
  267. </view>
  268. </view>
  269. </view>
  270. <!-- 修改空状态显示条件 -->
  271. <view v-if="isDataLoaded && worksList.length === 0" class="empty-state">
  272. <image src="@/static/icon/xx_img_zanwuxiaoxi.png" mode="aspectFit" class="empty-image">
  273. </image>
  274. <text class="empty-text">暂无帖子</text>
  275. <text class="empty-subtext">快来发布你的第一个帖子吧~</text>
  276. </view>
  277. </view>
  278. </template>
  279. <!-- 加载更多提示 -->
  280. <!-- <view class="loading-more" v-if="isLoading">加载中...</view>
  281. <view class="no-more" v-if="!hasMore && worksList.length > 0">没有更多作品了</view>
  282. <view class="no-more" v-if="!hasMore && worksList.length === 0">暂无作品</view> -->
  283. </view>
  284. <view class="blankHeight"></view>
  285. </view>
  286. <view class="reserveASeatBom"></view>
  287. <!-- 确认框 -->
  288. <CustomConfirm ref="customConfirm"></CustomConfirm>
  289. <!-- 提示框 -->
  290. <DialogBox ref="DialogBox"></DialogBox>
  291. <tabbar-view :tabbars="tabbars" :currentIndex="4" ref="tabbar"></tabbar-view>
  292. <!-- SharePopup组件 -->
  293. <SharePopup :visible="showShare" :userId="userId" :share-title="shareTitle" :share-desc="shareDesc"
  294. :share-img="shareImg" view="makeDetail" @close="showShare = false" />
  295. <DialogBox ref="DialogBox"></DialogBox>
  296. </view>
  297. </template>
  298. <script>
  299. import tabbarView from "@/components/tabbar/tabbar.vue";
  300. import tabbar from "@/mixins/tabbar";
  301. import CustomConfirm from "@/components/custome-confirm/customeConfirm.vue";
  302. import CircleAvatar from "@/components/CircleAvatar/CircleAvatar.vue";
  303. import meCard from "@/components/meCard/meCard.vue";
  304. import WorkItem from "@/components/WorkItem/WorkItem.vue";
  305. import { mapState } from 'vuex'
  306. import { scientificCounting } from "@/common/util.js";
  307. import { RgbQuant } from '@/common/RgbQuant.js';
  308. export default {
  309. components: {
  310. tabbarView,
  311. CustomConfirm,
  312. CircleAvatar,
  313. meCard,
  314. WorkItem,
  315. },
  316. mixins: [tabbar],
  317. data() {
  318. return {
  319. bgImage: '',
  320. title: "",
  321. sel: 1,
  322. firstLevelNavActive: 0,
  323. labelBoxHeight: 0,
  324. myinfo: {
  325. avator: "../../static/logo.png",
  326. nickname: "",
  327. join_name: "",
  328. num_1: 0,
  329. num_2: 0,
  330. num_3: 0,
  331. num_4: 0,
  332. is_login: "no",
  333. num_history: 0,
  334. num_collection: 0,
  335. },
  336. aihao_tags: [],
  337. menu_list: [],
  338. data_list: [],
  339. activeTab: 0,
  340. offset: 0,
  341. hasMore: true,
  342. isLoading: false,
  343. isDataLoaded: false,
  344. worksList: [],
  345. showShare: false,
  346. shareTitle: "",
  347. shareDesc: "",
  348. shareImg: "",
  349. userId: 0,
  350. headerBoxStyle: {
  351. background: 'linear-gradient(360deg, #16210E 0%, rgba(55,73,36,0) 100%)'
  352. },
  353. };
  354. },
  355. onLoad(e) {
  356. // setTimeout(function() {
  357. // uni.setNavigationBarColor({
  358. // frontColor: '#ffffff',
  359. // backgroundColor: '#00000000',
  360. // animation: {
  361. // duration: 400,
  362. // timingFunc: 'easeIn'
  363. // }
  364. // })
  365. // }, 200);
  366. uni.$on('switchToMyPage', (data) => {
  367. if (data.type === 'article') {
  368. this.firstLevelNavActiveSwitch(1);
  369. } else if (data.type === 'generatingInProgress') {
  370. this.firstLevelNavActiveSwitch(0)
  371. this.switchTab(1);
  372. } else {
  373. this.firstLevelNavActiveSwitch(0)
  374. this.switchTab(0);
  375. }
  376. });
  377. },
  378. onUnload() {
  379. // 移除事件监听
  380. uni.$off('switchToMyPage');
  381. },
  382. computed: {
  383. ...mapState('switchingModule', ['isRecharge'])
  384. },
  385. onShow() {
  386. uni.$emit("check_login", () => { });
  387. this.offset = 0;
  388. this.hasMore = true;
  389. this.worksList = [];
  390. this.loadInfo();
  391. // 使用nextTick确保DOM已更新
  392. this.$nextTick(() => {
  393. this.getLabelBoxHeight();
  394. });
  395. // 检查全局变量,如果需要切换到生成中标签
  396. if (getApp().globalData.needSwitchToGenerating) {
  397. setTimeout(() => {
  398. this.switchTab(1);
  399. // 重置全局变量
  400. getApp().globalData.needSwitchToGenerating = false;
  401. }, 300);
  402. } else {
  403. this.loadWorksList();
  404. }
  405. },
  406. onReachBottom() {
  407. if (this.hasMore && !this.isLoading) {
  408. this.loadMoreWorks();
  409. }
  410. },
  411. methods: {
  412. clickShare(item) {
  413. this.showShare = true;
  414. },
  415. async showConfirm() {
  416. let that = this;
  417. this.$refs["customConfirm"]
  418. .confirm({
  419. title: "确认解绑",
  420. content: "解绑微信账号后将无法继续使用它登录该App账号?",
  421. DialogType: "inquiry",
  422. btn1: "再考虑一下",
  423. btn2: "确认解绑",
  424. animation: 0,
  425. })
  426. .then((res) => { });
  427. },
  428. onBack() { },
  429. chkSel() {
  430. if (this.sel == 1) {
  431. this.sel = 0;
  432. } else {
  433. this.sel = 1;
  434. }
  435. },
  436. goPage(page) {
  437. console.log(999);
  438. uni.navigateTo({
  439. url: page,
  440. });
  441. },
  442. initiateFundraising() {
  443. if (this.myinfo.my_level < 3) {
  444. this.$refs["DialogBox"]
  445. .confirm({
  446. title: "提示",
  447. content: "您当前的等级为" + this.myinfo.my_level + "级,需要达到3级才能发起募集",
  448. DialogType: "inquiry",
  449. btn1: "取消",
  450. btn2: "去查看等级",
  451. animation: 0,
  452. })
  453. .then((res) => {
  454. this.goPage('/pages/my/creativeExpert')
  455. }, (res) => {
  456. });
  457. return;
  458. }
  459. this.goPage('/pages/my/initiateCrowdfunding')
  460. },
  461. async calculateThemeColor(imageUrl) {
  462. if (!imageUrl) {
  463. // 如果没有图片,则使用默认样式
  464. this.headerBoxStyle = {
  465. background: 'linear-gradient(to bottom, rgba(0, 0, 0, 0.5), transparent)'
  466. };
  467. return;
  468. }
  469. console.log('开始计算主题色, imageUrl:', imageUrl);
  470. const canvasId = 'themeCanvas';
  471. const ctx = uni.createCanvasContext(canvasId, this);
  472. uni.getImageInfo({
  473. src: imageUrl,
  474. success: (imageInfo) => {
  475. console.log('图片信息获取成功:', imageInfo);
  476. const canvasWidth = 100; // 缩小图片以加快处理速度
  477. const canvasHeight = Math.floor(canvasWidth * (imageInfo.height / imageInfo.width));
  478. // 绘制图片到canvas
  479. ctx.drawImage(imageInfo.path, 0, 0, canvasWidth, canvasHeight);
  480. ctx.draw(false, () => {
  481. console.log('Canvas 绘制完成');
  482. // 获取像素数据
  483. uni.canvasGetImageData({
  484. canvasId: canvasId,
  485. x: 0,
  486. y: 0,
  487. width: canvasWidth,
  488. height: canvasHeight,
  489. success: (res) => {
  490. console.log('像素数据获取成功');
  491. const pixels = res.data;
  492. // 使用 RgbQuant 提取主要颜色
  493. const quant = new RgbQuant({
  494. colors: 16, // 提取16种主要颜色
  495. method: 2, // 使用 WuQuant 算法
  496. });
  497. quant.sample(pixels);
  498. const palette = quant.quantize();
  499. if (quant.vboxes && quant.vboxes.length > 0) {
  500. let dominantColor = null;
  501. let maxPopulation = 0;
  502. // 找到像素数最多的颜色区域
  503. quant.vboxes.forEach(vbox => {
  504. const population = vbox.size(quant.histogram);
  505. if (population > maxPopulation) {
  506. maxPopulation = population;
  507. dominantColor = vbox.color(quant.histogram);
  508. }
  509. });
  510. if (dominantColor) {
  511. const [r, g, b] = dominantColor.map(value => Math.min(255, Math.max(0, value)));
  512. const themeColor = `rgba(${r}, ${g}, ${b}, 0.5)`;
  513. console.log('计算出的主题色 (Dominant):', themeColor);
  514. // 更新 header-box 的背景样式
  515. this.headerBoxStyle = {
  516. background: `linear-gradient(to bottom, ${themeColor}, transparent)`
  517. };
  518. }
  519. }
  520. },
  521. fail: (err) => {
  522. console.error('获取像素数据失败:', err);
  523. }
  524. });
  525. });
  526. },
  527. fail: (err) => {
  528. console.error('获取图片信息失败:', err);
  529. }
  530. });
  531. },
  532. async loadInfo() {
  533. console.log({
  534. uuid: getApp().globalData.uuid,
  535. skey: getApp().globalData.skey,
  536. });
  537. uni.request({
  538. url: this.$apiHost + "/User/getinfo",
  539. data: {
  540. uuid: getApp().globalData.uuid,
  541. skey: getApp().globalData.skey,
  542. },
  543. header: {
  544. "content-type": "application/json",
  545. sign: getApp().globalData.headerSign,
  546. },
  547. success: (res) => {
  548. console.log("----:", JSON.parse(JSON.stringify(res.data)));
  549. if (res.data) {
  550. this.shareTitle = res.data.nickname
  551. this.shareDesc = res.data.content
  552. this.shareImg = res.data.avator
  553. this.userId = res.data.user_id
  554. }
  555. if (res.data.need_login == "yes") {
  556. // getApp().globalData.skey = "";
  557. // getApp().globalData.uuid = "";
  558. uni.removeStorageSync("wapptoken");
  559. uni.redirectTo({
  560. url: "/pages/login/login",
  561. });
  562. return;
  563. }
  564. if (res.data.aihao) {
  565. this.aihao_tags = res.data.aihao.split(",");
  566. }
  567. this.myinfo = res.data;
  568. this.bgImage = res.data.bgimg;
  569. // 在获取到背景图片后,计算主题色
  570. // this.calculateThemeColor(this.bgImage);
  571. },
  572. complete: (com) => {
  573. // uni.hideLoading();
  574. },
  575. fail: (e) => {
  576. console.log("----e:", e);
  577. },
  578. });
  579. uni.request({
  580. url: this.$apiHost + "/Member/getinfoData",
  581. data: {
  582. uuid: getApp().globalData.uuid,
  583. skey: getApp().globalData.skey,
  584. },
  585. header: {
  586. "content-type": "application/json",
  587. sign: getApp().globalData.headerSign,
  588. },
  589. success: async (res) => {
  590. console.log("----:", JSON.parse(JSON.stringify(res.data)));
  591. if (res.data) {
  592. this.bgImage = res.data.bgimg;
  593. if (this.bgImage) {
  594. // 计算主题色并更新蒙版背景
  595. // const gradient = await this.calculateThemeColor(this.bgImage);
  596. const gradient = `linear-gradient(to bottom,transparent, rgba(0, 0, 0, .8))`;
  597. this.headerBoxStyle = {
  598. background: gradient
  599. };
  600. }
  601. }
  602. },
  603. complete: (com) => {
  604. // uni.hideLoading();
  605. },
  606. fail: (e) => {
  607. console.log("----e:", e);
  608. },
  609. });
  610. },
  611. onLogout() {
  612. let that = this;
  613. this.$refs["DialogBox"]
  614. .confirm({
  615. title: "提示",
  616. content: "确定退出吗?",
  617. DialogType: "inquiry",
  618. btn1: "取消",
  619. btn2: "退出",
  620. animation: 0,
  621. })
  622. .then((res) => {
  623. uni.request({
  624. url: that.$apiHost + "/My/logout",
  625. data: {
  626. uuid: getApp().globalData.uuid,
  627. skey: getApp().globalData.skey,
  628. },
  629. header: {
  630. "content-type": "application/json",
  631. sign: getApp().globalData.headerSign,
  632. },
  633. success: (res) => {
  634. console.log("----:", res.data);
  635. // getApp().globalData.skey = "";
  636. // getApp().globalData.uuid = "";
  637. uni.removeStorageSync("wapptoken");
  638. uni.redirectTo({
  639. url: "/pages/login/login",
  640. });
  641. },
  642. complete: (com) => {
  643. // uni.hideLoading();
  644. },
  645. fail: (e) => {
  646. console.log("----e:", e);
  647. },
  648. });
  649. });
  650. },
  651. switchTab(index) {
  652. this.activeTab = index;
  653. this.offset = 0;
  654. this.hasMore = true;
  655. this.worksList = [];
  656. this.loadWorksList();
  657. },
  658. loadWorksList() {
  659. if (this.isLoading) return;
  660. this.isLoading = true;
  661. this.isDataLoaded = false;
  662. // 根据activeTab选择不同的API
  663. let apiUrl = "";
  664. if (this.firstLevelNavActive == 0) {
  665. if (this.activeTab === 0) {
  666. apiUrl = "/Work/getlist";
  667. } else {
  668. apiUrl = "/WorkAI/getMyQueueList";
  669. }
  670. } else if (this.firstLevelNavActive == 1) {
  671. apiUrl = "/Article/getlist";
  672. }
  673. uni.request({
  674. url: this.$apiHost + apiUrl,
  675. data: {
  676. uuid: getApp().globalData.uuid,
  677. skey: getApp().globalData.skey,
  678. type: "my",
  679. offset: this.offset,
  680. status: this.activeTab === 0 ? 1 : undefined,
  681. },
  682. header: {
  683. "content-type": "application/json",
  684. sign: getApp().globalData.headerSign,
  685. },
  686. success: (res) => {
  687. console.log("列表数据:", JSON.parse(JSON.stringify(res.data)));
  688. if (res.data.success == "yes" && res.data.list) {
  689. if (res.data.list.length > 0) {
  690. this.worksList = [...this.worksList, ...res.data.list];
  691. this.offset += res.data.list.length;
  692. }
  693. if (res.data.list.length < 20) {
  694. this.hasMore = false;
  695. }
  696. } else {
  697. this.hasMore = false;
  698. this.worksList = [];
  699. }
  700. if (this.activeTab === 0) {
  701. this.updateDataList();
  702. }
  703. console.log("作品列表数据:", this.worksList);
  704. },
  705. complete: () => {
  706. this.isLoading = false;
  707. this.isDataLoaded = true;
  708. },
  709. fail: (e) => {
  710. console.log("请求列表失败:", e);
  711. this.isLoading = false;
  712. this.isDataLoaded = true;
  713. this.worksList = [];
  714. },
  715. });
  716. },
  717. firstLevelNavActiveSwitch(n) {
  718. this.firstLevelNavActive = n;
  719. this.offset = 0;
  720. this.hasMore = true;
  721. this.worksList = [];
  722. if (this.firstLevelNavActive == 0) {
  723. this.activeTab = 0;
  724. }
  725. this.loadWorksList();
  726. },
  727. loadMoreWorks() {
  728. if (this.hasMore && !this.isLoading) {
  729. this.loadWorksList();
  730. }
  731. },
  732. updateDataList() {
  733. this.data_list = this.worksList.map((item) => {
  734. return {
  735. url: item.images || item.img_url || item.url || "../../static/logo.png",
  736. title: item.title || item.description || "作品",
  737. id: item.id,
  738. };
  739. });
  740. },
  741. goWork(item) {
  742. uni.$emit("check_login", () => { });
  743. // , //任务状态(1:排队中,3:生成失败,4:生成失败,9:创作完成)
  744. if (this.activeTab == 0) {
  745. uni.navigateTo({
  746. // url: "/pages/index/workDetail?id=" + item.id,
  747. url: "/pages/makedetail/makeDetail?id=" +
  748. item.queue_id +
  749. "&queueId=" +
  750. item.id,
  751. });
  752. } else {
  753. if (item.status >= 9) {
  754. uni.navigateTo({
  755. url: "/pages/makedetail/makeDetail?id=" + item.id,
  756. });
  757. }
  758. if (item.status < 9 && item.status != 3 && item.status != 4) {
  759. // <!-- <text v-if="item.task_type === 1">灵感创作</text>
  760. // <text v-else-if="item.task_type === 2">音乐</text> -->
  761. var url = "";
  762. if (item.task_type === 1) {
  763. url = "/makedetail/makeImgDetail";
  764. }
  765. if (item.task_type === 2) {
  766. url = "/makedetail/makeMusicDetail";
  767. }
  768. if (url) {
  769. uni.navigateTo({
  770. url: "/pages" + url + "?id=" + item.id,
  771. });
  772. }
  773. }
  774. }
  775. },
  776. goWork2(item) {
  777. uni.navigateTo({
  778. // url: "/pages/index/workDetail?id=" + item.id,
  779. url: "/pages/index/articleDetail?id=" + item.id,
  780. });
  781. },
  782. navigateToSettings() {
  783. uni.$emit("check_login", () => {
  784. uni.navigateTo({
  785. url: "/pages/my/setting",
  786. });
  787. });
  788. },
  789. navigateToFollow() {
  790. uni.navigateTo({
  791. url: "/pages/my/follow",
  792. });
  793. },
  794. formatText(text) {
  795. if (!text) return '';
  796. return text.length > 20 ? text.substring(0, 20) + '...' : text;
  797. },
  798. scientificCounting(num) {
  799. if (!num) {
  800. return 0;
  801. }
  802. if (num < 1000) {
  803. return num;
  804. } else if (num < 1000000) {
  805. return (num / 1000).toFixed(1) + 'k';
  806. } else if (num < 1000000000) {
  807. return (num / 1000000).toFixed(1) + 'M';
  808. } else {
  809. return (num / 1000000000).toFixed(1) + 'B';
  810. }
  811. },
  812. // 获取label-box高度的方法
  813. getLabelBoxHeight() {
  814. setTimeout(() => {
  815. const query = uni.createSelectorQuery();
  816. query.select('#labelBox').boundingClientRect(data => {
  817. if (data) {
  818. this.labelBoxHeight = data.height;
  819. console.log('label-box高度:', this.labelBoxHeight);
  820. }
  821. }).exec();
  822. }, 100);
  823. },
  824. },
  825. };
  826. </script>
  827. <style scoped lang="scss">
  828. @import "my.scss";
  829. .empty-state {
  830. display: flex;
  831. flex-direction: column;
  832. align-items: center;
  833. justify-content: center;
  834. padding: 60rpx 0;
  835. margin-top: 40rpx;
  836. background: #FFFFFF;
  837. border-radius: 20rpx;
  838. width: 710rpx;
  839. .empty-image {
  840. width: 240rpx;
  841. height: 240rpx;
  842. margin-bottom: 30rpx;
  843. }
  844. .empty-text {
  845. font-size: 32rpx;
  846. color: #333333;
  847. margin-bottom: 16rpx;
  848. font-weight: 500;
  849. }
  850. .empty-subtext {
  851. font-size: 28rpx;
  852. color: #999999;
  853. }
  854. }
  855. </style>