初始提交:一场soul的创业实验-永平 网站与小程序

Made-with: Cursor
This commit is contained in:
卡若
2026-03-07 22:58:43 +08:00
commit b7c35a89b0
513 changed files with 89020 additions and 0 deletions

View File

@@ -0,0 +1,65 @@
/**
* Soul创业派对 - 选择导师stitch_soul
*/
const app = getApp()
Page({
data: {
statusBarHeight: 44,
mentors: [],
loading: true,
searchKw: '',
filterSkill: '',
skills: ['全部', '项目结构判断', '产品架构', 'BP梳理', '职业转型'],
},
onLoad() {
this.setData({ statusBarHeight: app.globalData.statusBarHeight || 44 })
this.loadMentors()
},
onSearchInput(e) {
this.setData({ searchKw: e.detail.value })
this.loadMentors()
},
onFilterTap(e) {
const skill = e.currentTarget.dataset.skill
this.setData({ filterSkill: skill === '全部' ? '' : skill })
this.loadMentors()
},
async loadMentors() {
this.setData({ loading: true })
try {
let url = '/api/miniprogram/mentors'
const params = []
if (this.data.searchKw) params.push(`q=${encodeURIComponent(this.data.searchKw)}`)
if (this.data.filterSkill) params.push(`skill=${encodeURIComponent(this.data.filterSkill)}`)
if (params.length) url += '?' + params.join('&')
const res = await app.request({ url, silent: true })
if (res?.success && res.data) {
this.setData({ mentors: res.data })
} else {
this.setData({ mentors: [] })
}
} catch (e) {
this.setData({ mentors: [] })
}
this.setData({ loading: false })
},
onRefresh() {
this.loadMentors()
},
goDetail(e) {
const id = e.currentTarget.dataset.id
wx.navigateTo({ url: `/pages/mentor-detail/mentor-detail?id=${id}` })
},
goBack() {
getApp().goBackOrToHome()
},
})

View File

@@ -0,0 +1 @@
{"usingComponents":{},"navigationStyle":"custom"}

View File

@@ -0,0 +1,70 @@
<!-- 选择导师 -->
<view class="page">
<view class="nav-bar" style="padding-top: {{statusBarHeight}}px;">
<view class="nav-back" bindtap="goBack"><text class="back-icon"></text></view>
<text class="nav-title">选择导师</text>
<view class="nav-placeholder-r"></view>
</view>
<view style="height: {{statusBarHeight + 44}}px;"></view>
<view class="search-bar">
<view class="search-input-wrap">
<text class="search-icon">🔍</text>
<input
class="search-input"
placeholder="搜索导师、技能或行业..."
value="{{searchKw}}"
bindinput="onSearchInput"
/>
</view>
</view>
<view class="filter-row">
<view
class="filter-tag {{!filterSkill ? 'filter-active' : ''}}"
data-skill="全部"
bindtap="onFilterTap"
>全部</view>
<view
wx:for="{{skills}}"
wx:key="*this"
wx:if="{{item !== '全部'}}"
class="filter-tag {{filterSkill === item ? 'filter-active' : ''}}"
data-skill="{{item}}"
bindtap="onFilterTap"
>{{item}}</view>
</view>
<view class="section-header">
<text class="section-title">推荐导师</text>
<text class="section-more" bindtap="loadMentors">查看全部 </text>
</view>
<view class="loading" wx:if="{{loading}}">加载中...</view>
<view class="mentor-list" wx:else>
<view class="mentor-card" wx:for="{{mentors}}" wx:key="id">
<view class="mentor-card-inner">
<view class="mentor-avatar-wrap">
<image wx:if="{{item.avatar}}" class="mentor-avatar" src="{{item.avatar}}" mode="aspectFill"></image>
<view wx:else class="mentor-avatar-placeholder">{{item.name ? item.name[0] : '?'}}</view>
</view>
<view class="mentor-info">
<text class="mentor-name">{{item.name}}</text>
<text class="mentor-intro">{{item.intro || ''}}</text>
<view class="mentor-tags" wx:if="{{item.tagsArr && item.tagsArr.length}}">
<text class="mentor-tag" wx:for="{{item.tagsArr}}" wx:key="*this" wx:for-item="tag">{{tag}}</text>
</view>
<view class="mentor-price-row">
<view class="mentor-price-wrap">
<text class="mentor-price-num">¥{{item.priceSingle || 0}}</text>
<text class="mentor-price-unit">起 / 单次咨询</text>
</view>
<view class="mentor-btn" data-id="{{item.id}}" bindtap="goDetail">预约</view>
</view>
</view>
</view>
</view>
</view>
<view class="empty" wx:if="{{!loading && mentors.length === 0}}">暂无导师</view>
<view class="bottom-space"></view>
</view>

View File

@@ -0,0 +1,40 @@
/* 按 mentor_listing_screen 设计稿 */
.page { background: #000; min-height: 100vh; color: #fff; }
.nav-bar { position: fixed; top: 0; left: 0; right: 0; z-index: 100; display: flex; align-items: center; justify-content: space-between; height: 44px; padding: 0 24rpx; background: rgba(0,0,0,0.95); border-bottom: 1rpx solid #27272a; }
.nav-back { width: 60rpx; }
.back-icon { font-size: 44rpx; color: #fff; }
.nav-title { font-size: 34rpx; font-weight: 500; }
.nav-placeholder-r { width: 60rpx; }
.search-bar { padding: 24rpx 24rpx 16rpx; }
.search-input-wrap { display: flex; align-items: center; background: #1C1C1E; border-radius: 24rpx; padding: 24rpx 32rpx; border: 1rpx solid #27272a; }
.search-icon { font-size: 36rpx; color: #71717a; margin-right: 16rpx; flex-shrink: 0; }
.search-input { flex: 1; font-size: 28rpx; color: #fff; background: transparent; }
.filter-row { display: flex; gap: 24rpx; padding: 24rpx; overflow-x: auto; }
.filter-tag { flex-shrink: 0; padding: 12rpx 32rpx; border-radius: 999rpx; font-size: 24rpx; background: #1C1C1E; border: 1rpx solid #27272a; color: #d4d4d8; }
.filter-active { background: #4FD1C5; border-color: #4FD1C5; color: #000; font-weight: 600; }
.section-header { display: flex; justify-content: space-between; align-items: flex-end; padding: 0 24rpx 24rpx; }
.section-title { font-size: 32rpx; font-weight: bold; color: #e4e4e7; }
.section-more { font-size: 24rpx; color: #4FD1C5; font-weight: 500; }
.loading { padding: 48rpx; text-align: center; color: #71717a; }
.mentor-list { padding: 0 24rpx 48rpx; }
.mentor-card { margin-bottom: 24rpx; background: #1C1C1E; border-radius: 32rpx; padding: 32rpx; border: 1rpx solid #27272a; }
.mentor-card-inner { display: flex; gap: 32rpx; }
.mentor-avatar-wrap { width: 112rpx; height: 112rpx; flex-shrink: 0; }
.mentor-avatar { width: 112rpx; height: 112rpx; border-radius: 50%; display: block; border: 1rpx solid #3f3f46; }
.mentor-avatar-placeholder { width: 112rpx; height: 112rpx; border-radius: 50%; background: rgba(79,209,197,0.2); border: 1rpx solid #3f3f46; display: flex; align-items: center; justify-content: center; font-size: 40rpx; font-weight: bold; color: #4FD1C5; }
.mentor-info { flex: 1; min-width: 0; }
.mentor-name { display: block; font-size: 32rpx; font-weight: bold; color: #fff; margin-bottom: 8rpx; }
.mentor-intro { display: block; font-size: 24rpx; color: #A1A1AA; margin-bottom: 16rpx; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.mentor-tags { display: flex; flex-wrap: wrap; gap: 12rpx; margin-bottom: 24rpx; }
.mentor-tag { font-size: 20rpx; padding: 8rpx 16rpx; background: #2C2C2E; color: #E5E7EB; border-radius: 12rpx; border: 1rpx solid rgba(63,63,70,0.5); }
.mentor-price-row { display: flex; justify-content: space-between; align-items: center; padding-top: 24rpx; border-top: 1rpx solid #27272a; }
.mentor-price-wrap { display: flex; align-items: baseline; gap: 8rpx; }
.mentor-price-num { font-size: 36rpx; font-weight: bold; color: #4FD1C5; }
.mentor-price-unit { font-size: 24rpx; color: #71717a; }
.mentor-btn { padding: 12rpx 32rpx; background: #fff; color: #000; font-size: 24rpx; font-weight: bold; border-radius: 999rpx; }
.empty { padding: 96rpx; text-align: center; color: rgba(255,255,255,0.4); }
.bottom-space { height: 80rpx; }