与牧同行-小程序用户端
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

757 lines
13 KiB

  1. .forum-page {
  2. min-height: 100vh;
  3. background: linear-gradient(180deg, #f8fafc 0%, #f1f5f9 100%);
  4. position: relative;
  5. font-family: '思源宋体 Light' !important;
  6. }
  7. /* 顶部栏 */
  8. .header {
  9. background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
  10. padding: 40rpx 30rpx;
  11. border-radius: 0 0 40rpx 40rpx;
  12. box-shadow: 0 10rpx 40rpx rgba(102, 126, 234, 0.15);
  13. margin-bottom: 30rpx;
  14. }
  15. .header-content {
  16. display: flex;
  17. flex-direction: column;
  18. gap: 30rpx;
  19. }
  20. .header-main {
  21. display: flex;
  22. flex-direction: column;
  23. gap: 10rpx;
  24. }
  25. .title-text {
  26. font-size: 44rpx;
  27. font-weight: 800;
  28. color: white;
  29. letter-spacing: -0.5rpx;
  30. }
  31. .title-sub {
  32. font-size: 26rpx;
  33. color: rgba(255, 255, 255, 0.9);
  34. font-weight: 400;
  35. }
  36. /* 搜索框 */
  37. .search-section {
  38. padding: 0 30rpx 25rpx;
  39. }
  40. .search-box {
  41. display: flex;
  42. align-items: center;
  43. background: white;
  44. border-radius: 50rpx;
  45. padding: 0 30rpx;
  46. height: 88rpx;
  47. box-shadow: 0 15rpx 50rpx rgba(0, 0, 0, 0.05);
  48. border: 2rpx solid #e2e8f0;
  49. transition: all 0.3s ease;
  50. }
  51. .search-box:focus-within {
  52. border-color: #667eea;
  53. box-shadow: 0 15rpx 50rpx rgba(102, 126, 234, 0.15);
  54. }
  55. .search-icon {
  56. width: 36rpx;
  57. height: 36rpx;
  58. margin-right: 20rpx;
  59. }
  60. .search-input {
  61. flex: 1;
  62. font-size: 30rpx;
  63. height: 88rpx;
  64. line-height: 88rpx;
  65. color: #1e293b;
  66. box-sizing: border-box;
  67. }
  68. .search-clear {
  69. width: 44rpx;
  70. height: 44rpx;
  71. display: flex;
  72. align-items: center;
  73. justify-content: center;
  74. background: #f1f5f9;
  75. border-radius: 50%;
  76. }
  77. .clear-text {
  78. font-size: 32rpx;
  79. color: #94a3b8;
  80. line-height: 1;
  81. }
  82. /* 搜索加载提示 */
  83. .search-loading {
  84. display: flex;
  85. flex-direction: column;
  86. align-items: center;
  87. justify-content: center;
  88. padding: 100rpx 30rpx;
  89. text-align: center;
  90. }
  91. .search-spinner {
  92. width: 60rpx;
  93. height: 60rpx;
  94. border: 4rpx solid rgba(102, 126, 234, 0.1);
  95. border-top-color: #667eea;
  96. border-radius: 50%;
  97. animation: spin 1s linear infinite;
  98. margin-bottom: 30rpx;
  99. }
  100. .search-loading-text {
  101. font-size: 30rpx;
  102. color: #64748b;
  103. font-weight: 500;
  104. }
  105. /* 帖子列表区域 */
  106. .post-list-section {
  107. height: calc(100vh - 320rpx);
  108. padding: 0 20rpx;
  109. box-sizing: border-box;
  110. }
  111. /* 空状态 */
  112. .empty-state {
  113. display: flex;
  114. flex-direction: column;
  115. align-items: center;
  116. justify-content: center;
  117. padding: 150rpx 30rpx;
  118. text-align: center;
  119. }
  120. .empty-text {
  121. font-size: 32rpx;
  122. color: #94a3b8;
  123. margin-bottom: 50rpx;
  124. line-height: 1.5;
  125. max-width: 400rpx;
  126. }
  127. .empty-btn {
  128. background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
  129. color: white;
  130. font-size: 30rpx;
  131. font-weight: 600;
  132. padding: 24rpx 60rpx;
  133. border-radius: 50rpx;
  134. box-shadow: 0 10rpx 30rpx rgba(102, 126, 234, 0.3);
  135. border: none;
  136. margin: 0;
  137. }
  138. .empty-btn::after {
  139. border: none;
  140. }
  141. /* 帖子卡片 */
  142. .post-list {
  143. padding: 10rpx;
  144. }
  145. .post-card {
  146. background: white;
  147. border-radius: 24rpx;
  148. margin-bottom: 25rpx;
  149. box-shadow: 0 10rpx 40rpx rgba(0, 0, 0, 0.04);
  150. border: 1rpx solid #f1f5f9;
  151. position: relative;
  152. overflow: hidden;
  153. transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1);
  154. }
  155. .post-card:active {
  156. transform: translateY(-4rpx);
  157. box-shadow: 0 20rpx 60rpx rgba(0, 0, 0, 0.1);
  158. }
  159. /* 帖子内容 */
  160. .post-content {
  161. padding: 20rpx;
  162. }
  163. .post-type {
  164. display: flex;
  165. align-items: center;
  166. justify-content: space-between;
  167. border-bottom: 1rpx solid #f1f5f9;
  168. padding-bottom: 20rpx;
  169. }
  170. /* 帖子标题 */
  171. .post-title-wrapper {
  172. margin: 20rpx 0;
  173. }
  174. .post-title {
  175. font-size: 34rpx;
  176. font-weight: 700;
  177. color: #1e293b;
  178. line-height: 1.4;
  179. display: -webkit-box;
  180. -webkit-line-clamp: 2;
  181. -webkit-box-orient: vertical;
  182. overflow: hidden;
  183. }
  184. /* 帖子摘要 */
  185. .post-summary {
  186. font-size: 28rpx;
  187. color: #64748b;
  188. line-height: 1.6;
  189. margin-bottom: 25rpx;
  190. display: -webkit-box;
  191. -webkit-line-clamp: 3;
  192. -webkit-box-orient: vertical;
  193. overflow: hidden;
  194. }
  195. /* 图片区域 */
  196. .post-images {
  197. margin-bottom: 25rpx;
  198. }
  199. .images-grid {
  200. width: 100%;
  201. display: grid;
  202. grid-template-columns: repeat(3,1fr);
  203. position: relative;
  204. }
  205. .post-image {
  206. width: 180rpx;
  207. height: 180rpx;
  208. border-radius: 16rpx;
  209. flex-shrink: 0;
  210. object-fit: cover;
  211. }
  212. /* 帖子底部信息 */
  213. .post-footer {
  214. display: flex;
  215. align-items: center;
  216. justify-content: flex-end;
  217. padding-top: 25rpx;
  218. border-top: 1rpx solid #f1f5f9;
  219. }
  220. /* 用户信息 */
  221. .user-info {
  222. display: flex;
  223. align-items: center;
  224. gap: 15rpx;
  225. }
  226. .user-avatar {
  227. width: 64rpx;
  228. height: 64rpx;
  229. border-radius: 50%;
  230. border: 2rpx solid white;
  231. box-shadow: 0 6rpx 20rpx rgba(0, 0, 0, 0.08);
  232. }
  233. .username {
  234. font-size: 28rpx;
  235. font-weight: 600;
  236. color: #334155;
  237. }
  238. /* 元信息 */
  239. .post-meta {
  240. display: flex;
  241. align-items: center;
  242. gap: 25rpx;
  243. }
  244. .meta-item {
  245. display: flex;
  246. align-items: center;
  247. gap: 8rpx;
  248. }
  249. .meta-icon {
  250. width: 28rpx;
  251. height: 28rpx;
  252. opacity: 0.5;
  253. }
  254. .meta-count {
  255. font-size: 26rpx;
  256. font-weight: 600;
  257. color: #64748b;
  258. }
  259. .post-time {
  260. font-size: 24rpx;
  261. color: #94a3b8;
  262. font-weight: 500;
  263. }
  264. /* 加载更多 */
  265. .load-more {
  266. padding: 50rpx 0;
  267. text-align: center;
  268. }
  269. .loading-spinner {
  270. display: flex;
  271. flex-direction: column;
  272. align-items: center;
  273. gap: 20rpx;
  274. }
  275. .spinner {
  276. width: 40rpx;
  277. height: 40rpx;
  278. border: 4rpx solid rgba(102, 126, 234, 0.1);
  279. border-top-color: #667eea;
  280. border-radius: 50%;
  281. animation: spin 1s linear infinite;
  282. }
  283. @keyframes spin {
  284. 0% { transform: rotate(0deg); }
  285. 100% { transform: rotate(360deg); }
  286. }
  287. .loading-text {
  288. font-size: 28rpx;
  289. color: #94a3b8;
  290. font-weight: 500;
  291. }
  292. /* 没有更多了 */
  293. .no-more {
  294. display: flex;
  295. align-items: center;
  296. justify-content: center;
  297. gap: 30rpx;
  298. padding: 50rpx 0;
  299. }
  300. .no-more-line {
  301. flex: 1;
  302. height: 1rpx;
  303. background: linear-gradient(90deg, transparent, #e2e8f0, transparent);
  304. }
  305. .no-more-text {
  306. font-size: 26rpx;
  307. color: #cbd5e1;
  308. font-weight: 500;
  309. padding: 0 20rpx;
  310. }
  311. /* 固定发布按钮(左下角) */
  312. .floating-create-btn {
  313. position: fixed;
  314. left: 40rpx;
  315. bottom: 40rpx;
  316. width: 100rpx;
  317. height: 100rpx;
  318. background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
  319. border-radius: 50%;
  320. display: flex;
  321. align-items: center;
  322. justify-content: center;
  323. box-shadow: 0 15rpx 50rpx rgba(102, 126, 234, 0.4);
  324. z-index: 100;
  325. transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1);
  326. }
  327. .floating-create-btn:active {
  328. transform: scale(0.95);
  329. box-shadow: 0 10rpx 30rpx rgba(102, 126, 234, 0.3);
  330. }
  331. .create-icon {
  332. width: 44rpx;
  333. height: 44rpx;
  334. }
  335. /* 返回顶部按钮 - 修复图标显示 */
  336. .back-to-top-btn {
  337. position: fixed;
  338. right: 40rpx;
  339. bottom: 40rpx;
  340. width: 100rpx;
  341. height: 100rpx;
  342. background: white;
  343. border-radius: 50%;
  344. display: flex;
  345. align-items: center;
  346. justify-content: center;
  347. box-shadow: 0 10rpx 40rpx rgba(0, 0, 0, 0.1);
  348. z-index: 100;
  349. opacity: 0;
  350. transform: translateY(50rpx) scale(0.8);
  351. transition: all 0.4s cubic-bezier(0.175, 0.885, 0.32, 1.275);
  352. pointer-events: none;
  353. }
  354. .back-to-top-btn.show {
  355. opacity: 1;
  356. transform: translateY(0) scale(1);
  357. pointer-events: auto;
  358. }
  359. .back-to-top-btn:active {
  360. transform: translateY(2rpx) scale(0.98);
  361. background: #f8fafc;
  362. transition: transform 0.1s ease;
  363. }
  364. .back-top-icon {
  365. font-size: 40rpx;
  366. color: #667eea;
  367. font-weight: bold;
  368. transition: all 0.3s ease;
  369. }
  370. .back-to-top-btn:active .back-top-icon {
  371. transform: translateY(-2rpx);
  372. }
  373. /* 发布模态框 */
  374. .post-modal-overlay {
  375. position: fixed;
  376. top: 0;
  377. left: 0;
  378. right: 0;
  379. bottom: 0;
  380. background: rgba(0, 0, 0, 0.5);
  381. backdrop-filter: blur(10rpx);
  382. display: flex;
  383. align-items: flex-end;
  384. justify-content: center;
  385. z-index: 1000;
  386. animation: fadeIn 0.3s ease;
  387. }
  388. .post-modal-content {
  389. background: white;
  390. width: 100%;
  391. border-radius: 40rpx 40rpx 0 0;
  392. max-height: 85vh;
  393. overflow-y: auto;
  394. animation: slideUp 0.3s ease;
  395. }
  396. .modal-header {
  397. display: flex;
  398. justify-content: space-between;
  399. align-items: center;
  400. padding: 40rpx 30rpx 30rpx;
  401. border-bottom: 1rpx solid #f1f5f9;
  402. }
  403. .modal-title {
  404. font-size: 38rpx;
  405. font-weight: 700;
  406. color: #1e293b;
  407. }
  408. .modal-close {
  409. width: 50rpx;
  410. height: 50rpx;
  411. display: flex;
  412. align-items: center;
  413. justify-content: center;
  414. background: #f1f5f9;
  415. border-radius: 50%;
  416. }
  417. .close-icon {
  418. font-size: 36rpx;
  419. color: #64748b;
  420. line-height: 1;
  421. }
  422. .modal-body {
  423. padding: 30rpx;
  424. box-sizing: border-box;
  425. }
  426. .form-field {
  427. margin-bottom: 40rpx;
  428. }
  429. .field-header {
  430. display: flex;
  431. justify-content: space-between;
  432. align-items: center;
  433. margin-bottom: 16rpx;
  434. }
  435. .field-label {
  436. font-size: 30rpx;
  437. font-weight: 600;
  438. color: #1e293b;
  439. }
  440. .field-counter, .field-hint {
  441. font-size: 26rpx;
  442. color: #94a3b8;
  443. }
  444. .title-input {
  445. font-family: '思源宋体 Light' !important;
  446. background: #f8fafc;
  447. border-radius: 16rpx;
  448. font-size: 30rpx;
  449. width: 100%;
  450. height: 80rpx;
  451. line-height: 80rpx;
  452. padding: 0 20rpx;
  453. box-sizing: border-box;
  454. transition: all 0.3s ease;
  455. border: 2rpx solid transparent;
  456. }
  457. .title-input:focus {
  458. border-color: #667eea;
  459. background: white;
  460. box-shadow: 0 0 0 4rpx rgba(102, 126, 234, 0.1);
  461. outline: none;
  462. }
  463. .content-input {
  464. background: #f8fafc;
  465. border-radius: 16rpx;
  466. font-size: 30rpx;
  467. min-height: 200rpx;
  468. line-height: 1.6;
  469. padding: 20rpx;
  470. box-sizing: border-box;
  471. width: 100%;
  472. transition: all 0.3s ease;
  473. border: 2rpx solid transparent;
  474. }
  475. .content-input:focus {
  476. border-color: #667eea;
  477. background: white;
  478. box-shadow: 0 0 0 4rpx rgba(102, 126, 234, 0.1);
  479. outline: none;
  480. }
  481. .image-upload-area {
  482. margin-top: 10rpx;
  483. }
  484. .uploaded-images {
  485. display: flex;
  486. flex-wrap: wrap;
  487. gap: 20rpx;
  488. margin-bottom: 20rpx;
  489. }
  490. .image-item {
  491. position: relative;
  492. width: 180rpx;
  493. height: 180rpx;
  494. }
  495. .preview-image {
  496. width: 100%;
  497. height: 100%;
  498. border-radius: 16rpx;
  499. object-fit: cover;
  500. }
  501. .image-remove {
  502. position: absolute;
  503. top: -12rpx;
  504. right: -12rpx;
  505. width: 44rpx;
  506. height: 44rpx;
  507. background: #ef4444;
  508. border-radius: 50%;
  509. display: flex;
  510. align-items: center;
  511. justify-content: center;
  512. box-shadow: 0 6rpx 20rpx rgba(239, 68, 68, 0.3);
  513. }
  514. .remove-icon {
  515. font-size: 28rpx;
  516. color: white;
  517. line-height: 1;
  518. font-weight: bold;
  519. }
  520. .upload-btn {
  521. width: 180rpx;
  522. height: 180rpx;
  523. border: 2rpx dashed #cbd5e1;
  524. border-radius: 16rpx;
  525. display: flex;
  526. flex-direction: column;
  527. align-items: center;
  528. justify-content: center;
  529. background: #f8fafc;
  530. transition: all 0.3s ease;
  531. gap: 15rpx;
  532. }
  533. .upload-btn:active {
  534. border-color: #667eea;
  535. background: rgba(102, 126, 234, 0.05);
  536. }
  537. .camera-icon {
  538. width: 48rpx;
  539. height: 48rpx;
  540. filter: brightness(0);
  541. }
  542. .upload-text {
  543. font-size: 26rpx;
  544. color: #64748b;
  545. font-weight: 500;
  546. }
  547. .modal-footer {
  548. display: flex;
  549. gap: 20rpx;
  550. padding: 30rpx;
  551. background: #f8fafc;
  552. border-top: 1rpx solid #f1f5f9;
  553. }
  554. .cancel-btn, .submit-btn {
  555. flex: 1;
  556. border-radius: 16rpx;
  557. font-size: 32rpx;
  558. font-weight: 600;
  559. border: none;
  560. margin: 0;
  561. transition: all 0.3s ease;
  562. }
  563. .cancel-btn::after, .submit-btn::after {
  564. border: none;
  565. }
  566. .cancel-btn {
  567. background: white;
  568. color: #64748b;
  569. border: 1rpx solid #e2e8f0;
  570. }
  571. .cancel-btn:active {
  572. background: #f8fafc;
  573. }
  574. .submit-btn {
  575. background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
  576. color: white;
  577. box-shadow: 0 10rpx 30rpx rgba(102, 126, 234, 0.3);
  578. }
  579. .submit-btn:active:not([disabled]) {
  580. transform: translateY(-2rpx);
  581. box-shadow: 0 15rpx 40rpx rgba(102, 126, 234, 0.4);
  582. }
  583. .submit-btn[disabled] {
  584. background: #cbd5e1;
  585. box-shadow: none;
  586. color: #94a3b8;
  587. }
  588. /* 首次加载遮罩 */
  589. .loading-overlay {
  590. position: fixed;
  591. top: 0;
  592. left: 0;
  593. right: 0;
  594. bottom: 0;
  595. background: rgba(255, 255, 255, 0.9);
  596. backdrop-filter: blur(10rpx);
  597. display: flex;
  598. align-items: center;
  599. justify-content: center;
  600. z-index: 999;
  601. }
  602. .loading-content {
  603. display: flex;
  604. flex-direction: column;
  605. align-items: center;
  606. gap: 30rpx;
  607. }
  608. .spinner-large {
  609. width: 80rpx;
  610. height: 80rpx;
  611. border: 6rpx solid rgba(102, 126, 234, 0.1);
  612. border-top-color: #667eea;
  613. border-radius: 50%;
  614. animation: spin 1s linear infinite;
  615. }
  616. .loading-tip {
  617. font-size: 32rpx;
  618. color: #64748b;
  619. font-weight: 500;
  620. }
  621. /* 动画 */
  622. @keyframes fadeIn {
  623. from { opacity: 0; }
  624. to { opacity: 1; }
  625. }
  626. @keyframes slideUp {
  627. from { transform: translateY(100%); }
  628. to { transform: translateY(0); }
  629. }
  630. /* 添加返回顶部按钮的呼吸动画 */
  631. @keyframes breathe {
  632. 0%, 100% {
  633. box-shadow: 0 10rpx 40rpx rgba(0, 0, 0, 0.1);
  634. }
  635. 50% {
  636. box-shadow: 0 10rpx 40rpx rgba(102, 126, 234, 0.3);
  637. }
  638. }
  639. .back-to-top-btn.show {
  640. animation: breathe 3s ease-in-out infinite;
  641. }
  642. /* 响应式调整 */
  643. @media (min-width: 768px) {
  644. .post-card {
  645. max-width: 600rpx;
  646. margin-left: auto;
  647. margin-right: auto;
  648. }
  649. .floating-create-btn {
  650. left: calc(50% - 250rpx);
  651. }
  652. .back-to-top-btn {
  653. right: calc(50% - 250rpx);
  654. }
  655. }