完成供需API接口对接

dev
lynn 6 months ago
parent be2b86ad2a
commit 61faf51f9f

@ -40,6 +40,8 @@ let apiApp = {
// 供应需求 // 供应需求
supplyDemandSave: '/api/mobile/supply-demand/save', supplyDemandSave: '/api/mobile/supply-demand/save',
supplyDemandList: '/api/mobile/supply-demand/index',
supplyDemandDetail: '/api/mobile/supply-demand/detail',
} }
// 此处第二个参数vm就是我们在页面使用的this你可以通过vm获取vuex等操作 // 此处第二个参数vm就是我们在页面使用的this你可以通过vm获取vuex等操作
@ -90,6 +92,8 @@ const install = (Vue, vm) => {
// 供应需求 // 供应需求
let supplyDemandSave = (params = {}) => vm.$u.post(apiApp.supplyDemandSave, params); let supplyDemandSave = (params = {}) => vm.$u.post(apiApp.supplyDemandSave, params);
let supplyDemandList = (params = {}) => vm.$u.get(apiApp.supplyDemandList, params);
let supplyDemandDetail = (params = {}) => vm.$u.get(apiApp.supplyDemandDetail, params);
// 将各个定义的接口名称统一放进对象挂载到vm.$u.api(因为vm就是this也即this.$u.api)下 // 将各个定义的接口名称统一放进对象挂载到vm.$u.api(因为vm就是this也即this.$u.api)下
vm.$u.api = { vm.$u.api = {
@ -132,6 +136,8 @@ const install = (Vue, vm) => {
// 供应需求 // 供应需求
supplyDemandSave, supplyDemandSave,
supplyDemandList,
supplyDemandDetail,
}; };
} }

@ -1,67 +1,83 @@
<template> <template>
<view class="container" v-if="detail.user"> <view class="container" v-if="detail">
<view class="user-info-header"> <view class="user-info-header">
<u-avatar :text="detail.user.name.charAt(0)" size="80"></u-avatar> <u-avatar :src="detail.user && detail.user.headimgurl || 'https://via.placeholder.com/80'" size="80"></u-avatar>
<view class="user-details"> <view class="user-details">
<text class="user-name">{{ detail.user.name }}</text> <text class="user-name">{{ detail.user && detail.user.name || detail.user && detail.user.nickname || '匿名用户' }}</text>
<text class="post-time">{{ detail.time }}</text> <text class="post-time">{{ detail.created_at }}</text>
</view> </view>
<view class="stats"> <view class="stats">
<text class="type-badge">{{ detail.type === 'supply' ? '供应' : '需求' }}</text> <text class="type-badge" :class="detail.type === 1 ? 'supply' : 'demand'">{{ detail.type === 1 ? '供应' : '需求' }}</text>
<text class="views">{{ detail.messageCount }}人私信 {{ detail.viewCount }}浏览</text> <text class="views">{{ detail.contact_count }}人私信 {{ detail.view_count }}浏览</text>
</view> </view>
</view> </view>
<view class="content-card"> <view class="content-card">
<text class="title">{{ detail.title }}</text> <text class="title">{{ detail.title }}</text>
<text class="description">{{ detail.description }}</text> <text class="description">{{ detail.content }}</text>
<!-- <image class="content-image" :src="detail.image" mode="widthFix"></image> --> <view class="tags" v-if="detail.tag">
<view class="tags"> <text v-for="tag in detail.tag.split(',')" :key="tag" class="tag">{{ tag }}</text>
<text v-for="tag in detail.tags" :key="tag" class="tag">{{ tag }}</text>
</view> </view>
</view> </view>
<view class="footer"> <view class="footer">
<view class="footer-action"> <view class="footer-action" @click="toggleCollect">
<u-icon name="star" size="40"></u-icon> <u-icon :name="isCollected ? 'star-fill' : 'star'" size="40" :color="isCollected ? '#f29100' : '#606266'"></u-icon>
<text>收藏</text> <text :style="{ color: isCollected ? '#f29100' : '#606266' }">收藏</text>
</view> </view>
<u-button type="primary" shape="circle" class="message-btn">私信</u-button> <u-button type="primary" shape="circle" class="message-btn" @click="goToChat"></u-button>
</view> </view>
</view> </view>
</template> </template>
<script> <script>
import uAvatar from '@/uview-ui/components/u-avatar/u-avatar.vue';
import uIcon from '@/uview-ui/components/u-icon/u-icon.vue';
import uButton from '@/uview-ui/components/u-button/u-button.vue';
export default { export default {
components: {
uAvatar,
uIcon,
uButton
},
data() { data() {
return { return {
detail: {} detail: null,
isCollected: false
} }
}, },
onLoad(options) { onLoad(options) {
// , options.id console.log("页面ID:", options.id);
console.log("页面ID:", options.id)
this.fetchDetailData(options.id); this.fetchDetailData(options.id);
}, },
methods: { methods: {
fetchDetailData(id) { fetchDetailData(id) {
// this.$u.api.supplyDemandDetail({ id: id }).then(res => {
this.detail = { console.log('详情数据:', res);
id: id, if (res && res.id) {
user: { this.detail = res;
id: 'user123', } else {
name: '张云', this.$u.toast('获取详情失败');
avatar: '' // avatar an be used here if available }
}, }).catch(err => {
time: '2小时前', console.error('获取详情失败:', err);
type: 'supply', this.$u.toast('网络错误,请重试');
messageCount: 16, });
viewCount: 265, },
title: '提供企业管理咨询服务', toggleCollect() {
description: '专业企业管理咨询团队, 具有10年以上行业经验, 擅长企业战略规划、组织架构优化、流程梳理等。已服务过多家上市公司专业企业管理咨询团队, 具有10年以上行业经验, 擅长企业战略规划、组织架构优化、流程梳理等。', this.isCollected = !this.isCollected;
image: 'https://via.placeholder.com/700x300.png/E8E8E8/A9A9A9?text=专业诚信敬业高能', // Placeholder image this.$u.toast(this.isCollected ? '收藏成功' : '取消收藏');
tags: ['管理咨询', '战略规划', '管理咨询'] },
}; goToChat() {
if (this.detail && this.detail.user && this.detail.user.id) {
const userName = this.detail.user.name || this.detail.user.nickname || '匿名用户';
uni.navigateTo({
url: `/packages/chat/chatWindow?userId=${this.detail.user.id}&userName=${userName}`
});
} else {
this.$u.toast('用户信息不完整');
}
} }
} }
} }
@ -106,12 +122,20 @@
.type-badge { .type-badge {
font-size: 24rpx; font-size: 24rpx;
background-color: #fdf3e8;
color: #C9A36D;
padding: 8rpx 15rpx; padding: 8rpx 15rpx;
border-radius: 10rpx; border-radius: 10rpx;
} }
.type-badge.supply {
background-color: #fff0e6;
color: #f29100;
}
.type-badge.demand {
background-color: #e6f0ff;
color: #007aff;
}
.views { .views {
font-size: 24rpx; font-size: 24rpx;
color: #909399; color: #909399;

@ -1,31 +1,31 @@
<template> <template>
<view class="container"> <view class="container">
<view class="search-bar"> <view class="search-bar">
<u-search placeholder="请输入关键词" v-model="keyword" :show-action="false"></u-search> <u-search placeholder="请输入关键词" v-model="keyword" :show-action="false" @search="search" @input="onSearchInput"></u-search>
</view> </view>
<u-tabs :list="tabs" :is-scroll="false" :current="currentTab" @change="changeTab"></u-tabs> <u-tabs :list="tabs" :is-scroll="false" :current="currentTab" @change="changeTab"></u-tabs>
<view class="list-container"> <view class="list-container">
<view v-for="item in filteredList" :key="item.id" class="list-item"> <view v-for="item in list" :key="item.id" class="list-item">
<view class="item-header"> <view class="item-header">
<view :class="['type-badge', item.type === 'supply' ? 'supply' : 'demand']">{{ item.type === 'supply' ? '供应' : '需求' }}</view> <view :class="['type-badge', item.type === 1 ? 'supply' : 'demand']">{{ item.type === 1 ? '供应' : '需求' }}</view>
<text class="time">{{ item.time }}</text> <text class="time">{{ item.created_at }}</text>
</view> </view>
<text class="title">{{ item.title }}</text> <text class="title">{{ item.title }}</text>
<text class="description">{{ item.description }}</text> <text class="description">{{ item.content }}</text>
<view class="tags"> <view class="tags" v-if="item.tag">
<text v-for="tag in item.tags" :key="tag" class="tag">{{ tag }}</text> <text v-for="tag in item.tag.split(',')" :key="tag" class="tag">{{ tag }}</text>
</view> </view>
<u-line color="#e8e8e8" margin="20rpx 0" /> <u-line color="#e8e8e8" margin="20rpx 0" />
<view class="item-footer"> <view class="item-footer">
<view class="user-info"> <view class="user-info">
<u-avatar :src="item.user.avatar" size="60"></u-avatar> <u-avatar :src="item.user_avatar || 'https://via.placeholder.com/60'" size="60"></u-avatar>
<text class="user-name">{{ item.user.name }}</text> <text class="user-name">{{ item.user_name || '匿名用户' }}</text>
</view> </view>
<view class="actions"> <view class="actions">
<view class="view-button view-button-check" @click="goToDetail(item.id)"> <view class="view-button view-button-check" @click="goToDetail(item.id)">
<text class="button-text">查看</text> <text class="button-text">查看</text>
</view> </view>
<view class="view-button view-button-msg" @click="goToChat(item.user)"> <view class="view-button view-button-msg" @click="goToChat(item)">
<text class="button-text">私信</text> <text class="button-text">私信</text>
</view> </view>
</view> </view>
@ -40,13 +40,22 @@
<script> <script>
import uSearch from '@/uview-ui/components/u-search/u-search.vue'; import uSearch from '@/uview-ui/components/u-search/u-search.vue';
import uLoadmore from '@/uview-ui/components/u-loadmore/u-loadmore.vue'; import uLoadmore from '@/uview-ui/components/u-loadmore/u-loadmore.vue';
import uTabs from '@/uview-ui/components/u-tabs/u-tabs.vue';
import uLine from '@/uview-ui/components/u-line/u-line.vue';
import uAvatar from '@/uview-ui/components/u-avatar/u-avatar.vue';
import { base } from '@/common/util.js';
export default { export default {
components: { components: {
uSearch, uSearch,
uLoadmore uLoadmore,
uTabs,
uLine,
uAvatar
}, },
data() { data() {
return { return {
base,
keyword: '', keyword: '',
currentTab: 0, currentTab: 0,
tabs: [{ tabs: [{
@ -56,52 +65,96 @@
}, { }, {
name: '需求' name: '需求'
}], }],
list: [{ list: [],
id: 1, page: 1,
type: 'supply', pageSize: 10,
time: '2小时前', status: 'loadmore',
title: '提供企业管理咨询服务', loading: false
description: '专业企业管理咨询团队具有10年以上行业经验擅长企业战略规划、组织架构优化、流程梳理等。已服务过多家上市公司...',
tags: ['管理咨询', '战略规划', '管理咨询'],
user: {
name: '张云',
avatar: 'https://via.placeholder.com/60'
}
},
{
id: 2,
type: 'demand',
time: '2小时前',
title: '提供企业管理咨询服务',
description: '我们是一家初创公司目前在开发一款AI智能客服产品需要寻找有经验的技术合作伙伴共同推进项目发展...',
tags: ['AI', '技术合作', '客服系统'],
user: {
name: '李经理',
avatar: 'https://via.placeholder.com/60'
}
}
],
status: 'nomore'
} }
}, },
computed: { onLoad() {
filteredList() { this.fetchList();
let list = this.list; },
if (this.currentTab === 1) { onReachBottom() {
list = list.filter(item => item.type === 'supply'); if (this.status === 'loadmore' && !this.loading) {
} else if (this.currentTab === 2) { this.page++;
list = list.filter(item => item.type === 'demand'); this.fetchList();
} }
},
if (this.keyword) { watch: {
list = list.filter(item => item.title.includes(this.keyword) || item.description.includes(this.keyword)); keyword(newVal, oldVal) {
//
if (oldVal && !newVal) {
this.page = 1;
this.list = [];
this.status = 'loadmore';
this.fetchList();
} }
return list;
} }
}, },
methods: { methods: {
changeTab(index) { changeTab(index) {
this.currentTab = index; this.currentTab = index;
this.page = 1;
this.list = [];
this.status = 'loadmore';
this.fetchList();
},
search() {
this.page = 1;
this.list = [];
this.status = 'loadmore';
this.fetchList();
},
onSearchInput(value) {
//
// watch
},
fetchList() {
if (this.loading) return;
this.loading = true;
const params = {
page: this.page,
pageSize: this.pageSize
};
// tabtype
if (this.currentTab === 1) {
params.type = 1; //
} else if (this.currentTab === 2) {
params.type = 2; //
}
//
if (this.keyword) {
params.keyword = this.keyword;
}
this.$u.api.supplyDemandList(params).then(res => {
// res supplyDemands
const supplyDemands = res.supplyDemands;
const newList = supplyDemands.data || [];
if (this.page === 1) {
this.list = newList;
} else {
this.list = [...this.list, ...newList];
}
//
if (supplyDemands.current_page >= supplyDemands.last_page) {
this.status = 'nomore';
} else {
this.status = 'loadmore';
}
}).catch(err => {
console.error('获取供需列表失败:', err);
this.$u.toast('网络错误,请重试');
}).finally(() => {
this.loading = false;
});
}, },
goToPublish() { goToPublish() {
uni.navigateTo({ uni.navigateTo({
@ -113,10 +166,10 @@
url: `/packages/supply/detail?id=${id}` url: `/packages/supply/detail?id=${id}`
}) })
}, },
goToChat(user) { goToChat(item) {
// id //
uni.navigateTo({ uni.navigateTo({
url: `/packages/chat/chatWindow?userId=${user.id}` url: `/packages/chat/chatWindow?userId=${item.user_id}&userName=${item.user_name}`
}) })
} }
} }
@ -189,6 +242,8 @@
line-height: 1.6; line-height: 1.6;
margin-bottom: 30rpx; margin-bottom: 30rpx;
display: block; display: block;
max-height: 120rpx; /* 约3行文字的高度 */
overflow: hidden;
} }
.tags { .tags {

Loading…
Cancel
Save