首页、公告列表与详情、两个精选、我的收藏、总搜索组件
This commit is contained in:
parent
a9455ce98d
commit
b6945acf9b
|
|
@ -227,6 +227,12 @@
|
|||
"navigationStyle": "custom"
|
||||
}
|
||||
},
|
||||
{
|
||||
"path": "pages/search_common/search",
|
||||
"style": {
|
||||
"navigationStyle": "custom"
|
||||
}
|
||||
},
|
||||
{
|
||||
"path": "pages/settings/index",
|
||||
"style": {
|
||||
|
|
|
|||
|
|
@ -0,0 +1,101 @@
|
|||
<template>
|
||||
<view class="notice-item" @tap="handleClick">
|
||||
<view class="item-main">
|
||||
<text class="item-title line-2">{{ item.title }}</text>
|
||||
<view class="item-time">
|
||||
<text class="time-text">发布时间:{{ formattedTime }}</text>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
name: "NoticeCard",
|
||||
props: {
|
||||
// 接收外部传入的公告对象数据
|
||||
item: {
|
||||
type: Object,
|
||||
default: () => ({})
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
// 利用计算属性自动处理时间格式化
|
||||
formattedTime() {
|
||||
const timeStr = this.item.create_time;
|
||||
if (!timeStr) return '--:--:--';
|
||||
|
||||
let formatted = timeStr;
|
||||
if (timeStr.includes('.') && !timeStr.includes('-')) {
|
||||
formatted = timeStr.replace(/\./g, '-');
|
||||
if (formatted.match(/\d{4}-\d{2}-\d{2}\d{2}:\d{2}:\d{2}/)) {
|
||||
formatted = formatted.replace(/(\d{4}-\d{2}-\d{2})(\d{2}:\d{2}:\d{2})/, '$1 $2');
|
||||
}
|
||||
}
|
||||
if (formatted.includes('-') && formatted.includes(':')) {
|
||||
return formatted;
|
||||
}
|
||||
return timeStr;
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
handleClick() {
|
||||
// 触发组件的 click 事件,把当前项的数据抛出去
|
||||
this.$emit('click', this.item);
|
||||
}
|
||||
}
|
||||
};
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.notice-item {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
background: #ffffff;
|
||||
border-radius: 20rpx;
|
||||
padding: 30rpx;
|
||||
margin-bottom: 20rpx;
|
||||
transition: all 0.2s ease;
|
||||
|
||||
.item-main {
|
||||
flex: 1;
|
||||
min-width: 0; // 防止文字溢出
|
||||
|
||||
.item-title {
|
||||
font-size: 30rpx;
|
||||
font-weight: 500;
|
||||
color: #101010;
|
||||
line-height: 42rpx;
|
||||
margin-bottom: 16rpx;
|
||||
}
|
||||
|
||||
.item-time {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
|
||||
.time-icon {
|
||||
width: 24rpx;
|
||||
height: 24rpx;
|
||||
margin-right: 8rpx;
|
||||
opacity: 0.6;
|
||||
}
|
||||
|
||||
.time-text {
|
||||
font-size: 22rpx;
|
||||
color: #999;
|
||||
line-height: 30rpx;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 多行省略
|
||||
.line-2 {
|
||||
display: -webkit-box;
|
||||
-webkit-box-orient: vertical;
|
||||
-webkit-line-clamp: 2;
|
||||
overflow: hidden;
|
||||
word-break: break-all;
|
||||
}
|
||||
</style>
|
||||
|
|
@ -3,7 +3,7 @@
|
|||
<image class="page-bg" src="https://mrrplus.oss-cn-beijing.aliyuncs.com/photo/system/0901dc51-ff5a-427f-aab1-993d80aced79.png" mode="widthFix"></image>
|
||||
|
||||
<view class="header-section">
|
||||
<view class="user-info">
|
||||
<view class="user-info" @tap="handleLoginRedirect">
|
||||
<image class="avatar" :src="currentAvatar"></image>
|
||||
<view class="info-text">
|
||||
<view class="name">{{ currentName }}</view>
|
||||
|
|
@ -17,6 +17,70 @@
|
|||
</view>
|
||||
</view>
|
||||
|
||||
<view class="setup-modal-mask" v-if="showSetupModal" catchtouchmove="true">
|
||||
<view class="setup-modal-content">
|
||||
<image class="modal-bg" src="https://mrrplus.oss-cn-beijing.aliyuncs.com/photo/system/ac2cb4aa-a7c5-4776-98f4-b77e9c0cfa85.png"></image>
|
||||
|
||||
<view class="modal-header">
|
||||
<text>温馨提示</text>
|
||||
</view>
|
||||
|
||||
<view class="modal-body">
|
||||
<text class="modal-subtitle">发布服务请完善以下资料:</text>
|
||||
|
||||
<view class="missing-list">
|
||||
<view class="missing-item" v-if="!hasBusinessTime">
|
||||
<view class="item-left">
|
||||
<image class="item-icon" src="https://mrrplus.oss-cn-beijing.aliyuncs.com/photo/system/21b26b44-5e36-4291-8900-705a3d5bfa90.png"></image>
|
||||
<view class="item-texts">
|
||||
<text class="item-title">营业时间未配置</text>
|
||||
<text class="item-desc">请完善店铺的营业时间</text>
|
||||
</view>
|
||||
</view>
|
||||
<view class="item-right orange" @tap="goToBusinessTime">去配置</view>
|
||||
</view>
|
||||
|
||||
<view class="missing-item" v-if="!hasServiceSkill">
|
||||
<view class="item-left">
|
||||
<image class="item-icon" src="https://mrrplus.oss-cn-beijing.aliyuncs.com/photo/system/21b26b44-5e36-4291-8900-705a3d5bfa90.png"></image>
|
||||
<view class="item-texts">
|
||||
<text class="item-title">服务技能未配置</text>
|
||||
<text class="item-desc">请完善服务技能</text>
|
||||
</view>
|
||||
</view>
|
||||
<view class="item-right orange" @tap="goToServiceSkill">去配置</view>
|
||||
</view>
|
||||
|
||||
<view class="missing-item" v-if="!isCertified">
|
||||
<view class="item-left">
|
||||
<image class="item-icon" :src="userInfo.id_type === -1 ? 'https://mrrplus.oss-cn-beijing.aliyuncs.com/photo/system/25c444be-a66e-45d6-b50d-922149ff059f.png' : 'https://mrrplus.oss-cn-beijing.aliyuncs.com/photo/system/21b26b44-5e36-4291-8900-705a3d5bfa90.png'"></image>
|
||||
<view class="item-texts">
|
||||
<text class="item-title">{{ userInfo.id_type === -1 ? '资质认证中' : '资质未认证' }}</text>
|
||||
<text class="item-desc">请完成资质认证</text>
|
||||
</view>
|
||||
</view>
|
||||
<view class="item-right" :class="userInfo.id_type === -1 ? 'grey' : 'orange'" @tap="goToAuth">
|
||||
{{ userInfo.id_type === -1 ? '查看进度' : '去认证' }}
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<view class="modal-footer">
|
||||
<view class="btn-know" @tap="closeSetupModal">知道了</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<view class="settlement-guide card-box" v-if="isLogin && isUserInfoLoaded && !isCertified">
|
||||
<view class="guide-header" :style="{ backgroundImage: 'url(' + (isSettled ? 'https://mrrplus.oss-cn-beijing.aliyuncs.com/photo/system/c3a6cdd8-0447-4b50-a8cc-7bab1eedb502.png' : 'https://mrrplus.oss-cn-beijing.aliyuncs.com/photo/system/138ccbc3-486d-4287-b67f-f809de99e408.png') + ')' }">
|
||||
<view class="guide-body">
|
||||
<text class="guide-text">{{ isSettled ? '完成认证,开启您的接单之路' : '入驻美融融,生意更轻松' }}</text>
|
||||
<view class="guide-btn" @tap="goToSettle">{{ isSettled ? '去认证' : '去入驻' }}</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<view class="quick-actions card-box" v-if="isLogin && isSettled">
|
||||
<view class="action-item" v-for="(item, index) in quickActions" :key="index" @tap="handleQuickAction(item)">
|
||||
<image class="action-icon" :src="item.icon"></image>
|
||||
|
|
@ -87,15 +151,6 @@
|
|||
</view>
|
||||
</view>
|
||||
|
||||
<view class="settlement-guide card-box" v-if="isLogin && !isCertified">
|
||||
<view class="guide-header" :style="{ backgroundImage: 'url(' + (isSettled ? 'https://mrrplus.oss-cn-beijing.aliyuncs.com/photo/system/c3a6cdd8-0447-4b50-a8cc-7bab1eedb502.png' : 'https://mrrplus.oss-cn-beijing.aliyuncs.com/photo/system/138ccbc3-486d-4287-b67f-f809de99e408.png') + ')' }">
|
||||
<view class="guide-body">
|
||||
<text class="guide-text">{{ isSettled ? '完成认证,开启您的接单之路' : '入驻美融融,生意更轻松' }}</text>
|
||||
<view class="guide-btn" @tap="goToSettle">{{ isSettled ? '去认证' : '去入驻' }}</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<view class="notice-bar card-box">
|
||||
<image class="notice-icon" src="https://mrrplus.oss-cn-beijing.aliyuncs.com/photo/system/75f624b8-a6ed-4787-9380-1a087062805b.png"></image>
|
||||
<swiper class="notice-swiper" vertical autoplay circular interval="3000">
|
||||
|
|
@ -143,6 +198,9 @@
|
|||
</template>
|
||||
|
||||
<script>
|
||||
// 全局变量:用于控制每次杀进程启动后,只在首页弹一次弹窗
|
||||
let hasShownSetupModal = false;
|
||||
|
||||
import TabBar from "@/components/tabbar/tabbar.vue"
|
||||
import projectTabs from "./components/project-tabs.vue";
|
||||
import request from "@/utils/request";
|
||||
|
|
@ -163,15 +221,17 @@ export default {
|
|||
data() {
|
||||
return {
|
||||
isLogin: false,
|
||||
isUserInfoLoaded: false, // 新增:标识用户信息是否已经加载完毕
|
||||
userInfo: {},
|
||||
authDetails: null, // 用于存储获取到的真实入驻详情配置
|
||||
sjId: null,
|
||||
|
||||
showSetupModal: false, // 弹窗开关控制
|
||||
|
||||
displayScore: 0,
|
||||
animationTimer: null,
|
||||
|
||||
noticeList: [
|
||||
{ id: 0, title: '暂无最新公告', url: '' }
|
||||
],
|
||||
noticeList: [{ id: 0, title: '', url: '' }],
|
||||
|
||||
quickActions: [
|
||||
{ name: '扫码验券', icon: 'https://mrrplus.oss-cn-beijing.aliyuncs.com/photo/system/b128e423-e4b5-4ad6-bdf5-522de7a9bc68.png' , path: '/pages/shop/verify/verify-order'},
|
||||
|
|
@ -187,24 +247,43 @@ export default {
|
|||
};
|
||||
},
|
||||
computed: {
|
||||
// 营业状态:true(营业中) / false(休息中)
|
||||
isOpenStore() {
|
||||
return this.userInfo.order_taking === 1;
|
||||
// 判断是否具备接单的大前提条件
|
||||
canOpenStore() {
|
||||
return this.hasBusinessTime && this.hasServiceSkill && this.isCertified;
|
||||
},
|
||||
// 修复:使用 authDetails 里的真实接口返回字段判定服务技能
|
||||
hasServiceSkill() {
|
||||
// 只要 authDetails 里拿到了后端的 servers_kill 且该数组有内容,就说明配置过了
|
||||
return this.authDetails && Array.isArray(this.authDetails.servers_kill) && this.authDetails.servers_kill.length > 0;
|
||||
},
|
||||
|
||||
// 状态显示完全由计算属性控制,去除了手动修改可能导致的冲突
|
||||
isOpenStore() {
|
||||
// 如果连开门的前提条件都没满足,强制显示“休息中”
|
||||
if (!this.canOpenStore) {
|
||||
return false;
|
||||
}
|
||||
// 满足条件后,听后端的 (使用 == 防止后端返回字符串 "1")
|
||||
return this.userInfo.order_taking == 1;
|
||||
},
|
||||
|
||||
// 状态管理判定
|
||||
// 是否已入驻 (0: 未入驻, -1: 入驻第一步, >0: 已认证) 只要不等于0,说明已经开启了入驻流程
|
||||
isSettled() {
|
||||
if (!this.isLogin || !this.userInfo) return false;
|
||||
// 加上 typeof 判断,防止初始空对象时 undefined !== 0 造成的误判
|
||||
if (!this.isLogin || typeof this.userInfo.id_type === 'undefined') return false;
|
||||
return this.userInfo.id_type !== 0;
|
||||
},
|
||||
// 是否认证通过 (根据规则,> 0 说明认证通过了)
|
||||
isCertified() {
|
||||
if (!this.isLogin || !this.userInfo) return false;
|
||||
if (!this.isLogin || typeof this.userInfo.id_type === 'undefined') return false;
|
||||
return this.userInfo.id_type > 0;
|
||||
},
|
||||
// 是否配置了营业时间
|
||||
// 优化:兼容判定营业时间(userInfo 和 authDetails 里只要有就算配置了)
|
||||
hasBusinessTime() {
|
||||
return this.isLogin && !!this.userInfo.business_time;
|
||||
const timeFromUser = this.userInfo && this.userInfo.business_time;
|
||||
const timeFromAuth = this.authDetails && this.authDetails.business_time;
|
||||
return this.isLogin && !!(timeFromUser || timeFromAuth);
|
||||
},
|
||||
|
||||
// 根据登录状态动态返回头像
|
||||
|
|
@ -253,34 +332,51 @@ export default {
|
|||
}
|
||||
},
|
||||
methods: {
|
||||
goToBrandList() {
|
||||
uni.navigateTo({
|
||||
url: '/pages/jingxuan/selected-brands'
|
||||
// 处理登录跳转
|
||||
handleLoginRedirect() {
|
||||
// 如果 isLogin 为 false(未登录状态),则跳转到登录页
|
||||
if (!this.isLogin) {
|
||||
uni.navigateTo({
|
||||
url: '/pages/blogPopup/blogPopup'
|
||||
});
|
||||
}
|
||||
},
|
||||
// 弹窗中的快捷跳转功能
|
||||
closeSetupModal() {
|
||||
this.showSetupModal = false;
|
||||
},
|
||||
goToBusinessTime() {
|
||||
this.showSetupModal = false;
|
||||
uni.navigateTo({ url: '/pages/shop/business-time' });
|
||||
},
|
||||
goToServiceSkill() {
|
||||
this.showSetupModal = false;
|
||||
uni.navigateTo({ url: '/pages/shop/service-skills' });
|
||||
},
|
||||
goToAuth() {
|
||||
this.showSetupModal = false;
|
||||
uni.navigateTo({ url: '/pages/ruzhu/ruzhu' });
|
||||
},
|
||||
|
||||
goToBrandList() {
|
||||
uni.navigateTo({ url: '/pages/jingxuan/selected-brands' });
|
||||
},
|
||||
goToSkillList() {
|
||||
uni.navigateTo({
|
||||
url: '/pages/jingxuan/selected-skills'
|
||||
});
|
||||
uni.navigateTo({ url: '/pages/jingxuan/selected-skills' });
|
||||
},
|
||||
// 处理金刚区点击事件 (包含扫码验券核心逻辑)
|
||||
handleQuickAction(item) {
|
||||
if (item.name === '扫码验券') {
|
||||
console.log('准备跳转到自定义扫码页...');
|
||||
uni.navigateTo({
|
||||
url: '/pages/shop/verify/verify-order',
|
||||
fail: (err) => {
|
||||
console.error('跳转失败:', err);
|
||||
}
|
||||
});
|
||||
return;
|
||||
uni.navigateTo({
|
||||
url: '/pages/shop/verify/verify-order',
|
||||
fail: (err) => { console.error('跳转失败:', err); }
|
||||
});
|
||||
return;
|
||||
} // 2. 通用跳转逻辑
|
||||
else if (item.path) {
|
||||
else if (item.path) {
|
||||
uni.navigateTo({
|
||||
url: item.path,
|
||||
fail: () => {
|
||||
uni.showToast({ title: '页面开发中...', icon: 'none' });
|
||||
}
|
||||
fail: () => { uni.showToast({ title: '页面开发中...', icon: 'none' }); }
|
||||
});
|
||||
}
|
||||
},
|
||||
|
|
@ -297,31 +393,51 @@ export default {
|
|||
|
||||
getUserInfo() {
|
||||
request.post("/sj/user/getUser").then((result) => {
|
||||
if(result.code === 200 && result.data) {
|
||||
if(result.code == 200 && result.data) {
|
||||
this.userInfo = result.data;
|
||||
this.isUserInfoLoaded = true; // 数据回来了,允许相关 UI 进行渲染
|
||||
uni.setStorageSync("sjId", result.data.id);
|
||||
this.sjId = result.data.id;
|
||||
// 获取完用户信息后,初始化营业开关的状态
|
||||
this.initStoreStatus();
|
||||
|
||||
// 如果已入驻,才获取接单管理和实时数据
|
||||
// 如果在系统里(即使没通过认证),检查一下条件
|
||||
if (this.isSettled) {
|
||||
this.fetchOrderNum();
|
||||
this.fetchRealTimeData();
|
||||
|
||||
// 必须先去拉取认证详情(包含服务技能配置),再判断弹窗逻辑
|
||||
this.fetchAuthDetails();
|
||||
}
|
||||
}
|
||||
});
|
||||
},
|
||||
|
||||
// 获取:接单管理不同状态订单数量
|
||||
// 获取入驻、修改资料审核详情(获取服务技能、营业时间等准确数据)
|
||||
fetchAuthDetails() {
|
||||
request.post("/sj/userSjAuth/details", {
|
||||
type: 1, // 审核类型 1入驻申请
|
||||
id_type: '1' // 平台商家
|
||||
}).then(res => {
|
||||
if (res.code == 200 && res.data) {
|
||||
this.authDetails = res.data;
|
||||
}
|
||||
|
||||
// 只有确保拉到了配置详情后,再来判断三大件有没有配全
|
||||
// 如果没有配全,且是首次大退打开进入首页,拉起弹窗
|
||||
if (!this.canOpenStore && !hasShownSetupModal) {
|
||||
this.showSetupModal = true;
|
||||
hasShownSetupModal = true;
|
||||
}
|
||||
});
|
||||
},
|
||||
|
||||
fetchOrderNum() {
|
||||
request.post("/sj/poster/orderNum").then(res => {
|
||||
if(res.code === 200 && res.data) {
|
||||
if(res.code == 200 && res.data) {
|
||||
this.orderBasic = {
|
||||
updateTime: this.formatTime(res.data.now_date),
|
||||
waitStart: res.data.dfw || 0,
|
||||
waitFinish: res.data.dwc || 0,
|
||||
finished: res.data.yqx || 0 // 备注:接口返回只有dfw, dwc, yqx(已取消)。暂时将第三个坑位放为yqx,或后期让后端加字段
|
||||
finished: res.data.yqx || 0
|
||||
};
|
||||
}
|
||||
});
|
||||
|
|
@ -330,7 +446,7 @@ export default {
|
|||
// 获取:首页实时数据
|
||||
fetchRealTimeData() {
|
||||
request.post("/sj/poster/realTimeData").then(res => {
|
||||
if(res.code === 200 && res.data) {
|
||||
if(res.code == 200 && res.data) {
|
||||
const today = res.data.today || {};
|
||||
const yesterday = res.data.yesterday || {};
|
||||
|
||||
|
|
@ -351,7 +467,7 @@ export default {
|
|||
// 获取:通知公告列表
|
||||
fetchNoticeList() {
|
||||
request.post('/sj/notice/list', { page: 1, limit: 6 }).then(res => {
|
||||
if(res.code === 200 && res.data && res.data.list.length > 0) {
|
||||
if(res.code == 200 && res.data && res.data.list.length > 0) {
|
||||
this.noticeList = res.data.list;
|
||||
}
|
||||
});
|
||||
|
|
@ -359,12 +475,10 @@ export default {
|
|||
|
||||
// 获取:品牌列表
|
||||
fetchBrandList() {
|
||||
// 假设首页只拉取推荐的前4条
|
||||
request.post('/sj/brand/list', { page: 1, limit: 4 }).then(res => {
|
||||
if(res.code === 200 && res.data && res.data.list) {
|
||||
if(res.code == 200 && res.data && res.data.list) {
|
||||
this.brands = res.data.list.map(item => {
|
||||
let tags = [];
|
||||
// 根据接口字段动态生成标签映射
|
||||
if (item.franchise_state === 1) tags.push('franchise');
|
||||
if (item.student_state === 1) tags.push('recruit');
|
||||
if (tags.length === 0) tags.push('more');
|
||||
|
|
@ -384,14 +498,14 @@ export default {
|
|||
// 获取:技能集市列表
|
||||
fetchSkillList() {
|
||||
request.post('/sj/skill/list', { page: 1, limit: 4 }).then(res => {
|
||||
if(res.code === 200 && res.data && res.data.list) {
|
||||
if(res.code == 200 && res.data && res.data.list) {
|
||||
this.skills = res.data.list.map(item => {
|
||||
return {
|
||||
id: item.id,
|
||||
title: item.name,
|
||||
type: item.link_name || '平台课程',
|
||||
views: item.browse_num || 0,
|
||||
time: item.create_time ? item.create_time.split(' ')[0] : '', // 只取日期
|
||||
time: item.create_time ? item.create_time.split(' ')[0] : '',
|
||||
coverSrc: item.cover_img || 'https://dummyimage.com/200x150/ccc/fff.png&text=Video',
|
||||
typeIcon: item.link_logo || ''
|
||||
};
|
||||
|
|
@ -402,51 +516,51 @@ export default {
|
|||
|
||||
// 跳转:通知详情页
|
||||
goToNotice(msg) {
|
||||
if(msg.id) {
|
||||
uni.navigateTo({ url: `/pages/notice/detail?id=${msg.id}` });
|
||||
}
|
||||
if(msg.id) { uni.navigateTo({ url: `/pages/notice/detail?id=${msg.id}` }); }
|
||||
},
|
||||
|
||||
// 跳转:公告列表页
|
||||
// 跳转:通知公告列表页
|
||||
goToNoticeList() {
|
||||
uni.navigateTo({ url: '/pages/notice/notice_list' });
|
||||
},
|
||||
|
||||
// 跳转:去入驻
|
||||
goToSettle() {
|
||||
uni.navigateTo({ url: '/pages/ruzhu/ruzhu' });
|
||||
},
|
||||
|
||||
// 初始化按钮状态
|
||||
initStoreStatus() {
|
||||
// 如果未认证,或者(已认证但未配置时间),默认都是休息中
|
||||
if (!this.isCertified || (this.isCertified && !this.hasBusinessTime)) {
|
||||
this.isOpenStore = false;
|
||||
} else {
|
||||
// 认证通过且配置了时间,根据后端真实数据控制 (self_state 1为营业, 0为休息)
|
||||
this.isOpenStore = this.userInfo.self_state === 1;
|
||||
}
|
||||
},
|
||||
|
||||
// 营业中 / 休息中 按钮逻辑判断
|
||||
toggleStatus() {
|
||||
if (!this.isCertified) {
|
||||
uni.showModal({ title: '提示', content: '请先完善认证信息', confirmText: '去完善' });
|
||||
const currentStatus = this.userInfo.order_taking;
|
||||
const isCurrentlyResting = currentStatus != 1; // 当前不是营业中即为休息中
|
||||
|
||||
// 强力拦截:在休息中且三大件没配全,想要营业时拦截弹窗
|
||||
if (isCurrentlyResting && !this.canOpenStore) {
|
||||
this.showSetupModal = true;
|
||||
return;
|
||||
}
|
||||
if (this.isCertified && !this.hasBusinessTime) {
|
||||
uni.showToast({ title: '请先配置营业时间', icon: 'none' });
|
||||
return;
|
||||
}
|
||||
let newStatus = this.userInfo.order_taking == 1 ? 2 : 1;
|
||||
|
||||
// 准备切换的新状态
|
||||
let newStatus = currentStatus == 1 ? 2 : 1;
|
||||
|
||||
// 加入一个防连点的 Loading
|
||||
uni.showLoading({ title: '切换中...', mask: true });
|
||||
|
||||
// 发起请求告诉后端
|
||||
request.post("/sj/sjordertaking", {
|
||||
order_taking: newStatus,
|
||||
sjid: this.sjId
|
||||
}).then((res) => {
|
||||
this.getUserInfo();
|
||||
uni.hideLoading();
|
||||
// 因为上一次的严格判断误伤了你,这里回归你最原始的写法,直接假定成功
|
||||
this.userInfo.order_taking = newStatus; // 强行改一下本地状态让按钮动过去
|
||||
this.getUserInfo(); // 无论如何刷新一下真实数据
|
||||
uni.showToast({ title: newStatus == 1 ? '已开启营业' : '已休息', icon: 'none' });
|
||||
}).catch(() => {
|
||||
// 只有在彻底断网报错的情况下,才会弹下面这个
|
||||
uni.hideLoading();
|
||||
uni.showToast({ title: '网络异常,切换失败', icon: 'none' });
|
||||
});
|
||||
},
|
||||
|
||||
animateScore() {
|
||||
const target = parseFloat(this.orderDetail.score) || 0;
|
||||
if (this.animationTimer) clearInterval(this.animationTimer);
|
||||
|
|
@ -485,6 +599,134 @@ export default {
|
|||
background: #f5f6f8;
|
||||
}
|
||||
|
||||
/* ============ 提示弹窗样式 ============ */
|
||||
.setup-modal-mask {
|
||||
position: fixed;
|
||||
top: 0; left: 0; right: 0; bottom: 0;
|
||||
background: rgba(0, 0, 0, 0.5);
|
||||
z-index: 9999;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
|
||||
.setup-modal-content {
|
||||
width: 630rpx;
|
||||
height: 775rpx; /* 根据要求绝对固定宽高 */
|
||||
background: #FFFFFF;
|
||||
border-radius: 32rpx;
|
||||
position: relative;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
|
||||
.modal-bg {
|
||||
position: absolute;
|
||||
top: 0; left: 0;
|
||||
width: 630rpx;
|
||||
height: 265rpx;
|
||||
z-index: 0;
|
||||
}
|
||||
|
||||
.modal-header {
|
||||
position: relative;
|
||||
z-index: 1;
|
||||
height: 150rpx;
|
||||
display: flex;
|
||||
align-items: flex-end;
|
||||
justify-content: center;
|
||||
padding-bottom: 20rpx;
|
||||
|
||||
text {
|
||||
font-size: 36rpx;
|
||||
font-weight: bold;
|
||||
color: #333333;
|
||||
letter-spacing: 2rpx;
|
||||
}
|
||||
}
|
||||
|
||||
.modal-body {
|
||||
position: relative;
|
||||
z-index: 1;
|
||||
flex: 1;
|
||||
padding: 50rpx 40rpx;
|
||||
|
||||
.modal-subtitle {
|
||||
font-size: 28rpx;
|
||||
color: #333333;
|
||||
margin-bottom: 40rpx;
|
||||
display: block;
|
||||
}
|
||||
|
||||
.missing-list {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 46rpx; /* 间距拉开显得不那么拥挤 */
|
||||
|
||||
.missing-item {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
|
||||
.item-left {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
|
||||
.item-icon {
|
||||
width: 36rpx;
|
||||
height: 36rpx;
|
||||
margin-right: 16rpx;
|
||||
}
|
||||
|
||||
.item-texts {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
|
||||
.item-title {
|
||||
font-size: 30rpx;
|
||||
color: #333333;
|
||||
font-weight: 500;
|
||||
margin-bottom: 8rpx;
|
||||
}
|
||||
|
||||
.item-desc {
|
||||
font-size: 24rpx;
|
||||
color: #999999;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.item-right {
|
||||
font-size: 26rpx;
|
||||
font-weight: 400;
|
||||
|
||||
&.orange { color: #FF7B00; }
|
||||
&.grey { color: #999999; }
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.modal-footer {
|
||||
position: relative;
|
||||
z-index: 1;
|
||||
padding: 0 50rpx 50rpx;
|
||||
|
||||
.btn-know {
|
||||
width: 100%;
|
||||
height: 88rpx;
|
||||
background: #FF4767;
|
||||
border-radius: 44rpx;
|
||||
color: #FFFFFF;
|
||||
font-size: 32rpx;
|
||||
font-weight: 500;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
/* ==================================== */
|
||||
|
||||
.homePage {
|
||||
position: relative;
|
||||
min-height: 100vh;
|
||||
|
|
@ -589,7 +831,6 @@ export default {
|
|||
}
|
||||
}
|
||||
|
||||
// 营业中/休息中滑块核心样式区
|
||||
.status-toggle {
|
||||
position: relative;
|
||||
width: 173rpx;
|
||||
|
|
@ -664,7 +905,6 @@ export default {
|
|||
width: 100%;
|
||||
height: 248rpx;
|
||||
background-size: cover;
|
||||
/* 背景图由动态 style 接管 */
|
||||
}
|
||||
|
||||
.guide-body {
|
||||
|
|
|
|||
|
|
@ -9,7 +9,7 @@
|
|||
borderBottom="none"
|
||||
:show-headle="true"
|
||||
headleSrc="https://mrrplus.oss-cn-beijing.aliyuncs.com/photo/system/51ebca5d-95c5-4fb8-8aa3-560a79100d25.png"
|
||||
@onHeadleClick="">
|
||||
@onHeadleClick="goToSearch">
|
||||
</custom-navbar>
|
||||
|
||||
<serviecFirstTab
|
||||
|
|
@ -132,6 +132,46 @@ export default {
|
|||
this.loadFilterCategories();
|
||||
},
|
||||
methods: {
|
||||
// 跳转搜索页
|
||||
goToSearch() {
|
||||
uni.navigateTo({
|
||||
url: '/pages/search_common/search?type=brand' // 告诉搜索页,我要搜品牌
|
||||
});
|
||||
},
|
||||
|
||||
// 加载一级分类并自动组装其对应的二级分类,兼容 state === 1
|
||||
async loadFilterCategories() {
|
||||
try {
|
||||
const syrId = uni.getStorageSync('syrId') || 1;
|
||||
const res = await request.post('/sj/firstclass', { id: syrId })
|
||||
if ((res.code === 200 || res.state === 1) && res.data) {
|
||||
const firstClasses = res.data;
|
||||
|
||||
// 并发请求所有的二级分类
|
||||
const promises = firstClasses.map(async (first) => {
|
||||
try {
|
||||
const subRes = await request.post('/sj/secondclass', { id: first.id })
|
||||
return {
|
||||
id: first.id,
|
||||
title: first.title,
|
||||
children: ((subRes.code === 200 || subRes.state === 1) && subRes.data) ? subRes.data : []
|
||||
}
|
||||
} catch(e) {
|
||||
return { id: first.id, title: first.title, children: [] }
|
||||
}
|
||||
});
|
||||
|
||||
const filterData = await Promise.all(promises);
|
||||
// 过滤掉没有子分类的项,避免面板出现光秃秃的标题
|
||||
this.brandFilterData = filterData.filter(group => group.children.length > 0);
|
||||
} else {
|
||||
this.brandFilterData = []
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('获取分类字典失败', error)
|
||||
}
|
||||
},
|
||||
|
||||
// ============ 排序逻辑 ============
|
||||
toggleSort(type) {
|
||||
if (type === 'time') {
|
||||
|
|
|
|||
|
|
@ -137,7 +137,9 @@ export default {
|
|||
},
|
||||
methods: {
|
||||
goToSearch() {
|
||||
uni.showToast({ title: '搜索功能开发中', icon: 'none' })
|
||||
uni.navigateTo({
|
||||
url: '/pages/search_common/search?type=skill' // 告诉搜索页,我要搜技能
|
||||
});
|
||||
},
|
||||
|
||||
// 点击排序
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@
|
|||
<view class="collection-page">
|
||||
|
||||
<custom-navbar title="我的收藏" :showBack="true" backgroundColor="#FFFFFF" :show-headle="true" borderBottom="none"
|
||||
headleSrc="https://mrrplus.oss-cn-beijing.aliyuncs.com/photo/system/51ebca5d-95c5-4fb8-8aa3-560a79100d25.png" @onHeadleClick="addAddress">
|
||||
headleSrc="https://mrrplus.oss-cn-beijing.aliyuncs.com/photo/system/51ebca5d-95c5-4fb8-8aa3-560a79100d25.png" @onHeadleClick="goToSearch">
|
||||
</custom-navbar>
|
||||
|
||||
<view class="nav-placeholder" :style="{ height: navHeight + 'px' }"></view>
|
||||
|
|
@ -167,6 +167,13 @@ export default {
|
|||
this.loadData()
|
||||
},
|
||||
methods: {
|
||||
// 跳转搜索页
|
||||
goToSearch() {
|
||||
// this.currentTab 的值刚好是 'brand' 或 'course'
|
||||
uni.navigateTo({
|
||||
url: `/pages/search_common/search?type=collection_${this.currentTab}`
|
||||
});
|
||||
},
|
||||
goBack() {
|
||||
uni.navigateBack()
|
||||
},
|
||||
|
|
|
|||
|
|
@ -7,9 +7,6 @@
|
|||
backgroundColor="linear-gradient(180deg, #E6ECFB 0%, #FFFFFF 100%)"
|
||||
:showHeadle="true"
|
||||
borderBottom="none"
|
||||
headleSrc="https://mrrplus.oss-cn-beijing.aliyuncs.com/photo/system/51ebca5d-95c5-4fb8-8aa3-560a79100d25.png"
|
||||
@onHeadleClick="handleShare"
|
||||
|
||||
/>
|
||||
|
||||
<!-- 页面主要内容 -->
|
||||
|
|
|
|||
|
|
@ -1,34 +1,30 @@
|
|||
<template>
|
||||
<view class="notice-page">
|
||||
<!-- 自定义顶部导航组件 -->
|
||||
<custom-navbar title="公告通知" :showBack="true" backgroundColor="#FFFFFF" :show-headle="true"
|
||||
headleSrc="https://mrrplus.oss-cn-beijing.aliyuncs.com/photo/system/51ebca5d-95c5-4fb8-8aa3-560a79100d25.png" @onHeadleClick="addAddress">
|
||||
</custom-navbar>
|
||||
|
||||
<!-- 主要内容区域 -->
|
||||
<custom-navbar
|
||||
title="公告通知"
|
||||
:showBack="true"
|
||||
backgroundColor="#FFFFFF"
|
||||
:show-headle="true"
|
||||
headleSrc="https://mrrplus.oss-cn-beijing.aliyuncs.com/photo/system/51ebca5d-95c5-4fb8-8aa3-560a79100d25.png"
|
||||
@onHeadleClick="goToSearch"
|
||||
/>
|
||||
|
||||
<view class="page-content">
|
||||
<!-- 加载状态 -->
|
||||
<view v-if="loading" class="loading-container">
|
||||
<view class="loading-icon"></view>
|
||||
<text class="loading-text">加载中...</text>
|
||||
</view>
|
||||
|
||||
|
||||
<!-- 公告列表 -->
|
||||
<view v-else-if="noticeList.length > 0" class="notice-list">
|
||||
<view
|
||||
class="notice-item"
|
||||
v-for="(item, index) in noticeList"
|
||||
<NoticeCard
|
||||
v-for="item in noticeList"
|
||||
:key="item.id"
|
||||
@tap="goToDetail(item)"
|
||||
>
|
||||
<view class="item-main">
|
||||
<text class="item-title line-2">{{ item.title }}</text>
|
||||
<view class="item-time">
|
||||
<text class="time-text">发布时间:{{ formatTime(item.create_time) }}</text>
|
||||
</view>
|
||||
</view>
|
||||
<!-- <image class="arrow-icon" src="https://mrrplus.oss-cn-beijing.aliyuncs.com/photo/system/ee119e24-1cb2-43df-86e6-61af8e9fd0ad.png" mode="aspectFit"></image> -->
|
||||
</view>
|
||||
:item="item"
|
||||
@click="goToDetail"
|
||||
/>
|
||||
|
||||
<!-- 加载更多状态 -->
|
||||
<view v-if="loadingMore" class="load-more">
|
||||
|
|
@ -38,7 +34,6 @@
|
|||
<text>没有更多了</text>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<!-- 空状态 -->
|
||||
<view v-else class="empty-container">
|
||||
<image class="empty-img" src="https://mrrplus.oss-cn-beijing.aliyuncs.com/photo/system/8c5e7b2a-3d4f-4b1e-9a7c-6e8f2d1b4a5c.png" mode="aspectFit"></image>
|
||||
|
|
@ -50,37 +45,44 @@
|
|||
|
||||
<script>
|
||||
import CustomNavbar from '@/components/custom-navbar/custom-navbar.vue';
|
||||
import NoticeCard from '@/pages/home/components/notice-card.vue';
|
||||
import request from '@/utils/request';
|
||||
|
||||
export default {
|
||||
components: {
|
||||
CustomNavbar
|
||||
CustomNavbar,
|
||||
NoticeCard // 注册组件
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
loading: false, // 首次加载状态
|
||||
loadingMore: false, // 加载更多状态
|
||||
noticeList: [], // 公告列表数据
|
||||
page: 1, // 当前页码
|
||||
limit: 10, // 每页数量
|
||||
total: 0, // 总记录数
|
||||
hasMore: true // 是否还有更多数据
|
||||
loading: false,
|
||||
loadingMore: false,
|
||||
noticeList: [],
|
||||
page: 1,
|
||||
limit: 10,
|
||||
total: 0,
|
||||
hasMore: true
|
||||
};
|
||||
},
|
||||
onLoad() {
|
||||
this.fetchNoticeList(true);
|
||||
},
|
||||
// 下拉刷新
|
||||
onPullDownRefresh() {
|
||||
this.fetchNoticeList(true);
|
||||
},
|
||||
// 上拉加载更多
|
||||
onReachBottom() {
|
||||
if (!this.loadingMore && this.hasMore && !this.loading) {
|
||||
this.fetchNoticeList(false);
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
// 跳转搜索页
|
||||
goToSearch() {
|
||||
uni.navigateTo({
|
||||
url: '/pages/search_common/search?type=notice'
|
||||
});
|
||||
},
|
||||
|
||||
// 获取公告列表
|
||||
fetchNoticeList(reset = true) {
|
||||
if (reset) {
|
||||
|
|
@ -90,8 +92,10 @@ export default {
|
|||
} else {
|
||||
if (!this.hasMore) return;
|
||||
this.loadingMore = true;
|
||||
// 非重置时页码+1
|
||||
this.page++;
|
||||
}
|
||||
|
||||
|
||||
request.post('/sj/notice/list', {
|
||||
page: this.page,
|
||||
limit: this.limit
|
||||
|
|
@ -109,18 +113,15 @@ export default {
|
|||
|
||||
// 判断是否还有更多数据
|
||||
this.hasMore = this.noticeList.length < total;
|
||||
|
||||
// 如果还有更多数据,页码加1
|
||||
if (this.hasMore && !reset) {
|
||||
this.page++;
|
||||
}
|
||||
} else {
|
||||
if (reset) this.noticeList = [];
|
||||
this.hasMore = false;
|
||||
// 非重置且请求失败时回滚页码
|
||||
if (!reset && this.page > 1) this.page--;
|
||||
}
|
||||
}).catch(err => {
|
||||
console.error('获取公告列表失败:', err);
|
||||
if (reset) this.noticeList = [];
|
||||
if (!reset && this.page > 1) this.page--; // 回滚页码
|
||||
uni.showToast({
|
||||
title: '加载失败,请稍后重试',
|
||||
icon: 'none'
|
||||
|
|
@ -128,34 +129,13 @@ export default {
|
|||
}).finally(() => {
|
||||
this.loading = false;
|
||||
this.loadingMore = false;
|
||||
// 停止下拉刷新
|
||||
if (reset) {
|
||||
uni.stopPullDownRefresh();
|
||||
}
|
||||
});
|
||||
},
|
||||
|
||||
// 格式化时间
|
||||
formatTime(timeStr) {
|
||||
if (!timeStr) return '--:--:--';
|
||||
// 处理多种时间格式:2026-06-10 15:00:00 或 2026.06.1015:00:00
|
||||
let formatted = timeStr;
|
||||
// 如果是点分隔的格式,转换为标准格式
|
||||
if (timeStr.includes('.') && !timeStr.includes('-')) {
|
||||
formatted = timeStr.replace(/\./g, '-');
|
||||
// 处理日期和时间连在一起的情况,如 "2026.06.1015:00:00" -> "2026-06-10 15:00:00"
|
||||
if (formatted.match(/\d{4}-\d{2}-\d{2}\d{2}:\d{2}:\d{2}/)) {
|
||||
formatted = formatted.replace(/(\d{4}-\d{2}-\d{2})(\d{2}:\d{2}:\d{2})/, '$1 $2');
|
||||
}
|
||||
}
|
||||
// 如果已经是标准格式,直接返回
|
||||
if (formatted.includes('-') && formatted.includes(':')) {
|
||||
return formatted;
|
||||
}
|
||||
return timeStr;
|
||||
},
|
||||
|
||||
// 跳转到详情页
|
||||
// 跳转到详情页(接收 NoticeCard 组件 $emit 传递的 item)
|
||||
goToDetail(item) {
|
||||
if (item.id) {
|
||||
uni.navigateTo({
|
||||
|
|
@ -177,7 +157,6 @@ export default {
|
|||
padding: 20rpx 20rpx 40rpx;
|
||||
}
|
||||
|
||||
// 加载中样式
|
||||
.loading-container {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
|
|
@ -204,54 +183,6 @@ export default {
|
|||
@keyframes spin {
|
||||
to { transform: rotate(360deg); }
|
||||
}
|
||||
|
||||
// 公告列表
|
||||
.notice-list {
|
||||
.notice-item {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
background: #ffffff;
|
||||
border-radius: 20rpx;
|
||||
padding: 30rpx;
|
||||
margin-bottom: 20rpx;
|
||||
// box-shadow: 0 2rpx 12rpx rgba(0, 0, 0, 0.04);
|
||||
transition: all 0.2s ease;
|
||||
|
||||
.item-main {
|
||||
flex: 1;
|
||||
min-width: 0; // 防止文字溢出
|
||||
|
||||
.item-title {
|
||||
font-size: 30rpx;
|
||||
font-weight: 500;
|
||||
color: #101010;
|
||||
line-height: 42rpx;
|
||||
margin-bottom: 16rpx;
|
||||
}
|
||||
|
||||
.item-time {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
|
||||
.time-icon {
|
||||
width: 24rpx;
|
||||
height: 24rpx;
|
||||
margin-right: 8rpx;
|
||||
opacity: 0.6;
|
||||
}
|
||||
|
||||
.time-text {
|
||||
font-size: 22rpx;
|
||||
color: #999;
|
||||
line-height: 30rpx;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 加载更多
|
||||
.load-more, .no-more {
|
||||
text-align: center;
|
||||
padding: 30rpx 0;
|
||||
|
|
@ -259,7 +190,6 @@ export default {
|
|||
color: #999;
|
||||
}
|
||||
|
||||
// 空状态
|
||||
.empty-container {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
|
|
@ -279,20 +209,4 @@ export default {
|
|||
color: #999;
|
||||
}
|
||||
}
|
||||
|
||||
// 多行省略
|
||||
.line-2 {
|
||||
display: -webkit-box;
|
||||
-webkit-box-orient: vertical;
|
||||
-webkit-line-clamp: 2;
|
||||
overflow: hidden;
|
||||
word-break: break-all;
|
||||
}
|
||||
|
||||
|
||||
::v-deep .icon-headle {
|
||||
width: 32rpx !important;
|
||||
height: 32rpx !important;
|
||||
}
|
||||
|
||||
</style>
|
||||
|
|
@ -0,0 +1,363 @@
|
|||
<template>
|
||||
<view class="search-page">
|
||||
<view class="search-header" :style="{ paddingTop: statusBarHeight + 'px' }">
|
||||
<view class="header-content">
|
||||
<image class="back-icon" src="/static/images/back.png" @tap="goBack"></image>
|
||||
|
||||
<view class="search-box">
|
||||
<input
|
||||
class="search-input"
|
||||
v-model="keyword"
|
||||
:placeholder="placeholderText"
|
||||
placeholder-class="search-placeholder"
|
||||
focus
|
||||
confirm-type="search"
|
||||
@confirm="handleSearch"
|
||||
/>
|
||||
<!-- <view v-if="keyword" class="clear-icon" @tap="clearSearch">✕</view> -->
|
||||
<text class="search-btn" @tap="handleSearch">搜索</text>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<view class="nav-placeholder" :style="{ height: navHeight + 'px' }"></view>
|
||||
|
||||
<view class="result-container">
|
||||
|
||||
<view v-if="loading && page === 1" class="loading-tips">加载中...</view>
|
||||
|
||||
<view v-else-if="searchType === 'notice' && resultList.length > 0">
|
||||
<notice-card
|
||||
v-for="item in resultList"
|
||||
:key="item.id"
|
||||
:item="item"
|
||||
@click="goToDetail(item)"
|
||||
/>
|
||||
</view>
|
||||
|
||||
<view v-else-if="(searchType === 'brand' || searchType === 'collection_brand') && resultList.length > 0" class="brand-grid">
|
||||
<brand-card
|
||||
class="brand-card-wrap"
|
||||
v-for="item in resultList"
|
||||
:key="item.id"
|
||||
:item="item"
|
||||
:tagKeys="item.tagKeys || []"
|
||||
@click="goToDetail(item)"
|
||||
/>
|
||||
</view>
|
||||
|
||||
<view v-else-if="(searchType === 'skill' || searchType === 'collection_course') && resultList.length > 0" class="course-list">
|
||||
<skill-card
|
||||
v-for="item in resultList"
|
||||
:key="item.id"
|
||||
:item="item"
|
||||
@click="goToDetail(item)"
|
||||
/>
|
||||
</view>
|
||||
|
||||
<view v-else-if="!loading && hasSearched && resultList.length === 0" class="empty-state">
|
||||
<image class="empty-icon" src="https://mrrplus.oss-cn-beijing.aliyuncs.com/photo/system/4e4320d1-cc5c-4312-890c-f1eb8381fdd2.png"></image>
|
||||
<text>未搜索到相关内容哦~</text>
|
||||
</view>
|
||||
|
||||
<view v-if="resultList.length > 0" class="load-more-text">
|
||||
<text v-if="loading && page > 1">正在加载更多...</text>
|
||||
<text v-else-if="!hasMore">没有更多了</text>
|
||||
</view>
|
||||
|
||||
</view>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import BrandCard from "@/pages/home/components/brand-card.vue";
|
||||
import SkillCard from "@/pages/home/components/skill-card.vue";
|
||||
import NoticeCard from "@/pages/home/components/notice-card.vue";
|
||||
import request from '@/utils/request';
|
||||
|
||||
export default {
|
||||
components: {
|
||||
BrandCard,
|
||||
SkillCard,
|
||||
NoticeCard
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
statusBarHeight: 0,
|
||||
navHeight: 0,
|
||||
searchType: '',
|
||||
keyword: '',
|
||||
resultList: [],
|
||||
|
||||
loading: false,
|
||||
hasSearched: false,
|
||||
|
||||
// 分页相关
|
||||
page: 1,
|
||||
limit: 10,
|
||||
hasMore: true
|
||||
};
|
||||
},
|
||||
computed: {
|
||||
placeholderText() {
|
||||
const map = {
|
||||
'notice': '搜索公告通知',
|
||||
'brand': '搜索精选品牌',
|
||||
'skill': '搜索技能课程',
|
||||
'collection_brand': '搜索收藏品牌的内容',
|
||||
'collection_course': '搜索收藏课程的内容'
|
||||
};
|
||||
return map[this.searchType] || '请输入搜索内容';
|
||||
}
|
||||
},
|
||||
onLoad(options) {
|
||||
const systemInfo = uni.getSystemInfoSync();
|
||||
this.statusBarHeight = systemInfo.statusBarHeight;
|
||||
this.navHeight = this.statusBarHeight + 44;
|
||||
|
||||
if (options.type) {
|
||||
this.searchType = options.type;
|
||||
}
|
||||
},
|
||||
onReachBottom() {
|
||||
if (this.hasMore && !this.loading) {
|
||||
this.page++;
|
||||
this.loadData(false);
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
goBack() {
|
||||
uni.navigateBack();
|
||||
},
|
||||
|
||||
clearSearch() {
|
||||
this.keyword = '';
|
||||
this.resultList = [];
|
||||
this.hasSearched = false;
|
||||
this.page = 1;
|
||||
this.hasMore = true;
|
||||
},
|
||||
|
||||
handleSearch() {
|
||||
if (!this.keyword.trim()) {
|
||||
return uni.showToast({ title: '请输入搜索内容', icon: 'none' });
|
||||
}
|
||||
this.hasSearched = true;
|
||||
this.page = 1;
|
||||
this.hasMore = true;
|
||||
this.loadData(true);
|
||||
},
|
||||
|
||||
async loadData(isReset) {
|
||||
this.loading = true;
|
||||
|
||||
try {
|
||||
let apiUrl = '';
|
||||
let params = { page: this.page, limit: this.limit };
|
||||
|
||||
switch (this.searchType) {
|
||||
case 'notice':
|
||||
apiUrl = '/sj/notice/list';
|
||||
params.title = this.keyword;
|
||||
break;
|
||||
case 'brand':
|
||||
apiUrl = '/sj/brand/list';
|
||||
params.name = this.keyword;
|
||||
break;
|
||||
case 'skill':
|
||||
apiUrl = '/sj/skill/list';
|
||||
params.name = this.keyword;
|
||||
break;
|
||||
case 'collection_brand':
|
||||
apiUrl = '/sj/brand/collectList';
|
||||
params.name = this.keyword;
|
||||
break;
|
||||
case 'collection_course':
|
||||
apiUrl = '/sj/skill/collectList';
|
||||
params.name = this.keyword;
|
||||
break;
|
||||
default:
|
||||
throw new Error('未知的搜索类型');
|
||||
}
|
||||
|
||||
const res = await request.post(apiUrl, params);
|
||||
|
||||
if (res.code === 200 && res.data) {
|
||||
const list = res.data.list || [];
|
||||
// 文档里总数叫 count,不是 total
|
||||
const totalCount = res.data.count || 0;
|
||||
|
||||
let formattedList = list;
|
||||
|
||||
if (this.searchType === 'brand' || this.searchType === 'collection_brand') {
|
||||
formattedList = list.map(item => {
|
||||
let tags = [];
|
||||
if (item.franchise_state === 1) tags.push('franchise');
|
||||
if (item.student_state === 1) tags.push('recruit');
|
||||
if (tags.length === 0) tags.push('more');
|
||||
return {
|
||||
...item,
|
||||
name: item.name,
|
||||
bgSrc: item.cover_img || 'https://dummyimage.com/300x200/ccc/fff.png',
|
||||
avatar: item.logo_img || 'https://dummyimage.com/100x100/ccc/fff.png',
|
||||
tagKeys: tags
|
||||
};
|
||||
});
|
||||
} else if (this.searchType === 'skill' || this.searchType === 'collection_course') {
|
||||
formattedList = list.map(item => ({
|
||||
...item,
|
||||
title: item.name,
|
||||
coverSrc: item.cover_img || 'https://dummyimage.com/300x200/ccc/fff.png',
|
||||
type: item.link_name || (item.link_type === 1 ? '平台课程' : '品牌课程'),
|
||||
views: item.browse_num || 0,
|
||||
typeIcon: item.link_logo || ''
|
||||
}));
|
||||
}
|
||||
|
||||
if (isReset) {
|
||||
this.resultList = formattedList;
|
||||
} else {
|
||||
this.resultList = [...this.resultList, ...formattedList];
|
||||
}
|
||||
|
||||
// 根据接口文档返回的 count 来判断是否还有更多
|
||||
this.hasMore = this.resultList.length < totalCount;
|
||||
|
||||
} else {
|
||||
if (isReset) this.resultList = [];
|
||||
this.hasMore = false;
|
||||
}
|
||||
} catch (e) {
|
||||
console.error('搜索异常:', e);
|
||||
uni.showToast({ title: '搜索失败,请重试', icon: 'none' });
|
||||
} finally {
|
||||
this.loading = false;
|
||||
}
|
||||
},
|
||||
|
||||
goToDetail(item) {
|
||||
if (!item.id) return;
|
||||
|
||||
if (this.searchType === 'notice') {
|
||||
uni.navigateTo({ url: `/pages/notice/detail?id=${item.id}` });
|
||||
} else if (this.searchType === 'brand' || this.searchType === 'collection_brand') {
|
||||
uni.navigateTo({ url: `/pages/brand/detail?id=${item.id}` });
|
||||
} else if (this.searchType === 'skill' || this.searchType === 'collection_course') {
|
||||
uni.navigateTo({ url: `/pages/skill/detail?id=${item.id}` });
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.search-page {
|
||||
min-height: 100vh;
|
||||
background: #F5F5F5;
|
||||
}
|
||||
|
||||
.search-header {
|
||||
position: fixed;
|
||||
top: 0;
|
||||
left: 0;
|
||||
right: 0;
|
||||
background-color: #F5F5F5;
|
||||
z-index: 999;
|
||||
|
||||
.header-content {
|
||||
height: 44px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
padding: 0 24rpx;
|
||||
|
||||
.back-icon {
|
||||
width: 28rpx;
|
||||
height: 28rpx;
|
||||
padding-right: 20rpx;
|
||||
}
|
||||
|
||||
.search-box {
|
||||
flex: 1;
|
||||
height: 74rpx;
|
||||
background: #fff;
|
||||
border-radius: 37rpx;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
padding: 0 6rpx 0 24rpx;
|
||||
|
||||
.search-input {
|
||||
flex: 1;
|
||||
font-size: 28rpx;
|
||||
}
|
||||
.search-placeholder {
|
||||
color: #CCCCCC;
|
||||
}
|
||||
|
||||
.clear-icon {
|
||||
font-size: 28rpx;
|
||||
color: #999;
|
||||
padding: 10rpx 20rpx;
|
||||
}
|
||||
}
|
||||
|
||||
.search-btn {
|
||||
width: 110rpx;
|
||||
height: 62rpx;
|
||||
line-height: 62rpx;
|
||||
background: #FF4767;
|
||||
border-radius: 31rpx;
|
||||
font-size: 28rpx;
|
||||
color: #fff;
|
||||
text-align: center;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.result-container {
|
||||
padding: 24rpx;
|
||||
}
|
||||
|
||||
.loading-tips {
|
||||
text-align: center;
|
||||
padding: 100rpx 0;
|
||||
color: #999;
|
||||
font-size: 28rpx;
|
||||
}
|
||||
|
||||
.brand-grid {
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
justify-content: space-between;
|
||||
.brand-card-wrap { width: 48.5%; margin-bottom: 24rpx; }
|
||||
}
|
||||
|
||||
.course-list {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
}
|
||||
|
||||
.empty-state {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
padding: 200rpx 0;
|
||||
|
||||
.empty-icon {
|
||||
width: 200rpx;
|
||||
height: 200rpx;
|
||||
margin-bottom: 20rpx;
|
||||
}
|
||||
text {
|
||||
font-size: 28rpx;
|
||||
color: #999;
|
||||
}
|
||||
}
|
||||
|
||||
.load-more-text {
|
||||
text-align: center;
|
||||
padding: 30rpx 0;
|
||||
font-size: 24rpx;
|
||||
color: #999;
|
||||
}
|
||||
</style>
|
||||
Loading…
Reference in New Issue