公告通知+核销扫描
This commit is contained in:
parent
af91692ba6
commit
d008710130
26
pages.json
26
pages.json
|
|
@ -150,7 +150,13 @@
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"path": "pages/add/add",
|
"path": "pages/notice/notice_list",
|
||||||
|
"style": {
|
||||||
|
"navigationStyle": "custom"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"path": "pages/notice/detail",
|
||||||
"style": {
|
"style": {
|
||||||
"navigationStyle": "custom"
|
"navigationStyle": "custom"
|
||||||
}
|
}
|
||||||
|
|
@ -584,6 +590,24 @@
|
||||||
"navigationStyle": "custom"
|
"navigationStyle": "custom"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"path": "pages/shop/verify/verify-order",
|
||||||
|
"style": {
|
||||||
|
"navigationStyle": "custom"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"path": "pages/shop/verify/manual-verify",
|
||||||
|
"style": {
|
||||||
|
"navigationStyle": "custom"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"path": "pages/shop/verify/verify-order-detail",
|
||||||
|
"style": {
|
||||||
|
"navigationStyle": "custom"
|
||||||
|
}
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"path": "pages/shop/photoAlbum/photoManage",
|
"path": "pages/shop/photoAlbum/photoManage",
|
||||||
"style": {
|
"style": {
|
||||||
|
|
|
||||||
|
|
@ -18,7 +18,7 @@
|
||||||
</view>
|
</view>
|
||||||
|
|
||||||
<view class="quick-actions card-box" v-if="isLogin && isSettled">
|
<view class="quick-actions card-box" v-if="isLogin && isSettled">
|
||||||
<view class="action-item" v-for="(item, index) in quickActions" :key="index">
|
<view class="action-item" v-for="(item, index) in quickActions" :key="index" @tap="handleQuickAction(item)">
|
||||||
<image class="action-icon" :src="item.icon"></image>
|
<image class="action-icon" :src="item.icon"></image>
|
||||||
<text class="action-text">{{ item.name }}</text>
|
<text class="action-text">{{ item.name }}</text>
|
||||||
</view>
|
</view>
|
||||||
|
|
@ -29,7 +29,7 @@
|
||||||
<view class="header-left">
|
<view class="header-left">
|
||||||
<text class="title">接单管理</text>
|
<text class="title">接单管理</text>
|
||||||
<text class="update-time">更新时间:{{ orderBasic.updateTime }}</text>
|
<text class="update-time">更新时间:{{ orderBasic.updateTime }}</text>
|
||||||
<image class="refresh-icon" src="https://mrrplus.oss-cn-beijing.aliyuncs.com/photo/system/31c6eebc-5538-4c66-9b32-24dced170a99.png"></image>
|
<image class="refresh-icon" src="https://mrrplus.oss-cn-beijing.aliyuncs.com/photo/system/31c6eebc-5538-4c66-9b32-24dced170a99.png" @tap="fetchOrderNum"></image>
|
||||||
</view>
|
</view>
|
||||||
<view class="header-right">更多数据 <image class="more-right-icon" src="https://mrrplus.oss-cn-beijing.aliyuncs.com/photo/system/ee119e24-1cb2-43df-86e6-61af8e9fd0ad.png"></image></view>
|
<view class="header-right">更多数据 <image class="more-right-icon" src="https://mrrplus.oss-cn-beijing.aliyuncs.com/photo/system/ee119e24-1cb2-43df-86e6-61af8e9fd0ad.png"></image></view>
|
||||||
</view>
|
</view>
|
||||||
|
|
@ -54,7 +54,7 @@
|
||||||
<view class="header-left">
|
<view class="header-left">
|
||||||
<text class="title">当日实时数据</text>
|
<text class="title">当日实时数据</text>
|
||||||
<text class="update-time">更新时间:{{ orderDetail.updateTime }}</text>
|
<text class="update-time">更新时间:{{ orderDetail.updateTime }}</text>
|
||||||
<image class="refresh-icon" src="https://mrrplus.oss-cn-beijing.aliyuncs.com/photo/system/31c6eebc-5538-4c66-9b32-24dced170a99.png"></image>
|
<image class="refresh-icon" src="https://mrrplus.oss-cn-beijing.aliyuncs.com/photo/system/31c6eebc-5538-4c66-9b32-24dced170a99.png" @tap="fetchRealTimeData"></image>
|
||||||
</view>
|
</view>
|
||||||
</view>
|
</view>
|
||||||
<view class="detail-content">
|
<view class="detail-content">
|
||||||
|
|
@ -173,41 +173,32 @@ export default {
|
||||||
userInfo: {}, // 用户信息数据源
|
userInfo: {}, // 用户信息数据源
|
||||||
syrId: null,
|
syrId: null,
|
||||||
|
|
||||||
isOpenStore: false, // true为营业中(圆点在右),false为休息中(圆点在左)。由后续逻辑决定初始化状态。
|
|
||||||
displayScore: 0,
|
displayScore: 0,
|
||||||
animationTimer: null,
|
animationTimer: null,
|
||||||
|
|
||||||
// 通知公告数据:预留接口,支持最新6条轮播
|
// 通知公告数据
|
||||||
noticeList: [
|
noticeList: [
|
||||||
{ id: 1, title: '商家券更新了!品牌专区上新了!', url: '/pages/...' },
|
{ id: 0, title: '暂无最新公告', url: '' }
|
||||||
{ id: 2, title: '系统维护通知:今晚凌晨将进行升级', url: '/pages/...' },
|
|
||||||
{ id: 3, title: '平台新政策发布,请及时查看', url: '/pages/...' }
|
|
||||||
],
|
],
|
||||||
|
|
||||||
quickActions: [
|
quickActions: [
|
||||||
{ name: '扫码验券', icon: 'https://mrrplus.oss-cn-beijing.aliyuncs.com/photo/system/b128e423-e4b5-4ad6-bdf5-522de7a9bc68.png' },
|
{ name: '扫码验券', icon: 'https://mrrplus.oss-cn-beijing.aliyuncs.com/photo/system/b128e423-e4b5-4ad6-bdf5-522de7a9bc68.png' , path: '/pages/shop/verify/verify-order'},
|
||||||
{ name: '服务管理', icon: 'https://mrrplus.oss-cn-beijing.aliyuncs.com/photo/system/a90f02a2-9d39-440a-ad20-a4337bcd1b38.png' },
|
{ name: '服务管理', icon: 'https://mrrplus.oss-cn-beijing.aliyuncs.com/photo/system/a90f02a2-9d39-440a-ad20-a4337bcd1b38.png' , path: '/pages/artisan/service-list'},
|
||||||
{ name: '工位管理', icon: 'https://mrrplus.oss-cn-beijing.aliyuncs.com/photo/system/4c503603-6c2f-4a7a-9329-5e54b8ca769e.png' },
|
{ name: '工位管理', icon: 'https://mrrplus.oss-cn-beijing.aliyuncs.com/photo/system/4c503603-6c2f-4a7a-9329-5e54b8ca769e.png' , path: '/pages/shop/workSpace/list'},
|
||||||
{ name: '财务管理', icon: 'https://mrrplus.oss-cn-beijing.aliyuncs.com/photo/system/728c659e-e395-4473-b83e-7e04539f7ec6.png' }
|
{ name: '财务管理', icon: 'https://mrrplus.oss-cn-beijing.aliyuncs.com/photo/system/728c659e-e395-4473-b83e-7e04539f7ec6.png' , path: '/pages/wallet/wallet'}
|
||||||
],
|
],
|
||||||
orderBasic: { updateTime: '15:30', waitStart: 23, waitFinish: 43, finished: 234 },
|
orderBasic: { updateTime: '--:--', waitStart: 0, waitFinish: 0, finished: 0 },
|
||||||
orderDetail: { updateTime: '15:30', score: '82.2', visitors: 0, yVisitors: 100, orders: 234, yOrders: 1000, amount: '1.34', yAmount: '1.4' },
|
orderDetail: { updateTime: '--:--', score: '0.0', visitors: 0, yVisitors: 0, orders: 0, yOrders: 0, amount: '0.00', yAmount: '0.00' },
|
||||||
|
|
||||||
brands: [
|
brands: [],
|
||||||
{ name: '蜜丝卡伦美甲美睫', bgSrc: 'https://mrrplus.oss-cn-beijing.aliyuncs.com/photo/system/d02b2d8b-0e01-4c6d-bbee-c60dccf4867c.jpg', avatar: 'https://dummyimage.com/100x100/ccc/fff.png&text=Avatar', tagKeys: ['franchise', 'recruit'] },
|
skills: []
|
||||||
{ name: 'ALNL 清莲爱丽', bgSrc: 'https://mrrplus.oss-cn-beijing.aliyuncs.com/photo/system/d02b2d8b-0e01-4c6d-bbee-c60dccf4867c.jpg', avatar: 'https://dummyimage.com/100x100/ccc/fff.png&text=Avatar', tagKeys: ['recruit'] },
|
|
||||||
{ name: 'IL COLPO依宝美容', bgSrc: 'https://mrrplus.oss-cn-beijing.aliyuncs.com/photo/system/d02b2d8b-0e01-4c6d-bbee-c60dccf4867c.jpg', avatar: 'https://dummyimage.com/100x100/ccc/fff.png&text=Avatar', tagKeys: ['franchise'] },
|
|
||||||
{ name: '蜜丝卡伦美甲美睫', bgSrc: 'https://mrrplus.oss-cn-beijing.aliyuncs.com/photo/system/d02b2d8b-0e01-4c6d-bbee-c60dccf4867c.jpg', avatar: 'https://dummyimage.com/100x100/ccc/fff.png&text=Avatar', tagKeys: ['more'] }
|
|
||||||
],
|
|
||||||
skills: [
|
|
||||||
{ title: '穿戴甲的操作视频扫码验券操作123564798', type: '平台课程', views: '83.6万', time: '7小时前', coverSrc: 'https://dummyimage.com/200x150/ccc/fff.png&text=Video' },
|
|
||||||
{ title: '脸部按摩操作步骤详情', type: '脸缘品牌', views: '8334', time: '1天前', coverSrc: 'https://dummyimage.com/200x150/ccc/fff.png&text=Video' },
|
|
||||||
{ title: '全身SPA的操作视频操作教程', type: '平台课程', views: '2344', time: '3天前', coverSrc: 'https://dummyimage.com/200x150/ccc/fff.png&text=Video' },
|
|
||||||
{ title: '穿戴甲的操作视频扫码验券操作...', type: '平台课程', views: '836', time: '4月26日', coverSrc: 'https://dummyimage.com/200x150/ccc/fff.png&text=Video' }
|
|
||||||
]
|
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
computed: {
|
computed: {
|
||||||
|
// 营业状态:true(营业中) / false(休息中)
|
||||||
|
isOpenStore() {
|
||||||
|
return this.userInfo.order_taking === 1;
|
||||||
|
},
|
||||||
// 状态管理判定
|
// 状态管理判定
|
||||||
// 是否已入驻 (0: 未入驻, -1: 入驻第一步, >0: 已认证) 只要不等于0,说明已经开启了入驻流程
|
// 是否已入驻 (0: 未入驻, -1: 入驻第一步, >0: 已认证) 只要不等于0,说明已经开启了入驻流程
|
||||||
isSettled() {
|
isSettled() {
|
||||||
|
|
@ -256,13 +247,13 @@ export default {
|
||||||
if (this.isLogin) {
|
if (this.isLogin) {
|
||||||
this.getUserInfo();
|
this.getUserInfo();
|
||||||
}
|
}
|
||||||
|
// 通知、品牌、技能 这三个接口不强依赖登录,无论登没登录都获取
|
||||||
|
this.fetchNoticeList();
|
||||||
|
this.fetchBrandList();
|
||||||
|
this.fetchSkillList();
|
||||||
},
|
},
|
||||||
onLoad() {
|
onLoad() {
|
||||||
uni.hideTabBar();
|
uni.hideTabBar();
|
||||||
this.getNoticeList(); // 获取最新通知
|
|
||||||
},
|
|
||||||
mounted() {
|
|
||||||
this.animateScore();
|
|
||||||
},
|
},
|
||||||
watch: {
|
watch: {
|
||||||
'orderDetail.score'() {
|
'orderDetail.score'() {
|
||||||
|
|
@ -270,34 +261,154 @@ export default {
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
|
// 处理金刚区点击事件 (包含扫码验券核心逻辑)
|
||||||
|
handleQuickAction(item) {
|
||||||
|
if (item.name === '扫码验券') {
|
||||||
|
console.log('准备跳转到自定义扫码页...');
|
||||||
|
|
||||||
|
uni.navigateTo({
|
||||||
|
url: '/pages/shop/verify/verify-order',
|
||||||
|
fail: (err) => {
|
||||||
|
console.error('跳转失败:', err);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
return;
|
||||||
|
} // 2. 通用跳转逻辑
|
||||||
|
else if (item.path) {
|
||||||
|
uni.navigateTo({
|
||||||
|
url: item.path,
|
||||||
|
fail: () => {
|
||||||
|
uni.showToast({ title: '页面开发中...', icon: 'none' });
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
// 格式化时间 (提取 HH:mm)
|
||||||
|
formatTime(dateTimeStr) {
|
||||||
|
if (!dateTimeStr) return '--:--';
|
||||||
|
const arr = dateTimeStr.split(' ');
|
||||||
|
if (arr.length > 1) {
|
||||||
|
return arr[1].substring(0, 5); // 截取 HH:mm
|
||||||
|
}
|
||||||
|
return dateTimeStr;
|
||||||
|
},
|
||||||
|
|
||||||
getUserInfo() {
|
getUserInfo() {
|
||||||
request.post("/sj/user/getUser").then((result) => {
|
request.post("/sj/user/getUser").then((result) => {
|
||||||
|
if(result.code === 200 && result.data) {
|
||||||
this.userInfo = result.data;
|
this.userInfo = result.data;
|
||||||
uni.setStorageSync("syrId", result.data.id);
|
uni.setStorageSync("syrId", result.data.id);
|
||||||
this.syrId = result.data.id;
|
this.syrId = result.data.id;
|
||||||
|
|
||||||
// 获取完用户信息后,初始化营业开关的状态
|
// 获取完用户信息后,初始化营业开关的状态
|
||||||
this.initStoreStatus();
|
this.initStoreStatus();
|
||||||
|
|
||||||
|
// 如果已入驻,才获取接单管理和实时数据
|
||||||
|
if (this.isSettled) {
|
||||||
|
this.fetchOrderNum();
|
||||||
|
this.fetchRealTimeData();
|
||||||
|
}
|
||||||
|
}
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
|
||||||
// 接口预留:获取通知公告(仅拉取当前角色关联的最新6条)
|
// 获取:接单管理不同状态订单数量
|
||||||
getNoticeList() {
|
fetchOrderNum() {
|
||||||
// request.post('/api/notice/getLatest', { role: 'merchant', limit: 6 }).then(res => {
|
request.post("/sj/poster/orderNum").then(res => {
|
||||||
// this.noticeList = 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,或你后期让后端加字段
|
||||||
|
};
|
||||||
|
}
|
||||||
|
});
|
||||||
|
},
|
||||||
|
|
||||||
|
// 获取:首页实时数据
|
||||||
|
fetchRealTimeData() {
|
||||||
|
request.post("/sj/poster/realTimeData").then(res => {
|
||||||
|
if(res.code === 200 && res.data) {
|
||||||
|
const today = res.data.today || {};
|
||||||
|
const yesterday = res.data.yesterday || {};
|
||||||
|
|
||||||
|
this.orderDetail = {
|
||||||
|
updateTime: this.formatTime(res.data.now_date),
|
||||||
|
score: today.rating_num || 0,
|
||||||
|
visitors: today.visitor_num || 0,
|
||||||
|
yVisitors: yesterday.visitor_num || 0,
|
||||||
|
orders: today.place_order || 0,
|
||||||
|
yOrders: yesterday.place_order || 0,
|
||||||
|
amount: today.deal_money || 0,
|
||||||
|
yAmount: yesterday.deal_money || 0
|
||||||
|
};
|
||||||
|
}
|
||||||
|
});
|
||||||
|
},
|
||||||
|
|
||||||
|
// 获取:通知公告列表
|
||||||
|
fetchNoticeList() {
|
||||||
|
request.post('/sj/notice/list', { page: 1, limit: 6 }).then(res => {
|
||||||
|
if(res.code === 200 && res.data && res.data.list.length > 0) {
|
||||||
|
this.noticeList = res.data.list;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
},
|
||||||
|
|
||||||
|
// 获取:品牌列表
|
||||||
|
fetchBrandList() {
|
||||||
|
// 假设首页只拉取推荐的前4条
|
||||||
|
request.post('/sj/brand/list', { page: 1, limit: 4 }).then(res => {
|
||||||
|
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');
|
||||||
|
|
||||||
|
return {
|
||||||
|
id: item.id,
|
||||||
|
name: item.name,
|
||||||
|
bgSrc: item.cover_img || 'https://mrrplus.oss-cn-beijing.aliyuncs.com/photo/system/d02b2d8b-0e01-4c6d-bbee-c60dccf4867c.jpg',
|
||||||
|
avatar: item.logo_img || 'https://dummyimage.com/100x100/ccc/fff.png&text=Avatar',
|
||||||
|
tagKeys: tags
|
||||||
|
};
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
},
|
||||||
|
|
||||||
|
// 获取:技能集市列表
|
||||||
|
fetchSkillList() {
|
||||||
|
request.post('/sj/skill/list', { page: 1, limit: 4 }).then(res => {
|
||||||
|
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] : '', // 只取日期
|
||||||
|
coverSrc: item.cover_img || 'https://dummyimage.com/200x150/ccc/fff.png&text=Video'
|
||||||
|
};
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
},
|
},
|
||||||
|
|
||||||
// 跳转:通知详情页
|
// 跳转:通知详情页
|
||||||
goToNotice(msg) {
|
goToNotice(msg) {
|
||||||
if(msg.url) {
|
if(msg.id) {
|
||||||
uni.navigateTo({ url: msg.url });
|
uni.navigateTo({ url: `/pages/notice/detail?id=${msg.id}` });
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
// 跳转:公告列表页
|
// 跳转:公告列表页
|
||||||
goToNoticeList() {
|
goToNoticeList() {
|
||||||
// uni.navigateTo({ url: '/pages/notice/list' });
|
uni.navigateTo({ url: '/pages/notice/notice_list' });
|
||||||
},
|
},
|
||||||
|
|
||||||
// 跳转:去入驻
|
// 跳转:去入驻
|
||||||
|
|
@ -318,36 +429,26 @@ export default {
|
||||||
|
|
||||||
// 营业中 / 休息中 按钮逻辑判断
|
// 营业中 / 休息中 按钮逻辑判断
|
||||||
toggleStatus() {
|
toggleStatus() {
|
||||||
// 1、入驻未认证 (id_type == -1),弹窗提示未完善项,引导完善
|
// 校验逻辑保留你之前的认证状态检查
|
||||||
if (!this.isCertified) {
|
if (!this.isCertified) {
|
||||||
uni.showModal({
|
uni.showModal({ title: '提示', content: '请先完善认证信息', confirmText: '去完善' });
|
||||||
title: '提示',
|
|
||||||
content: '请先完善认证信息',
|
|
||||||
confirmText: '去完善',
|
|
||||||
success: (res) => {
|
|
||||||
if (res.confirm) {
|
|
||||||
// uni.navigateTo({ url: '/pages/artisan/syr-info-change' });
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// 2、入驻认证通过,未配置营业时间,默认休息中,跳转至营业时间管理
|
|
||||||
if (this.isCertified && !this.hasBusinessTime) {
|
if (this.isCertified && !this.hasBusinessTime) {
|
||||||
uni.showToast({ title: '请先配置营业时间', icon: 'none' });
|
uni.showToast({ title: '请先配置营业时间', icon: 'none' });
|
||||||
setTimeout(() => {
|
|
||||||
// uni.navigateTo({ url: '/pages/shop/business-time' });
|
|
||||||
}, 800);
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// 3、认证通过并配置时间,仅作为开关,不跳转页面
|
// 真正的请求逻辑
|
||||||
if (this.isCertified && this.hasBusinessTime) {
|
let newStatus = this.userInfo.order_taking == 1 ? 2 : 1;
|
||||||
this.isOpenStore = !this.isOpenStore;
|
request.post("/sj/sjordertaking", {
|
||||||
// 预留接口:发送请求同步给后端当前状态
|
order_taking: newStatus,
|
||||||
// request.post('/api/store/toggleStatus', { status: this.isOpenStore ? 1 : 0 });
|
sjid: this.syrId // 使用你在 getUserInfo 存入的 sjId/syrId
|
||||||
}
|
}).then((res) => {
|
||||||
|
// 成功后重新拉取最新信息以更新 UI
|
||||||
|
this.getUserInfo();
|
||||||
|
uni.showToast({ title: newStatus == 1 ? '已开启营业' : '已休息', icon: 'none' });
|
||||||
|
});
|
||||||
},
|
},
|
||||||
|
|
||||||
animateScore() {
|
animateScore() {
|
||||||
|
|
@ -591,7 +692,7 @@ export default {
|
||||||
.guide-btn {
|
.guide-btn {
|
||||||
width: 534rpx;
|
width: 534rpx;
|
||||||
height: 70rpx;
|
height: 70rpx;
|
||||||
border-radius: 55rpx;
|
border-radius: 35rpx;
|
||||||
border: 1rpx solid #FF4767;
|
border: 1rpx solid #FF4767;
|
||||||
|
|
||||||
color: #FF4767;
|
color: #FF4767;
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,359 @@
|
||||||
|
<template>
|
||||||
|
<view class="notice-detail-page">
|
||||||
|
<!-- 自定义顶部导航组件 -->
|
||||||
|
<custom-navbar
|
||||||
|
title="公告通知详情"
|
||||||
|
:showBack="true"
|
||||||
|
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"
|
||||||
|
|
||||||
|
/>
|
||||||
|
|
||||||
|
<!-- 页面主要内容 -->
|
||||||
|
<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="detailData.id" class="detail-card">
|
||||||
|
<!-- 标题 -->
|
||||||
|
<text class="detail-title">{{ detailData.title }}</text>
|
||||||
|
|
||||||
|
<!-- 发布时间 -->
|
||||||
|
<view class="detail-time">
|
||||||
|
<text class="time-text">时间:{{ formatTime(detailData.create_time) }}</text>
|
||||||
|
<text class="browse-text"> <image class="browse-icon" src="https://mrrplus.oss-cn-beijing.aliyuncs.com/photo/system/6133cbef-5861-40f8-80f5-d8a86477c94f.png" mode="aspectFit"></image> {{ detailData.browse_num }}</text>
|
||||||
|
</view>
|
||||||
|
|
||||||
|
<!-- 富文本内容 -->
|
||||||
|
<view class="detail-content">
|
||||||
|
<rich-text :nodes="detailData.content"></rich-text>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
|
||||||
|
<!-- 空状态或错误 -->
|
||||||
|
<view v-else-if="!loading && !detailData.id" 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>
|
||||||
|
<text class="empty-text">公告不存在或已删除</text>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
import CustomNavbar from '@/components/custom-navbar/custom-navbar.vue';
|
||||||
|
import request from '@/utils/request';
|
||||||
|
|
||||||
|
export default {
|
||||||
|
components: {
|
||||||
|
CustomNavbar
|
||||||
|
},
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
loading: false, // 加载状态
|
||||||
|
detailData: { // 公告详情数据
|
||||||
|
id: null,
|
||||||
|
title: '',
|
||||||
|
create_time: '',
|
||||||
|
content: ''
|
||||||
|
}
|
||||||
|
};
|
||||||
|
},
|
||||||
|
onLoad(options) {
|
||||||
|
const id = options.id;
|
||||||
|
if (id) {
|
||||||
|
this.fetchNoticeDetail(id);
|
||||||
|
} else {
|
||||||
|
uni.showToast({
|
||||||
|
title: '参数错误',
|
||||||
|
icon: 'none'
|
||||||
|
});
|
||||||
|
setTimeout(() => {
|
||||||
|
uni.navigateBack();
|
||||||
|
}, 1500);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
// 获取公告详情
|
||||||
|
fetchNoticeDetail(id) {
|
||||||
|
this.loading = true;
|
||||||
|
request.post('/sj/notice/details', { id: id })
|
||||||
|
.then(res => {
|
||||||
|
if (res.code === 200 && res.data) {
|
||||||
|
this.detailData = res.data;
|
||||||
|
// 动态设置页面标题(可选)
|
||||||
|
uni.setNavigationBarTitle({
|
||||||
|
title: this.detailData.title || '公告详情'
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
uni.showToast({
|
||||||
|
title: res.msg || '获取详情失败',
|
||||||
|
icon: 'none'
|
||||||
|
});
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.catch(err => {
|
||||||
|
console.error('获取公告详情失败:', err);
|
||||||
|
uni.showToast({
|
||||||
|
title: '网络异常,请稍后重试',
|
||||||
|
icon: 'none'
|
||||||
|
});
|
||||||
|
})
|
||||||
|
.finally(() => {
|
||||||
|
this.loading = false;
|
||||||
|
});
|
||||||
|
},
|
||||||
|
|
||||||
|
formatTime(timeStr) {
|
||||||
|
if (!timeStr) return '--:--:--';
|
||||||
|
let formatted = timeStr;
|
||||||
|
if (timeStr.includes('.') && !timeStr.includes('-')) {
|
||||||
|
const match = timeStr.match(/(\d{4})\.(\d{2})\.(\d{2})(\d{2}:\d{2}:\d{2})/);
|
||||||
|
if (match) {
|
||||||
|
formatted = `${match[1]}-${match[2]}-${match[3]} ${match[4]}`;
|
||||||
|
} else {
|
||||||
|
formatted = timeStr.replace(/\./g, '-');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// 如果是标准格式直接返回,否则返回原字符串
|
||||||
|
if (formatted.includes('-') && formatted.includes(':')) {
|
||||||
|
// 转换回点分隔显示,以匹配设计图风格: 2026.05.08 15:00:00
|
||||||
|
const datePart = formatted.split(' ')[0];
|
||||||
|
const timePart = formatted.split(' ')[1] || '';
|
||||||
|
if (datePart && datePart.includes('-')) {
|
||||||
|
const dotDate = datePart.replace(/-/g, '.');
|
||||||
|
return `${dotDate} ${timePart}`.trim();
|
||||||
|
}
|
||||||
|
return formatted;
|
||||||
|
}
|
||||||
|
return timeStr;
|
||||||
|
},
|
||||||
|
|
||||||
|
}
|
||||||
|
};
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style lang="scss" scoped>
|
||||||
|
.notice-detail-page {
|
||||||
|
min-height: 100vh;
|
||||||
|
background-color: #fff;
|
||||||
|
}
|
||||||
|
|
||||||
|
.page-content {
|
||||||
|
// padding: 20rpx 24rpx 60rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 加载状态
|
||||||
|
.loading-container {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
padding: 120rpx 0;
|
||||||
|
|
||||||
|
.loading-icon {
|
||||||
|
width: 60rpx;
|
||||||
|
height: 60rpx;
|
||||||
|
border: 4rpx solid #e0e0e0;
|
||||||
|
border-top-color: #FF4767;
|
||||||
|
border-radius: 50%;
|
||||||
|
animation: spin 0.8s linear infinite;
|
||||||
|
margin-bottom: 20rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
.loading-text {
|
||||||
|
font-size: 26rpx;
|
||||||
|
color: #999;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@keyframes spin {
|
||||||
|
to { transform: rotate(360deg); }
|
||||||
|
}
|
||||||
|
|
||||||
|
// 详情卡片
|
||||||
|
.detail-card {
|
||||||
|
background: #ffffff;
|
||||||
|
border-radius: 24rpx;
|
||||||
|
padding: 20rpx 30rpx;
|
||||||
|
margin-bottom: 30rpx;
|
||||||
|
|
||||||
|
.detail-title {
|
||||||
|
display: block;
|
||||||
|
margin-bottom: 14rpx;
|
||||||
|
font-weight: 500;
|
||||||
|
font-size: 40rpx;
|
||||||
|
color: #333333;
|
||||||
|
line-height: 56rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
.detail-time {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
margin-bottom: 30rpx;
|
||||||
|
justify-content: space-between; // 两端对齐
|
||||||
|
// border-bottom: 1rpx solid #f0f0f0;
|
||||||
|
|
||||||
|
.time-icon {
|
||||||
|
width: 28rpx;
|
||||||
|
height: 28rpx;
|
||||||
|
margin-right: 10rpx;
|
||||||
|
opacity: 0.6;
|
||||||
|
}
|
||||||
|
|
||||||
|
.time-text {
|
||||||
|
font-weight: 400;
|
||||||
|
font-size: 28rpx;
|
||||||
|
color: #B6B6B6;
|
||||||
|
line-height: 40rpx;
|
||||||
|
}
|
||||||
|
.browse-icon {
|
||||||
|
width: 38rpx;
|
||||||
|
height: 22rpx;
|
||||||
|
// margin-right: 10rpx;
|
||||||
|
}
|
||||||
|
.browse-text {
|
||||||
|
margin-right: 10rpx;
|
||||||
|
font-weight: 400;
|
||||||
|
font-size: 28rpx;
|
||||||
|
color: #B08463;
|
||||||
|
line-height: 40rpx;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.detail-content {
|
||||||
|
font-weight: 400;
|
||||||
|
font-size: 28rpx;
|
||||||
|
color: #2A2A2A;
|
||||||
|
line-height: 40rpx;
|
||||||
|
overflow-x: hidden;
|
||||||
|
|
||||||
|
// 对rich-text内部样式进行补充
|
||||||
|
::v-deep img {
|
||||||
|
max-width: 100%;
|
||||||
|
height: auto;
|
||||||
|
display: block;
|
||||||
|
margin: 30rpx 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
::v-deep p {
|
||||||
|
margin-bottom: 20rpx; // 重置外边距,避免多余间距
|
||||||
|
padding: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 在需要分段的地方手动创建间距
|
||||||
|
::v-deep br {
|
||||||
|
display: block; // 让 <br> 标签表现正常
|
||||||
|
margin-bottom: 30rpx; // 控制段落间距
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 空状态
|
||||||
|
.empty-container {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
padding: 150rpx 0;
|
||||||
|
|
||||||
|
.empty-img {
|
||||||
|
width: 200rpx;
|
||||||
|
height: 200rpx;
|
||||||
|
margin-bottom: 30rpx;
|
||||||
|
opacity: 0.6;
|
||||||
|
}
|
||||||
|
|
||||||
|
.empty-text {
|
||||||
|
font-size: 28rpx;
|
||||||
|
color: #999;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 底部会员营销卡片(根据设计图样式)
|
||||||
|
.member-card {
|
||||||
|
background: linear-gradient(135deg, #FFE6E8 0%, #FFF0E6 100%);
|
||||||
|
border-radius: 24rpx;
|
||||||
|
padding: 30rpx;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: space-between;
|
||||||
|
margin-top: 20rpx;
|
||||||
|
box-shadow: 0 4rpx 16rpx rgba(0, 0, 0, 0.04);
|
||||||
|
|
||||||
|
.member-info {
|
||||||
|
flex: 1;
|
||||||
|
|
||||||
|
.member-price {
|
||||||
|
display: block;
|
||||||
|
font-size: 32rpx;
|
||||||
|
font-weight: bold;
|
||||||
|
color: #FF4767;
|
||||||
|
line-height: 44rpx;
|
||||||
|
margin-bottom: 8rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
.member-desc {
|
||||||
|
display: block;
|
||||||
|
font-size: 24rpx;
|
||||||
|
color: #333;
|
||||||
|
line-height: 34rpx;
|
||||||
|
margin-bottom: 12rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
.member-tag {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
|
||||||
|
.tag-text, .tag-gift {
|
||||||
|
font-size: 20rpx;
|
||||||
|
background: rgba(255, 71, 103, 0.15);
|
||||||
|
padding: 4rpx 12rpx;
|
||||||
|
border-radius: 20rpx;
|
||||||
|
color: #FF4767;
|
||||||
|
margin-right: 12rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
.tag-gift {
|
||||||
|
background: rgba(255, 193, 7, 0.2);
|
||||||
|
color: #E6A100;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.member-btn {
|
||||||
|
background: linear-gradient(135deg, #FF4767, #FF6B8A);
|
||||||
|
border-radius: 48rpx;
|
||||||
|
padding: 14rpx 28rpx;
|
||||||
|
text-align: center;
|
||||||
|
min-width: 160rpx;
|
||||||
|
box-shadow: 0 4rpx 12rpx rgba(255, 71, 103, 0.3);
|
||||||
|
|
||||||
|
.btn-text {
|
||||||
|
display: block;
|
||||||
|
font-size: 26rpx;
|
||||||
|
font-weight: 600;
|
||||||
|
color: #FFFFFF;
|
||||||
|
line-height: 36rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
.btn-sub {
|
||||||
|
display: block;
|
||||||
|
font-size: 20rpx;
|
||||||
|
color: rgba(255, 255, 255, 0.9);
|
||||||
|
line-height: 28rpx;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
::v-deep .icon-headle {
|
||||||
|
width: 32rpx !important;
|
||||||
|
height: 32rpx !important;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
|
@ -0,0 +1,298 @@
|
||||||
|
<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>
|
||||||
|
|
||||||
|
<!-- 主要内容区域 -->
|
||||||
|
<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"
|
||||||
|
: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>
|
||||||
|
|
||||||
|
<!-- 加载更多状态 -->
|
||||||
|
<view v-if="loadingMore" class="load-more">
|
||||||
|
<text>加载更多...</text>
|
||||||
|
</view>
|
||||||
|
<view v-else-if="!hasMore && noticeList.length > 0" class="no-more">
|
||||||
|
<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>
|
||||||
|
<text class="empty-text">暂无公告通知</text>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
import CustomNavbar from '@/components/custom-navbar/custom-navbar.vue';
|
||||||
|
import request from '@/utils/request';
|
||||||
|
|
||||||
|
export default {
|
||||||
|
components: {
|
||||||
|
CustomNavbar
|
||||||
|
},
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
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: {
|
||||||
|
// 获取公告列表
|
||||||
|
fetchNoticeList(reset = true) {
|
||||||
|
if (reset) {
|
||||||
|
this.page = 1;
|
||||||
|
this.hasMore = true;
|
||||||
|
this.loading = true;
|
||||||
|
} else {
|
||||||
|
if (!this.hasMore) return;
|
||||||
|
this.loadingMore = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
request.post('/sj/notice/list', {
|
||||||
|
page: this.page,
|
||||||
|
limit: this.limit
|
||||||
|
}).then(res => {
|
||||||
|
if (res.code === 200 && res.data) {
|
||||||
|
const list = res.data.list || [];
|
||||||
|
const total = res.data.total || 0;
|
||||||
|
this.total = total;
|
||||||
|
|
||||||
|
if (reset) {
|
||||||
|
this.noticeList = list;
|
||||||
|
} else {
|
||||||
|
this.noticeList = [...this.noticeList, ...list];
|
||||||
|
}
|
||||||
|
|
||||||
|
// 判断是否还有更多数据
|
||||||
|
this.hasMore = this.noticeList.length < total;
|
||||||
|
|
||||||
|
// 如果还有更多数据,页码加1
|
||||||
|
if (this.hasMore && !reset) {
|
||||||
|
this.page++;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (reset) this.noticeList = [];
|
||||||
|
this.hasMore = false;
|
||||||
|
}
|
||||||
|
}).catch(err => {
|
||||||
|
console.error('获取公告列表失败:', err);
|
||||||
|
if (reset) this.noticeList = [];
|
||||||
|
uni.showToast({
|
||||||
|
title: '加载失败,请稍后重试',
|
||||||
|
icon: 'none'
|
||||||
|
});
|
||||||
|
}).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;
|
||||||
|
},
|
||||||
|
|
||||||
|
// 跳转到详情页
|
||||||
|
goToDetail(item) {
|
||||||
|
if (item.id) {
|
||||||
|
uni.navigateTo({
|
||||||
|
url: `/pages/notice/detail?id=${item.id}`
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style lang="scss" scoped>
|
||||||
|
.notice-page {
|
||||||
|
min-height: 100vh;
|
||||||
|
background-color: #f5f6f8;
|
||||||
|
}
|
||||||
|
|
||||||
|
.page-content {
|
||||||
|
padding: 20rpx 20rpx 40rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 加载中样式
|
||||||
|
.loading-container {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
padding: 120rpx 0;
|
||||||
|
|
||||||
|
.loading-icon {
|
||||||
|
width: 60rpx;
|
||||||
|
height: 60rpx;
|
||||||
|
border: 4rpx solid #e0e0e0;
|
||||||
|
border-top-color: #FF4767;
|
||||||
|
border-radius: 50%;
|
||||||
|
animation: spin 0.8s linear infinite;
|
||||||
|
margin-bottom: 20rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
.loading-text {
|
||||||
|
font-size: 26rpx;
|
||||||
|
color: #999;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@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;
|
||||||
|
font-size: 24rpx;
|
||||||
|
color: #999;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 空状态
|
||||||
|
.empty-container {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
padding: 150rpx 0;
|
||||||
|
|
||||||
|
.empty-img {
|
||||||
|
width: 200rpx;
|
||||||
|
height: 200rpx;
|
||||||
|
margin-bottom: 30rpx;
|
||||||
|
opacity: 0.6;
|
||||||
|
}
|
||||||
|
|
||||||
|
.empty-text {
|
||||||
|
font-size: 28rpx;
|
||||||
|
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,153 @@
|
||||||
|
<template>
|
||||||
|
<view class="manual-verify">
|
||||||
|
<CustomNavbar title="" backgroundColor="#FFFFFF"></CustomNavbar>
|
||||||
|
|
||||||
|
<view class="content">
|
||||||
|
<view class="tip">请输入6位核销码</view>
|
||||||
|
|
||||||
|
<view class="code-inputs" @tap="focusInput">
|
||||||
|
<view
|
||||||
|
class="input-box"
|
||||||
|
:class="{ filled: code[i-1] }"
|
||||||
|
v-for="i in 6"
|
||||||
|
:key="i"
|
||||||
|
>
|
||||||
|
{{ code[i-1] || '' }}
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
|
||||||
|
<input
|
||||||
|
class="hidden-input"
|
||||||
|
type="number"
|
||||||
|
maxlength="6"
|
||||||
|
:value="code"
|
||||||
|
:focus="inputFocus"
|
||||||
|
@input="onInput"
|
||||||
|
@blur="resetFocus"
|
||||||
|
confirm-type="done"
|
||||||
|
/>
|
||||||
|
|
||||||
|
<button class="confirm-btn" :class="{ active: code.length === 6 }" @tap="submitCode">
|
||||||
|
确认
|
||||||
|
</button>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
import CustomNavbar from "@/components/custom-navbar/custom-navbar.vue";
|
||||||
|
import request from "@/utils/request";
|
||||||
|
|
||||||
|
export default {
|
||||||
|
components: { CustomNavbar },
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
code: '',
|
||||||
|
inputFocus: false
|
||||||
|
};
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
focusInput() {
|
||||||
|
this.inputFocus = false;
|
||||||
|
this.$nextTick(() => {
|
||||||
|
this.inputFocus = true;
|
||||||
|
});
|
||||||
|
},
|
||||||
|
resetFocus() {
|
||||||
|
this.inputFocus = false;
|
||||||
|
},
|
||||||
|
onInput(e) {
|
||||||
|
let value = e.detail.value;
|
||||||
|
value = value.replace(/\D/g, '');
|
||||||
|
if (value.length > 6) value = value.slice(0, 6);
|
||||||
|
this.code = value;
|
||||||
|
},
|
||||||
|
submitCode() {
|
||||||
|
if (this.code.length !== 6) {
|
||||||
|
uni.showToast({ title: '请输入6位核销码', icon: 'none' });
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
request.post('/sj/poster/useOrderServerCode', {
|
||||||
|
server_code: this.code,
|
||||||
|
id: this.orderId,
|
||||||
|
order_type: this.orderType
|
||||||
|
}).then(res => {
|
||||||
|
if (res.code === 200) {
|
||||||
|
uni.showToast({ title: '核销成功' });
|
||||||
|
setTimeout(() => uni.navigateBack(), 1500);
|
||||||
|
} else {
|
||||||
|
uni.showToast({ title: res.msg || '核销失败', icon: 'none' });
|
||||||
|
}
|
||||||
|
}).catch(() => {
|
||||||
|
uni.showToast({ title: '网络异常', icon: 'none' });
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style lang="scss">
|
||||||
|
.manual-verify {
|
||||||
|
padding-top: 150rpx;
|
||||||
|
background-color: #fff;
|
||||||
|
min-height: 100vh;
|
||||||
|
|
||||||
|
.tip {
|
||||||
|
font-weight: 500;
|
||||||
|
font-size: 46rpx;
|
||||||
|
color: #333333;
|
||||||
|
line-height: 65rpx;
|
||||||
|
text-align: left;
|
||||||
|
margin-bottom: 80rpx;
|
||||||
|
margin-left: 48rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
.code-inputs {
|
||||||
|
display: flex;
|
||||||
|
justify-content: center;
|
||||||
|
gap: 24rpx;
|
||||||
|
margin-bottom: 80rpx;
|
||||||
|
padding: 0 30rpx;
|
||||||
|
|
||||||
|
.input-box {
|
||||||
|
width: 88rpx;
|
||||||
|
height: 88rpx;
|
||||||
|
border-radius: 12rpx;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
font-size: 48rpx;
|
||||||
|
font-weight: 500;
|
||||||
|
color: #333;
|
||||||
|
background-color: #F3F3F3;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.confirm-btn {
|
||||||
|
margin: 0 49rpx;
|
||||||
|
background: #ff476685;
|
||||||
|
color: #fff;
|
||||||
|
border-radius: 88rpx;
|
||||||
|
height: 96rpx;
|
||||||
|
line-height: 96rpx;
|
||||||
|
font-size: 36rpx;
|
||||||
|
font-weight: 500;
|
||||||
|
box-shadow: 0 8rpx 20rpx rgba(255, 71, 103, 0.2);
|
||||||
|
transition: all 0.2s;
|
||||||
|
|
||||||
|
&.active {
|
||||||
|
background: #FF4767;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.hidden-input {
|
||||||
|
position: fixed;
|
||||||
|
top: 0;
|
||||||
|
left: 0;
|
||||||
|
width: 2px;
|
||||||
|
height: 2px;
|
||||||
|
opacity: 0;
|
||||||
|
background: transparent;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
|
@ -0,0 +1,216 @@
|
||||||
|
<template>
|
||||||
|
<view class="verify-page">
|
||||||
|
|
||||||
|
<barcode
|
||||||
|
class="barcode-view"
|
||||||
|
autostart="true"
|
||||||
|
flash="false"
|
||||||
|
zoom="false"
|
||||||
|
frameColor="#FF4767" scanbarColor="#FF4767"
|
||||||
|
@marked="onScanCode">
|
||||||
|
</barcode>
|
||||||
|
|
||||||
|
<view class="full-mask"></view>
|
||||||
|
|
||||||
|
<view class="nav-bar" :style="{ paddingTop: statusBarHeight + 'px', height: (statusBarHeight + 44) + 'px' }">
|
||||||
|
<view class="back-btn" @tap="goBack">
|
||||||
|
<image class="back-icon" src="https://mrrplus.oss-cn-beijing.aliyuncs.com/photo/system/ea671fc8-435e-46fe-ba69-6d728328149a.png"></image>
|
||||||
|
</view>
|
||||||
|
<text class="nav-title">扫码验券</text>
|
||||||
|
<view class="right-placeholder"></view>
|
||||||
|
</view>
|
||||||
|
|
||||||
|
<view class="bottom-bar">
|
||||||
|
<view class="action-btn" @tap="goToManualVerify">
|
||||||
|
<image class="btn-icon" src="https://mrrplus.oss-cn-beijing.aliyuncs.com/photo/system/acb1ead0-d0d7-4db1-b779-7bb1cffa6594.png"></image>
|
||||||
|
<text class="btn-text">输入核销码</text>
|
||||||
|
</view>
|
||||||
|
|
||||||
|
<view class="action-btn" @tap="chooseFromAlbum">
|
||||||
|
<image class="btn-icon" src="https://mrrplus.oss-cn-beijing.aliyuncs.com/photo/system/7d6de32b-091d-4103-8138-14ae217e5f47.png"></image>
|
||||||
|
<text class="btn-text">相册</text>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
|
||||||
|
</view>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
import request from "@/utils/request";
|
||||||
|
|
||||||
|
export default {
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
statusBarHeight: 44, // 默认状态栏高度
|
||||||
|
isProcessing: false // 防抖开关
|
||||||
|
}
|
||||||
|
},
|
||||||
|
onLoad() {
|
||||||
|
const sysInfo = uni.getSystemInfoSync();
|
||||||
|
if(sysInfo.statusBarHeight) {
|
||||||
|
this.statusBarHeight = sysInfo.statusBarHeight;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
goBack() {
|
||||||
|
uni.navigateBack();
|
||||||
|
},
|
||||||
|
|
||||||
|
// nvue 下 barcode 的回调事件叫 @marked
|
||||||
|
onScanCode(e) {
|
||||||
|
if (this.isProcessing) return;
|
||||||
|
this.isProcessing = true;
|
||||||
|
|
||||||
|
// 并且扫码获取的内容在 e.detail.message 里
|
||||||
|
const code = e.detail.message;
|
||||||
|
this.handleCodeResult(code);
|
||||||
|
},
|
||||||
|
|
||||||
|
// 统一处理扫码结果
|
||||||
|
handleCodeResult(code) {
|
||||||
|
if (!code) {
|
||||||
|
this.isProcessing = false;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
uni.showLoading({ title: '查询订单中...' });
|
||||||
|
|
||||||
|
request.post('/sj/poster/getOrderByCode', { server_code: code }).then(result => {
|
||||||
|
uni.hideLoading();
|
||||||
|
|
||||||
|
if (result.code === 200 && result.data) {
|
||||||
|
uni.showToast({ title: '扫码成功!', icon: 'none' });
|
||||||
|
const orderDataStr = encodeURIComponent(JSON.stringify(result.data));
|
||||||
|
uni.navigateTo({
|
||||||
|
url: `/pages/shop/verify/verify-order-detail?data=${orderDataStr}`
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
// 如果无效,立即退出页面回首页
|
||||||
|
uni.showToast({ title: result.msg, icon: 'none' });
|
||||||
|
|
||||||
|
// 延迟 500ms 让用户看到 Toast,然后自动退回主页
|
||||||
|
setTimeout(() => {
|
||||||
|
uni.navigateBack({ delta: 1 });
|
||||||
|
}, 500);
|
||||||
|
}
|
||||||
|
}).catch((err) => {
|
||||||
|
uni.hideLoading();
|
||||||
|
uni.showToast({ title: '请求失败,退出重试', icon: 'none' });
|
||||||
|
setTimeout(() => {
|
||||||
|
uni.navigateBack({ delta: 1 });
|
||||||
|
}, 800);
|
||||||
|
});
|
||||||
|
},
|
||||||
|
|
||||||
|
chooseFromAlbum() {
|
||||||
|
uni.chooseImage({
|
||||||
|
count: 1,
|
||||||
|
success: (res) => {
|
||||||
|
uni.scanCode({
|
||||||
|
onlyFromCamera: false,
|
||||||
|
scanType: ['qrCode'],
|
||||||
|
success: (scanRes) => {
|
||||||
|
this.handleCodeResult(scanRes.result);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
},
|
||||||
|
|
||||||
|
goToManualVerify() {
|
||||||
|
uni.navigateTo({ url: '/pages/shop/verify/manual-verify' });
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style>
|
||||||
|
.verify-page {
|
||||||
|
flex: 1;
|
||||||
|
background-color: #000000;
|
||||||
|
}
|
||||||
|
|
||||||
|
.barcode-view {
|
||||||
|
position: absolute;
|
||||||
|
top: 0;
|
||||||
|
left: 0;
|
||||||
|
right: 0;
|
||||||
|
bottom: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.full-mask {
|
||||||
|
position: absolute;
|
||||||
|
top: 0;
|
||||||
|
left: 0;
|
||||||
|
right: 0;
|
||||||
|
bottom: 0;
|
||||||
|
background-color: rgba(0, 0, 0, 0.3);
|
||||||
|
}
|
||||||
|
|
||||||
|
.nav-bar {
|
||||||
|
position: absolute;
|
||||||
|
top: 0;
|
||||||
|
left: 0;
|
||||||
|
right: 0;
|
||||||
|
flex-direction: row;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: space-between;
|
||||||
|
padding-left: 30rpx;
|
||||||
|
padding-right: 30rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
.back-btn {
|
||||||
|
width: 60rpx;
|
||||||
|
height: 88rpx;
|
||||||
|
justify-content: center;
|
||||||
|
align-items: flex-start;
|
||||||
|
}
|
||||||
|
|
||||||
|
.back-icon {
|
||||||
|
width: 18rpx;
|
||||||
|
height: 36rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
.nav-title {
|
||||||
|
font-size: 36rpx;
|
||||||
|
font-weight: bold;
|
||||||
|
color: #FFFFFF;
|
||||||
|
}
|
||||||
|
|
||||||
|
.right-placeholder {
|
||||||
|
width: 60rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
.bottom-bar {
|
||||||
|
position: absolute;
|
||||||
|
bottom: 80rpx;
|
||||||
|
left: 0;
|
||||||
|
right: 0;
|
||||||
|
height: 120rpx;
|
||||||
|
flex-direction: row;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: space-around;
|
||||||
|
}
|
||||||
|
|
||||||
|
.action-btn {
|
||||||
|
flex-direction: row;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
width: 325rpx;
|
||||||
|
height: 105rpx;
|
||||||
|
background-color: rgba(0, 0, 0, 0.4);
|
||||||
|
border-radius: 20rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
.btn-icon {
|
||||||
|
width: 40rpx;
|
||||||
|
height: 38rpx;
|
||||||
|
margin-right: 16rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
.btn-text {
|
||||||
|
font-weight: 500;
|
||||||
|
font-size: 32rpx;
|
||||||
|
color: #FFFFFF;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
Loading…
Reference in New Issue