userHomepage.vue 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600
  1. <template>
  2. <view class="page">
  3. <view class="topBody">
  4. <view class="header">
  5. <view class="card-box">
  6. <view class="card-top">
  7. <view class="top-box">
  8. <view class="hello-box" @click="goBack">
  9. <text class="fa fa-angle-left" style="color: #000; font-size: 55rpx;"></text>
  10. </view>
  11. <view class="settingBtn-box">
  12. <image @click="clickShare()" src="@/static/me/wd_icon_fenxian.png" mode=""></image>
  13. </view>
  14. </view>
  15. <view class="userinfo-box">
  16. <view class="userinfo-left">
  17. <CircleAvatar class="avator" :src="myinfo.avator"></CircleAvatar>
  18. </view>
  19. <view class="userinfo-right">
  20. <view class="nickname">
  21. <text class="one-omit">{{ myinfo.nickname }}</text>
  22. <image src="../../static/icon/wd_icon_nan.png" mode="widthFix" v-if="myinfo.sex_id == 1"></image>
  23. <image src="../../static/icon/wd_icon_nv.png" mode="widthFix" v-else-if="myinfo.sex_id == 2"></image>
  24. <view class="level">Lv{{ myinfo.my_level }}</view>
  25. </view>
  26. <view class="label">
  27. <view v-for="(item, index) in aihao_tags" :key="index + item">
  28. {{ item }}
  29. </view>
  30. </view>
  31. </view>
  32. </view>
  33. <view class="intro_row">
  34. <block v-if="myinfo.content == ''">
  35. <text class="intro_text two-omit">简介</text>
  36. </block>
  37. <uv-text v-else class="intro_text two-omit">
  38. {{ myinfo.content }}
  39. </uv-text>
  40. </view>
  41. <view class="bom">
  42. <view class="follow_info">
  43. <view class="follow-box">
  44. <view class="num">{{ myinfo.num_attention }}</view>
  45. <view class="label">关注</view>
  46. </view>
  47. <view class="separator"></view>
  48. <view class="follow-box">
  49. <view class="num">{{ myinfo.num_fans }}</view>
  50. <view class="label">粉丝</view>
  51. </view>
  52. <view class="separator"></view>
  53. <view class="follow-box">
  54. <view class="num">{{ myinfo.num_like }}</view>
  55. <view class="label">获赞</view>
  56. </view>
  57. </view>
  58. <view class="points-box">
  59. <text class="followTheAuthor followTheAuthor1" v-if="!myinfo.is_attention"
  60. @click="followTheAuthor(1)">+关注</text>
  61. <text class="followTheAuthor followTheAuthor0" v-else @click="followTheAuthor(0)">已关注</text>
  62. </view>
  63. </view>
  64. </view>
  65. </view>
  66. </view>
  67. <view class="myinfo">
  68. <!-- 作品列表 -->
  69. <view class="numlist1" style="margin-top: 30rpx">
  70. <WorkItem v-for="(item, index) in worksList" :subtitle="true" :key="index" :item="item"
  71. @click="goWork(item)" />
  72. </view>
  73. </view>
  74. </view>
  75. <!-- 确认框 -->
  76. <CustomConfirm ref="customConfirm"></CustomConfirm>
  77. <!-- 提示框 -->
  78. <DialogBox ref="DialogBox"></DialogBox>
  79. <!-- SharePopup组件 -->
  80. <SharePopup :visible="showShare" :userId="userId" :share-title="shareTitle" :share-desc="shareDesc" :share-img="shareImg" view="userHomepage"
  81. @close="showShare = false" />
  82. </view>
  83. </template>
  84. <script>
  85. import tabbar from "@/mixins/tabbar";
  86. import CustomConfirm from "@/components/custome-confirm/customeConfirm.vue";
  87. import CircleAvatar from "@/components/CircleAvatar/CircleAvatar.vue";
  88. import WorkItem from "@/components/WorkItem/WorkItem.vue";
  89. import SharePopup from "@/components/SharePopup/SharePopup.vue";
  90. import DialogBox from "@/components/DialogBox/DialogBox.vue";
  91. export default {
  92. components: {
  93. CustomConfirm,
  94. CircleAvatar,
  95. WorkItem,
  96. SharePopup,
  97. DialogBox
  98. },
  99. mixins: [tabbar],
  100. data() {
  101. return {
  102. firstLevelNavActive: 0,
  103. myinfo: {
  104. avator: "../../static/logo.png",
  105. nickname: "",
  106. content: "",
  107. sex_id: 1,
  108. my_level: 1,
  109. num_attention: 0,
  110. num_fans: 0,
  111. num_like: 0,
  112. wxkf: ""
  113. },
  114. aihao_tags: [],
  115. activeTab: 0,
  116. offset: 0,
  117. hasMore: true,
  118. isLoading: false,
  119. worksList: [],
  120. showShare: false,
  121. shareTitle: "分享标题",
  122. shareDesc: "分享描述",
  123. shareImg: "https://your-share-image.com/image.jpg",
  124. userId: 0,
  125. id: 0,
  126. };
  127. },
  128. onLoad(e) {
  129. if (e.id) {
  130. this.id = e.id
  131. }
  132. },
  133. onShow() {
  134. uni.$emit("check_login", () => { });
  135. this.offset = 0;
  136. this.hasMore = true;
  137. this.worksList = [];
  138. this.loadInfo();
  139. this.loadWorksList();
  140. },
  141. onReachBottom() {
  142. if (this.hasMore && !this.isLoading) {
  143. this.loadMoreWorks();
  144. }
  145. },
  146. methods: {
  147. // 关注作者
  148. followTheAuthor(n) {
  149. uni.request({
  150. url: this.$apiHost + "/Member/attention",
  151. data: {
  152. uuid: getApp().globalData.uuid,
  153. id: this.id,
  154. },
  155. header: {
  156. "content-type": "application/json",
  157. sign: getApp().globalData.headerSign,
  158. },
  159. success: (res) => {
  160. console.log("点赞结果:", res.data);
  161. uni.showToast({
  162. title: res.data.str,
  163. icon: "none",
  164. });
  165. this.loadInfo();
  166. },
  167. fail: (e) => {
  168. console.log("关注失败:", e);
  169. uni.showToast({
  170. title: "网络请求失败",
  171. icon: "none",
  172. });
  173. },
  174. });
  175. },
  176. goBack() {
  177. uni.navigateBack({
  178. delta: 1,
  179. });
  180. },
  181. clickShare(item) {
  182. this.showShare = true;
  183. },
  184. goPage(page) {
  185. if (page == "kefu") {
  186. let that = this;
  187. // #ifdef APP-PLUS
  188. plus.share.getServices((res) => {
  189. const wechat = res.find((i) => i.id === "weixin");
  190. if (wechat) {
  191. wechat.openCustomerServiceChat(
  192. {
  193. corpid: "wwbc06aa8311b6ac08",
  194. url: that.myinfo.wxkf,
  195. },
  196. (src) => {
  197. console.log("success:");
  198. },
  199. (err) => {
  200. console.log("error:");
  201. }
  202. );
  203. } else {
  204. uni.showToast({
  205. title: "没有检测到微信,请先安装",
  206. icon: "error",
  207. });
  208. }
  209. });
  210. // #endif
  211. } else if (page != "") {
  212. uni.navigateTo({
  213. url: page,
  214. });
  215. }
  216. },
  217. loadInfo() {
  218. console.log({
  219. uuid: getApp().globalData.uuid,
  220. skey: getApp().globalData.skey,
  221. });
  222. uni.request({
  223. url: this.$apiHost + "/Member/getHomeInfo",
  224. data: {
  225. uuid: getApp().globalData.uuid,
  226. skey: getApp().globalData.skey,
  227. user_id: this.id,
  228. },
  229. header: {
  230. "content-type": "application/json",
  231. sign: getApp().globalData.headerSign,
  232. },
  233. success: (res) => {
  234. console.log("----:", JSON.parse(JSON.stringify(res.data)));
  235. this.shareTitle = res.data.nickname
  236. this.shareDesc = res.data.content
  237. this.shareImg = res.data.avator
  238. this.userId = res.data.user_id
  239. if (res.data.need_login == "yes") {
  240. uni.removeStorageSync("wapptoken");
  241. uni.redirectTo({
  242. url: "/pages/login/login",
  243. });
  244. return;
  245. }
  246. if (res.data.aihao) {
  247. this.aihao_tags = res.data.aihao.split(",");
  248. }
  249. this.myinfo = res.data;
  250. },
  251. complete: (com) => {
  252. // uni.hideLoading();
  253. },
  254. fail: (e) => {
  255. console.log("----e:", e);
  256. },
  257. });
  258. },
  259. switchTab(index) {
  260. this.activeTab = index;
  261. this.offset = 0;
  262. this.hasMore = true;
  263. this.worksList = [];
  264. this.loadWorksList();
  265. },
  266. loadWorksList() {
  267. if (this.isLoading) return;
  268. this.isLoading = true;
  269. // 根据activeTab选择不同的API
  270. uni.request({
  271. url: this.$apiHost + '/Work/getlist',
  272. data: {
  273. uuid: getApp().globalData.uuid,
  274. skey: getApp().globalData.skey,
  275. type: "other", // 固定为my,表示获取自己的作品
  276. offset: this.offset,
  277. user_id: this.id
  278. },
  279. header: {
  280. "content-type": "application/json",
  281. sign: getApp().globalData.headerSign,
  282. },
  283. success: (res) => {
  284. console.log("列表数据:", JSON.parse(JSON.stringify(res.data)));
  285. if (res.data.success == "yes" && res.data.list) {
  286. if (res.data.list.length > 0) {
  287. this.worksList = [...this.worksList, ...res.data.list];
  288. this.offset += res.data.list.length;
  289. }
  290. if (res.data.list.length < 20) {
  291. this.hasMore = false;
  292. }
  293. } else {
  294. this.hasMore = false;
  295. }
  296. },
  297. complete: () => {
  298. this.isLoading = false;
  299. },
  300. fail: (e) => {
  301. console.log("请求列表失败:", e);
  302. this.isLoading = false;
  303. },
  304. });
  305. },
  306. firstLevelNavActiveSwitch(n) {
  307. this.firstLevelNavActive = n;
  308. this.offset = 0;
  309. this.hasMore = true;
  310. this.worksList = [];
  311. if (this.firstLevelNavActive == 0) {
  312. this.activeTab = 0;
  313. }
  314. this.loadWorksList();
  315. },
  316. loadMoreWorks() {
  317. if (this.hasMore && !this.isLoading) {
  318. this.loadWorksList();
  319. }
  320. },
  321. updateDataList() {
  322. this.data_list = this.worksList.map((item) => {
  323. return {
  324. url:
  325. item.images || item.img_url || item.url || "../../static/logo.png",
  326. title: item.title || item.description || "作品",
  327. id: item.id,
  328. };
  329. });
  330. },
  331. goWork(item) {
  332. uni.$emit("check_login", () => { });
  333. uni.navigateTo({
  334. url: "/pages/index/workDetail?id=" + item.id,
  335. });
  336. },
  337. navigateToFollow() {
  338. uni.navigateTo({
  339. url: "/pages/my/follow",
  340. });
  341. },
  342. },
  343. };
  344. </script>
  345. <style scoped lang="scss">
  346. // 导入FontAwesome
  347. @import url("https://cdnjs.cloudflare.com/ajax/libs/font-awesome/4.7.0/css/font-awesome.min.css");
  348. page {
  349. background-color: #fff;
  350. padding-top: var(--status-bar-height);
  351. padding-bottom: 144rpx;
  352. }
  353. .page {
  354. background-color: #fff;
  355. width: 100%;
  356. min-height: 100vh;
  357. }
  358. .topBody {
  359. width: 750rpx;
  360. }
  361. .header {
  362. padding: 20rpx;
  363. padding-top: 48rpx;
  364. background: linear-gradient(225deg, #cdff9f 0%, #acff5f 30%, #d0ffa5 100%);
  365. min-height: 720rpx;
  366. margin-bottom: -210rpx;
  367. .card-box {
  368. width: 100%;
  369. min-height: 440rpx;
  370. position: relative;
  371. left: 0;
  372. top: 0%;
  373. overflow: hidden;
  374. .card-top {
  375. height: 435rpx;
  376. width: 100%;
  377. background: url("../../static/me/my-card-bg.png") top center / 100% auto,
  378. #fff;
  379. position: absolute;
  380. top: 0%;
  381. left: 0;
  382. z-index: 5;
  383. padding: 24rpx;
  384. padding-top: 16rpx;
  385. box-sizing: border-box;
  386. border-radius: 25rpx;
  387. .top-box {
  388. display: flex;
  389. justify-content: space-between;
  390. padding-top: 8rpx;
  391. background: url("../../static/me/car-top-bg-center.png") top center/ 146rpx 50rpx no-repeat;
  392. .hello-box {
  393. font-family: "CustomFont" !important;
  394. font-size: 36rpx;
  395. font-weight: 700;
  396. }
  397. .settingBtn-box {
  398. width: 74rpx;
  399. display: flex;
  400. align-items: center;
  401. justify-content: space-between;
  402. image {
  403. width: 64rpx;
  404. height: 64rpx;
  405. }
  406. }
  407. }
  408. .userinfo-box {
  409. min-height: 120rpx;
  410. width: 100%;
  411. display: flex;
  412. .avator {
  413. width: 120rpx;
  414. height: 120rpx;
  415. margin-right: 16rpx;
  416. }
  417. .userinfo-right {
  418. .nickname {
  419. font-weight: bold;
  420. margin-bottom: 0rpx;
  421. display: flex;
  422. flex-direction: row;
  423. justify-content: flex-start;
  424. align-items: center;
  425. display: flex;
  426. >text {
  427. max-width: 380rpx;
  428. font-family: "PingFang SC-Bold";
  429. font-weight: 400;
  430. font-size: 36rpx;
  431. }
  432. image {
  433. width: 36rpx;
  434. margin-left: 8rpx;
  435. margin-right: 10rpx;
  436. }
  437. .level {
  438. font-weight: 400;
  439. font-size: 20rpx;
  440. font-family: "PingFang SC-Bold";
  441. background: linear-gradient(360deg, #acf934 0%, #ffe439 100%);
  442. border-radius: 8rpx;
  443. padding: 2rpx 8rpx;
  444. }
  445. }
  446. .label {
  447. height: 55rpx;
  448. height: 110rpx;
  449. overflow: hidden;
  450. >view {
  451. color: #acf934;
  452. font-family: "PingFang SC-Medium";
  453. font-weight: 400;
  454. font-size: 20rpx;
  455. background: #1f1f1f;
  456. border-radius: 6px 6px 6px 6px;
  457. display: inline-block;
  458. margin-left: 10rpx;
  459. margin-bottom: 10rpx;
  460. padding: 6rpx 16rpx;
  461. }
  462. }
  463. }
  464. }
  465. .intro_row {
  466. width: 100%;
  467. margin-bottom: 20rpx;
  468. display: flex;
  469. align-items: center;
  470. .intro_text {
  471. color: #1f1f1f;
  472. font-size: 28rpx;
  473. font-family: "PingFang SC-Bold";
  474. font-weight: 400;
  475. padding-right: 0rpx;
  476. }
  477. .add_icon {
  478. width: 28rpx;
  479. margin-left: 10rpx;
  480. }
  481. }
  482. .bom {
  483. display: flex;
  484. align-items: center;
  485. justify-content: space-between;
  486. .follow_info {
  487. display: flex;
  488. align-items: center;
  489. justify-content: space-between;
  490. width: 340rpx;
  491. .follow-box {
  492. display: flex;
  493. flex-direction: column;
  494. align-items: center;
  495. justify-content: center;
  496. text-align: center;
  497. }
  498. .num {
  499. width: 100%;
  500. font-size: 36rpx;
  501. font-weight: bold;
  502. color: #333;
  503. }
  504. .label {
  505. width: 100%;
  506. font-size: 28rpx;
  507. color: #999;
  508. }
  509. .separator {
  510. width: 2rpx;
  511. height: 24rpx;
  512. background-color: #e5e5e5;
  513. margin: 0 30rpx;
  514. }
  515. }
  516. .points-box {
  517. display: flex;
  518. justify-content: space-between;
  519. .followTheAuthor {
  520. padding: 6rpx 40rpx 8rpx 35rpx;
  521. border-radius: 26rpx;
  522. margin-right: 16rpx;
  523. transition: all 0.6s;
  524. border: 2rpx solid transparent;
  525. &.followTheAuthor1 {
  526. color: #acf934;
  527. background: #1f1f1f;
  528. }
  529. &.followTheAuthor0 {
  530. border: 2rpx solid #1f1f1f;
  531. background: #fff;
  532. }
  533. }
  534. }
  535. }
  536. }
  537. }
  538. }
  539. .myinfo {
  540. width: 100%;
  541. display: flex;
  542. flex-direction: column;
  543. border-radius: 28rpx 28rpx 0 0;
  544. padding: 24rpx 20rpx;
  545. justify-content: flex-start;
  546. box-sizing: border-box;
  547. background: #fff;
  548. .numlist1 {
  549. display: grid;
  550. grid-template-columns: repeat(2, 1fr);
  551. }
  552. }
  553. </style>