index.vue 18 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719
  1. <template>
  2. <view class="container" :data-theme="theme">
  3. <!-- :style="userInfo.avatar?{ backgroundImage: `url(${userInfo.avatar})` }: ''" -->
  4. <!-- #ifdef MP || APP -->
  5. <NavBar navTitle="个人主页" :isBackgroundColor="false" iconColor='#fff'></NavBar>
  6. <!-- #endif -->
  7. <view class="header">
  8. <view class="header-bg" :style="{'background-image': userInfo.avatar}">
  9. <img :src="userInfo.avatar" alt="">
  10. <view class="header-bg-mc"></view>
  11. </view>
  12. <view class="user_wrapper flex-between-center">
  13. <image v-if="userInfo.userLevelIcon" class="level_icon" :src="userInfo.userLevelIcon" alt="">
  14. <view class="flex-y-center row-middle">
  15. <image :src="userInfo.avatar || urlDomain+'crmebimage/presets/morenT.png'" class="picture">
  16. </image>
  17. <view class="user_text flex-1">
  18. <view class="name acea-row">
  19. <text>{{userInfo.isLogoff ? "用户已注销": (userInfo.nickname || '')}}</text>
  20. </view>
  21. <!-- <view v-if="userInfo.id" class="user_id">ID: {{userInfo.id || ''}}</view> -->
  22. <view class="flex-between-center mt-16" @click="onEdit('school')">
  23. <view class="user_id">学校: {{school || '暂无'}}</view>
  24. <text v-show="userInfo.id==uid" class="ml10 iconfont icon-fabuzhongcao"></text>
  25. </view>
  26. </view>
  27. </view>
  28. <view v-if="id && id!=uid" @click.stop="followAuthor">
  29. <button v-if="!userInfo.isConcerned" class="follow_btn focus">
  30. <text class="iconfont icon-jiahao2"></text>关注
  31. </button>
  32. <button v-else class="follow_btn focused">已关注</button>
  33. </view>
  34. <view v-if="userInfo.id==uid">
  35. <navigator hover-class="none" :url="`/pages/discover/discover_release/index?fair=${true}`"
  36. class="follow_btn focus bg-color">
  37. 去发布
  38. </navigator>
  39. </view>
  40. </view>
  41. <view class="acea-row plant_info" @click="onEdit('signature')">
  42. <view v-if="!userInfo.signature && userInfo.id==uid">点击可编辑个性签名</view>
  43. <view class="" v-if="userInfo.signature" style="width: 92%;">
  44. <view class="acea-row" v-if="userInfo.isMore || userInfo.signature.length<=30">
  45. <text class="signature">{{userInfo.signature}}</text>
  46. <text v-if="userInfo.isMore" class="more" @click.stop="moreTap">收起</text>
  47. </view>
  48. <view v-else class="acea-row">
  49. <text class="info signature">{{userInfo.signature.slice(0,23)}}...</text>
  50. <text class="more" @click.stop="moreTap"> 展开</text>
  51. </view>
  52. </view>
  53. <text v-show="userInfo.id==uid" class="ml10 iconfont icon-fabuzhongcao"></text>
  54. </view>
  55. <view class="plant_info" style="padding-bottom: 30rpx;">
  56. <view class="count_wrapper acea-row">
  57. <navigator :url="!id ? '/pages/discover/discover_follow/index?type=follow' : ''" class="item"
  58. hover-class="none">
  59. <text class="mr10">{{userInfo.concernedNum}}</text> 关注
  60. </navigator>
  61. <navigator :url="!id ? '/pages/discover/discover_follow/index?type=fans' : ''" class="item"
  62. hover-class="none">
  63. <text class="mr10">{{userInfo.fansNum}}</text> 粉丝
  64. </navigator>
  65. <view class="item">
  66. <text class="mr10">{{userInfo.likeNum}}</text> 获赞
  67. </view>
  68. </view>
  69. </view>
  70. <view v-if="!id && isShow" class="tab_count relative">
  71. <text @click.stop="changeTab(0)" :class="tab==0 ? 'on' : ''">我发布的</text>
  72. <text @click.stop="changeTab(1)" :class="tab==1 ? 'on' : ''">我想要的</text>
  73. <text @click.stop="changeTab(2)" :class="tab==2 ? 'on' : ''">我收藏的</text>
  74. </view>
  75. </view>
  76. <view class="main">
  77. <view class="tab-conts">
  78. <view v-if="list.length > 0" class="goods-wrap flex-1">
  79. <view class="goods">
  80. <!-- <WaterfallsFlow v-if="list.length" :wfList="list" :fromType="1" fromTo="home">
  81. </WaterfallsFlow> -->
  82. <WaterfallsFlow :wfList='list' :type="1" :isDynamics="true" :userFair="true" :isManage="manage">
  83. <template slot-scope="{item}">
  84. <WaterfallsFlowItem :item="item" :type="1" :isStore="1" />
  85. </template>
  86. </WaterfallsFlow>
  87. </view>
  88. </view>
  89. <view class="empty-boxs noContent" v-if="list.length == 0 && !loading">
  90. <emptyPage title="暂无更多内容~" mTop="13%" :imgSrc="urlDomain+'crmebimage/presets/noguanzhu.png'">
  91. </emptyPage>
  92. </view>
  93. <view class='loadingicon acea-row row-center-wrapper'>
  94. <text class='loading iconfont icon-jiazai' :hidden='loading==false'></text>
  95. <view class="end" :hidden="loading || list.length == 0"><text
  96. :class="loaded ? 'loaded' : ''">{{loadTitle}}</text>
  97. </view>
  98. </view>
  99. </view>
  100. </view>
  101. <uni-popup ref="inputDialog" type="dialog">
  102. <view v-if="isShowSignature" class="tui-modal-custom">
  103. <view class="fs-32 fw-500 lh-44rpx text-center">{{fieldStr == 'signature' ? '编辑简介' : '编辑学校'}}</view>
  104. <view class="mt-24 bg--w111-f5f5f5 rd-16rpx p-24">
  105. <textarea v-if="fieldStr == 'signature'" class="w-full fs-26 h-342" ref="myTextarea" v-model="signature" :focus="focus"
  106. :always-embed="true" :adjust-position="true" cursor-spacing="85rpx"
  107. placeholder="请输入内容" :maxlength="100" name="desc" />
  108. <input v-if="fieldStr == 'school'" class="placeholder" type='text' v-model='school' :focus="focus"
  109. placeholder='请输入学校' placeholder-class='placeholder'></input>
  110. </view>
  111. <view class="flex-between-center mt-40">
  112. <view class="w-244 h-72 rd-36rpx flex-center fs-26 font-color close-btn" @tap="handleInputClose">取消
  113. </view>
  114. <view class="w-244 h-72 rd-36rpx flex-center bg-color text--w111-fff fs-26"
  115. @tap="handleInputConfirm">保存
  116. </view>
  117. </view>
  118. </view>
  119. </uni-popup>
  120. </view>
  121. </template>
  122. <script>
  123. // +----------------------------------------------------------------------
  124. // | CRMEB [ CRMEB赋能开发者,助力企业发展 ]
  125. // +----------------------------------------------------------------------
  126. // | Copyright (c) 2016~2025 https://www.crmeb.com All rights reserved.
  127. // +----------------------------------------------------------------------
  128. // | Licensed CRMEB并不是自由软件,未经许可不能去掉CRMEB相关版权
  129. // +----------------------------------------------------------------------
  130. // | Author: CRMEB Team <admin@crmeb.com>
  131. // +----------------------------------------------------------------------
  132. import WaterfallsFlow from '@/components/WaterfallsFlow/WaterfallsFlow.vue'
  133. import WaterfallsFlowItem from '@/components/discoverFlowItem/discoverFlowItem.vue'
  134. import emptyPage from '@/components/emptyPage.vue';
  135. import NavBar from '@/components/navBar.vue';
  136. import {
  137. userHomeApi,
  138. myHomeApi,
  139. authorNoteApi,
  140. mySecondHandListApi,
  141. myLikeListApi,
  142. secondHandListApi,
  143. secondHandFollowListApi,
  144. editSignatureApi,
  145. editSchoolApi
  146. } from '@/api/discover.js';
  147. import {
  148. toLogin
  149. } from '@/libs/login.js';
  150. import {
  151. mapGetters
  152. } from "vuex";
  153. import {
  154. discoverFollowAuthor
  155. } from '@/libs/follow.js';
  156. const app = getApp();
  157. let sysHeight = uni.getSystemInfoSync().statusBarHeight;
  158. export default {
  159. components: {
  160. WaterfallsFlow,
  161. WaterfallsFlowItem,
  162. emptyPage,
  163. NavBar
  164. },
  165. data() {
  166. return {
  167. sysHeight: sysHeight,
  168. urlDomain: this.$Cache.get("imgHost"),
  169. theme: app.globalData.theme,
  170. list: [], // 内容列表
  171. loadTitle: '加载更多',
  172. loading: false,
  173. loaded: false,
  174. isShowAuth: false, //是否隐藏授权
  175. isAuto: false, //没有授权的不会自动授权
  176. userInfo: {},
  177. where: {
  178. page: 1,
  179. limit: 10
  180. },
  181. tab: 0,
  182. id: '', //作者id
  183. isShow: false,
  184. focus: false,
  185. isShowSignature: false, // 是否显示简介编辑内容
  186. signature: '', //弹窗中的签名
  187. school: '',
  188. fieldStr: '',
  189. manage: 1
  190. }
  191. },
  192. created() {},
  193. computed: {
  194. ...mapGetters(['isLogin', 'uid']),
  195. },
  196. watch: {},
  197. onLoad: function(options) {
  198. this.id = options.id ? options.id : '';
  199. },
  200. onShow() {
  201. // if (this.id) {
  202. // this.isShow = false
  203. // this.getUserHome(this.id);
  204. // this.authorNoteList();
  205. // } else {
  206. this.isShow = true
  207. this.getMyHome();
  208. this.myNoteList();
  209. // }
  210. },
  211. onReady() {},
  212. mounted: function() {},
  213. methods: {
  214. moreTap() {
  215. this.$set(this.userInfo, 'isMore', !this.userInfo.isMore)
  216. },
  217. //个性签名取消
  218. handleInputClose() {
  219. this.$refs.inputDialog.close()
  220. this.isShowSignature = false;
  221. },
  222. //个性签名保存
  223. handleInputConfirm() {
  224. const api = this.fieldStr == 'signature' ? editSignatureApi({signature: this.signature}) : editSchoolApi({school: this.school});
  225. api.then(res => {
  226. uni.showToast({
  227. title: res.data,
  228. icon: 'none'
  229. })
  230. this.getMyHome();
  231. }).catch(err => {
  232. uni.showToast({
  233. title: err,
  234. icon: 'none'
  235. })
  236. });
  237. // 关闭窗口后,恢复默认内容
  238. this.$refs.inputDialog.close()
  239. this.isShowSignature = false;
  240. },
  241. //编辑个性签名
  242. onEdit(str) {
  243. if (this.userInfo.id == this.uid) {
  244. this.fieldStr = str;
  245. this.isShowSignature = true;
  246. this.signature = this.userInfo.signature;
  247. this.$refs.inputDialog.open();
  248. }
  249. },
  250. //回退页面之后重新加载页面
  251. reFresh() {
  252. this.loading = false;
  253. this.loaded = false;
  254. this.where = {
  255. page: 1,
  256. limit: 10
  257. }
  258. this.list = []
  259. // if (this.id) {
  260. // this.getUserHome(this.id);
  261. // this.authorNoteList();
  262. // } else {
  263. this.getMyHome();
  264. this.myNoteList();
  265. // }
  266. },
  267. //获取我的用户信息
  268. getMyHome() {
  269. myHomeApi().then(res => {
  270. console.log(res.data)
  271. this.userInfo = res.data;
  272. this.signature = this.userInfo.signature
  273. this.school = this.userInfo.school
  274. this.isMore = false;
  275. }).catch(err => {
  276. uni.showToast({
  277. title: err,
  278. icon: 'none'
  279. })
  280. });
  281. },
  282. //逛逛用户主页
  283. getUserHome(id) {
  284. userHomeApi(id).then(res => {
  285. this.userInfo = res.data
  286. }).catch(err => {
  287. uni.showToast({
  288. title: err,
  289. icon: 'none'
  290. })
  291. });
  292. },
  293. // 关注作者
  294. followAuthor: function() {
  295. if (this.isLogin) {
  296. if (this.userInfo.isLogoff) return;
  297. discoverFollowAuthor(this.id).then(() => {
  298. this.$set(this.userInfo, 'isConcerned', !this.userInfo.isConcerned);
  299. });
  300. } else {
  301. toLogin();
  302. }
  303. },
  304. changeTab(tab) {
  305. this.tab = tab
  306. this.where.page = 1
  307. this.loaded = this.loading = false
  308. this.list = []
  309. if (tab === 0) {
  310. this.manage = 1;
  311. this.myNoteList();
  312. } else if (tab === 1) {
  313. this.manage = 0;
  314. this.myLikeList();
  315. } else if (tab === 2) {
  316. this.manage = 0;
  317. this.myFollowList()
  318. }
  319. },
  320. // 获取我的点赞作品
  321. myFollowList: function() {
  322. let that = this;
  323. if (that.loaded || that.loading) return;
  324. that.loading = true;
  325. that.loadTitle = '';
  326. secondHandFollowListApi(that.where).then(res => {
  327. let list = res.data.list;
  328. let goods = that.$util.SplitArray(list, that.list);
  329. that.loaded = list.length < that.where.limit;
  330. that.loading = false;
  331. that.loadTitle = that.loaded ? '到底了' : '加载更多';
  332. that.$set(that, 'list', goods);
  333. that.$set(that.where, 'page', that.where.page + 1);
  334. }).catch(err => {
  335. that.loading = false;
  336. uni.showToast({
  337. title: err,
  338. icon: 'none'
  339. })
  340. })
  341. },
  342. // 获取我的点赞作品
  343. myLikeList: function() {
  344. let that = this;
  345. if (that.loaded || that.loading) return;
  346. that.loading = true;
  347. that.loadTitle = '';
  348. secondHandListApi(that.where).then(res => {
  349. let list = res.data.list;
  350. let goods = that.$util.SplitArray(list, that.list);
  351. that.loaded = list.length < that.where.limit;
  352. that.loading = false;
  353. that.loadTitle = that.loaded ? '到底了' : '加载更多';
  354. that.$set(that, 'list', goods);
  355. that.$set(that.where, 'page', that.where.page + 1);
  356. }).catch(err => {
  357. that.loading = false;
  358. uni.showToast({
  359. title: err,
  360. icon: 'none'
  361. })
  362. })
  363. },
  364. // 获取我的的作品
  365. myNoteList: function() {
  366. let that = this;
  367. if (that.loaded || that.loading) return;
  368. that.loading = true;
  369. that.loadTitle = '';
  370. mySecondHandListApi(that.where).then(res => {
  371. let list = res.data.list;
  372. let goods = that.$util.SplitArray(list, that.list);
  373. that.loaded = list.length < that.where.limit;
  374. that.loading = false;
  375. that.loadTitle = that.loaded ? '到底了' : '加载更多';
  376. that.$set(that, 'list', goods);
  377. that.$set(that.where, 'page', that.where.page + 1);
  378. }).catch(err => {
  379. that.loading = false;
  380. uni.showToast({
  381. title: err,
  382. icon: 'none'
  383. })
  384. })
  385. },
  386. // 作者的作品
  387. authorNoteList: function() {
  388. let that = this;
  389. if (that.loaded || that.loading) return;
  390. that.loading = true;
  391. that.loadTitle = '';
  392. this.where.authorId = this.id
  393. authorNoteApi(this.where.authorId, that.where).then(res => {
  394. let list = res.data.list;
  395. let goods = that.$util.SplitArray(list, that.list);
  396. that.loaded = list.length < that.where.limit;
  397. that.loading = false;
  398. that.loadTitle = that.loaded ? '到底了' : '加载更多';
  399. that.$set(that, 'list', goods);
  400. that.$set(that.where, 'page', that.where.page + 1);
  401. }).catch(err => {
  402. that.loading = false;
  403. uni.showToast({
  404. title: err,
  405. icon: 'none'
  406. })
  407. })
  408. }
  409. },
  410. onReachBottom() {
  411. // if (this.id) {
  412. // this.authorNoteList();
  413. // } else {
  414. if (this.tab === 0) {
  415. this.myNoteList();
  416. } else {
  417. this.myLikeList();
  418. }
  419. // }
  420. },
  421. onPullDownRefresh() {},
  422. // 滚动监听
  423. onPageScroll(e) {
  424. // 传入scrollTop值并触发所有easy-loadimage组件下的滚动监听事件
  425. uni.$emit('scroll');
  426. }
  427. }
  428. </script>
  429. <style lang="scss" scoped>
  430. .close-btn {
  431. @include coupons_border_color(theme);
  432. }
  433. .tui-modal-custom {
  434. width: 600rpx;
  435. position: relative;
  436. box-sizing: border-box;
  437. padding: 40rpx;
  438. border-radius: 16px;
  439. background-color: #fff;
  440. z-index: 9999;
  441. .h-342 {
  442. min-height: 268rpx;
  443. max-height: 268rpx;
  444. ;
  445. overflow-y: scroll;
  446. }
  447. }
  448. .signature {
  449. overflow: hidden;
  450. display: -webkit-box;
  451. -webkit-line-clamp: 5;
  452. -webkit-box-orient: vertical;
  453. text-overflow: ellipsis;
  454. width: 88%;
  455. }
  456. .goods-wrap {
  457. padding-top: 24rpx;
  458. }
  459. .more {
  460. font-weight: 600;
  461. margin-left: 8rpx;
  462. }
  463. .container {
  464. background: #ffffff;
  465. min-height: 100vh;
  466. }
  467. .header-bg {
  468. position: absolute;
  469. width: 100%;
  470. height: 650rpx;
  471. top: 0;
  472. /* #ifdef MP || APP-PLUS */
  473. z-index: -1;
  474. /* #endif */
  475. /* #ifdef H5 */
  476. z-index: 0;
  477. /* #endif */
  478. z-index: 0;
  479. filter: blur(0);
  480. overflow: hidden;
  481. img {
  482. width: 100%;
  483. height: 100%;
  484. filter: blur(16rpx);
  485. transform: scale(1.5);
  486. }
  487. .header-bg-mc {
  488. position: absolute;
  489. top: 0;
  490. width: 100%;
  491. height: 100%;
  492. background-image: linear-gradient(180deg, rgba(0, 0, 0, 0.5) 0%, rgba(0, 0, 0, 0.1) 39%, rgba(0, 0, 0, 0.7) 100%);
  493. }
  494. }
  495. .header {
  496. width: 750rpx;
  497. padding: 20rpx 0 0;
  498. box-sizing: border-box;
  499. background: linear-gradient(360deg, #72798E 0%, #384857 99%);
  500. opacity: 1;
  501. .tab_count {
  502. text-align: center;
  503. background: #ffffff;
  504. padding: 30rpx 0 15rpx 0;
  505. border-radius: 12px 12px 0 0;
  506. text {
  507. font-size: 28rpx;
  508. color: #999999;
  509. margin: 0 30rpx;
  510. position: relative;
  511. padding-bottom: 14rpx;
  512. &.on {
  513. font-size: 32rpx;
  514. color: #282828;
  515. font-weight: bold;
  516. &::after {
  517. content: "";
  518. width: 80%;
  519. height: 5rpx;
  520. @include main_bg_color(theme);
  521. position: absolute;
  522. bottom: 0;
  523. left: 12rpx;
  524. }
  525. .underline {
  526. opacity: 1;
  527. }
  528. }
  529. }
  530. }
  531. .user_wrapper {
  532. align-items: center;
  533. justify-content: space-between;
  534. padding: 0 34rpx;
  535. position: relative;
  536. .level_icon {
  537. position: absolute;
  538. width: 38rpx;
  539. height: 38rpx;
  540. margin: 4rpx 0 0 6rpx;
  541. border: none;
  542. z-index: 11;
  543. bottom: 2rpx;
  544. left: 124rpx;
  545. }
  546. .image,
  547. uni-image,
  548. image {
  549. width: 140rpx;
  550. height: 140rpx;
  551. border-radius: 100%;
  552. border: 4rpx solid #ffffff;
  553. }
  554. .user_text {
  555. margin-left: 30rpx;
  556. color: #FFFFFF;
  557. .name {
  558. font-size: 34rpx;
  559. font-weight: bold;
  560. align-items: center;
  561. }
  562. .user_id {
  563. text-overflow: ellipsis;
  564. white-space: nowrap;
  565. overflow: hidden;
  566. max-width: 300rpx;
  567. font-size: 24rpx;
  568. }
  569. }
  570. }
  571. .plant_info {
  572. position: relative;
  573. padding: 0 34rpx;
  574. margin-top: 30rpx;
  575. justify-content: space-between;
  576. color: #ffffff;
  577. font-size: 24rpx;
  578. .count_wrapper {
  579. color: #FFFFFF;
  580. font-size: 24rpx;
  581. .item {
  582. text-align: center;
  583. margin-right: 60rpx;
  584. &:last-child {
  585. margin-right: 0;
  586. }
  587. text {
  588. font-size: 30rpx;
  589. margin-top: 10rpx;
  590. }
  591. }
  592. }
  593. }
  594. .iconfont {
  595. font-size: 24rpx;
  596. margin-right: 12rpx;
  597. }
  598. .follow_btn {
  599. color: #ffffff;
  600. font-size: 26rpx;
  601. display: flex;
  602. align-items: center;
  603. justify-content: center;
  604. width: 146rpx;
  605. height: 62rpx;
  606. @include linear-gradient(theme);
  607. border-radius: 33rpx;
  608. .icon-fabu {
  609. font-size: 24rpx;
  610. }
  611. &.focused {
  612. background: transparent;
  613. color: #FFFFFF;
  614. border: 1px solid #FFFFFF;
  615. }
  616. }
  617. }
  618. .main {
  619. background: #ffffff;
  620. position: relative;
  621. }
  622. .goods {
  623. // display: flex;
  624. // flex-wrap: wrap;
  625. // justify-content: space-between;
  626. // width: 750rpx;
  627. padding: 0 24rpx;
  628. }
  629. .empty {
  630. margin: 130rpx 0 150rpx;
  631. text-align: center;
  632. image,
  633. uni-image {
  634. display: inline-block;
  635. width: 414rpx;
  636. height: 305rpx;
  637. }
  638. text {
  639. display: block;
  640. color: #999999;
  641. font-size: 26rpx;
  642. }
  643. }
  644. .end {
  645. margin-top: 50rpx 0;
  646. text-align: center;
  647. text {
  648. color: #999999;
  649. font-size: 22rpx;
  650. position: relative;
  651. &.loaded {
  652. &::before,
  653. &::after {
  654. content: "";
  655. display: inline-block;
  656. width: 22rpx;
  657. height: 1rpx;
  658. background: #999999;
  659. position: absolute;
  660. top: 18rpx;
  661. opacity: .5;
  662. }
  663. &::before {
  664. left: -30rpx;
  665. }
  666. &::after {
  667. right: -30rpx;
  668. }
  669. }
  670. }
  671. }
  672. </style>