crowdfundingDetails.vue 25 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065
  1. <template>
  2. <view class="crowdfunding-details">
  3. <view class="custom-navbar" :style="navBgStyle">
  4. <view class="navbar-left scale-tap" @click="goBack">
  5. <image src="@/static/crowdFunding/back.png" mode="widthFix"></image>
  6. </view>
  7. <view class="navbar-center one-omit" style="max-width: 70vw; " :style="{ opacity: navBgOpacity }">
  8. {{ detail.title }}
  9. </view>
  10. <view class="navbar-right scale-tap" @click="showShare = true">
  11. <image src="@/static/crowdFunding/share.png" mode="widthFix"></image>
  12. </view>
  13. </view>
  14. <!-- 顶部视频图片混合轮播 -->
  15. <view class="swiper-container">
  16. <swiper class="top-swiper" :indicator-dots="false" circular :current="currentMediaIndex"
  17. @change="handleSwiperChange" :duration="300">
  18. <swiper-item v-for="(item, idx) in mediaList" :key="idx" class="swiper-item">
  19. <view v-if="item.type === 'video'" class="media-wrapper">
  20. <video class="swiper-video" :src="item.src" :poster="item.poster" :id="'video-' + idx" controls
  21. object-fit="contain" enable-progress-gesture="false" :loop="false"
  22. :show-fullscreen-btn="false" :show-play-btn="true" :enable-play-gesture="false"
  23. @ended="onVideoEnded" @play="onVideoPlay(idx)" @pause="onVideoPause"></video>
  24. </view>
  25. <image v-else class="swiper-img" :src="item.src" mode="aspectFill" />
  26. </swiper-item>
  27. </swiper>
  28. <!-- 自定义指示点 -->
  29. <view class="custom-dots">
  30. <view v-for="(item, index) in mediaList" :key="index"
  31. :class="['dot', currentMediaIndex === index ? 'active' : '']" @click="switchMedia(index)"></view>
  32. </view>
  33. </view>
  34. <view class="content">
  35. <!-- 项目信息 -->
  36. <view class="section project-card">
  37. <view class="project-title">{{ detail.title }}</view>
  38. <view class="progress-bar-wrap">
  39. <uv-line-progress height="8rpx" :showText="false" :percentage="detail.progress"
  40. inactiveColor="#F0F0F0" activeColor="#ACF934"></uv-line-progress>
  41. <view class="progress-percent">{{ detail.progress + '%' }}</view>
  42. </view>
  43. <view class="project-stats">
  44. <view class="stat-block">
  45. <view class="stat-main amountOfMoney">¥{{ detail.current_amount }}</view>
  46. <view class="stat-sub">{{ detail.supporter_count }}人支持</view>
  47. </view>
  48. <view class="stat-block">
  49. <view class="stat-main">{{ detail.daysRemaining }}天</view>
  50. <view class="stat-sub">剩余时间</view>
  51. </view>
  52. <view class="stat-block">
  53. <view class="stat-main">¥{{ detail.goal_amount }}</view>
  54. <view class="stat-sub">众筹目标</view>
  55. </view>
  56. </view>
  57. </view>
  58. <!-- 项目更新 -->
  59. <view class="section project-update" v-if="projectUpdate && projectUpdate.numb">
  60. <view class="project-update-left scale-tap"
  61. @click="goPage('/pages/crowdFunding/projectUpdateDetails?id=' + projectUpdate.id)">
  62. <view class="project-update-left-title">
  63. <view>·第{{ projectUpdate.numb }}次更新</view>
  64. <view style="color: #999;">{{ projectUpdate.create_time }}</view>
  65. </view>
  66. <view class="project-update-left-content">
  67. <view class="two-omit">{{ projectUpdate.title }}</view>
  68. <view class="image">
  69. <image :src="projectUpdate.image" />
  70. </view>
  71. </view>
  72. </view>
  73. <view class="project-update-right scale-tap"
  74. @click="goPage('/pages/crowdFunding/discussionArea?tags=update&id=' + projectId)">
  75. <view>历史更新</view>
  76. <image src="@/static/crowdFunding/updateDetails.png"></image>
  77. </view>
  78. </view>
  79. <view class="section comment scale-tap"
  80. @click="goPage('/pages/crowdFunding/discussionArea?tags=comment&id=' + projectId)">
  81. <view class="comment-title">
  82. <view>项目讨论({{ totalNumberOfComments }})</view>
  83. <view class="comment-more"">查看更多
  84. <image src=" @/static/crowdFunding/right.png">
  85. </image>
  86. </view>
  87. </view>
  88. <view class="comment-content">
  89. <block v-for="(item, idx) in commentList" :key="idx">
  90. <view class="comment-item">
  91. <image class="comment-avatar" :src="item.avatar"></image>
  92. <view class="comment-item-main">
  93. <view class="comment-item-content">{{ item.content }}</view>
  94. </view>
  95. <view class="comment-item-like">
  96. <image class="like-icon"
  97. :src="item.liked ? '/static/icon/icon-18.png' : '/static/icon/icon-19.png'"></image>
  98. <text class="like-num">{{ item.likeNum }}</text>
  99. </view>
  100. </view>
  101. </block>
  102. </view>
  103. </view>
  104. <!-- 塔罗牌介绍 -->
  105. <view class="section poster">
  106. <view class="initiator-bar">
  107. <image class="initiator-avatar" :src="detail.creator_avatar" />
  108. <view class="initiator-info">
  109. <text class="initiator-name">{{ detail.creator_nickname }}</text>
  110. <text class="initiator-tag">发起人</text>
  111. </view>
  112. <view class="initiator-service-btn blick-btn-animation"
  113. @click="goPage('/pages/crowdFunding/customerService?id=' + detail.creator_id + '&zc_id=' + detail.id)">
  114. <image class="service-icon" src="@/static/crowdFunding/service.png" />
  115. <text>客服</text>
  116. </view>
  117. </view>
  118. <block v-for="(item, idx) in detail.content_images" :key="idx">
  119. <image class="intro-img" :src="item" mode="widthFix" />
  120. </block>
  121. </view>
  122. <!-- 风险说明 -->
  123. <view class="section risk-section">
  124. <view class="risk-row">
  125. <view class="risk-title">退款政策</view>
  126. <view class="risk-more ">查看更多
  127. <image src="@/static/crowdFunding/right.png" class="risk-more-icon" />
  128. </view>
  129. </view>
  130. <view class="risk-desc">众筹结束前最后1个小时无法申请退款</view>
  131. <view class="risk-row risk-row-border">
  132. <view class="risk-title">风险提示</view>
  133. </view>
  134. <view class="risk-content">
  135. <view>1. 您参与众筹是支持将创意变为现实的过程,而不是直接的商品交易,因此存在一定风险。请您根据自己的判断选择,支持众筹项目。</view>
  136. <view>2. 众筹存在于发起人与支持者之间,摩点作为第三方平台,提供网络空间、技术支持等服务。众筹的回报产品和承诺由发起人负责。</view>
  137. </view>
  138. </view>
  139. </view>
  140. <view class="bottom-bar-reserveASeat"></view>
  141. <view class="bottom-bar">
  142. <view class="bottom-bar-left">
  143. <view class="bar-btn" @click="toggleFavorite">
  144. <image v-if="isFavorite" src="@/static/crowdFunding/collect-active.png"
  145. class="scale-tap bar-icon" />
  146. <image v-else src="@/static/crowdFunding/collect.png" class="scale-tap bar-icon" />
  147. <view class="bar-text">{{ isFavorite ? '已收藏' : '收藏' }}</view>
  148. </view>
  149. <!-- <view class="bar-btn">
  150. <image v-if="true" src="@/static/crowdFunding/like.png" class=" scale-tap bar-icon" />
  151. <image v-else src="@/static/crowdFunding/like-active.png" class=" scale-tap bar-icon" />
  152. <view class="bar-text">看好</view>
  153. </view> -->
  154. </view>
  155. <button class="buy-btn blick-btn-animation" @click="specificationsOpen()">立即购买支持</button>
  156. </view>
  157. <image src="@/static/crowdFunding/backToTop.png" class="back-top scale-tap" v-show="navBgOpacity > 0.9"
  158. @click="scrollToTop"></image>
  159. <!-- 分享弹窗 -->
  160. <SharePopup :visible="showShare" :userId="0" :share-title="shareTitle" :share-desc="shareDesc"
  161. :share-img="shareImg" view="crowdfundingDetails" @close="showShare = false" :isReportContent="true" />
  162. <productSpecifications ref="specSheet" :rewards="rewards" :title="detail.title" @confirm="onSpecConfirm" />
  163. </view>
  164. </template>
  165. <script>
  166. import VideoPlayer from "@/components/VideoPlayer/VideoPlayer.vue";
  167. import SharePopup from "@/components/SharePopup/SharePopup.vue";
  168. import productSpecifications from "./components/productSpecifications/productSpecifications.vue";
  169. export default {
  170. components: {
  171. VideoPlayer,
  172. SharePopup,
  173. productSpecifications
  174. },
  175. data() {
  176. return {
  177. mediaList: [],
  178. videoPlaying: false,
  179. currentMediaIndex: 0,
  180. commentList: [
  181. ],
  182. navBgOpacity: 0,
  183. swiperHeight: 0,
  184. showShare: false,
  185. shareTitle: '【Woh】灯塔 塔罗牌 治愈风泛传特系',
  186. shareDesc: '快来支持这个有趣的众筹项目吧!',
  187. shareImg: require('@/static/crowdFunding/top-img.png'),
  188. userId: 0, // 可根据实际登录用户赋值
  189. isFavorite: false, // 是否已收藏
  190. projectId: null, // 当前项目id
  191. detail: {}, // 众筹详情
  192. projectUpdate: '',
  193. rewards: [],
  194. totalNumberOfComments: 0
  195. }
  196. },
  197. computed: {
  198. navBgStyle() {
  199. return {
  200. background: `rgba(255,255,255,${this.navBgOpacity})`,
  201. transition: 'background 0.3s'
  202. }
  203. }
  204. },
  205. methods: {
  206. // 返回上一页
  207. goBack() {
  208. uni.navigateBack({
  209. delta: 1,
  210. });
  211. },
  212. scrollToTop() {
  213. uni.pageScrollTo({
  214. scrollTop: 0,
  215. duration: 300
  216. });
  217. },
  218. switchMedia(index) {
  219. if (this.currentMediaIndex === index) return;
  220. // 如果当前在播放视频,先暂停
  221. if (this.mediaList[this.currentMediaIndex]?.type === 'video') {
  222. const videoContext = uni.createVideoContext('video-' + this.currentMediaIndex, this);
  223. if (videoContext) {
  224. videoContext.pause();
  225. }
  226. }
  227. this.currentMediaIndex = index;
  228. },
  229. handleSwiperChange(e) {
  230. const lastIndex = this.currentMediaIndex;
  231. this.currentMediaIndex = e.detail.current;
  232. // 如果上一个是视频,暂停它
  233. if (this.mediaList[lastIndex]?.type === 'video') {
  234. const videoContext = uni.createVideoContext('video-' + lastIndex, this);
  235. if (videoContext) {
  236. videoContext.pause();
  237. this.videoPlaying = false;
  238. }
  239. }
  240. },
  241. onVideoPlay(idx) {
  242. // 更新当前播放的视频索引
  243. this.videoPlaying = true;
  244. if (this.currentMediaIndex !== idx) {
  245. this.currentMediaIndex = idx;
  246. }
  247. },
  248. onVideoPause() {
  249. this.videoPlaying = false;
  250. },
  251. onVideoEnded() {
  252. this.videoPlaying = false;
  253. },
  254. goPage(url) {
  255. uni.navigateTo({
  256. url: url
  257. });
  258. },
  259. onSpecConfirm(selectedSpec) {
  260. uni.navigateTo({
  261. url: '/pages/crowdFunding/orderConfirm',
  262. success: function(res) {
  263. // 通过 eventChannel 向被打开页面传送数据
  264. res.eventChannel.emit('acceptDataFromOpener', { selectedSpec: selectedSpec, detail: this.detail });
  265. }.bind(this)
  266. });
  267. },
  268. specificationsOpen() {
  269. this.$refs.specSheet.show();
  270. },
  271. toggleFavorite() {
  272. if (!this.projectId) {
  273. return;
  274. }
  275. const action = this.isFavorite ? 'remove' : 'add';
  276. uni.request({
  277. url: this.$apiHost + '/crowdfund/favorite',
  278. method: 'POST',
  279. header: {
  280. "content-type": "application/x-www-form-urlencoded",
  281. },
  282. data: {
  283. uuid: getApp().globalData.uuid,
  284. skey: getApp().globalData.skey,
  285. crowdfund_id: this.projectId,
  286. action
  287. },
  288. success: (res) => {
  289. console.log(res.data, "收藏");
  290. if (res.data && res.data.success && res.data.success == 'yes') {
  291. this.isFavorite = !this.isFavorite;
  292. uni.showToast({ title: this.isFavorite ? '已收藏' : '已取消收藏', icon: 'none' });
  293. } else {
  294. uni.showToast({ title: res.data.msg || '操作失败', icon: 'none' });
  295. }
  296. },
  297. fail: () => {
  298. uni.showToast({ title: '网络错误', icon: 'none' });
  299. }
  300. });
  301. },
  302. getDetail() {
  303. if (!this.projectId) return;
  304. uni.request({
  305. url: this.$apiHost + '/crowdfund/detail',
  306. method: 'GET',
  307. data: {
  308. id: this.projectId,
  309. uuid: getApp().globalData.uuid,
  310. skey: getApp().globalData.skey
  311. },
  312. success: (res) => {
  313. if (res.data && res.data.success === 'yes' && res.data.data) {
  314. this.processingDataDetails(res.data.data);
  315. // 可根据接口返回字段设置isFavorite等
  316. }
  317. }
  318. });
  319. uni.request({
  320. url: this.$apiHost + '/crowdfund/favorite/status',
  321. method: 'GET',
  322. data: {
  323. crowdfund_id: this.projectId,
  324. uuid: getApp().globalData.uuid,
  325. skey: getApp().globalData.skey
  326. },
  327. success: (res) => {
  328. if (res.data && res.data.success === 'yes' && res.data.data) {
  329. console.log(res.data.data, "收藏");
  330. this.isFavorite = res.data.data.is_favorited;
  331. // 可根据接口返回字段设置isFavorite等
  332. }
  333. }
  334. });
  335. uni.request({
  336. url: this.$apiHost + '/crowdfund/articles',
  337. method: 'GET',
  338. data: {
  339. crowdfund_id: this.projectId,
  340. page: 1,
  341. pageSize: 1,
  342. uuid: getApp().globalData.uuid,
  343. skey: getApp().globalData.skey
  344. },
  345. success: (res) => {
  346. if (res.data && res.data.success === 'yes' && res.data.data) {
  347. if (Array.isArray(res.data.data.list)) {
  348. this.projectUpdate = res.data.data.list[0]
  349. this.projectUpdate.create_time = this.projectUpdate.create_time.replace(/-/g, '.').slice(0, 16)
  350. console.log(this.projectUpdate, 8888);
  351. }
  352. }
  353. }
  354. });
  355. uni.request({
  356. url: this.$apiHost + '/Article/getcomments',
  357. data: {
  358. uuid: getApp().globalData.uuid,
  359. type: 'crowdfund',
  360. id: this.projectId,
  361. page: 1,
  362. limit: 2,
  363. },
  364. header: {
  365. "content-type": "application/json",
  366. 'sign': getApp().globalData.headerSign
  367. },
  368. success: (res) => {
  369. console.log("评论列表:", res.data);
  370. if (res.data.success == "yes") {
  371. this.totalNumberOfComments = res.data.total
  372. // 确保数据存在且是数组,然后只取前两条
  373. this.commentList = (res.data.list || []).slice(0, 2).map(item => ({
  374. avatar: item.user_avatar || '',
  375. content: item.user_content || '',
  376. likeNum: item.like_count || 0,
  377. liked: item.is_like || false
  378. }));
  379. } else {
  380. // 如果请求失败,使用默认空数组
  381. this.commentList = [];
  382. uni.showToast({
  383. title: '获取评论列表失败',
  384. icon: 'none'
  385. });
  386. }
  387. },
  388. fail: (e) => {
  389. console.log("----e:", e);
  390. // 请求失败时使用默认空数组
  391. this.commentList = [];
  392. }
  393. });
  394. },
  395. processingDataDetails(data) {
  396. this.detail = data;
  397. // 确保 image_list 始终是一个数组
  398. data.image_list = data.image_list || [];
  399. const videoItem = data.video_url ? [{
  400. type: 'video',
  401. poster: data.main_image,
  402. src: data.video_url,
  403. }] : [];
  404. const imageItems = data.image_list.map(v => ({
  405. type: 'image',
  406. src: v
  407. }));
  408. // 计算剩余天数
  409. if (data.start_time && data.end_time) {
  410. const startDate = new Date(data.start_time.replace(/-/g, '/'));
  411. const endDate = new Date(data.end_time.replace(/-/g, '/'));
  412. const now = new Date();
  413. // 如果当前时间在开始时间之前,显示总天数
  414. if (now < startDate) {
  415. this.detail.daysRemaining = Math.ceil((endDate - startDate) / (1000 * 60 * 60 * 24));
  416. }
  417. // 如果当前时间在结束时间之后,显示0天
  418. else if (now > endDate) {
  419. this.detail.daysRemaining = 0;
  420. }
  421. // 如果当前时间在开始和结束时间之间,显示剩余天数
  422. else {
  423. this.detail.daysRemaining = Math.ceil((endDate - now) / (1000 * 60 * 60 * 24));
  424. }
  425. } else {
  426. this.detail.daysRemaining = 0;
  427. }
  428. // 计算进度
  429. this.detail.progress = data.current_amount / data.goal_amount
  430. if (Number.isNaN) this.detail.progress = 0
  431. this.mediaList = [...videoItem, ...imageItems];
  432. this.rewards = data.rewards
  433. console.log("回报数据", this.rewards);
  434. console.log("顶部轮播数据", this.mediaList, "mediaList");
  435. console.log("详情", this.detail, "detail");
  436. }
  437. },
  438. mounted() {
  439. this.$nextTick(() => {
  440. // 动态获取轮播图高度
  441. uni.createSelectorQuery().in(this).select('.top-swiper').boundingClientRect(rect => {
  442. if (rect) {
  443. this.swiperHeight = rect.height;
  444. }
  445. }).exec();
  446. });
  447. },
  448. onPageScroll(e) {
  449. const threshold = this.swiperHeight || uni.upx2px(400); // 优先用实际高度
  450. let opacity = 0;
  451. if (e.scrollTop > 0) {
  452. opacity = Math.min(e.scrollTop / threshold, 1);
  453. }
  454. this.navBgOpacity = opacity;
  455. },
  456. onLoad(options) {
  457. // 获取id
  458. this.projectId = options.id || null;
  459. this.getDetail();
  460. }
  461. }
  462. </script>
  463. <style lang="scss" scoped>
  464. .crowdfunding-details {
  465. /* 自定义导航栏样式 */
  466. .custom-navbar {
  467. display: flex;
  468. flex-direction: row;
  469. align-items: center;
  470. justify-content: space-between;
  471. width: 100%;
  472. height: calc(90rpx + var(--status-bar-height));
  473. padding: 0 20rpx;
  474. position: fixed;
  475. top: 0;
  476. z-index: 100;
  477. padding: 12rpx 24rpx;
  478. padding-top: calc(var(--status-bar-height) + 12rpx);
  479. background: transparent;
  480. transition: background 0.3s;
  481. image {
  482. width: 64rpx;
  483. height: 64rpx;
  484. }
  485. }
  486. .swiper-container {
  487. position: relative;
  488. width: 100vw;
  489. height: 100vw;
  490. background: #000;
  491. .top-swiper {
  492. width: 100%;
  493. height: 100%;
  494. .swiper-item {
  495. width: 100%;
  496. height: 100%;
  497. display: flex;
  498. align-items: center;
  499. justify-content: center;
  500. }
  501. .media-wrapper {
  502. width: 100%;
  503. height: 100%;
  504. display: flex;
  505. align-items: center;
  506. justify-content: center;
  507. background: #000;
  508. }
  509. .swiper-video {
  510. width: 100%;
  511. height: 100%;
  512. }
  513. .swiper-img {
  514. width: 100%;
  515. height: 100%;
  516. object-fit: cover;
  517. }
  518. }
  519. .custom-dots {
  520. position: absolute;
  521. bottom: 20rpx;
  522. left: 50%;
  523. transform: translateX(-50%);
  524. display: flex;
  525. gap: 16rpx;
  526. .dot {
  527. width: 12rpx;
  528. height: 12rpx;
  529. border-radius: 50%;
  530. background: rgba(255, 255, 255, 0.5);
  531. transition: all 0.3s;
  532. &.active {
  533. width: 24rpx;
  534. border-radius: 6rpx;
  535. background: #fff;
  536. }
  537. }
  538. }
  539. }
  540. .content {
  541. background: #f2f6f2;
  542. padding: 20rpx;
  543. .section {
  544. background: #fff;
  545. border-radius: 12rpx;
  546. padding: 16rpx;
  547. padding-bottom: 20rpx;
  548. margin: 12rpx 0;
  549. .section-title {
  550. font-size: 28rpx;
  551. font-family: 'PingFang SC-Medium';
  552. margin-bottom: 6rpx;
  553. }
  554. .section-content {
  555. color: #333;
  556. font-size: 24rpx;
  557. line-height: 1.8;
  558. }
  559. .intro-img {
  560. width: 100%;
  561. margin: 0;
  562. padding: 0;
  563. margin-bottom: -10rpx;
  564. }
  565. }
  566. .project-card {
  567. padding-bottom: 15rpx;
  568. .project-title {
  569. font-size: 36rpx;
  570. color: 1f1f1f;
  571. font-family: "PingFang SC-Bold";
  572. font-weight: 400;
  573. }
  574. .progress-bar-wrap {
  575. display: flex;
  576. align-items: center;
  577. font-size: 20rpx;
  578. color: #1F1F1F;
  579. padding-top: 30rpx;
  580. padding-bottom: 14rpx;
  581. .progress-percent {
  582. padding-left: 12rpx;
  583. }
  584. }
  585. .project-stats {
  586. display: flex;
  587. justify-content: space-between;
  588. padding-top: 0;
  589. .stat-block {
  590. display: flex;
  591. flex-direction: column;
  592. align-items: center;
  593. text-align: center;
  594. justify-content: center;
  595. color: #1F1F1F;
  596. &:first-child {
  597. align-items: flex-start;
  598. }
  599. &:last-child {
  600. display: flex;
  601. flex-direction: column;
  602. align-items: center;
  603. text-align: center;
  604. justify-content: center;
  605. color: #1F1F1F;
  606. &:first-child {
  607. align-items: flex-start;
  608. }
  609. &:last-child {
  610. align-items: flex-end;
  611. }
  612. .stat-main {
  613. font-size: 28rpx;
  614. &.amountOfMoney {
  615. font-size: 32rpx;
  616. font-family: "PingFang SC-Bold";
  617. }
  618. }
  619. .stat-sub {
  620. font-size: 20rpx;
  621. }
  622. }
  623. }
  624. }
  625. }
  626. .project-update {
  627. background: transparent;
  628. height: 166rpx;
  629. display: flex;
  630. width: 100%;
  631. justify-content: space-between;
  632. padding: 0;
  633. >view {
  634. border-radius: 12rpx;
  635. background: #fff;
  636. flex-shrink: 0;
  637. }
  638. .project-update-left {
  639. width: 590rpx;
  640. height: 100%;
  641. padding: 16rpx;
  642. .project-update-left-title {
  643. display: flex;
  644. justify-content: space-between;
  645. align-items: center;
  646. font-size: 22rpx;
  647. }
  648. .project-update-left-content {
  649. display: flex;
  650. align-items: center;
  651. margin-top: 8rpx;
  652. >view {
  653. font-size: 24rpx;
  654. font-weight: 400;
  655. font-family: "PingFang SC-Bold";
  656. }
  657. .image {
  658. width: 180rpx;
  659. height: 78rpx;
  660. overflow: hidden;
  661. margin-left: 26rpx;
  662. border-radius: 8rpx;
  663. image {
  664. overflow: hidden;
  665. width: 100%;
  666. }
  667. }
  668. }
  669. }
  670. .project-update-right {
  671. width: 108rpx;
  672. height: 100%;
  673. font-size: 22rpx;
  674. display: flex;
  675. align-items: center;
  676. justify-content: center;
  677. flex-direction: column;
  678. image {
  679. margin-top: 12rpx;
  680. width: 28rpx;
  681. height: 28rpx;
  682. }
  683. }
  684. }
  685. .poster {
  686. padding: 0;
  687. padding-top: 16rpx;
  688. }
  689. }
  690. .comment {
  691. border-radius: 12rpx;
  692. background: #fff;
  693. margin-top: 24rpx;
  694. padding: 0 0 16rpx 0;
  695. .comment-title {
  696. display: flex;
  697. justify-content: space-between;
  698. align-items: center;
  699. font-size: 26rpx;
  700. color: #333;
  701. padding: 18rpx 20rpx 0 20rpx;
  702. .comment-more {
  703. color: #999;
  704. font-size: 22rpx;
  705. display: flex;
  706. align-items: center;
  707. image {
  708. width: 20rpx;
  709. height: 20rpx;
  710. margin-left: 4rpx;
  711. }
  712. }
  713. }
  714. .comment-content {
  715. padding: 0 20rpx;
  716. .comment-item {
  717. display: flex;
  718. //align-items: flex-start;
  719. align-items: center;
  720. padding: 18rpx 0 0 0;
  721. border-bottom: 1rpx solid #f5f5f5;
  722. &:last-child {
  723. border-bottom: none;
  724. }
  725. .comment-avatar {
  726. width: 48rpx;
  727. height: 48rpx;
  728. border-radius: 50%;
  729. margin-right: 16rpx;
  730. flex-shrink: 0;
  731. }
  732. .comment-item-main {
  733. flex: 1;
  734. display: flex;
  735. flex-direction: column;
  736. .comment-item-content {
  737. color: #1f1f1f;
  738. font-size: 24rpx;
  739. line-height: 1.7;
  740. margin-bottom: 8rpx;
  741. display: -webkit-box;
  742. -webkit-line-clamp: 2;
  743. -webkit-box-orient: vertical;
  744. overflow: hidden;
  745. text-overflow: ellipsis;
  746. word-break: break-all;
  747. }
  748. }
  749. .comment-item-like {
  750. display: flex;
  751. align-items: center;
  752. margin-left: 36rpx;
  753. .like-icon {
  754. width: 28rpx;
  755. height: 28rpx;
  756. margin-right: 4rpx;
  757. }
  758. .like-num {
  759. font-size: 22rpx;
  760. color: #888;
  761. }
  762. }
  763. }
  764. }
  765. }
  766. .bottom-bar-reserveASeat {
  767. width: 100%;
  768. height: calc(12rpx + 88rpx + var(--window-bottom) + 30rpx);
  769. }
  770. .bottom-bar {
  771. position: fixed;
  772. left: 0;
  773. right: 0;
  774. bottom: 0;
  775. z-index: 999;
  776. display: flex;
  777. align-items: center;
  778. justify-content: space-between;
  779. background: #fff;
  780. padding: 14rpx 40rpx;
  781. padding-bottom: calc(14rpx + var(--window-bottom));
  782. box-sizing: border-box;
  783. .bottom-bar-left {
  784. display: flex;
  785. align-items: center;
  786. gap: 32rpx;
  787. .bar-btn {
  788. display: flex;
  789. flex-direction: column;
  790. align-items: center;
  791. justify-content: center;
  792. width: 80rpx;
  793. height: 80rpx;
  794. border-radius: 12rpx;
  795. .bar-icon {
  796. width: 48rpx;
  797. height: 48rpx;
  798. margin-bottom: 4rpx;
  799. }
  800. .bar-text {
  801. font-size: 20rpx;
  802. color: #1f1f1f;
  803. font-family: "PingFang SC";
  804. }
  805. }
  806. }
  807. .buy-btn {
  808. width: 588rpx;
  809. height: 88rpx;
  810. background: #1f1f1f;
  811. color: #ACF934;
  812. font-size: 32rpx;
  813. border-radius: 80rpx;
  814. border: none;
  815. font-weight: bold;
  816. text-align: center;
  817. line-height: 80rpx;
  818. margin-left: 24rpx;
  819. }
  820. }
  821. }
  822. .back-top {
  823. position: fixed;
  824. bottom: calc(126rpx + var(--window-bottom));
  825. right: 16rpx;
  826. width: 82rpx;
  827. height: 82rpx;
  828. }
  829. .initiator-bar {
  830. display: flex;
  831. align-items: center;
  832. justify-content: space-between;
  833. background: #fff;
  834. border-radius: 10rpx;
  835. padding: 18rpx 24rpx 18rpx 18rpx;
  836. margin: 0;
  837. .initiator-avatar {
  838. width: 64rpx;
  839. height: 64rpx;
  840. border-radius: 50%;
  841. margin-right: 18rpx;
  842. flex-shrink: 0;
  843. }
  844. .initiator-info {
  845. display: flex;
  846. align-items: center;
  847. flex: 1;
  848. min-width: 0;
  849. }
  850. .initiator-name {
  851. font-size: 30rpx;
  852. color: #222;
  853. font-weight: bold;
  854. margin-right: 12rpx;
  855. max-width: 260rpx;
  856. overflow: hidden;
  857. text-overflow: ellipsis;
  858. white-space: nowrap;
  859. }
  860. .initiator-tag {
  861. background: #1a1a1a;
  862. color: #b6ff4b;
  863. font-size: 20rpx;
  864. border-radius: 8rpx;
  865. padding: 2rpx 12rpx;
  866. margin-left: 2rpx;
  867. }
  868. .initiator-service-btn {
  869. display: flex;
  870. align-items: center;
  871. background: #1a1a1a;
  872. color: #b6ff4b;
  873. font-size: 28rpx;
  874. border-radius: 128rpx;
  875. padding: 0 24rpx 0 12rpx;
  876. height: 56rpx;
  877. margin-left: 18rpx;
  878. font-weight: bold;
  879. }
  880. .service-icon {
  881. width: 32rpx;
  882. height: 32rpx;
  883. margin-right: 8rpx;
  884. }
  885. }
  886. .scale-tap {
  887. transition: transform 0.15s;
  888. }
  889. .scale-tap:active {
  890. transform: scale(0.92);
  891. }
  892. .risk-section {
  893. background: #fff;
  894. border-radius: 12rpx;
  895. margin: 24rpx 0 0 0;
  896. padding: 0 0 18rpx 0;
  897. position: relative;
  898. overflow: hidden;
  899. .risk-row {
  900. display: flex;
  901. align-items: center;
  902. justify-content: space-between;
  903. padding: 18rpx 24rpx 0 0rpx;
  904. font-size: 28rpx;
  905. color: #1f1f1f;
  906. background: #fff;
  907. &.risk-row-border {
  908. border-top: 1rpx solid #f2f2f2;
  909. margin-top: 18rpx;
  910. padding-top: 18rpx;
  911. }
  912. }
  913. .risk-title {
  914. font-size: 28rpx;
  915. color: #1f1f1f;
  916. font-family: 'PingFang SC-Bold';
  917. font-weight: 400;
  918. }
  919. .risk-more {
  920. color: #1f1f1f;
  921. font-size: 24rpx;
  922. display: flex;
  923. align-items: center;
  924. font-weight: 400;
  925. font-family: 'PingFang SC-Bold';
  926. .risk-more-icon {
  927. width: 24rpx;
  928. height: 24rpx;
  929. margin-left: 4rpx;
  930. margin-top: 4rpx;
  931. }
  932. }
  933. .risk-desc {
  934. font-size: 24rpx;
  935. color: #999;
  936. padding: 8rpx 24rpx 0 0;
  937. font-family: 'PingFang SC-Regular';
  938. }
  939. .risk-content {
  940. font-size: 24rpx;
  941. color: #999;
  942. padding: 12rpx 24rpx 0 0;
  943. font-family: 'PingFang SC-Regular';
  944. line-height: 1.7;
  945. >view {
  946. margin-bottom: 6rpx;
  947. }
  948. }
  949. }
  950. </style>