Prechádzať zdrojové kódy

Merge branch 'fxw' of http://39.101.143.165:8090/hxl13994548489/LocalLivingServicesUniapp into fxw

baijunde 3 týždňov pred
rodič
commit
9d3924f3f4

+ 2 - 0
App.vue

@@ -4,6 +4,7 @@
 <script>
 	import Vue from 'vue'
 	import appUpdate from 'common/util/appUpdate.js'
+	import { updateMsgTabBadge } from '@/common/util/msgBadge.js'
 	export default {
 		onLaunch: function() {
 			uni.getSystemInfo({
@@ -164,6 +165,7 @@
 		},
 		onShow: function() {
 			console.log('App Show')
+			updateMsgTabBadge()
 		},
 		onHide: function() {
 			console.log('App Hide')

+ 112 - 0
common/util/msgBadge.js

@@ -0,0 +1,112 @@
+import { http } from '@/common/service/service.js'
+import { ACCESS_TOKEN } from '@/common/util/constants.js'
+
+/** 消息 tab 在 tabBar.list 中的下标 */
+export const MSG_TAB_INDEX = 2
+
+/** 是否未读:status === '0' */
+export function isUnreadNotice(item) {
+	return item && String(item.status) === '0'
+}
+
+/**
+ * 设置消息 tab 角标(仅未读;已读不显示)
+ * @param {number|string} count 未读数
+ */
+export function setMsgTabBadge(count) {
+	const n = Number(count) || 0
+	if (n > 0) {
+		uni.setTabBarBadge({
+			index: MSG_TAB_INDEX,
+			text: n > 99 ? '99+' : String(n),
+			fail: () => {}
+		})
+	} else {
+		uni.removeTabBarBadge({
+			index: MSG_TAB_INDEX,
+			fail: () => {}
+		})
+		uni.hideTabBarRedDot({
+			index: MSG_TAB_INDEX,
+			fail: () => {}
+		})
+	}
+}
+
+/**
+ * 从分类列表统计未读数(不含已读)
+ */
+function countUnreadFromList(list) {
+	const unread = (list || []).filter(isUnreadNotice)
+	if (!unread.length) return 0
+	const hasCount = unread.some(
+		(i) => i.unreadCount != null || i.unReadCount != null
+	)
+	if (hasCount) {
+		return unread.reduce(
+			(sum, i) => sum + Number(i.unreadCount || i.unReadCount || 0),
+			0
+		)
+	}
+	return unread.length
+}
+
+/**
+ * 拉取未读消息数并更新消息 tab 角标(只统计没看过的)
+ */
+export function updateMsgTabBadge() {
+	const token = uni.getStorageSync(ACCESS_TOKEN)
+	if (!token) {
+		setMsgTabBadge(0)
+		return Promise.resolve(0)
+	}
+	// 先按未读拉分页,客户端再过滤一次,避免拿到已读/总数据
+	return http
+		.post('/localUserNotice/localUserNotice/getPageListNew', {
+			pageNo: 1,
+			pageSize: 200,
+			userType: 1,
+			status: '0'
+		})
+		.then((res) => {
+			const result = (res.data && res.data.result) || {}
+			const records = Array.isArray(result.records)
+				? result.records
+				: result.page && Array.isArray(result.page.records)
+					? result.page.records
+					: []
+			const unreadRecords = records.filter(isUnreadNotice)
+			// 若返回记录全是未读,且接口给了 total,可用 total;否则只用未读条数
+			const allUnread =
+				records.length > 0 && unreadRecords.length === records.length
+			const apiTotal =
+				result.total != null
+					? result.total
+					: result.page && result.page.total != null
+						? result.page.total
+						: null
+			let count = unreadRecords.length
+			if (allUnread && apiTotal != null && Number(apiTotal) >= count) {
+				count = Number(apiTotal)
+			}
+			setMsgTabBadge(count)
+			return count
+		})
+		.catch(() => {
+			return http
+				.get('/localUserNotice/localUserNotice/getListNew', {
+					params: { userType: 1 }
+				})
+				.then((res) => {
+					const count = countUnreadFromList(
+						(res.data && res.data.result) || []
+					)
+					setMsgTabBadge(count)
+					return count
+				})
+				.catch(() => {
+					setMsgTabBadge(0)
+					return 0
+				})
+		})
+}

+ 37 - 74
components/index_nav.vue

@@ -1,15 +1,7 @@
 <template>
-	<!-- <swiper class="screen-swiper" :class="dotStyle?'square-dot':'round-dot'" :indicator-dots="true" :circular="true"
-		:autoplay="false" interval="5000" duration="500">
-		<swiper-item class="item">
-			
-		</swiper-item>
-	</swiper> -->
 	<view class="item">
 		<view class="card" v-for="(item,index) in swiperList" :key="index" @click="jump(item)">
-			<image :src="item.url" mode="aspectFill"
-				>
-			</image>
+			<image :src="item.url" mode="aspectFill"></image>
 			{{item.name}}
 		</view>
 		<!-- 弹窗 -->
@@ -38,82 +30,61 @@
 		},
 		data() {
 			return {
-				dotStyle: true,
 				baseList: [{
 						name: '店铺设置',
-						url: '/static/index/shop.png',
+						url: '/static/newIndex/shop.png',
 						path: '/pages/store/settings'
 					},
-					{
-						name: '团餐活动',
-						url: '/static/index/groupMeal.png',
-						path: '/pages/groupMeal/goods/list'
-					},
 					{
 						name: '菜品管理',
-						url: '/static/index/product.png',
+						url: '/static/newIndex/productShop.png',
 						path: '/pages/merchantDish/dish/list',
 						needTopUp: true
 					},
 					{
 						name: '商品管理',
-						url: '/static/index/product.png',
+						url: '/static/newIndex/product.png',
 						path: '/pages/product/index'
 					},
 					{
-						name: '优惠券',
-						url: '/static/index/coupon.png',
-						path: '/pages/coupon/coupon'
+						name: '门店管理',
+						url: '/static/newIndex/store.png',
+						path: '/pages/index/shop',
+						needTopUp: true
 					},
 					{
-						name: '退款管理',
-						url: '/static/index/refund.png'
+						name: '储值管理',
+						url: '/static/newIndex/toup.png',
+						path: '/pages/topUp/index',
+						needTopUp: true
 					},
 					{
-						name: '订单管理',
-						url: '/static/index/indent.png',
-						path:'/pages/order/index',
-						type:'tabbar'
+						name: '广告管理',
+						url: '/static/newIndex/ad.png',
+						path: '/pages/adManagement/adlist'
 					},
 					{
-						name: '提现管理',
-						url: '/static/index/withdraw.png',
-						path:'/pages/finance/index',
-						type:'tabbar'
+						name: '优惠券',
+						url: '/static/newIndex/coupon.png',
+						path: '/pages/coupon/coupon'
 					},
 					{
 						name: '客户评价',
-						url: '/static/index/evaluate.png',
+						url: '/static/newIndex/evaluate.png',
 						path: '/pages/evaluate/evaluate'
 					},
-					{
-						name: '广告管理',
-						url: '/static/index/ad.png',
-						path: '/pages/adManagement/adlist'
-					},
-					{
-						name: '储值管理',
-						url: '/static/index/toup.png',
-						path: '/pages/topUp/index',
-						needTopUp: true
-					},
 					{
 						name: '团餐设置',
-						url: '/static/index/groupMeal.png',
+						url: '/static/newIndex/groupMeal.png',
 						path: '/pages/merchantDish/settings/index',
 						needGroupMeal: true
 					},
 					{
 						name: '团餐订单',
-						url: '/static/index/indent.png',
+						url: '/static/newIndex/groupMealOrder.png',
 						path: '/pages/merchantDish/orders/index',
 						needGroupMeal: true
 					},
-					{
-						name: '全部服务',
-						url: '/static/index/all.png',
-						path: '/pages/index/full'
-					},
 				],
 				// 弹窗
 				modalText: {
@@ -135,26 +106,21 @@
 		methods: {
 			async jump(item) {
 				if (!item.path) {
-					uni,uni.showToast({
+					uni.showToast({
 						title: '功能暂未开放',
-						icon:'none'
+						icon: 'none'
 					});
 					return
 				};
-				console.log(item.path)
-				if(item.type){
+				if (item.type) {
 					uni.switchTab({
-						url:item.path
+						url: item.path
 					})
-					
-				}else{
+				} else {
 					uni.navigateTo({
 						url: item.path
 					});
 				}
-				
-				
-				
 			}
 		}
 	}
@@ -166,30 +132,27 @@
 		height: 100%;
 		display: flex;
 		flex-wrap: wrap;
-		// justify-content: space-between;
-		column-gap: 30rpx;
-		
+		column-gap: 0;
 	}
 
 	.card {
-		width: 100rpx;
+		width: 20%;
 		display: flex;
 		flex-direction: column;
-		margin-bottom: 20rpx;
-		justify-content: space-between;
+		margin-bottom: 28rpx;
+		justify-content: flex-start;
 		align-items: center;
 		font-size: 24rpx;
+		color: #1d2129;
+		line-height: 34rpx;
+
 		image {
-			width: 60rpx;
-			height: 60rpx;
-			margin-bottom: 8rpx;
+			width: 72rpx;
+			height: 72rpx;
+			margin-bottom: 12rpx;
 		}
 	}
 
-	// .card:nth-child(-n+5) {
-	// 	margin-bottom: 40rpx;
-	// }
-
 	::v-deep .uni-swiper-wrapper {
 		-webkit-transform: translate3d(0px, 0, 0);
 		-moz-transform: translate3d(0px, 0, 0);
@@ -197,4 +160,4 @@
 		-ms-transform: translate3d(0px, 0, 0);
 		transform: translate3d(0px, 0, 0);
 	}
-</style>
+</style>

+ 7 - 7
pages.json

@@ -744,19 +744,19 @@
 				"iconPath": "static/tabbar/index_tab.png",
 				"selectedIconPath": "static/tabbar/index_select_tab.png"
 			},
-			{ 
-				"text": "消息",
-				"pagePath": "pages/message/message",
-				"iconPath": "static/tabbar/msg_tab.png",
-				"selectedIconPath": "static/tabbar/msg_select_tab.png"
-			},
 			{
 				"text": "订单",
 				"pagePath": "pages/order/index",
 				"iconPath": "static/tabbar/order_tab.png",
 				"selectedIconPath": "static/tabbar/order_select_tab.png"
 			},
-      {
+			{
+				"text": "消息",
+				"pagePath": "pages/message/message",
+				"iconPath": "static/tabbar/msg_tab.png",
+				"selectedIconPath": "static/tabbar/msg_select_tab.png"
+			},
+			{
 				"text": "财务",
 				"pagePath": "pages/finance/index",
 				"iconPath": "static/tabbar/finance_tab.png",

+ 319 - 223
pages/index/index.vue

@@ -1,36 +1,41 @@
 <template>
 	<view class="index">
-		<view class="head">
-		  <!-- 顶部状态栏占位 -->
-		  <view class="top"></view>
-		  <!-- 头部内容 -->
-		  <view class="header" @click="shopDetails">
-		    <view class="logo">
-		      <image :src="logo?logo:'/static/index/address.png'" mode=""></image>
-		    </view>
-		    {{ name }}
-		    <image src="/static/index/down.png" mode=""></image>
-		  </view>
-		  <view class="data_box">
-		    <view class="title" @click="scanRecordaa">
-		      今日概况
-		    </view>
-		    <view class="data">
-		      <view class="item">
-		        <span>{{ numberOrders }}</span>订单数
-		      </view>
-		      <view class="item">
-		        <span>{{ turnover }}</span>营业总额(元)
-		      </view>
-		      <view class="item" @click="goUser">
-		        <span>{{ newCustomer || 0 }}</span>新客
-		      </view>
-		    </view>
-		  </view>
-		  
-		</view>
 		<view class="head-back">
-		  <image src="/static/index/top-back.png" mode="widthFix"></image>
+			<image src="/static/newIndex/index-bg.png" mode="widthFix"></image>
+		</view>
+
+		<view class="head">
+			<!-- 顶部状态栏占位 -->
+			<view class="top"></view>
+			<!-- 头部内容 -->
+			<view class="header">
+				<view class="shop-info" @click="shopDetails">
+					<view class="logo">
+						<image :src="logo ? logo : '/static/index/address.png'" mode="aspectFill"></image>
+					</view>
+					<view class="shop-meta">
+						<view class="shop-name">
+							<text class="name-text">{{ name }}</text>
+							<image class="down-icon" src="/static/index/down.png" mode=""></image>
+						</view>
+						<view class="phone">手机号 {{ phone || '--' }}</view>
+					</view>
+				</view>
+				<view class="logout-btn" @click.stop="loginOut">退出账号</view>
+			</view>
+			<view class="data_box">
+				<view class="data">
+					<view class="item">
+						<span>{{ numberOrders || 0 }}</span>订单数
+					</view>
+					<view class="item">
+						<span>{{ turnover || 0 }}</span>营业总额(元)
+					</view>
+					<view class="item" @click="goUser">
+						<span>{{ newCustomer || 0 }}</span>新客
+					</view>
+				</view>
+			</view>
 		</view>
 
 		<view class="service">
@@ -39,7 +44,7 @@
 					<view class="scan blue" @click="scanRecord">
 						<view class="">
 							<span>核销记录</span><br />
-							查看历史核销记录<u-icon name="arrow-right" ></u-icon>
+							查看历史核销记录<u-icon name="arrow-right"></u-icon>
 						</view>
 						<view class="back">
 							<image src="/static/index/recores-back.png" mode=""></image>
@@ -49,7 +54,7 @@
 					<view class="scan green" @click="goOrder">
 						<view class="">
 							<span>售卖订单</span><br />
-							查看历史订单记录<u-icon name="arrow-right" ></u-icon>
+							查看历史售卖记录<u-icon name="arrow-right"></u-icon>
 						</view>
 						<view class="back">
 							<image src="/static/index/order-back.png" mode=""></image>
@@ -70,36 +75,34 @@
 				<indexNav :showTopUp="showTopUp" :showGroupMeal="showGroupMeal" />
 			</view>
 		</view>
-		<!-- 完善信息弹窗,storeStatus == 3 (店铺已经审核通过 ) -->
-		<checkPopup :status="storeStatus" :describe="describe" :referenceId="referenceId" @cutPopup="isPopup = false"
-			v-if="isPopup" />
-		<!-- <view class="message">
-			<view class="title">
-				实时消息
+
+		<!-- 消息通知 -->
+		<view class="message">
+			<view class="msg-head">
+				<text class="title">消息通知</text>
+				<view class="more" @click="goMessage">
+					查看更多
+					<u-icon name="arrow-right" color="#999" size="24"></u-icon>
+				</view>
 			</view>
-			<view class="msg">
-				<view class="item" v-for="(item,index) in msg" :key="index">
+			<view class="msg" v-if="msg.length">
+				<view class="item" v-for="(item, index) in msg" :key="item.id || index" @click="toNotification(item)">
 					<view class="type">
 						<view class="img">
-							<image src="/static/index/deal.png" mode="" v-if="item.msgType=='1'"></image>
-							<image src="/static/index/verify.png" mode="" v-if="item.msgType=='2'"></image>
-							<image src="/static/index/client.png" mode="" v-if="item.msgType=='3'"></image>
-							<image src="/static/index/system.png" mode="" v-if="item.msgType=='4'"></image>
-							<span v-if="item.msgType=='1'">交易信息</span>
-							<span v-if="item.msgType=='2'">产品核销</span>
-							<span v-if="item.msgType=='3'">客户评价</span>
-							<span v-if="item.msgType=='4'">系统消息</span>
-						</view>
-						<view class="time">
-							{{item.msgDate}}
+							<image :src="msgIcon(item.category)" mode=""></image>
+							<span>{{ item.categoryName }}</span>
 						</view>
 					</view>
-					<view class="details">
-						{{item.msgContent}}
-					</view>
+					<view class="details">{{ item.content }}</view>
+					<view class="time">{{ item.createTimeDisplay }}</view>
 				</view>
 			</view>
-		</view> -->
+			<view class="msg-empty" v-else>暂无消息</view>
+		</view>
+
+		<!-- 完善信息弹窗,storeStatus == 3 (店铺已经审核通过 ) -->
+		<checkPopup :status="storeStatus" :describe="describe" :referenceId="referenceId" @cutPopup="isPopup = false"
+			v-if="isPopup" />
 	</view>
 </template>
 
@@ -107,6 +110,8 @@
 	import indexNav from "@/components/index_nav.vue";
 	import checkPopup from "@/components/check-popup.vue";
 	import prepaidApi from "@/api/memberPrepaid.js";
+	import api from "@/api/api";
+	import { updateMsgTabBadge, setMsgTabBadge, isUnreadNotice } from "@/common/util/msgBadge.js";
 	export default {
 		components: {
 			indexNav,
@@ -118,17 +123,22 @@
 				newCustomer: "", //新客
 				turnover: "", //营业总额
 				name: "",
-				num: 222,
+				phone: "",
 				msg: [],
+				categoryIcons: {
+					"1": "/static/index/deal.png",
+					"2": "/static/index/verify.png",
+					"3": "/static/index/system.png",
+				},
 				merchantId: "",
 				storeStatus: 0, //商户店铺设置状态
 				userId: "", //用户id
 				describe: "", //描述
 				isPopup: false, //弹窗是否出现
 				referenceId: "", //邀请码
-				logo: '',
+				logo: "",
 				showTopUp: false, // 行业是否为美食
-				showGroupMeal: false // 团餐报名是否审核通过
+				showGroupMeal: false, // 团餐报名是否审核通过
 			};
 		},
 		onLoad: function() {
@@ -152,10 +162,24 @@
 					url: "/pages/scan/manual",
 				});
 			},
-			goOrder(){
+			goOrder() {
+				uni.switchTab({
+					url: "/pages/order/index",
+				});
+			},
+			goMessage() {
 				uni.switchTab({
-					url:'/pages/order/index'
-				})
+					url: "/pages/message/message",
+				});
+			},
+			msgIcon(category) {
+				return this.categoryIcons[category] || "/static/index/system.png";
+			},
+			toNotification(item) {
+				const str = this.$u.queryParams(item);
+				uni.navigateTo({
+					url: `/pages/message/details?${str}`,
+				});
 			},
 			//跳转至门店详情页
 			shopDetails() {
@@ -168,10 +192,22 @@
 					url: "/pages/scan/record",
 				});
 			},
-			scanRecordaa() {
-				// uni.navigateTo({
-				// 	url: '/pages/login/login'
-				// })
+			loginOut() {
+				uni.showModal({
+					title: "提示",
+					content: "是否确认退出当前账号?",
+					success: (res) => {
+						if (res.confirm) {
+							api.logout().then(() => {
+								setMsgTabBadge(0);
+								uni.clearStorageSync();
+								uni.navigateTo({
+									url: `/pages/login/login`,
+								});
+							});
+						}
+					},
+				});
 			},
 			gettodayData() {
 				this.$http
@@ -186,15 +222,20 @@
 			},
 			getMessage() {
 				this.$http
-					.get("/merchant/app/home/realMessage?merchantId=" + this.merchantId, {})
+					.get("/localUserNotice/localUserNotice/getListNew", {
+						params: {
+							userType: 1,
+						},
+					})
 					.then((res) => {
-						if (res.data.code == 200) {
-							this.msg = res.data.result.records;
-							// 	this.income = res.data.result.income
-							// 	this.newCustomer = res.data.result.newCustomer
-							// 	this.numberOrders = res.data.result.numberOrders
-						}
+						const list = res.data.result || [];
+						// 首页只展示未读,已读不展示
+						this.msg = list.filter(isUnreadNotice).slice(0, 5);
+					})
+					.catch(() => {
+						this.msg = [];
 					});
+				updateMsgTabBadge();
 			},
 			// getNum 已合并到 gettodayData,新客由 /merchant/account/todayOverview 返回
 			getNum() {},
@@ -208,7 +249,6 @@
 							if (res.data.result != 3) {
 								this.storeStatus = res.data.result;
 								this.describe = res.data.message;
-								// this.referenceId = res.data.result.referenceId
 								res.data.result == 3 ?
 									(this.isPopup = false) :
 									(this.isPopup = true);
@@ -226,7 +266,6 @@
 				prepaidApi
 					.checkIndustryEligibility(this.merchantId)
 					.then((res) => {
-						console.log('11111',res)
 						this.showTopUp = res.data.code === 200 && !!res.data.result;
 					})
 					.catch(() => {
@@ -236,7 +275,7 @@
 			/** 查询团餐报名状态,审核通过才展示团餐设置/团餐订单 */
 			checkGroupMealApply() {
 				this.$http
-					.post('/groupmeal/gmMerchantApplicationRecord/isApply', {})
+					.post("/groupmeal/gmMerchantApplicationRecord/isApply", {})
 					.then((res) => {
 						this.showGroupMeal =
 							res.data.code === 200 &&
@@ -249,7 +288,6 @@
 			},
 		},
 		mounted() {
-			// let info =
 			let that = this;
 		},
 		onShow() {
@@ -257,11 +295,11 @@
 			uni.getStorage({
 				key: "login_user_info",
 				success: function(res) {
-					console.log(res);
 					that.name = res.data.merchantName;
 					that.merchantId = res.data.merchantId;
 					that.userId = res.data.id;
 					that.logo = res.data.merchantHeadPhoto;
+					that.phone = res.data.phone || "";
 					that.gettodayData();
 					that.getMessage();
 					that.getNum();
@@ -277,142 +315,171 @@
 <style scoped lang="scss">
 	.index {
 		width: 100vw;
-		height: 100vh;
-		background: #F2F3F5;
+		min-height: 100vh;
+		background: #f2f3f5;
+		padding-bottom: 40rpx;
+		position: relative;
 		z-index: 1;
+
 		.head-back {
-		  position: fixed;
-		  top: 0;
-		  left: 0;
-		  width: 100%;
-		  // height: 100%;
-		  z-index: 1;
-		  
-		  image {
-		    width: 100%;
-		    height: 100%;
-		    // object-fit: cover; 
-		  }
+			position: absolute;
+			top: 0;
+			left: 0;
+			width: 100%;
+			z-index: 1;
+			pointer-events: none;
+
+			image {
+				width: 100%;
+				display: block;
+			}
 		}
+
 		.head {
-		  width: 100%;
-		  height: auto; 
-		  position: relative; 
-		  overflow: hidden;
+			width: 100%;
+			height: auto;
+			position: relative;
+			overflow: hidden;
 			z-index: 2;
-		  
-		  .top {
-		    width: 100%;
-		    height: var(--status-bar-height);
-		    background-color: transparent;
-		  }
-		  
-		  
-		
-		  .header {
-		    width: 100%;
-		    height: 56rpx;
-		    display: flex;
-		    align-items: center;
-		    padding: 0px 32rpx;
-		    font-size: 32rpx;
-		    font-weight: 600;
-		    position: relative;
-		    z-index: 10;
-		    // margin-top: 44rpx;
-		
-		    .logo {
-		      width: 56rpx;
-		      height: 56rpx;
-		      border-radius: 50%;
-		      overflow: hidden;
-		      margin-right: 10rpx;
-		
-		      image {
-		        width: 56rpx;
-		        height: 56rpx;
-		        margin: 0;
-		      }
-		    }
-		
-		    image {
-		      width: 25rpx;
-		      height: 25rpx;
-		      margin-left: 10rpx;
-		    }
-		  }
-		
-		  .data_box {
-		    width: 686rpx;
-		    height: 180rpx;
-		    margin: 36rpx auto 16rpx;
-		    background: #ffffff;
-		    box-shadow: 0px 2rpx 8rpx 0px rgba(214, 225, 237, 0.1);
-		    border-radius: 16rpx;
-		    position: relative;
-		    z-index: 19;
-		
-		    .title {
-		      display: flex;
-		      align-items: center;
-		      width: 100%;
-		      height: 53rpx;
-		      font-size: 26rpx;
-		      color: #86909C;
-		      padding: 18rpx;
-		
-		      image {
-		        width: 40rpx;
-		        height: 40rpx;
-		        margin-left: 10rpx;
-		      }
-		    }
-		
-		    .data {
-		      display: flex;
-		      justify-content: space-around;
-		      align-items: center;
-		      padding: 20rpx 0px;
-		
-		      .item {
-		        display: flex;
-		        flex-direction: column;
-		        justify-content: space-around;
-		        align-items: center;
-		        font-size: 24rpx;
-		        line-height: 28rpx;
-		        color: #86909C;
-		
-		        span {
-		          height: 62rpx;
-		          color: #333;
-		          font-size: 48rpx;
-		          font-weight: 600;
-		          line-height: 56rpx;
-		        }
-		      }
-		    }
-		  }
-		}
 
+			.top {
+				width: 100%;
+				height: var(--status-bar-height);
+				background-color: transparent;
+			}
+
+			.header {
+				width: 100%;
+				display: flex;
+				align-items: center;
+				justify-content: space-between;
+				padding: 16rpx 0rpx 0rpx 32rpx;
+				position: relative;
+				z-index: 10;
+
+				.shop-info {
+					flex: 1;
+					display: flex;
+					align-items: center;
+					min-width: 0;
+					margin-right: 20rpx;
+				}
+
+				.logo {
+					width: 72rpx;
+					height: 72rpx;
+					border-radius: 50%;
+					overflow: hidden;
+					margin-right: 16rpx;
+					flex-shrink: 0;
+
+					image {
+						width: 72rpx;
+						height: 72rpx;
+						margin: 0;
+					}
+				}
+
+				.shop-meta {
+					flex: 1;
+					min-width: 0;
+				}
+
+				.shop-name {
+					display: flex;
+					align-items: center;
+					font-size: 32rpx;
+					font-weight: 600;
+					color: #1d2129;
+					line-height: 44rpx;
+
+					.name-text {
+						overflow: hidden;
+						text-overflow: ellipsis;
+						white-space: nowrap;
+						max-width: 360rpx;
+					}
+
+					.down-icon {
+						width: 24rpx;
+						height: 24rpx;
+						margin-left: 8rpx;
+						flex-shrink: 0;
+					}
+				}
+
+				.phone {
+					margin-top: 4rpx;
+					font-size: 24rpx;
+					color: #86909c;
+					line-height: 34rpx;
+				}
 
+				.logout-btn {
+					flex-shrink: 0;
+					padding: 10rpx 24rpx;
+					font-size: 24rpx;
+					color: #4e5969;
+					background: rgba(255, 255, 255, 0.72);
+					border-radius: 28rpx 0rpx 0rpx 28rpx;
+					line-height: 34rpx;
+				}
+			}
+
+			.data_box {
+				width: 686rpx;
+				margin: 28rpx auto 16rpx;
+				background: #ffffff;
+				box-shadow: 0px 2rpx 8rpx 0px rgba(214, 225, 237, 0.1);
+				border-radius: 16rpx;
+				position: relative;
+				z-index: 19;
+
+				.data {
+					display: flex;
+					justify-content: space-around;
+					align-items: center;
+					padding: 36rpx 0;
+
+					.item {
+						display: flex;
+						flex-direction: column;
+						justify-content: space-around;
+						align-items: center;
+						font-size: 24rpx;
+						line-height: 28rpx;
+						color: #86909c;
+
+						span {
+							height: 62rpx;
+							color: #333;
+							font-size: 48rpx;
+							font-weight: 600;
+							line-height: 56rpx;
+						}
+					}
+				}
+			}
+		}
 
 		.service {
 			width: 686rpx;
-			// height: 468rpx;
 			box-shadow: 0px 2rpx 8rpx 0px rgba(214, 225, 237, 0.1);
 			border-radius: 16rpx;
 			margin: 0 auto;
-			
+			position: relative;
+			z-index: 2;
+
 			.main {
 				height: auto;
 				display: flex;
 				justify-content: space-between;
 				margin-bottom: 16rpx;
 				align-items: stretch;
-				background: #FFFFFF;
+				background: #ffffff;
 				padding: 20rpx;
 				border-radius: 20rpx;
+
 				.left {
 					flex: 1;
 					margin-right: 22rpx;
@@ -434,6 +501,7 @@
 						z-index: 2;
 						border-radius: 8rpx;
 						overflow: hidden;
+
 						.back {
 							width: 100%;
 							height: 100%;
@@ -459,27 +527,28 @@
 					}
 
 					.scan.blue {
-						color: #197FFD;
+						color: #197ffd;
 						margin-bottom: 22rpx;
 					}
 
 					.scan.green {
-						color: #14C584;
-						background: #E7FFF7;
+						color: #14c584;
+						background: #e7fff7;
 					}
 				}
 
 				.right {
 					width: 272rpx;
 					height: 340rpx;
-					color: #624FE3;
+					color: #624fe3;
 					font-size: 20rpx;
 					padding: 28rpx;
-					background: #F6F4FF;
+					background: #f6f4ff;
 					position: relative;
 					z-index: 2;
 					border-radius: 8rpx;
 					overflow: hidden;
+
 					.back {
 						width: 100%;
 						height: 100%;
@@ -507,28 +576,43 @@
 					}
 				}
 			}
-			.other{
+
+			.other {
 				width: 100%;
-				// height: 304rpx;
-				padding: 32rpx ;
-				background: #FFFFFF;
+				padding: 32rpx;
+				background: #ffffff;
 				border-radius: 16rpx;
 			}
 		}
 
 		.message {
-			width: 676rpx;
-			padding: 20rpx 16rpx;
-			margin: 20rpx auto 0px;
-			background: linear-gradient(0, #ffffff 0%, #e2efff 100%);
+			width: 686rpx;
+			padding: 28rpx 24rpx 8rpx;
+			margin: 16rpx auto 0;
+			background: #ffffff;
 			border-radius: 16rpx;
+			position: relative;
+			z-index: 2;
 
-			.title {
+			.msg-head {
 				width: 100%;
-				height: 53rpx;
 				display: flex;
 				align-items: center;
-				margin-bottom: 20rpx;
+				justify-content: space-between;
+				margin-bottom: 8rpx;
+
+				.title {
+					font-size: 30rpx;
+					font-weight: 600;
+					color: #1d2129;
+				}
+
+				.more {
+					display: flex;
+					align-items: center;
+					font-size: 24rpx;
+					color: #86909c;
+				}
 			}
 
 			.msg {
@@ -536,43 +620,55 @@
 
 				.item {
 					width: 100%;
-					border-bottom: 1px solid #dddddd;
-					margin-bottom: 20rpx;
+					padding: 24rpx 0;
+					border-bottom: 1px solid #f2f3f5;
+
+					&:last-child {
+						border-bottom: none;
+					}
 
 					.type {
 						width: 100%;
 						height: 38rpx;
 						display: flex;
 						align-items: center;
-						justify-content: space-between;
 						margin-bottom: 8rpx;
 
 						.img {
-							font-size: 26rpx;
+							font-size: 28rpx;
 							font-weight: 600;
+							color: #1d2129;
 							display: flex;
 							align-items: center;
 
 							image {
-								width: 30rpx;
-								height: 30rpx;
-								margin-right: 8rpx;
+								width: 36rpx;
+								height: 36rpx;
+								margin-right: 10rpx;
 							}
 						}
-
-						.time {
-							font-size: 22rpx;
-							color: #999999;
-						}
 					}
 
 					.details {
+						font-size: 24rpx;
+						color: #86909c;
+						line-height: 36rpx;
+						margin-bottom: 8rpx;
+					}
+
+					.time {
 						font-size: 22rpx;
-						color: #999999;
-						margin-bottom: 16rpx;
+						color: #c9cdd4;
 					}
 				}
 			}
+
+			.msg-empty {
+				padding: 40rpx 0 48rpx;
+				text-align: center;
+				font-size: 24rpx;
+				color: #c9cdd4;
+			}
 		}
 	}
-</style>
+</style>

+ 1 - 1
pages/merchantDish/dish/components/FormNextBtn.vue

@@ -38,7 +38,7 @@ export default {
 	height: 88rpx;
 	line-height: 88rpx;
 	text-align: center;
-	background: #449aff;
+	background: linear-gradient( 89deg, #10ABFE 0%, #2260F6 100%);
 	color: #fff;
 	border-radius: 44rpx;
 	font-size: 32rpx;

+ 11 - 4
pages/merchantDish/dish/form.vue

@@ -27,12 +27,13 @@
 			</view>
 			<view class="upload-row">
 				<text class="label required">菜品封面图</text>
-				<view class="tip">支持jpg、png格式,尺寸为750px * 750px</view>
+				<view class="tip">支持jpg、png格式,大小不超过2M</view>
 				<u-upload
 					:action="uploadAction"
 					:file-list="fileList.cover"
 					:form-data="uploadFormData"
 					:max-count="4"
+					:max-size="2 * 1024 * 1024"
 					:multiple="true"
 					:deletable="true"
 					:custom-btn="true"
@@ -42,6 +43,7 @@
 					preview-full-image
 					@on-success="onCoverSuccess"
 					@on-remove="onCoverRemove"
+					@on-oversize="onUploadOversize"
 				>
 					<view slot="addBtn" class="upload-btn">
 						<image class="upload-icon" src="/static/merchantDish/photo.png" mode="aspectFit"></image>
@@ -51,12 +53,13 @@
 			</view>
 			<view class="upload-row last">
 				<text class="label required">菜品图片详情</text>
-				<view class="tip">支持jpg、png格式,尺寸为750px * 750px</view>
+				<view class="tip">支持jpg、png格式,大小不超过2M</view>
 				<u-upload
 					:action="uploadAction"
 					:file-list="fileList.detail"
 					:form-data="uploadFormData"
 					:max-count="20"
+					:max-size="2 * 1024 * 1024"
 					:multiple="true"
 					:deletable="true"
 					:custom-btn="true"
@@ -66,6 +69,7 @@
 					preview-full-image
 					@on-success="onDetailSuccess"
 					@on-remove="onDetailRemove"
+					@on-oversize="onUploadOversize"
 				>
 					<view slot="addBtn" class="upload-btn">
 						<image class="upload-icon" src="/static/merchantDish/photo.png" mode="aspectFit"></image>
@@ -596,6 +600,9 @@ export default {
 				.filter(Boolean);
 			this.form[formKey] = urls.join(',');
 		},
+		onUploadOversize() {
+			uni.showToast({ title: '图片大小不能超过2M', icon: 'none' });
+		},
 		onCoverSuccess(res, index, lists) {
 			this.fileList.cover = lists;
 			this.processImageList(lists, 'cover');
@@ -1088,7 +1095,7 @@ export default {
 	}
 	&.save {
 		color: #fff;
-		background: linear-gradient(90deg, #77b6ff 0%, #449aff 100%);
+		background: linear-gradient( 89deg, #10ABFE 0%, #2260F6 100%);
 	}
 }
 .spec-value-dialog {
@@ -1212,7 +1219,7 @@ export default {
 	}
 	&.confirm {
 		color: #fff;
-		background: linear-gradient(90deg, #77b6ff 0%, #449aff 100%);
+		background: linear-gradient( 89deg, #10ABFE 0%, #2260F6 100%);
 	}
 }
 ::v-deep .u-radio {

+ 197 - 84
pages/merchantDish/dish/list.vue

@@ -21,18 +21,47 @@
 			></u-search>
 		</view>
 
-		<view class="filters">
-			<view class="filter-item" @click="openPicker('status')">
-				{{ statusLabel }}
-				<image class="filter-arrow" src="/static/merchantDish/selete.png" mode="aspectFit"></image>
-			</view>
-			<view class="filter-item" @click="openPicker('type')">
-				{{ typeLabel }}
-				<image class="filter-arrow" src="/static/merchantDish/selete.png" mode="aspectFit"></image>
+		<view class="filter-wrap">
+			<view class="filters">
+				<view :class="['filter-item', pickerShow && pickerType === 'status' ? 'active' : '']" @click="openPicker('status')">
+					<text class="filter-text">{{ statusLabel }}</text>
+					<image
+						:class="['filter-arrow', pickerShow && pickerType === 'status' ? 'up' : '']"
+						src="/static/merchantDish/selete.png"
+						mode="aspectFit"
+					></image>
+				</view>
+				<view :class="['filter-item', pickerShow && pickerType === 'type' ? 'active' : '']" @click="openPicker('type')">
+					<text class="filter-text">{{ typeLabel }}</text>
+					<image
+						:class="['filter-arrow', pickerShow && pickerType === 'type' ? 'up' : '']"
+						src="/static/merchantDish/selete.png"
+						mode="aspectFit"
+					></image>
+				</view>
+				<view :class="['filter-item', pickerShow && pickerType === 'category' ? 'active' : '']" @click="openPicker('category')">
+					<text class="filter-text">{{ categoryLabel }}</text>
+					<image
+						:class="['filter-arrow', pickerShow && pickerType === 'category' ? 'up' : '']"
+						src="/static/merchantDish/selete.png"
+						mode="aspectFit"
+					></image>
+				</view>
 			</view>
-			<view class="filter-item" @click="openPicker('category')">
-				{{ categoryLabel }}
-				<image class="filter-arrow" src="/static/merchantDish/selete.png" mode="aspectFit"></image>
+
+			<!-- 筛选下拉:状态 / 菜品类型 / 品类 -->
+			<view class="filter-dropdown" v-if="pickerShow">
+				<view class="filter-panel">
+					<view
+						v-for="(opt, idx) in pickerList"
+						:key="idx"
+						:class="['filter-option', isOptionActive(opt) ? 'on' : '']"
+						@click="onPick(opt)"
+					>
+						{{ opt.text }}
+					</view>
+				</view>
+				<view class="filter-mask" @click="closePicker"></view>
 			</view>
 		</view>
 
@@ -53,18 +82,13 @@
 				<template v-slot:list="{ data }">
 					<view class="list">
 						<view class="card" v-for="item in data" :key="item.id" @click="toggleSelect(item)">
-							<view class="check" v-if="batchMode">
-								<view :class="['dot', selectedIds.includes(item.id) ? 'on' : '']">
-									<u-icon v-if="selectedIds.includes(item.id)" name="checkmark" color="#fff" size="20"></u-icon>
-								</view>
-							</view>
+							<image
+								class="belong-tag"
+								:src="item.belong === 'group' ? '/static/merchantDish/groupmeal.png' : '/static/merchantDish/store.png'"
+								mode="heightFix"
+							></image>
 							<view class="thumb-wrap">
 								<image class="thumb" :src="item.image" mode="aspectFill"></image>
-								<image
-									class="belong-tag"
-									:src="item.belong === 'group' ? '/static/merchantDish/groupmeal.png' : '/static/merchantDish/store.png'"
-									mode="heightFix"
-								></image>
 							</view>
 							<view class="info">
 								<view class="row-top">
@@ -85,16 +109,21 @@
 										<view class="btn primary" @click="onOffShelf(item)">下架</view>
 									</template>
 									<template v-else-if="item.status === 'pending'">
-										<view class="btn" @click="onDelete(item)">删除</view>
-										<view class="btn" @click="goEdit(item)">编辑</view>
+										<text class="btn-link" @click="onDelete(item)">删除</text>
+										<text class="btn-link" @click="goEdit(item)">编辑</text>
 										<view class="btn primary" @click="onOnShelf(item)">上架</view>
 									</template>
 									<template v-else-if="item.status === 'rejected'">
-										<view class="btn" @click="onDelete(item)">删除</view>
-										<view class="btn" @click="goEdit(item)">编辑</view>
+										<text class="btn-link" @click="onDelete(item)">删除</text>
+										<text class="btn-link" @click="goEdit(item)">编辑</text>
 									</template>
 								</view>
 							</view>
+							<view class="check" v-if="batchMode">
+								<view :class="['dot', selectedIds.includes(item.id) ? 'on' : '']">
+									<u-icon v-if="selectedIds.includes(item.id)" name="checkmark" color="#fff" size="20"></u-icon>
+								</view>
+							</view>
 						</view>
 					</view>
 				</template>
@@ -131,17 +160,16 @@
 			</view>
 		</view>
 
-		<u-action-sheet :list="pickerList" v-model="pickerShow" @click="onPick"></u-action-sheet>
-
 		<!-- 团餐下架确认 -->
 		<view class="mask" v-if="offShelfShow" @click="closeOffShelf">
 			<view class="confirm-dialog" @click.stop>
+				<view class="confirm-title">提示</view>
 				<view class="confirm-content">
 					该菜品当前有未成团订单{{ (offShelfItem && offShelfItem.ungroupedOrderCount) || 0 }}份,已成团{{ (offShelfItem && offShelfItem.groupedOrderCount) || 0 }}份,是否要确定下架
 				</view>
 				<view class="confirm-footer">
 					<view class="confirm-btn" @click="closeOffShelf">取消</view>
-					<view class="confirm-btn primary" @click="confirmOffShelf">确定</view>
+					<view class="confirm-btn" @click="confirmOffShelf">确定</view>
 				</view>
 			</view>
 		</view>
@@ -168,9 +196,9 @@ const STATUS_OPTIONS = [
 ];
 
 const TYPE_OPTIONS = [
-	{ label: '全部品', value: '' },
-	{ label: '团餐', value: 'group' },
-	{ label: '门店', value: 'store' }
+	{ label: '全部品', value: '' },
+	{ label: '团餐菜品', value: 'group' },
+	{ label: '门店菜品', value: 'store' }
 ];
 
 export default {
@@ -207,7 +235,7 @@ export default {
 			return (STATUS_OPTIONS.find((i) => i.value === this.filterStatus) || {}).label || '全部';
 		},
 		typeLabel() {
-			return (TYPE_OPTIONS.find((i) => i.value === this.filterType) || {}).label || '全部品';
+			return (TYPE_OPTIONS.find((i) => i.value === this.filterType) || {}).label || '全部品';
 		},
 		categoryLabel() {
 			return (this.categoryOptions.find((i) => i.value === this.filterCategory) || {}).label || '全部品类';
@@ -322,6 +350,10 @@ export default {
 		},
 		openPicker(type) {
 			if (this.batchMode) return;
+			if (this.pickerShow && this.pickerType === type) {
+				this.closePicker();
+				return;
+			}
 			this.pickerType = type;
 			const map = {
 				status: STATUS_OPTIONS,
@@ -331,15 +363,28 @@ export default {
 			this.pickerList = (map[type] || []).map((i) => ({ text: i.label, value: i.value }));
 			this.pickerShow = true;
 		},
-		onPick(e) {
-			const value = e && e.value !== undefined ? e.value : '';
+		closePicker() {
+			this.pickerShow = false;
+			this.pickerType = '';
+		},
+		isOptionActive(opt) {
+			const value = opt && opt.value !== undefined ? opt.value : '';
+			if (this.pickerType === 'status') return this.filterStatus === value;
+			if (this.pickerType === 'type') return this.filterType === value;
+			if (this.pickerType === 'category') return this.filterCategory === value;
+			return false;
+		},
+		onPick(opt) {
+			const value = opt && opt.value !== undefined ? opt.value : '';
 			if (this.pickerType === 'status') this.filterStatus = value;
 			if (this.pickerType === 'type') this.filterType = value;
 			if (this.pickerType === 'category') this.filterCategory = value;
 			this.selectedIds = [];
+			this.closePicker();
 			this.reloadList();
 		},
 		enterBatch() {
+			this.closePicker();
 			this.batchMode = true;
 			this.selectedIds = [];
 		},
@@ -373,9 +418,9 @@ export default {
 		confirmModal(content) {
 			return new Promise((resolve) => {
 				uni.showModal({
-					title: '',
+					title: '提示',
 					content,
-					confirmColor: '#449AFF',
+					confirmColor: '#333333',
 					success: (res) => resolve(!!res.confirm)
 				});
 			});
@@ -471,11 +516,6 @@ export default {
 	flex-direction: column;
 	overflow: hidden;
 }
-.nav-title {
-	font-size: 40rpx;
-	font-weight: 600;
-	color: #222;
-}
 .nav-right {
 	display: flex;
 	align-items: center;
@@ -496,33 +536,89 @@ export default {
 	background: #fff;
 	flex-shrink: 0;
 }
+
+/* ========== 筛选栏 + 下拉面板 ========== */
+.filter-wrap {
+	position: relative;
+	flex-shrink: 0;
+	z-index: 30;
+}
 .filters {
 	display: flex;
-	justify-content: space-between;
 	align-items: center;
 	background: #fff;
-	padding: 16rpx 24rpx 20rpx;
-	flex-shrink: 0;
+	padding: 24rpx 0;
+	position: relative;
+	z-index: 2;
 	.filter-item {
-		margin-right: 36rpx;
-		font-size: 30rpx;
-		color: #333;
+		flex: 1;
 		display: flex;
 		align-items: center;
+		justify-content: center;
+		font-size: 28rpx;
+		color: #666;
+		&.active {
+			color: #449aff;
+		}
+		.filter-text {
+			max-width: 180rpx;
+			overflow: hidden;
+			text-overflow: ellipsis;
+			white-space: nowrap;
+		}
 	}
 	.filter-arrow {
-		width: 20rpx;
-		height: 20rpx;
+		width: 18rpx;
+		height: 18rpx;
 		margin-left: 8rpx;
+		flex-shrink: 0;
+		transition: transform 0.2s;
+		&.up {
+			transform: rotate(180deg);
+		}
+	}
+}
+.filter-dropdown {
+	position: absolute;
+	left: 0;
+	right: 0;
+	top: 100%;
+	z-index: 1;
+}
+.filter-panel {
+	position: relative;
+	z-index: 2;
+	background: #fff;
+	border-radius: 0 0 16rpx 16rpx;
+	box-shadow: 0 8rpx 24rpx rgba(0, 0, 0, 0.06);
+	padding: 8rpx 0 24rpx;
+	max-height: 560rpx;
+	overflow-y: auto;
+}
+.filter-option {
+	padding: 22rpx 48rpx;
+	font-size: 28rpx;
+	color: #222;
+	line-height: 1.4;
+	&.on {
+		color: #449aff;
 	}
 }
+.filter-mask {
+	position: absolute;
+	left: 0;
+	right: 0;
+	top: 0;
+	height: 100vh;
+	z-index: 1;
+	background: rgba(0, 0, 0, 0.4);
+}
+
 .banner {
-	// margin: 16rpx 24rpx 0;
 	height: 80rpx;
 	line-height: 80rpx;
 	background: #fff8e6;
 	font-size: 28rpx;
-	// border-radius: 8rpx;
 	text-align: center;
 }
 .list-wrap {
@@ -534,17 +630,29 @@ export default {
 	padding: 16rpx 24rpx;
 	box-sizing: border-box;
 }
+
+/* ========== 菜品卡片 ========== */
 .card {
 	display: flex;
 	background: #fff;
 	border-radius: 16rpx;
 	padding: 24rpx;
 	margin-bottom: 16rpx;
+	position: relative;
+	overflow: hidden;
+	.belong-tag {
+		position: absolute;
+		left: 0;
+		top: 0;
+		height: 36rpx;
+		width: auto;
+		z-index: 2;
+	}
 	.check {
 		display: flex;
-		align-items: flex-start;
-		padding-top: 40rpx;
-		margin-right: 16rpx;
+		align-items: center;
+		margin-left: 16rpx;
+		flex-shrink: 0;
 	}
 	.dot {
 		width: 36rpx;
@@ -561,7 +669,6 @@ export default {
 		}
 	}
 	.thumb-wrap {
-		position: relative;
 		width: 160rpx;
 		height: 160rpx;
 		flex-shrink: 0;
@@ -571,13 +678,6 @@ export default {
 			border-radius: 12rpx;
 			background: #eee;
 		}
-		.belong-tag {
-			position: absolute;
-			left: 0;
-			top: 0;
-			height: 36rpx;
-			width: auto;
-		}
 	}
 	.info {
 		flex: 1;
@@ -653,23 +753,31 @@ export default {
 	.actions {
 		display: flex;
 		justify-content: flex-end;
-		gap: 12rpx;
+		align-items: center;
+		gap: 24rpx;
 		margin-top: 16rpx;
 	}
+	.btn-link {
+		font-size: 26rpx;
+		color: #666;
+		line-height: 52rpx;
+		padding: 0 4rpx;
+	}
 	.btn {
-		font-size: 24rpx;
-		padding: 8rpx 24rpx;
-		border: 1rpx solid #ddd;
-		border-radius: 28rpx;
+		font-size: 26rpx;
+		padding: 0 28rpx;
+		height: 52rpx;
+		line-height: 52rpx;
+		border-radius: 26rpx;
 		color: #666;
 		background: #fff;
 		&.primary {
-			background: #449aff;
-			border-color: #449aff;
+			background: linear-gradient( 89deg, #10ABFE 0%, #2260F6 100%);
 			color: #fff;
 		}
 	}
 }
+
 .footer {
 	position: fixed;
 	left: 0;
@@ -686,7 +794,7 @@ export default {
 	color: #fff;
 	font-size: 32rpx;
 	border-radius: 44rpx;
-	background: linear-gradient(90deg, #77b6ff 0%, #449aff 100%);
+	background: linear-gradient( 89deg, #10ABFE 0%, #2260F6 100%);
 }
 .batch-footer {
 	position: fixed;
@@ -733,12 +841,12 @@ export default {
 		border-radius: 36rpx;
 		font-size: 26rpx;
 		&.danger {
-			background: #ff4d4f;
+			background: linear-gradient( 89deg, #10ABFE 0%, #2260F6 100%);
 			color: #fff;
 		}
 		&.outline {
-			border: 1rpx solid #ff4d4f;
-			color: #ff4d4f;
+			border: 1rpx solid #10ABFE;
+			color: #1C7CF9;
 		}
 		&.disabled {
 			background: #f0f0f0;
@@ -753,7 +861,7 @@ export default {
 	right: 0;
 	top: 0;
 	bottom: 0;
-	background: rgba(0, 0, 0, 0.45);
+	background: rgba(0, 0, 0, 0.5);
 	z-index: 1000;
 	display: flex;
 	align-items: center;
@@ -765,29 +873,34 @@ export default {
 	border-radius: 20rpx;
 	overflow: hidden;
 }
-.confirm-content {
-	padding: 48rpx 40rpx 40rpx;
+.confirm-title {
+	padding: 40rpx 40rpx 0;
 	text-align: center;
-	font-size: 30rpx;
+	font-size: 34rpx;
+	font-weight: 600;
 	color: #222;
-	line-height: 1.7;
+	line-height: 1.4;
+}
+.confirm-content {
+	padding: 24rpx 40rpx 48rpx;
+	text-align: center;
+	font-size: 28rpx;
+	color: #333;
+	line-height: 1.6;
 }
 .confirm-footer {
 	display: flex;
-	border-top: 1rpx solid #eee;
+	border-top: 1rpx solid #e5e5e5;
 }
 .confirm-btn {
 	flex: 1;
 	height: 96rpx;
 	line-height: 96rpx;
 	text-align: center;
-	font-size: 30rpx;
+	font-size: 32rpx;
 	color: #333;
 	&:first-child {
-		border-right: 1rpx solid #eee;
-	}
-	&.primary {
-		color: #449aff;
+		border-right: 1rpx solid #e5e5e5;
 	}
 }
 </style>

+ 2 - 2
pages/merchantDish/dish/sale-time.vue

@@ -674,7 +674,7 @@ export default {
 	&.primary {
 		flex: 1;
 		color: #fff;
-		background: linear-gradient(90deg, #77b6ff 0%, #449aff 100%);
+		background: linear-gradient( 89deg, #10ABFE 0%, #2260F6 100%);
 	}
 	&.disabled {
 		opacity: 0.5;
@@ -746,7 +746,7 @@ export default {
 	font-size: 30rpx;
 	color: #fff;
 	border-radius: 44rpx;
-	background: linear-gradient(90deg, #77b6ff 0%, #449aff 100%);
+	background: linear-gradient( 89deg, #10ABFE 0%, #2260F6 100%);
 }
 ::v-deep .u-radio {
 	margin-right: 24rpx;

+ 1 - 1
pages/merchantDish/dish/spec-detail.vue

@@ -255,7 +255,7 @@ export default {
 		height: 72rpx;
 		line-height: 72rpx;
 		border-radius: 36rpx;
-		background: #449aff;
+		background: linear-gradient( 89deg, #10ABFE 0%, #2260F6 100%);
 		color: #fff;
 		font-size: 28rpx;
 	}

+ 1 - 1
pages/merchantDish/settings/box-bind.vue

@@ -322,7 +322,7 @@ export default {
 		color: #fff;
 		font-size: 30rpx;
 		border-radius: 40rpx;
-		background: linear-gradient(90deg, #77b6ff 0%, #449aff 100%);
+		background: linear-gradient( 89deg, #10ABFE 0%, #2260F6 100%);
 		&.disabled {
 			opacity: 0.6;
 		}

+ 1 - 1
pages/merchantDish/settings/box-form.vue

@@ -282,7 +282,7 @@ export default {
 	color: #fff;
 	font-size: 32rpx;
 	border-radius: 44rpx;
-	background: linear-gradient(90deg, #77b6ff 0%, #449aff 100%);
+	background: linear-gradient( 89deg, #10ABFE 0%, #2260F6 100%);
 	&.disabled {
 		opacity: 0.6;
 	}

+ 1 - 1
pages/merchantDish/settings/box-list.vue

@@ -236,7 +236,7 @@ export default {
 	color: #fff;
 	font-size: 32rpx;
 	border-radius: 44rpx;
-	background: linear-gradient(90deg, #77b6ff 0%, #449aff 100%);
+	background: linear-gradient( 89deg, #10ABFE 0%, #2260F6 100%);
 }
 
 /* 空态按钮对齐设计:蓝描边胶囊 */

+ 2 - 0
pages/message/details.vue

@@ -31,6 +31,7 @@
 import ListScrollView from '@/components/list-scroll-view/index.vue';
 import throttleUtil from '@/utils/public.js';
 import { USER_INFO } from "@/common/util/constants"
+import { updateMsgTabBadge } from '@/common/util/msgBadge.js';
 export default {
   components: {
     ListScrollView
@@ -73,6 +74,7 @@ export default {
           status: '1'
         }).then(res => {
           item.status = '1';
+          updateMsgTabBadge();
         })
       }
       this.navigateToDetail(item);

+ 2 - 1
pages/message/message.vue

@@ -22,7 +22,7 @@
 </template>
 
 <script>
-
+import { updateMsgTabBadge } from '@/common/util/msgBadge.js';
 
 export default {
   data() {
@@ -37,6 +37,7 @@ export default {
   },
   async onShow() {
     this.getMsgList();
+    updateMsgTabBadge();
   },
   methods: {
     // 获取消息

BIN
static/newIndex/ad.png


BIN
static/newIndex/coupon.png


BIN
static/newIndex/evaluate.png


BIN
static/newIndex/groupMeal.png


BIN
static/newIndex/groupMealOrder.png


BIN
static/newIndex/index-bg.png


BIN
static/newIndex/product.png


BIN
static/newIndex/productShop.png


BIN
static/newIndex/shop.png


BIN
static/newIndex/store.png


BIN
static/newIndex/toup.png


BIN
static/tabbar/finance_select_tab.png


BIN
static/tabbar/finance_tab.png


BIN
static/tabbar/index_select_tab.png


BIN
static/tabbar/index_tab.png


BIN
static/tabbar/msg_select_tab.png


BIN
static/tabbar/msg_tab.png


BIN
static/tabbar/order_select_tab.png


BIN
static/tabbar/order_tab.png