Pārlūkot izejas kodu

景聚庭-点菜订单页面调整

huangguoce 1 mēnesi atpakaļ
vecāks
revīzija
217bc309fd

+ 48 - 0
api/psi/DishOrderService.js

@@ -2,6 +2,54 @@ import request from "../../common/request"
 import { PSI_MANAGEMANT as prefix } from "@/api/AppPath";
 
 export default class DishOrderService {
+  roomList(param) {
+    return request({
+      url: prefix + "/psi/dishRoom/list",
+      method: "get",
+      params: param,
+    });
+  }
+  findRoomById(id) {
+    return request({
+      url: prefix + "/psi/dishRoom/findById",
+      method: "get",
+      params: { id: id },
+    });
+  }
+  typeList() {
+    return request({
+      url: prefix + "/psi/dishMenu/orderTypeList",
+      method: "get",
+    });
+  }
+  dishList(param) {
+    return request({
+      url: prefix + "/psi/dishMenu/orderDishList",
+      method: "get",
+      params: param,
+    });
+  }
+  currentOrder(roomId) {
+    return request({
+      url: prefix + "/psi/dishOrder/currentOrder",
+      method: "get",
+      params: { roomId: roomId },
+    });
+  }
+  submit(param) {
+    return request({
+      url: prefix + "/psi/dishOrder/submit",
+      method: "post",
+      data: param,
+    });
+  }
+  cancelOrder(id) {
+    return request({
+      url: prefix + "/psi/dishOrder/cancelOrder",
+      method: "get",
+      params: { id: id },
+    });
+  }
   findOrderById(id) {
     return request({
       url: prefix + "/psi/dishOrder/findOrderById",

+ 19 - 1
pages.json

@@ -250,9 +250,27 @@
 			"style" : {}
 		},
 		{
+			"path" : "pages/psiManagement/dishManage/DishOrder",
+			"style" : {
+				"navigationBarTitleText": "景聚庭"
+			}
+		},
+		{
+			"path" : "pages/psiManagement/dishManage/DishOrderDetail",
+			"style" : {
+				"navigationBarTitleText": "景聚庭"
+			}
+		},
+		{
+			"path" : "pages/psiManagement/dishManage/DishOrderAdd",
+			"style" : {
+				"navigationBarTitleText": "景聚庭"
+			}
+		},
+		{
 			"path" : "pages/psiManagement/dishManage/DishOrderApproval",
 			"style" : {
-				"navigationBarTitleText": "点菜订单审批"
+				"navigationBarTitleText": "景聚庭"
 			}
 		},
 		{

+ 268 - 0
pages/psiManagement/dishManage/DishOrder.vue

@@ -0,0 +1,268 @@
+<template>
+	<view class="dish-order-page">
+		<view class="query-bar">
+			<input class="query-input" v-model="searchForm.roomName" placeholder="请输入包房名称" confirm-type="search"
+				@confirm="refreshRoomList" />
+			<input class="query-input" v-model="searchForm.roomNo" placeholder="请输入包房编号" confirm-type="search"
+				@confirm="refreshRoomList" />
+			<button class="query-btn primary" @click="refreshRoomList">查询</button>
+			<button class="query-btn" @click="resetSearch">重置</button>
+		</view>
+
+		<view v-if="roomLoading" class="state-box">
+			<u-loading-icon text="加载中" textSize="14"></u-loading-icon>
+		</view>
+		<scroll-view v-else scroll-y class="room-scroll">
+			<view class="room-grid">
+				<view v-for="item in roomList" :key="item.id" class="room-card"
+					:class="{ disabled: item.status === '1' }" @click="enterOrder(item)">
+					<view class="room-card-top">
+						<view class="room-title-wrap">
+							<view class="room-name">{{ item.roomName || '-' }}</view>
+							<view class="room-no">包房号:{{ item.roomNo || '-' }}</view>
+						</view>
+						<view class="room-status" :class="item.useStatus === '0' ? 'free' : 'busy'">
+							{{ item.useStatus === '0' ? '空闲中' : '使用中' }}
+						</view>
+					</view>
+					<view class="room-meta">
+						<view>
+							<text>容纳人数</text>
+							<strong>{{ item.capacity || 0 }} 人</strong>
+						</view>
+					</view>
+					<view class="room-remarks">{{ item.remarks || '暂无备注' }}</view>
+				</view>
+				<view v-if="roomList.length === 0" class="empty-room">暂无包房</view>
+			</view>
+		</scroll-view>
+	</view>
+</template>
+
+<script>
+import DishOrderService from '@/api/psi/DishOrderService'
+
+export default {
+	data() {
+		return {
+			searchForm: {
+				roomName: '',
+				roomNo: '',
+				status: '0'
+			},
+			roomList: [],
+			roomLoading: false,
+			dishOrderService: null
+		}
+	},
+	onLoad() {
+		uni.setNavigationBarTitle({ title: '点菜' })
+		this.dishOrderService = new DishOrderService()
+		this.refreshRoomList()
+	},
+	onShow() {
+		if (!this.dishOrderService) {
+			this.dishOrderService = new DishOrderService()
+		}
+		this.refreshRoomList()
+	},
+	methods: {
+		refreshRoomList() {
+			this.roomLoading = true
+			this.dishOrderService.roomList({ ...this.searchForm }).then((data) => {
+				this.roomList = Array.isArray(data) ? data : []
+			}).finally(() => {
+				this.roomLoading = false
+			})
+		},
+		resetSearch() {
+			this.searchForm.roomName = ''
+			this.searchForm.roomNo = ''
+			this.refreshRoomList()
+		},
+		enterOrder(room) {
+			if (room.status === '1') {
+				uni.showToast({ title: '该包房已停用', icon: 'none' })
+				return
+			}
+			uni.navigateTo({
+				url: `/pages/psiManagement/dishManage/DishOrderDetail?roomId=${room.id}`
+			})
+		}
+	}
+}
+</script>
+
+<style scoped>
+.dish-order-page {
+	height: calc(100vh - var(--window-top, 0px));
+	box-sizing: border-box;
+	display: flex;
+	flex-direction: column;
+	overflow: hidden;
+	padding: 24rpx;
+	background: #f5f6fa;
+}
+
+.query-bar {
+	flex-shrink: 0;
+	display: grid;
+	grid-template-columns: minmax(0, 1fr) minmax(0, 1fr) 140rpx 140rpx;
+	gap: 16rpx;
+	margin-bottom: 22rpx;
+	padding: 18rpx;
+	border-radius: 12rpx;
+	background: #fff;
+}
+
+.query-input {
+	height: 72rpx;
+	box-sizing: border-box;
+	padding: 0 22rpx;
+	border: 1rpx solid #dcdfe6;
+	border-radius: 8rpx;
+	font-size: 28rpx;
+	color: #303133;
+	background: #fff;
+}
+
+.query-btn {
+	height: 72rpx;
+	margin: 0;
+	padding: 0;
+	border-radius: 8rpx;
+	font-size: 28rpx;
+	line-height: 72rpx;
+	color: #606266;
+	background: #f7f8fa;
+}
+
+.query-btn.primary {
+	color: #fff;
+	background: #2979ff;
+}
+
+.room-scroll {
+	flex: 1;
+	height: 0;
+	min-height: 0;
+}
+
+.room-grid {
+	display: grid;
+	grid-template-columns: repeat(3, minmax(0, 1fr));
+	gap: 22rpx;
+	padding-bottom: 4rpx;
+}
+
+.room-card {
+	min-height: 260rpx;
+	box-sizing: border-box;
+	padding: 24rpx;
+	border: 3rpx solid #e5e7eb;
+	border-radius: 10rpx;
+	background: #fff;
+}
+
+.room-card.disabled {
+	background: #f7f8fa;
+}
+
+.room-card-top {
+	display: flex;
+	justify-content: space-between;
+	gap: 18rpx;
+}
+
+.room-title-wrap {
+	min-width: 0;
+	flex: 1;
+}
+
+.room-name {
+	font-size: 34rpx;
+	font-weight: 700;
+	color: #1f2937;
+	line-height: 46rpx;
+	overflow: hidden;
+	white-space: nowrap;
+	text-overflow: ellipsis;
+}
+
+.room-no {
+	margin-top: 8rpx;
+	font-size: 24rpx;
+	color: #909399;
+	line-height: 34rpx;
+}
+
+.room-status {
+	height: 44rpx;
+	padding: 0 18rpx;
+	border-radius: 999rpx;
+	font-size: 24rpx;
+	line-height: 44rpx;
+	white-space: nowrap;
+}
+
+.room-status.free {
+	color: #19be6b;
+	background: #e8f7ef;
+}
+
+.room-status.busy {
+	color: #2979ff;
+	background: #ecf5ff;
+}
+
+.room-meta {
+	display: grid;
+	grid-template-columns: repeat(2, minmax(0, 1fr));
+	gap: 12rpx;
+	margin-top: 28rpx;
+}
+
+.room-meta>view {
+	padding: 16rpx;
+	border-radius: 8rpx;
+	/* background: #f7f9fb; */
+}
+
+.room-meta text {
+	display: block;
+	font-size: 24rpx;
+	color: #909399;
+	line-height: 32rpx;
+}
+
+.room-meta strong {
+	display: block;
+	margin-top: 6rpx;
+	font-size: 30rpx;
+	color: #303133;
+	line-height: 40rpx;
+}
+
+.room-remarks {
+	margin-top: 22rpx;
+	font-size: 26rpx;
+	color: #606266;
+	line-height: 38rpx;
+	overflow: hidden;
+	display: -webkit-box;
+	-webkit-line-clamp: 2;
+	-webkit-box-orient: vertical;
+}
+
+.state-box,
+.empty-room {
+	flex: 1;
+	min-height: 360rpx;
+	display: flex;
+	align-items: center;
+	justify-content: center;
+	border-radius: 12rpx;
+	background: #fff;
+	color: #909399;
+}
+</style>

+ 666 - 0
pages/psiManagement/dishManage/DishOrderAdd.vue

@@ -0,0 +1,666 @@
+<template>
+	<view class="dish-order-add">
+		<view class="order-header">
+			<view>
+				<view class="room-name">{{ currentRoom.roomName || '-' }}</view>
+				<view class="room-no">包房号:{{ currentRoom.roomNo || '-' }}</view>
+			</view>
+			<button class="mini-btn primary" @click="backOrderDetail">返回订单</button>
+		</view>
+
+		<view class="order-main">
+			<view class="dish-panel">
+				<view class="dish-search">
+					<input class="search-input" v-model="dishSearchName" placeholder="搜索菜品名称" confirm-type="search"
+						@confirm="searchDish" />
+					<button class="search-btn" @click="searchDish">搜索</button>
+				</view>
+				<view class="dish-content">
+					<scroll-view scroll-y class="category-list">
+						<view v-for="item in categoryList" :key="item.id" class="category-item"
+							:class="{ active: activeTypeId === item.id }" @click="changeType(item)">
+							{{ item.name }}
+						</view>
+					</scroll-view>
+					<scroll-view scroll-y class="dish-list">
+						<view v-if="dishLoading" class="empty-box">加载中...</view>
+						<view v-else-if="dishList.length === 0" class="empty-box">暂无菜品</view>
+						<view v-else class="dish-grid">
+							<view v-for="item in dishList" :key="item.id" class="dish-card">
+								<image v-if="item.previewImageUrl" class="dish-image" :src="item.previewImageUrl"
+									mode="aspectFill"></image>
+								<view v-else class="dish-image dish-image-empty">暂无图片</view>
+								<view class="dish-info">
+									<view class="dish-name">{{ item.dishName }}</view>
+									<view class="dish-desc">{{ item.spec || item.taste || item.remarks || '暂无说明' }}</view>
+									<view class="dish-bottom">
+										<text class="dish-price">¥{{ formatMoney(item.salePrice) }}</text>
+										<button class="plain-btn" @click="addDish(item)">点菜</button>
+									</view>
+								</view>
+							</view>
+						</view>
+					</scroll-view>
+				</view>
+			</view>
+
+			<view class="ordered-panel">
+				<view class="ordered-title">本次加菜</view>
+				<scroll-view scroll-y class="ordered-list">
+					<view v-if="orderLoading" class="ordered-empty">加载中...</view>
+					<view v-else-if="orderedList.length === 0" class="ordered-empty">
+						<view class="ordered-empty-title">暂未加菜</view>
+						<view class="ordered-empty-sub">从左侧选择菜品后会显示在这里</view>
+					</view>
+					<view v-else>
+						<view class="ordered-head">
+							<text>菜品</text>
+							<text>单价</text>
+							<text>总价</text>
+							<text>数量</text>
+						</view>
+						<view v-for="item in orderedList" :key="item.dishId" class="ordered-item">
+							<view class="ordered-dish">
+								<view class="ordered-dish-name">{{ item.dishName }}</view>
+							</view>
+							<view class="ordered-price">¥{{ formatMoney(item.salePrice) }}</view>
+							<view class="ordered-total">¥{{ formatMoney(itemTotal(item)) }}</view>
+							<view class="ordered-qty">
+								<button class="qty-btn" @click="reduceDish(item)">-</button>
+								<text>{{ item.quantity }}</text>
+								<button class="qty-btn" @click="increaseOrderedDish(item)">+</button>
+							</view>
+						</view>
+					</view>
+				</scroll-view>
+				<view class="ordered-footer">
+					<view class="ordered-summary">
+						<text>共 {{ orderedList.length }} 项 ,本次加菜金额</text>
+						<strong>¥{{ formatMoney(orderTotal) }}</strong>
+					</view>
+					<button class="footer-btn primary" :disabled="submitting" @click="confirmSubmitOrder">下单</button>
+				</view>
+			</view>
+		</view>
+	</view>
+</template>
+
+<script>
+import DishOrderService from '@/api/psi/DishOrderService'
+import OSSSerivce from '@/api/sys/OSSService'
+
+export default {
+	data() {
+		return {
+			roomId: '',
+			orderId: '',
+			currentRoom: {},
+			currentOrder: null,
+			categoryList: [],
+			activeTypeId: 'all',
+			dishSearchName: '',
+			dishList: [],
+			orderedList: [],
+			existDishSortMap: {},
+			maxDishSort: 0,
+			dishLoading: false,
+			orderLoading: false,
+			submitting: false,
+			dishOrderService: null,
+			ossService: null
+		}
+	},
+	computed: {
+		orderTotal() {
+			return this.orderedList.reduce((total, item) => total + this.itemTotal(item), 0)
+		},
+		orderQuantity() {
+			return this.orderedList.reduce((total, item) => total + Number(item.quantity || 0), 0)
+		},
+		submitDetailList() {
+			let appendIndex = 0
+			return this.orderedList.map((item) => {
+				let dishSort = this.existDishSortMap[item.dishId]
+				if (!dishSort) {
+					appendIndex += 1
+					dishSort = this.maxDishSort + appendIndex
+				}
+				return {
+					dishId: item.dishId,
+					dishName: item.dishName,
+					quantity: item.quantity,
+					dishSort
+				}
+			})
+		}
+	},
+	onLoad(option) {
+		this.roomId = option && option.roomId ? option.roomId : ''
+		this.orderId = option && option.orderId ? option.orderId : ''
+		uni.setNavigationBarTitle({ title: '加菜' })
+		this.dishOrderService = new DishOrderService()
+		this.ossService = new OSSSerivce()
+		this.initPage()
+	},
+	methods: {
+		initPage() {
+			if (!this.roomId) {
+				this.backOrderDetail()
+				return
+			}
+			this.orderedList = []
+			this.activeTypeId = 'all'
+			this.dishSearchName = ''
+			this.loadRoom(this.roomId)
+			this.loadCurrentOrder(this.roomId)
+			this.loadCategoryList()
+			this.loadDishList()
+		},
+		loadRoom(roomId) {
+			this.dishOrderService.findRoomById(roomId).then((data) => {
+				this.currentRoom = data || {}
+			})
+		},
+		loadCurrentOrder(roomId) {
+			this.orderLoading = true
+			this.dishOrderService.currentOrder(roomId).then((data) => {
+				this.currentOrder = data || null
+				if (!this.currentOrder || !this.currentOrder.id) {
+					uni.showToast({ title: '当前包房暂无未结账订单,请先下单', icon: 'none' })
+					this.backOrderDetail()
+					return
+				}
+				this.buildDishSortMap(this.currentOrder.detailList || [])
+			}).finally(() => {
+				this.orderLoading = false
+			})
+		},
+		buildDishSortMap(detailList) {
+			this.existDishSortMap = {}
+			this.maxDishSort = 0
+			detailList.forEach((item) => {
+				const sort = Number(item.dishSort || 0)
+				if (item.dishId && sort > 0) {
+					this.existDishSortMap[item.dishId] = sort
+				}
+				if (sort > this.maxDishSort) {
+					this.maxDishSort = sort
+				}
+			})
+		},
+		loadCategoryList() {
+			this.dishOrderService.typeList().then((data) => {
+				this.categoryList = [
+					{ id: 'all', name: '所有菜品' },
+					...(Array.isArray(data) ? data.map(item => ({ id: item.id, name: item.name })) : [])
+				]
+			})
+		},
+		changeType(item) {
+			this.activeTypeId = item.id
+			this.dishSearchName = ''
+			this.loadDishList()
+		},
+		searchDish() {
+			this.activeTypeId = 'all'
+			this.loadDishList()
+		},
+		loadDishList() {
+			this.dishLoading = true
+			this.dishOrderService.dishList({
+				typeId: this.activeTypeId === 'all' ? '' : this.activeTypeId,
+				dishName: this.dishSearchName
+			}).then((data) => {
+				this.dishList = Array.isArray(data) ? data : []
+				this.loadDishImagePreview()
+			}).finally(() => {
+				this.dishLoading = false
+			})
+		},
+		addDish(dish) {
+			const row = this.orderedList.find(item => item.dishId === dish.id)
+			if (row) {
+				row.quantity += 1
+				return
+			}
+			this.orderedList.push(this.toOrderedItem(dish, 1))
+		},
+		increaseOrderedDish(item) {
+			item.quantity += 1
+		},
+		reduceDish(item) {
+			if (item.quantity <= 1) {
+				this.orderedList = this.orderedList.filter(row => row.dishId !== item.dishId)
+				return
+			}
+			item.quantity -= 1
+		},
+		confirmSubmitOrder() {
+			if (this.orderedList.length === 0) {
+				uni.showToast({ title: '请先选择菜品', icon: 'none' })
+				return
+			}
+			uni.showModal({
+				title: '提示',
+				content: '是否确认下单?',
+				success: (res) => {
+					if (res.confirm) {
+						this.submitOrder()
+					}
+				}
+			})
+		},
+		submitOrder() {
+			this.submitting = true
+			this.dishOrderService.submit({
+				id: this.currentOrder ? this.currentOrder.id : this.orderId,
+				roomId: this.roomId,
+				settleFlag: '0',
+				detailList: this.submitDetailList
+			}).then((data) => {
+				uni.showToast({ title: data || '下单成功', icon: 'none' })
+				this.backOrderDetail()
+			}).finally(() => {
+				this.submitting = false
+			})
+		},
+		toOrderedItem(item, quantity) {
+			return {
+				dishId: item.dishId || item.id,
+				dishName: item.dishName,
+				salePrice: Number(item.salePrice || 0),
+				quantity
+			}
+		},
+		itemTotal(item) {
+			return Number(item.salePrice || 0) * Number(item.quantity || 0)
+		},
+		loadDishImagePreview() {
+			this.dishList.forEach((row) => {
+				const urls = this.getImageUrls(row.imageUrl)
+				if (urls.length === 0) {
+					this.$set ? this.$set(row, 'previewImageUrl', '') : row.previewImageUrl = ''
+					this.$set ? this.$set(row, 'previewImageList', []) : row.previewImageList = []
+					return
+				}
+				this.$set ? this.$set(row, 'previewImageUrl', urls[0]) : row.previewImageUrl = urls[0]
+				this.$set ? this.$set(row, 'previewImageList', urls) : row.previewImageList = urls
+				Promise.all(urls.map(url => this.getPreviewUrl(url))).then((list) => {
+					row.previewImageUrl = list[0]
+					row.previewImageList = list
+				})
+			})
+		},
+		getImageUrls(value) {
+			if (!value) {
+				return []
+			}
+			return value.split(',').map(item => item.trim()).filter(item => item)
+		},
+		getPreviewUrl(url) {
+			if (!url) {
+				return Promise.resolve('')
+			}
+			if (url.indexOf('http') === 0) {
+				return Promise.resolve(url)
+			}
+			return this.ossService.getTemporaryUrl(url).catch(() => url)
+		},
+		formatMoney(value) {
+			return Number(value || 0).toFixed(2)
+		},
+		backOrderDetail() {
+			uni.navigateBack({
+				fail: () => {
+					uni.redirectTo({
+						url: `/pages/psiManagement/dishManage/DishOrderDetail?roomId=${this.roomId}`
+					})
+				}
+			})
+		}
+	}
+}
+</script>
+
+<style scoped>
+.dish-order-add {
+	height: calc(100vh - var(--window-top, 0px));
+	box-sizing: border-box;
+	display: flex;
+	flex-direction: column;
+	overflow: hidden;
+	padding: 20rpx;
+	background: #f5f6fa;
+}
+
+.order-header {
+	height: 92rpx;
+	display: flex;
+	align-items: center;
+	justify-content: space-between;
+	padding: 0 8rpx 18rpx;
+	box-sizing: border-box;
+	border-bottom: 1rpx solid #ebeef5;
+}
+
+.room-name {
+	font-size: 34rpx;
+	font-weight: 700;
+	color: #303133;
+	line-height: 44rpx;
+}
+
+.room-no {
+	font-size: 24rpx;
+	color: #909399;
+	line-height: 34rpx;
+}
+
+.mini-btn,
+.plain-btn,
+.footer-btn {
+	margin: 0;
+	padding: 0;
+	border-radius: 8rpx;
+	font-size: 26rpx;
+}
+
+.mini-btn {
+	width: 160rpx;
+	height: 64rpx;
+	line-height: 64rpx;
+	color: #fff;
+}
+
+.primary,
+.footer-btn.primary {
+	color: #fff;
+	background: #2979ff;
+}
+
+.order-main {
+	flex: 1;
+	min-height: 0;
+	display: grid;
+	grid-template-columns: minmax(0, 1fr) 600rpx;
+	gap: 18rpx;
+	padding-top: 18rpx;
+}
+
+.dish-panel,
+.ordered-panel {
+	min-height: 0;
+	display: flex;
+	flex-direction: column;
+	border: 1rpx solid #ebeef5;
+	border-radius: 10rpx;
+	background: #fff;
+	overflow: hidden;
+}
+
+.dish-search {
+	display: grid;
+	grid-template-columns: minmax(0, 1fr) 120rpx;
+	gap: 12rpx;
+	padding: 16rpx;
+	border-bottom: 1rpx solid #ebeef5;
+}
+
+.search-input {
+	height: 64rpx;
+	box-sizing: border-box;
+	padding: 0 18rpx;
+	border: 1rpx solid #dcdfe6;
+	border-radius: 8rpx;
+	font-size: 26rpx;
+}
+
+.search-btn {
+	height: 64rpx;
+	margin: 0;
+	padding: 0;
+	border-radius: 8rpx;
+	font-size: 26rpx;
+	line-height: 64rpx;
+	color: #fff;
+	background: #2979ff;
+}
+
+.dish-content {
+	flex: 1;
+	min-height: 0;
+	display: grid;
+	grid-template-columns: 150rpx minmax(0, 1fr);
+}
+
+.category-list {
+	height: 100%;
+	background: #f7f9fb;
+	border-right: 1rpx solid #ebeef5;
+}
+
+.category-item {
+	min-height: 78rpx;
+	display: flex;
+	align-items: center;
+	box-sizing: border-box;
+	padding: 0 16rpx;
+	border-left: 5rpx solid transparent;
+	font-size: 26rpx;
+	color: #606266;
+}
+
+.category-item.active {
+	color: #2979ff;
+	background: #fff;
+	border-left-color: #2979ff;
+	font-weight: 700;
+}
+
+.dish-list {
+	height: 100%;
+	box-sizing: border-box;
+	padding: 16rpx;
+}
+
+.dish-grid {
+	display: grid;
+	grid-template-columns: repeat(4, minmax(0, 1fr));
+	gap: 16rpx;
+}
+
+.dish-card {
+	min-width: 0;
+	border: 1rpx solid #ebeef5;
+	border-radius: 10rpx;
+	overflow: hidden;
+	background: #fff;
+}
+
+.dish-image {
+	width: 100%;
+	height: 150rpx;
+	background: #f2f3f5;
+}
+
+.dish-image-empty {
+	display: flex;
+	align-items: center;
+	justify-content: center;
+	font-size: 24rpx;
+	color: #909399;
+}
+
+.dish-info {
+	padding: 12rpx;
+}
+
+.dish-name,
+.ordered-dish-name {
+	overflow: hidden;
+	white-space: nowrap;
+	text-overflow: ellipsis;
+}
+
+.dish-name {
+	font-size: 28rpx;
+	font-weight: 700;
+	color: #303133;
+	line-height: 38rpx;
+}
+
+.dish-desc {
+	height: 42rpx;
+	margin-top: 8rpx;
+	font-size: 24rpx;
+	color: #606266;
+	line-height: 32rpx;
+	overflow: hidden;
+}
+
+.dish-bottom {
+	display: flex;
+	align-items: center;
+	justify-content: space-between;
+	gap: 10rpx;
+	margin-top: 12rpx;
+}
+
+.dish-price,
+.ordered-total {
+	color: #fa3534;
+}
+
+.dish-price {
+	font-size: 30rpx;
+	font-weight: 700;
+}
+
+.plain-btn {
+	width: 96rpx;
+	height: 54rpx;
+	line-height: 54rpx;
+	color: #2979ff;
+	background: #ecf5ff;
+}
+
+.ordered-title {
+	height: 76rpx;
+	display: flex;
+	align-items: center;
+	box-sizing: border-box;
+	padding: 0 18rpx;
+	border-bottom: 1rpx solid #ebeef5;
+	font-size: 30rpx;
+	font-weight: 700;
+	color: #303133;
+}
+
+.ordered-list {
+	flex: 1;
+	min-height: 0;
+	box-sizing: border-box;
+	padding: 14rpx;
+}
+
+.ordered-head,
+.ordered-item {
+	display: grid;
+	grid-template-columns: minmax(0, 1.2fr) 84rpx 96rpx 132rpx;
+	gap: 10rpx;
+	align-items: center;
+}
+
+.ordered-head {
+	height: 50rpx;
+	padding: 0 10rpx;
+	border-radius: 8rpx;
+	background: #f7f9fb;
+	font-size: 24rpx;
+	color: #909399;
+}
+
+.ordered-item {
+	min-height: 86rpx;
+	box-sizing: border-box;
+	padding: 12rpx 10rpx;
+	border-bottom: 1rpx solid #ebeef5;
+	font-size: 24rpx;
+	color: #606266;
+}
+
+.ordered-dish-name {
+	font-size: 26rpx;
+	font-weight: 700;
+	color: #303133;
+}
+
+.ordered-total {
+	font-weight: 700;
+}
+
+.ordered-qty {
+	display: flex;
+	align-items: center;
+	justify-content: flex-end;
+	gap: 8rpx;
+}
+
+.qty-btn {
+	width: 42rpx;
+	height: 42rpx;
+	margin: 0;
+	padding: 0;
+	border-radius: 50%;
+	font-size: 28rpx;
+	line-height: 42rpx;
+	color: #2979ff;
+	background: #ecf5ff;
+}
+
+.ordered-footer {
+	padding: 16rpx;
+	border-top: 1rpx solid #ebeef5;
+}
+
+.ordered-summary {
+	display: flex;
+	align-items: center;
+	justify-content: space-between;
+	margin-bottom: 14rpx;
+	font-size: 26rpx;
+	color: #606266;
+}
+
+.ordered-summary strong {
+	font-size: 36rpx;
+	color: #fa3534;
+}
+
+.footer-btn {
+	width: 100%;
+	height: 72rpx;
+	line-height: 72rpx;
+}
+
+.ordered-empty,
+.empty-box {
+	min-height: 240rpx;
+	display: flex;
+	flex-direction: column;
+	align-items: center;
+	justify-content: center;
+	color: #909399;
+	font-size: 26rpx;
+}
+
+.ordered-empty-title {
+	font-size: 30rpx;
+	color: #606266;
+}
+
+.ordered-empty-sub {
+	margin-top: 8rpx;
+	font-size: 24rpx;
+}
+</style>

+ 13 - 3
pages/psiManagement/dishManage/DishOrderApproval.vue

@@ -73,7 +73,10 @@
 						<view class="dish-qty">x {{ getDisplayQuantity(item) }}</view>
 					</view>
 					<view v-if="item.createTime && activeTab !== 'actual'" class="dish-time">
-						{{ activeTab === 'add' ? '加菜时间' : '减菜时间' }}:{{ item.createTime }}
+						{{ activeTab === 'add' ? '加菜时间' : '退菜时间' }}:{{ item.createTime }}
+					</view>
+					<view v-if="activeTab === 'reduce' && item.reason" class="dish-reason">
+						退菜原因:{{ item.reason }}
 					</view>
 				</view>
 			</view>
@@ -119,7 +122,7 @@ export default {
 			return [
 				{ name: 'actual', label: '实际菜单', count: this.getList(order.detailList).length },
 				{ name: 'add', label: '加菜', count: this.getList(order.addDishList).length },
-				{ name: 'reduce', label: '菜', count: this.getList(order.reduceDishList).length }
+				{ name: 'reduce', label: '退菜', count: this.getList(order.reduceDishList).length }
 			]
 		},
 		currentDetailList() {
@@ -480,7 +483,8 @@ export default {
 
 .dish-price,
 .dish-qty,
-.dish-time {
+.dish-time,
+.dish-reason {
 	font-size: 26rpx;
 	color: #606266;
 }
@@ -499,4 +503,10 @@ export default {
 	line-height: 36rpx;
 	color: #909399;
 }
+
+.dish-reason {
+	margin-top: 10rpx;
+	line-height: 38rpx;
+	word-break: break-all;
+}
 </style>

Failā izmaiņas netiks attēlotas, jo tās ir par lielu
+ 1380 - 0
pages/psiManagement/dishManage/DishOrderDetail.vue


+ 32 - 5
pages/workbench/workbench.vue

@@ -70,7 +70,11 @@
 <script>
 import userService from "@/api/sys/userService"
 import moment from 'moment'
-import { mapState, mapMutations, mapActions } from 'vuex'
+import {
+	mapState,
+	mapMutations,
+	mapActions
+} from 'vuex'
 import actCategoryService from "@/api/flowable/actCategoryService"
 import processService from "@/api/flowable/processService"
 import taskService from "@/api/flowable/taskService"
@@ -123,7 +127,11 @@ export default {
 	async mounted() {
 
 		let res = await actCategoryService.treeData()
-		let data = await processService.list({ current: 1, size: -1, type: 'ydd' })
+		let data = await processService.list({
+			current: 1,
+			size: -1,
+			type: 'ydd'
+		})
 		this.processMap = new Map()
 
 		let list = data.records
@@ -149,6 +157,11 @@ export default {
 						name: "入库记录",
 						notFlowable: true
 					})
+					jjtTest.push({
+						name: "点菜模块",
+						notFlowable: true
+					})
+
 					// this.processMap.set('物资管理', [item])
 				}
 				if (item.name === '物资管理-领用申请') {
@@ -291,6 +304,11 @@ export default {
 							url: '/pages/psiManagement/wareHouse/WareHouseList'
 						})
 						break;
+					case "点菜模块":
+						uni.navigateTo({
+							url: '/pages/psiManagement/dishManage/DishOrder'
+						})
+						break;
 				}
 			} else {
 				// 读取流程表单
@@ -299,8 +317,17 @@ export default {
 					status: 'start'
 				}).then((data) => {
 					console.log('data', data)
-					let processTitle = `${this.username} 在 ${moment(new Date()).format('YYYY-MM-DD HH:mm')} 发起了 [${row.name}]`
-					let query = { procDefId: row.id, procDefKey: row.key, status: 'start', title: `发起流程【${row.name}】`, formType: data.formType, formUrl: data.formUrl, formTitle: processTitle }
+					let processTitle =
+						`${this.username} 在 ${moment(new Date()).format('YYYY-MM-DD HH:mm')} 发起了 [${row.name}]`
+					let query = {
+						procDefId: row.id,
+						procDefKey: row.key,
+						status: 'start',
+						title: `发起流程【${row.name}】`,
+						formType: data.formType,
+						formUrl: data.formUrl,
+						formTitle: processTitle
+					}
 					uni.navigateTo({
 						url: '/pages/workbench/task/TaskForm?flow=' + JSON.stringify(query)
 					})
@@ -378,4 +405,4 @@ export default {
 	font-weight: 500;
 	color: #3a3a3a;
 }
-</style>
+</style>