my-resources.vue 16 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647
  1. <template>
  2. <view class="my-resources" :class="{ 'dark-mode': isDarkTheme }">
  3. <!-- 顶部导航栏 -->
  4. <view class="header">
  5. <text class="header-title">我的资源</text>
  6. <view class="header-right">
  7. <text class="dropdown-icon">▼</text>
  8. </view>
  9. </view>
  10. <!-- 搜索栏 -->
  11. <view class="search-bar">
  12. <view class="search-input-wrapper">
  13. <text class="search-icon">🔍</text>
  14. <input type="text" class="search-input" placeholder="请输入人搜索关键词" v-model="searchKeyword" @input="handleSearch" />
  15. </view>
  16. </view>
  17. <scroll-view scroll-y class="content">
  18. <!-- 资源列表 -->
  19. <view class="resource-item" v-for="(item, index) in resources" :key="index" @click="handleViewUserDetail(item)">
  20. <!-- 优质资源标签 -->
  21. <view class="quality-tag" v-if="item.isQuality">优质资源</view>
  22. <!-- 头部:头像 + 名字/性别 + 审核状态 -->
  23. <view class="resource-header">
  24. <image v-if="item.avatar" :src="item.avatar" mode="aspectFill" class="resource-avatar"></image>
  25. <view v-else class="resource-avatar-placeholder"></view>
  26. <view class="resource-info">
  27. <view class="name-gender-row">
  28. <text class="resource-name">{{ item.name }}</text>
  29. <text class="resource-gender">{{ item.gender }}</text>
  30. <text class="status-tag" :class="{ 'approved': item.status === '已审核', 'pending': item.status === '待审核' }">{{ item.status }}</text>
  31. </view>
  32. </view>
  33. <!-- 右侧点赞/加号 -->
  34. <view class="right-action" v-if="item.isPlus">
  35. <text class="heart-icon">💗</text>
  36. </view>
  37. </view>
  38. <!-- 标签 -->
  39. <view class="labels-section">
  40. <text class="label" v-for="(label, idx) in item.labels" :key="idx">{{ label }}</text>
  41. </view>
  42. <!-- 择偶要求 -->
  43. <view class="requirement-section">
  44. <text class="requirement-text">择偶要求: {{ item.requirement }}</text>
  45. </view>
  46. <!-- 联系方式 -->
  47. <view class="contact-section">
  48. <text class="contact-label">联系方式:</text>
  49. <text class="contact-number">{{ item.contact }}</text>
  50. <text class="copy-btn" @click.stop="handleCopy(item.contact)">复制</text>
  51. </view>
  52. <!-- 底部按钮 -->
  53. <view class="action-buttons">
  54. <text class="delete-btn" @click.stop="handleDelete(item.id)">删除</text>
  55. <text class="match-btn" @click.stop="handleMatch(item.id)">精准匹配</text>
  56. </view>
  57. </view>
  58. </scroll-view>
  59. <!-- 底部优质资源按钮 -->
  60. <view class="quality-resources-section fixed-bottom">
  61. <view class="quality-resources-btn" @click="navigateToQualityResources">
  62. <text class="btn-icon">⭐</text>
  63. <text class="btn-text">优质资源</text>
  64. </view>
  65. </view>
  66. <!-- 底部添加按钮 -->
  67. <view class="add-button" @click="handleAdd">
  68. <text class="add-button-icon">+</text>
  69. </view>
  70. <!-- 底部导航 -->
  71. <view class="tabbar">
  72. <view class="tabbar-item home" @click="navigateToWorkbench">
  73. <view class="tabbar-icon"></view>
  74. <text class="tabbar-text">工作台</text>
  75. </view>
  76. <view class="tabbar-item resources active" @click="navigateToMyResources">
  77. <view class="tabbar-icon"></view>
  78. <text class="tabbar-text">我的资源</text>
  79. </view>
  80. <view class="tabbar-item trophy" @click="navigateToRanking">
  81. <view class="tabbar-icon"></view>
  82. <text class="tabbar-text">排行榜</text>
  83. </view>
  84. <view class="tabbar-item message" @click="navigateToMessage">
  85. <view class="tabbar-icon">
  86. <view class="badge" v-if="unreadCount > 0">{{ unreadCount }}</view>
  87. </view>
  88. <text class="tabbar-text">消息</text>
  89. </view>
  90. <view class="tabbar-item mine" @click="navigateToMine">
  91. <view class="tabbar-icon"></view>
  92. <text class="tabbar-text">我的</text>
  93. </view>
  94. </view>
  95. </view>
  96. </template>
  97. <script>
  98. import api from '@/utils/api.js'
  99. export default {
  100. data() {
  101. return {
  102. searchKeyword: '',
  103. unreadCount: 3,
  104. resources: [
  105. {
  106. id: 1,
  107. avatar: '',
  108. name: '小高',
  109. gender: '男',
  110. status: '已审核',
  111. isPlus: false,
  112. labels: ['气质男', '小清新'],
  113. requirement: '165+ 本科',
  114. contact: '123****8912',
  115. isQuality: false
  116. },
  117. {
  118. id: 2,
  119. avatar: '',
  120. name: '小美',
  121. gender: '女',
  122. status: '已审核',
  123. isPlus: true,
  124. labels: ['温柔', '知性', '爱读书'],
  125. requirement: '175+ 硕士 有房',
  126. contact: '138****6543',
  127. isQuality: false
  128. },
  129. {
  130. id: 3,
  131. avatar: '',
  132. name: '阿强',
  133. gender: '男',
  134. status: '待审核',
  135. isPlus: false,
  136. labels: ['阳光', '运动型'],
  137. requirement: '160+ 大专以上',
  138. contact: '159****2234',
  139. isQuality: true
  140. }
  141. ],
  142. isDarkTheme: false
  143. }
  144. },
  145. onShow() {
  146. const stored = uni.getStorageSync('matchmakerDarkMode')
  147. if (stored === true || stored === false) {
  148. this.isDarkTheme = stored
  149. }
  150. },
  151. onLoad() {
  152. // 加载我的资源数据
  153. this.loadMyResources()
  154. },
  155. methods: {
  156. async loadMyResources() {
  157. try {
  158. const res = await api.matchmaker.getMyResources()
  159. if (res && res.data && res.data.length > 0) {
  160. this.resources = res.data
  161. }
  162. } catch (e) {
  163. console.error('加载资源数据失败:', e)
  164. }
  165. },
  166. handleSearch() {
  167. console.log('搜索关键词:', this.searchKeyword)
  168. },
  169. handleCopy(contact) {
  170. uni.setClipboardData({
  171. data: contact.replace(/\*+/g, ''),
  172. success: () => {
  173. uni.showToast({
  174. title: '复制成功',
  175. icon: 'success'
  176. })
  177. }
  178. })
  179. },
  180. handleDelete(id) {
  181. uni.showModal({
  182. title: '删除确认',
  183. content: '确定要删除该资源吗?',
  184. success: (res) => {
  185. if (res.confirm) {
  186. console.log('删除资源:', id)
  187. uni.showToast({
  188. title: '删除成功',
  189. icon: 'success'
  190. })
  191. }
  192. }
  193. })
  194. },
  195. handleMatch(id) {
  196. console.log('精准匹配:', id)
  197. uni.navigateTo({
  198. url: `/pages/matchmaker-workbench/precise-match?id=${id}`
  199. })
  200. },
  201. handleAdd() {
  202. uni.navigateTo({
  203. url: '/pages/matchmaker-workbench/add-resource'
  204. })
  205. },
  206. navigateToWorkbench() {
  207. uni.redirectTo({
  208. url: '/pages/matchmaker-workbench/index'
  209. })
  210. },
  211. navigateToMyResources() {
  212. // 已在我的资源页面,无需跳转
  213. },
  214. navigateToRanking() {
  215. uni.redirectTo({
  216. url: '/pages/matchmaker-workbench/ranking'
  217. })
  218. },
  219. navigateToMessage() {
  220. uni.redirectTo({
  221. url: '/pages/matchmaker-workbench/message'
  222. })
  223. },
  224. navigateToMine() {
  225. uni.redirectTo({
  226. url: '/pages/matchmaker-workbench/mine'
  227. })
  228. },
  229. navigateToQualityResources() {
  230. uni.navigateTo({
  231. url: '/pages/matchmaker-workbench/quality-resources'
  232. })
  233. },
  234. handleViewUserDetail(item) {
  235. // 跳转到客户详情页面,传递用户ID
  236. uni.navigateTo({
  237. url: `/pages/matchmaker-workbench/client-detail?id=${item.id}`
  238. })
  239. }
  240. }
  241. }
  242. </script>
  243. <style lang="scss" scoped>
  244. .my-resources {
  245. min-height: 100vh;
  246. background: #FFF9F9;
  247. display: flex;
  248. flex-direction: column;
  249. }
  250. /* 顶部导航栏 */
  251. .header {
  252. display: flex;
  253. align-items: center;
  254. justify-content: space-between;
  255. padding: 20rpx 30rpx;
  256. padding-top: calc(20rpx + env(safe-area-inset-top));
  257. background: #FFF9F9;
  258. .header-title {
  259. font-size: 36rpx;
  260. font-weight: bold;
  261. color: #9C27B0;
  262. }
  263. .header-right {
  264. .dropdown-icon {
  265. font-size: 24rpx;
  266. color: #9C27B0;
  267. }
  268. }
  269. }
  270. /* 搜索栏 */
  271. .search-bar {
  272. padding: 15rpx 20rpx;
  273. background: #FFF9F9;
  274. .search-input-wrapper {
  275. display: flex;
  276. align-items: center;
  277. background: #FFFFFF;
  278. border-radius: 25rpx;
  279. padding: 12rpx 20rpx;
  280. box-shadow: 0 2rpx 8rpx rgba(0, 0, 0, 0.05);
  281. .search-icon {
  282. font-size: 28rpx;
  283. margin-right: 12rpx;
  284. }
  285. .search-input {
  286. flex: 1;
  287. font-size: 26rpx;
  288. color: #333;
  289. border: none;
  290. outline: none;
  291. background: transparent;
  292. &::placeholder {
  293. color: #999;
  294. }
  295. }
  296. }
  297. }
  298. .content {
  299. flex: 1;
  300. overflow-y: auto;
  301. padding: 15rpx 20rpx 20rpx;
  302. }
  303. /* 优质资源按钮(紧贴加号按钮上方,稍微缩小) */
  304. .quality-resources-section {
  305. position: fixed;
  306. right: 30rpx; /* 与加号按钮右边对齐 */
  307. bottom: 240rpx; /* 在加号按钮正上方留一点间距 */
  308. z-index: 999;
  309. .quality-resources-btn {
  310. display: flex;
  311. align-items: center;
  312. justify-content: center;
  313. gap: 8rpx;
  314. padding: 14rpx 22rpx; /* 比之前的 20rpx 略小 */
  315. background: linear-gradient(135deg, #FFF3E0 0%, #FFE0B2 100%);
  316. border-radius: 18rpx;
  317. border: 2rpx solid #FFB74D;
  318. .btn-icon {
  319. font-size: 28rpx; /* 略小 */
  320. }
  321. .btn-text {
  322. font-size: 24rpx; /* 略小 */
  323. font-weight: bold;
  324. color: #FF9800;
  325. }
  326. }
  327. }
  328. /* 资源卡片 */
  329. .resource-item {
  330. background: #FFFFFF;
  331. border-radius: 16rpx;
  332. margin-bottom: 15rpx;
  333. padding: 20rpx;
  334. position: relative;
  335. box-shadow: 0 2rpx 8rpx rgba(0, 0, 0, 0.05);
  336. /* 优质资源标签 */
  337. .quality-tag {
  338. position: absolute;
  339. top: 15rpx;
  340. right: 15rpx;
  341. background: linear-gradient(135deg, #FFD700 0%, #FFA000 100%);
  342. color: #FFFFFF;
  343. font-size: 20rpx;
  344. font-weight: bold;
  345. padding: 6rpx 14rpx;
  346. border-radius: 12rpx;
  347. }
  348. /* 头部:头像 + 名字/性别 + 审核状态 */
  349. .resource-header {
  350. display: flex;
  351. align-items: center;
  352. margin-bottom: 15rpx;
  353. gap: 15rpx;
  354. .resource-avatar {
  355. width: 80rpx;
  356. height: 80rpx;
  357. border-radius: 50%;
  358. flex-shrink: 0;
  359. background: #E8E8E8;
  360. }
  361. .resource-avatar-placeholder {
  362. width: 80rpx;
  363. height: 80rpx;
  364. border-radius: 50%;
  365. flex-shrink: 0;
  366. background: linear-gradient(135deg, #E0E0E0, #BDBDBD);
  367. }
  368. .resource-info {
  369. flex: 1;
  370. .name-gender-row {
  371. display: flex;
  372. align-items: center;
  373. gap: 10rpx;
  374. .resource-name {
  375. font-size: 28rpx;
  376. font-weight: bold;
  377. color: #333;
  378. }
  379. .resource-gender {
  380. font-size: 24rpx;
  381. color: #666;
  382. }
  383. .status-tag {
  384. display: inline-block;
  385. padding: 4rpx 12rpx;
  386. border-radius: 12rpx;
  387. font-size: 20rpx;
  388. font-weight: bold;
  389. &.approved {
  390. background: #E8F5E8;
  391. color: #4CAF50;
  392. }
  393. &.pending {
  394. background: #FFF3E0;
  395. color: #FF9800;
  396. }
  397. }
  398. }
  399. }
  400. .right-action {
  401. .heart-icon {
  402. font-size: 28rpx;
  403. }
  404. }
  405. }
  406. /* 标签 */
  407. .labels-section {
  408. display: flex;
  409. flex-wrap: wrap;
  410. gap: 8rpx;
  411. margin-bottom: 12rpx;
  412. .label {
  413. display: inline-block;
  414. padding: 5rpx 14rpx;
  415. background: #F5F5F5;
  416. color: #666;
  417. border-radius: 12rpx;
  418. font-size: 22rpx;
  419. }
  420. }
  421. /* 择偶要求 */
  422. .requirement-section {
  423. margin-bottom: 12rpx;
  424. .requirement-text {
  425. font-size: 24rpx;
  426. color: #666;
  427. line-height: 1.4;
  428. }
  429. }
  430. /* 联系方式 */
  431. .contact-section {
  432. display: flex;
  433. align-items: center;
  434. margin-bottom: 15rpx;
  435. gap: 8rpx;
  436. .contact-label {
  437. font-size: 24rpx;
  438. color: #333;
  439. font-weight: bold;
  440. }
  441. .contact-number {
  442. flex: 1;
  443. font-size: 24rpx;
  444. color: #9C27B0;
  445. }
  446. .copy-btn {
  447. font-size: 22rpx;
  448. color: #9C27B0;
  449. font-weight: bold;
  450. }
  451. }
  452. /* 底部按钮 */
  453. .action-buttons {
  454. display: flex;
  455. justify-content: space-between;
  456. gap: 12rpx;
  457. .delete-btn {
  458. flex: 1;
  459. padding: 10rpx 20rpx;
  460. background: #FFEBEE;
  461. color: #E91E63;
  462. border-radius: 20rpx;
  463. font-size: 24rpx;
  464. font-weight: bold;
  465. text-align: center;
  466. }
  467. .match-btn {
  468. flex: 1;
  469. padding: 10rpx 20rpx;
  470. background: linear-gradient(135deg, #9C27B0 0%, #BA68C8 100%);
  471. color: #FFFFFF;
  472. border-radius: 20rpx;
  473. font-size: 24rpx;
  474. font-weight: bold;
  475. text-align: center;
  476. }
  477. }
  478. }
  479. /* 添加按钮 */
  480. .add-button {
  481. position: fixed;
  482. bottom: 130rpx;
  483. right: 30rpx;
  484. width: 90rpx;
  485. height: 90rpx;
  486. border-radius: 50%;
  487. background: linear-gradient(135deg, #9C27B0 0%, #BA68C8 100%);
  488. display: flex;
  489. align-items: center;
  490. justify-content: center;
  491. box-shadow: 0 4rpx 16rpx rgba(156, 39, 176, 0.3);
  492. z-index: 1000;
  493. .add-button-icon {
  494. font-size: 50rpx;
  495. color: #FFFFFF;
  496. line-height: 1;
  497. font-weight: bold;
  498. }
  499. }
  500. /* 底部导航 */
  501. .tabbar {
  502. position: fixed;
  503. bottom: 0;
  504. left: 0;
  505. right: 0;
  506. height: 100rpx;
  507. background: #FFFFFF;
  508. border-top: 1rpx solid #F0F0F0;
  509. display: flex;
  510. justify-content: space-around;
  511. align-items: center;
  512. padding-bottom: env(safe-area-inset-bottom);
  513. .tabbar-item {
  514. display: flex;
  515. flex-direction: column;
  516. align-items: center;
  517. gap: 8rpx;
  518. padding: 10rpx 0;
  519. .tabbar-icon {
  520. width: 44rpx;
  521. height: 44rpx;
  522. background-size: contain;
  523. background-repeat: no-repeat;
  524. background-position: center;
  525. position: relative;
  526. .badge {
  527. position: absolute;
  528. top: -8rpx;
  529. right: -8rpx;
  530. background: #FF4444;
  531. color: #FFFFFF;
  532. font-size: 20rpx;
  533. font-weight: bold;
  534. width: 32rpx;
  535. height: 32rpx;
  536. display: flex;
  537. align-items: center;
  538. justify-content: center;
  539. border-radius: 16rpx;
  540. }
  541. }
  542. .tabbar-text {
  543. font-size: 20rpx;
  544. color: #999;
  545. }
  546. &.active .tabbar-text {
  547. color: #9C27B0;
  548. font-weight: bold;
  549. }
  550. &.home .tabbar-icon {
  551. background-image: url('data:image/svg+xml,<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="%23999"><path d="M10 20v-6h4v6h5v-8h3L12 3 2 12h3v8z"/></svg>');
  552. }
  553. &.home.active .tabbar-icon {
  554. background-image: url('data:image/svg+xml,<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="%239C27B0"><path d="M10 20v-6h4v6h5v-8h3L12 3 2 12h3v8z"/></svg>');
  555. }
  556. &.resources .tabbar-icon {
  557. background-image: url('data:image/svg+xml,<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="%23999"><path d="M16 11c1.66 0 2.99-1.34 2.99-3S17.66 5 16 5c-1.66 0-3 1.34-3 3s1.34 3 3 3zm-8 0c1.66 0 2.99-1.34 2.99-3S9.66 5 8 5C6.34 5 5 6.34 5 8s1.34 3 3 3zm0 2c-2.33 0-7 1.17-7 3.5V19h14v-2.5c0-2.33-4.67-3.5-7-3.5zm8 0c-.29 0-.62.02-.97.05 1.16.84 1.97 1.97 1.97 3.45V19h6v-2.5c0-2.33-4.67-3.5-7-3.5z"/></svg>');
  558. }
  559. &.resources.active .tabbar-icon {
  560. background-image: url('data:image/svg+xml,<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="%239C27B0"><path d="M16 11c1.66 0 2.99-1.34 2.99-3S17.66 5 16 5c-1.66 0-3 1.34-3 3s1.34 3 3 3zm-8 0c1.66 0 2.99-1.34 2.99-3S9.66 5 8 5C6.34 5 5 6.34 5 8s1.34 3 3 3zm0 2c-2.33 0-7 1.17-7 3.5V19h14v-2.5c0-2.33-4.67-3.5-7-3.5zm8 0c-.29 0-.62.02-.97.05 1.16.84 1.97 1.97 1.97 3.45V19h6v-2.5c0-2.33-4.67-3.5-7-3.5z"/></svg>');
  561. }
  562. &.trophy .tabbar-icon {
  563. background-image: url('data:image/svg+xml,<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="%23999"><path d="M19 5h-2V3H7v2H5c-1.1 0-2 .9-2 2v1c0 2.55 1.92 4.63 4.39 4.94.63 1.5 1.98 2.63 3.61 2.96V19H7v2h10v-2h-4v-3.1c1.63-.33 2.98-1.46 3.61-2.96C19.08 12.63 21 10.55 21 8V7c0-1.1-.9-2-2-2zM5 8V7h2v3.82C5.84 10.4 5 9.3 5 8zm14 0c0 1.3-.84 2.4-2 2.82V7h2v1z"/></svg>');
  564. }
  565. &.trophy.active .tabbar-icon {
  566. background-image: url('data:image/svg+xml,<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="%239C27B0"><path d="M19 5h-2V3H7v2H5c-1.1 0-2 .9-2 2v1c0 2.55 1.92 4.63 4.39 4.94.63 1.5 1.98 2.63 3.61 2.96V19H7v2h10v-2h-4v-3.1c1.63-.33 2.98-1.46 3.61-2.96C19.08 12.63 21 10.55 21 8V7c0-1.1-.9-2-2-2zM5 8V7h2v3.82C5.84 10.4 5 9.3 5 8zm14 0c0 1.3-.84 2.4-2 2.82V7h2v1z"/></svg>');
  567. }
  568. &.message .tabbar-icon {
  569. background-image: url('data:image/svg+xml,<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="%23999"><path d="M20 2H4c-1.1 0-2 .9-2 2v18l4-4h14c1.1 0 2-.9 2-2V4c0-1.1-.9-2-2-2zm0 14H6l-2 2V4h16v12z"/></svg>');
  570. }
  571. &.message.active .tabbar-icon {
  572. background-image: url('data:image/svg+xml,<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="%239C27B0"><path d="M20 2H4c-1.1 0-2 .9-2 2v18l4-4h14c1.1 0 2-.9 2-2V4c0-1.1-.9-2-2-2zm0 14H6l-2 2V4h16v12z"/></svg>');
  573. }
  574. &.mine .tabbar-icon {
  575. background-image: url('data:image/svg+xml,<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="%23999"><path d="M12 12c2.21 0 4-1.79 4-4s-1.79-4-4-4-4 1.79-4 4 1.79 4 4 4zm0 2c-2.67 0-8 1.34-8 4v2h16v-2c0-2.66-5.33-4-8-4z"/></svg>');
  576. }
  577. &.mine.active .tabbar-icon {
  578. background-image: url('data:image/svg+xml,<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="%239C27B0"><path d="M12 12c2.21 0 4-1.79 4-4s-1.79-4-4-4-4 1.79-4 4 1.79 4 4 4zm0 2c-2.67 0-8 1.34-8 4v2h16v-2c0-2.66-5.33-4-8-4z"/></svg>');
  579. }
  580. }
  581. }
  582. </style>