上传代码

This commit is contained in:
2025-08-18 10:01:04 +08:00
commit d0be991e07
2614 changed files with 1130442 additions and 0 deletions

View File

@ -0,0 +1,217 @@
<template>
<view class="page-container">
<view style="width:750rpx; height:800rpx">
<picker mode="selector" :range="years" @change="onChangeYear">
<view class="year-selector">选择年份: {{ selectedYear }}</view>
</picker>
<l-echart ref="chartRef" @finished="fetchDataAndInit" class="charts"></l-echart>
</view>
</view>
</template>
<script>
import * as echarts from 'echarts';
import { apiImageUrl } from '../../API/api';
export default {
data() {
return {
selectedYear: new Date().getFullYear(),
years: [],
option: {
tooltip: {
trigger: 'axis',
axisPointer: {
type: 'shadow'
},
confine: true
},
legend: {
data: ['收款', '退款']
},
grid: {
left: 20,
right: 20,
bottom: 15,
top: 40,
containLabel: true
},
xAxis: [
{
type: 'value',
axisLine: {
lineStyle: {
color: '#999999'
}
},
axisLabel: {
color: '#666666'
}
}
],
yAxis: [
{
type: 'category',
axisTick: { show: false },
data: ['1月', '2月', '3月', '4月', '5月', '6月', '7月', '8月', '9月', '10月', '11月', '12月'],
axisLine: {
lineStyle: {
color: '#999999'
}
},
axisLabel: {
color: '#666666'
}
}
],
series: [
{
name: '收款',
type: 'bar',
stack: '总量',
label: {
normal: {
show: true
}
},
data: []
},
{
name: '退款',
type: 'bar',
stack: '总量',
label: {
normal: {
show: true,
position: 'left'
}
},
data: []
}
]
}
};
},
created() {
this.initYears();
},
methods: {
initYears() {
const currentYear = new Date().getFullYear();
for (let year = currentYear - 5; year <= currentYear; year++) {
this.years.push(year);
}
},
onChangeYear(e) {
this.selectedYear = this.years[e.detail.value];
this.fetchDataAndInit();
},
async fetchDataAndInit() {
try {
const [incomeData, refundData] = await Promise.all([
this.getMonthlyRevenue(this.selectedYear, 1),
this.getMonthlyRevenue(this.selectedYear, 2)
]);
console.log('Fetched monthly income:', incomeData);
console.log('Fetched monthly refunds:', refundData);
this.option.series[0].data = incomeData.map(Number);
this.option.series[1].data = refundData.map(revenue => -Math.abs(Number(revenue)));
this.initChart();
} catch (error) {
console.error('Error fetching monthly revenue:', error);
}
},
async getMonthlyRevenue(year, state) {
let revenues = [];
for (let month = 0; month < 12; month++) {
const startDate = new Date(year, month, 1).toISOString().split('T')[0];
const endDate = new Date(year, month + 1, 0).toISOString().split('T')[0];
try {
const response = await uni.request({
url: `${apiImageUrl}/api/orders/count/money`,
method: 'POST',
header: {
'cookie': uni.getStorageSync("cookie")
},
data: {
businessId: uni.getStorageSync("businessId"),
businessName: uni.getStorageSync("businessName"),
businessState: 0,
categoryId: 1,
endTime: endDate,
startTime: startDate,
state: state,
type: "1"
}
});
if (response[1].data && response[1].data.data !== undefined) {
const revenue = parseFloat(response[1].data.data);
revenues.push(isNaN(revenue) ? 0 : revenue);
} else {
revenues.push(0);
}
} catch (error) {
console.error(`Error fetching revenue for ${month + 1}月 with state ${state}:`, error);
revenues.push(0);
}
}
return revenues;
},
async initChart() {
const chart = await this.$refs.chartRef.init(echarts);
chart.setOption(this.option);
}
}
};
</script>
<style scoped>
.page-container {
background-color: #2237bf;
width: 100%;
height: 100vh;
padding: 20rpx;
box-sizing: border-box;
}
.year-selector {
width: 220px;
height: 30px;
margin: 0 auto;
margin-bottom: 15px;
text-align: center;
line-height: 30px;
background-color:rgba(245, 245, 220, 0.6);
border-radius: 20px;
box-shadow: 0 4px 6px rgba(0, 0, 0, 0.1), 0 1px 3px rgba(0, 0, 0, 0.08);
font-size: 14px;
color: #333;
cursor: pointer;
transition: all 0.2s ease-in-out;
&:hover,
&:active {
background-color: rgba(245, 245, 220, 0.8);
box-shadow: 0 6px 8px rgba(0, 0, 0, 0.15), 0 2px 4px rgba(0, 0, 0, 0.1);
}
}
.charts {
background-color: #fff;
width: 90%;
margin: 0 auto;
border: 1px solid #000;
border-radius: 15px;
}
</style>

View File

@ -0,0 +1,198 @@
<template>
<view>
<view class="navbar">
<view class="search">
<text class="icon-search">
<input type="text" v-model="announcement" placeholder="请输入内容" class="transparent-input"/>
</text>
</view>
<button @click="submitForm" class="search-button">提交</button>
</view>
<view class="contentList">
<view class="contentListItem" v-for="(item, index) in contentList" :key="item.id" @click.stop="deleteItem(item)">
<view class="contentDetail">{{ item.content }}</view>
<view class="contentTime">{{ formatDate(item.createTime) }}</view>
</view>
</view>
</view>
</template>
<script>
export default {
data() {
return {
announcement: '',
contentList: []
};
},
methods: {
async submitForm() {
if (!this.announcement.trim()) {
uni.showToast({ title: '内容不能为空,请输入内容', icon: 'none', duration: 2000 });
return;
}
try {
const res = await uni.request({
url: `${this.apiImageUrl}/api/businessInfo/add`,
method: 'POST',
data: { content: this.announcement },
header: {
'cookie': uni.getStorageSync("cookie"),
'Content-Type': 'application/json'
}
});
console.log('提交成功:', res);
this.announcement = '';
uni.showToast({ title: '发布成功', icon: 'success', duration: 2000 });
await this.loadContentList();
} catch (err) {
console.error('提交失败:', err);
uni.showToast({ title: '发布失败', icon: 'error', duration: 2000 });
}
},
async loadContentList() {
try {
const response = await uni.request({
url: `${this.apiImageUrl}/api/businessInfo/list/my`,
method: 'POST',
header: {
'cookie': uni.getStorageSync("cookie"),
'Content-Type': 'application/json'
}
});
this.contentList = response[1].data.data || [];
console.log(this.contentList);
} catch (err) {
console.log(err);
}
},
async deleteItem(item) {
try {
const contentId = item.id;
console.log(`尝试删除ID为${contentId}的内容`);
const deleteRes = await uni.request({
url: `${this.apiImageUrl}/api/businessInfo/delete`,
method: 'POST',
data: { id: contentId },
header: {
'cookie': uni.getStorageSync("cookie"),
'Content-Type': 'application/json'
}
});
console.log('删除成功:', deleteRes);
this.contentList = this.contentList.filter(i => i.id !== contentId);
uni.showToast({ title: '删除成功', icon: 'success', duration: 2000 });
} catch (err) {
console.error('删除失败:', err);
uni.showToast({ title: '删除失败', icon: 'error', duration: 2000 });
}
},
formatDate(dateStr) {
const date = new Date(dateStr);
const year = date.getFullYear();
const month = String(date.getMonth() + 1).padStart(2, '0');
const day = String(date.getDate()).padStart(2, '0');
return `${year}-${month}-${day}`;
}
},
computed: {
apiImageUrl() {
return process.env.VUE_APP_API_IMAGE_URL || 'https://xiaokuaisong.shop:6448';
}
},
mounted() {
this.loadContentList();
}
};
</script>
<style scoped lang="scss">
.contentList {
width: 90%;
margin: 0 auto;
}
.contentListItem {
display: flex;
align-items: center;
justify-content: space-between;
padding: 10px;
border-bottom: 1px solid #ccc;
background-color: #fff;
}
.contentDetail {
width: 65%;
height: inherit;
flex-grow: 1;
font-size: 14px;
color: #333;
padding-right: 10px;
}
.contentTime {
width: 25%;
height: inherit;
margin-right: auto;
font-size: 12px;
color: #666;
padding: 5px;
}
.navbar {
background-color: #4095e5;
display: flex;
flex-direction: row;
padding: 10px;
.search {
display: flex;
align-items: center;
padding: 0 10rpx 0 26rpx;
height: 50rpx;
color: #fff;
font-size: 28rpx;
border-radius: 32rpx;
background-color: rgba(255, 255, 255, 0.5);
width: 70%;
margin: 0 auto;
}
.icon-search {
margin-right: 10rpx;
}
.search-button {
margin-left: auto;
height: 50rpx;
background-color: #fff;
color: #4095e5;
border: none;
border-radius: 32rpx;
padding: 0 20rpx;
line-height: 50rpx;
font-size: 15px;
}
.transparent-input {
background-color: transparent;
border: none;
color: #fff;
outline: none;
width: 100%;
padding: 0 10rpx;
font-size: 28rpx;
}
}
</style>

View File

@ -0,0 +1,365 @@
<template>
<view class="content">
<button class="btn" type="primary" :loading="isSearching" @tap="startSearch">开始搜索 </button>
<button class="btn" type="warn" @tap="stopSearch">停止搜索</button>
<view v-for="(item) in list" :data-title="item.deviceId" :data-name="item.name" :data-advertisData="item.advertisServiceUUIDs"
:key="item.deviceId" @tap="bindViewTap">
<view class="item">
<view class="deviceId block">{{item.deviceId}}</view>
<view class="name block">{{item.name}}</view>
</view>
</view>
</view>
</template>
<script>
import {
mapState
} from 'vuex';
export default {
data() {
return {
isSearching: false,
list: [],
services: [],
serviceId: 0,
writeCharacter: false,
readCharacter: false,
notifyCharacter: false
};
},
computed: mapState(['sysinfo', 'Bluetooth']),
onLoad() {
// console.log(this.Bluetooth)
},
onUnload() {
if (this.isSearching) {
uni.stopBluetoothDevicesDiscovery();
}
},
methods: {
errorCodeTip(code) {
if (code == 0) {
} else if (code == 10000) {
uni.showToast({
title: '未初始化蓝牙适配器',
icon: 'none'
})
} else if (code == 10001) {
uni.showToast({
title: '当前蓝牙适配器不可用',
icon: 'none'
})
} else if (code == 10002) {
uni.showToast({
title: '没有找到指定设备',
icon: 'none'
})
} else if (code == 10003) {
uni.showToast({
title: '连接失败',
icon: 'none'
})
} else if (code == 10004) {
uni.showToast({
title: '没有找到指定服务',
icon: 'none'
})
} else if (code == 10005) {
uni.showToast({
title: '没有找到指定特征值',
icon: 'none'
})
} else if (code == 10006) {
uni.showToast({
title: '当前连接已断开',
icon: 'none'
})
} else if (code == 10007) {
uni.showToast({
title: '当前特征值不支持此操作',
icon: 'none'
})
} else if (code == 10008) {
uni.showToast({
title: '其余所有系统上报的异常',
icon: 'none'
})
} else if (code == 10009) {
uni.showToast({
title: 'Android 系统特有,系统版本低于 4.3 不支持 BLE',
icon: 'none'
})
}
},
startSearch() {
let that = this
uni.openBluetoothAdapter({
success(res) {
uni.getBluetoothAdapterState({
success(res2) {
console.log('getBluetoothAdapterState:', res2)
if (res2.available) {
that.isSearching = true;
if (res2.discovering) {
uni.showToast({
title: '正在搜索附近打印机设备',
icon: "none"
})
return;
}
that.getBluetoothDevices()
} else {
uni.showModal({
title: '提示',
content: '本机蓝牙不可用',
})
}
}
});
},
fail() {
uni.showModal({
title: '提示',
content: '蓝牙初始化失败,请打开蓝牙',
})
}
})
},
stopSearch() {
uni.stopBluetoothDevicesDiscovery({
success: (res) => {
this.isSearching = false;
console.log('stop:', res)
},
fail: (e) => {
console.log('stop:', e)
this.errorCodeTip(e.errCode);
}
})
},
checkPemission() {
let that = this
let {
BLEInformation
} = that.Bluetooth;
let platform = BLEInformation.platform;
that.getBluetoothDevices();
},
getBluetoothDevices() {
let that = this
that.list = [];
uni.startBluetoothDevicesDiscovery({
success(res) {
plus.bluetooth.onBluetoothDeviceFound((result) => {
console.log('onBluetoothDeviceFound:', result)
let arr = that.list;
let devices = [];
let list = result.devices;
for (let i = 0; i < list.length; ++i) {
if (list[i].name && list[i].name != "未知设备") {
let arrNew = arr.filter((item) => {
return item.deviceId == list[i].deviceId;
});
if (arrNew.length == 0) {
devices.push(list[i]);
}
}
}
that.list = arr.concat(devices);
});
that.time = setTimeout(() => {
plus.bluetooth.getBluetoothDevices({
success(res2) {
let devices = [];
let list = res2.devices;
for (let i = 0; i < list.length; ++i) {
if (list[i].name && list[i].name != "未知设备") {
devices.push(list[i]);
}
}
that.list = devices;
console.log('getBluetoothDevices:',res2);
},
})
clearTimeout(that.time);
}, 3000);
}
});
},
bindViewTap(e) {
let that = this;
let {
title
} = e.currentTarget.dataset;
let {
BLEInformation
} = that.Bluetooth;
this.stopSearch();
that.serviceId = 0;
that.writeCharacter = false;
that.readCharacter = false;
that.notifyCharacter = false;
uni.showLoading({
title: '正在连接',
})
console.log('deviceId:', title)
plus.bluetooth.createBLEConnection({
deviceId: title,
success(res) {
console.log('createBLEConnection success:', res)
BLEInformation.deviceId = title;
that.$store.commit('BLEInformationSet', BLEInformation);
uni.hideLoading()
that.getSeviceId()
},
fail(e) {
that.errorCodeTip(e.errCode);
uni.hideLoading()
}
})
},
getSeviceId() {
let that = this;
let {
BLEInformation
} = that.Bluetooth;
console.log('BLEInformation.deviceId:',BLEInformation.deviceId)
let t=setTimeout(()=>{
plus.bluetooth.getBLEDeviceServices({
deviceId: BLEInformation.deviceId,
success(res) {
console.log('getBLEDeviceServices success:',res)
that.services = res.services;
that.getCharacteristics()
},
fail: function(e) {
that.errorCodeTip(e.code);
console.log('getBLEDeviceServices fail:',e)
}
})
clearTimeout(t);
},1500)
},
getCharacteristics() {
var that = this
let {
services: list,
serviceId: num,
writeCharacter: write,
readCharacter: read,
notifyCharacter: notify
} = that;
let {
BLEInformation
} = that.Bluetooth;
plus.bluetooth.getBLEDeviceCharacteristics({
deviceId: BLEInformation.deviceId,
serviceId: list[num].uuid,
success(res) {
for (var i = 0; i < res.characteristics.length; ++i) {
var properties = res.characteristics[i].properties
var item = res.characteristics[i].uuid
if (!notify) {
if (properties.notify) {
BLEInformation.notifyCharaterId = item;
BLEInformation.notifyServiceId = list[num].uuid;
that.$store.commit('BLEInformationSet', BLEInformation);
notify = true
}
}
if (!write) {
if (properties.write) {
BLEInformation.writeCharaterId = item;
BLEInformation.writeServiceId = list[num].uuid;
that.$store.commit('BLEInformationSet', BLEInformation);
write = true
}
}
if (!read) {
if (properties.read) {
BLEInformation.readCharaterId = item;
BLEInformation.readServiceId = list[num].uuid;
that.$store.commit('BLEInformationSet', BLEInformation);
read = true
}
}
}
if (!write || !notify || !read) {
num++
that.writeCharacter = write;
that.readCharacter = read;
that.notifyCharacter = notify;
that.serviceId = num;
if (num == list.length) {
uni.showModal({
title: '提示',
content: '找不到该读写的特征值',
})
} else {
that.getCharacteristics()
}
} else {
that.openControl()
}
},
fail: function(e) {
console.log("getBLEDeviceCharacteristics fail",e);
that.errorCodeTip(e.errCode);
}
})
},
openControl: function() {
uni.navigateTo({
url: '/pages/sendCommand/sendCommand',
})
},
}
}
</script>
<style lang="less">
.btn {
margin-top: 50rpx;
height: 40px;
width: 600rpx;
line-height: 40px;
}
.item {
display: block;
font-family: Arial, Helvetica, sans-serif;
font-size: 14px;
margin: 0 30px;
margin-top: 10px;
background-color: #FFA850;
border-radius: 5px;
border-bottom: 2px solid #68BAEA;
}
.block {
display: block;
color: #ffffff;
padding: 5px;
}
</style>

View File

@ -0,0 +1,278 @@
<template>
<view class="container">
<view class="history-list">
<view class="history-item" v-for="(item, index) in historyList" :key="index">
<view class="history-info">
<image class="history-img" :src="item.imgUrl"></image>
<view class="nameTime">
<text class="history-title">{{ item.title }}</text>
<text class="time">{{ item.time.substr(0, 19).replace('T', ' ') }}</text>
</view>
<view class="star">
<text class="history-sale">{{ item.sale }}</text>
<uni-rate :readonly="true" :value="item.star" active-color="#13c2c2" :is-fill="false"
color="#13c2c2" :size="16"/>
</view>
</view>
<view class="extend">
<text @click="reviewUser(item)" class="messageDetail">{{ item.message }}</text>
<template v-if="item.businessReview && item.businessReview.trim() !== ''">
<view class="business-reply-container">
<text class="businessReviewTitle">商家回复</text>
<text class="businessReview">{{ item.businessReview }}</text>
</view>
</template>
</view>
</view>
</view>
</view>
</template>
<script>
import { onMounted } from "vue";
import {
apiImageUrl
} from '../../API/api';
export default {
name: 'HistoryList',
data() {
return {
historyList: []
};
},
onLoad() {
this.review();
},
mounted() {
this.review();
},
methods: {
review() {
uni.request({
url: `${apiImageUrl}/api/level/list/business`,
method: 'POST',
data:{
id:uni.getStorageSync("businessId")
},
header: {
'Content-Type': 'application/json',
'cookie': uni.getStorageSync("cookie") || ''
},
success: (res) => {
console.log(res);
console.log("成功");
this.historyList = res.data.data.map(item => ({
id: item.id,
businessId: item.businessId,
userId: item.userId,
orderId: item.orderId,
star: item.rating,
review: item.review,
businessReview: item.businessReview,
createTime: item.createTime,
imgUrl: 'https://tse2-mm.cn.bing.net/th/id/OIP-C.B32YODeRecLlETs7eOvyXwHaHa?pid=ImgDet&w=474&h=474&rs=1',
title: '大表哥',
sale: item.rating,
time: item.createTime,
message: item.review
}));
},
fail: () => {
console.log("失败");
}
});
},
reviewUser(item){
console.log(item.id);
const replyId=item.id
uni.showModal({
title: '请完成数据填写',
content: '',
editable:true,
placeholderText:'请输入回复信息',
confirmText: '确认',
cancelText: '取消',
success: (res) => {
if (res.confirm) {
console.log('输入的内容:', res.content);
const content=res.content
uni.request({
url:apiImageUrl+'/api/level/business/reply',
method:'POST',
header: {
'Content-Type': 'application/json',
'cookie': uni.getStorageSync("cookie") || ''
},
data:{
businessReview:content,
id:replyId
},
success(response) {
console.log("成功");
console.log(response);
onMounted(review())
},
fail(){
console.log("失败");
}
})
}
}
});
}
}
};
</script>
<style>
.container {
align-items: center;
padding: 20rpx;
}
.history-list {
width: 100%;
}
.history-item {
background-color: #fff;
border-radius: 10px;
box-shadow: 0 2px 5px rgba(0, 0, 0, 0.1);
padding: 15px;
margin-bottom: 20rpx;
}
.extend .business-reply-container {
background-color: #f4f4f4;
border-radius: 8px;
padding: 10px;
margin: 5px 0;
display: block;
color: #666;
font-size: 14px;
}
.extend .business-reply-container .businessReviewTitle {
color: #666;
font-size: 14px;
font-weight: normal;
margin-bottom: 5px;
display: block;
}
.extend .business-reply-container .businessReview {
display: block;
}
.messageDetail {
color: #000;
font-size: 14px;
}
.history-info {
display: flex;
flex-direction: row;
align-items: center;
}
.history-img {
width: 100rpx;
height: 100rpx;
border-radius: 50%;
margin-right: 10px;
}
.nameTime {
display: flex;
flex-direction: row;
align-items: flex-start;
margin-right: 10px;
}
.history-title,
.time {
margin: 0;
font-size: 12px;
margin-right: 10px;
}
.star {
display: flex;
flex-direction: column;
align-items: flex-end;
}
.history-sale {
font-size: 30rpx;
color: #000;
margin-top: 0;
margin-right: 5px;
}
.example-body {
padding: 10px;
}
.scroll-view {
/* #ifndef APP-NVUE */
width: 100%;
height: 100%;
/* #endif */
flex: 1
}
.scroll-view-box {
flex: 1;
position: absolute;
top: 0;
right: 0;
bottom: 0;
left: 0;
}
.info {
padding: 15px;
color: #666;
}
.info-text {
font-size: 14px;
color: #666;
}
.info-content {
padding: 5px 15px;
}
.card {
width: 100%;
height: 100px;
border-radius: 15px;
background-image: -webkit-linear-gradient(top, #fff, #B0D3F4);
}
.containerShow {
padding: 7px;
position: relative;
}
.img {
width: 60px;
height: 40px;
display: inline-block;
margin-top: 30px;
}
.imageItem {
width: 100%;
height: 100%;
border-radius: 15px;
margin: auto 0;
}
</style>

View File

@ -0,0 +1,565 @@
<template>
<view class="container">
<uni-pagination v-if="total > 0" :current="currentPage" :total="total" :pageSize="pageSize" @change="onPageChange"></uni-pagination>
<scroll-view scroll-y class="preview">
<!-- 商品详情 -->
<view class="tab-menu">
<view class="tab-item"
v-for="(tab, index) in tabs"
:key="index"
:class="{ active: currentIndex === index }"
@click="switchTab(index)">
{{ tab.name }}
</view>
</view>
<view class="content">
<block v-if="currentIndex === 0">
<view class="container1" v-for="(order, index) in orderList" :key="index">
<view class="box">
<view class="numberState">
<view class="number">#{{ order.id }}</view>
<view class="state">商家已自动接单</view>
</view>
<view class="time">下单时间:{{formatOrderTime(order.createTime)}}</view>
<view class="message">
<view class="name">{{order.userName}}</view>
<view class="phone">手机尾号{{ order.phone.slice(-4) }}</view>
</view>
<view class="button" @click="telephone(order)">电话联系</view>
<view class="sure" @click="dinner(index)">打印小票</view>
<!-- <button type='primary' @tap='receiptTest' :loading='isReceiptSend' :disabled='isReceiptSend'>票据测试</button> -->
<view class="sure" @click="refund(order)">确认退款</view>
<view class="sure" @click="finish(order)">确认出餐</view>
</view>
<view class="box2">
<view class="beizhu">
<view class="tag-view">
<uni-tag :mark="true" text="备注" type="warning" size="mini" />
</view>
顾客需要餐具
</view>
<view class="goods">1种商品共1件</view>
<view class="money">预计收入{{ order.totalPrice }}</view>
<uni-collapse-item title="订单详情" :show-animation="true">
<view v-for="(item, index) in order.orderDetailsVOList" :key="index" class="box3">
<text class="left3">{{ item.attributeNames || '未知菜品' }}</text>
<text class="right3">¥ {{ item.price }}</text>
</view>
</uni-collapse-item>
</view>
</view>
</block>
<block v-if="currentIndex === 1">
<view class="container1" v-for="(order, index) in refundOrderList" :key="index">
<view class="box">
<view class="numberState">
<view class="number">#{{ order.id }}</view>
<view class="state">订单已退款</view>
</view>
<view class="message">
<view class="name">{{order.userName}}</view>
<view class="phone">手机尾号{{ order.phone.slice(-4) }}</view>
</view>
<view class="sure" @click="refunddinner(index)">打印退款小票</view>
</view>
<view class="box2">
<view class="goods">1种商品共1件</view>
<view class="money">退款金额{{ order.totalPrice }}</view>
<uni-collapse-item title="订单详情" :show-animation="true">
<view v-for="(item, index) in order.orderDetailsVOList" :key="index" class="box3">
<text class="left3">{{ item.attributeNames || '未知菜品' }}</text>
<text class="right3">¥ {{ item.price }}</text>
</view>
</uni-collapse-item>
</view>
</view>
</block>
<block v-if="currentIndex === 2">
<!-- <view class="container1" v-for="(order, index) in orderList" :key="index">
<view class="box">
<view class="numberState">
<view class="number">#{{ order.id }}</view>
<view class="state">用户退款申请</view>
</view>
<view class="time">下单时间:{{formatOrderTime(order.createTime)}}</view>
<view class="message">
<view class="name">{{order.userName}}</view>
<view class="phone">手机尾号{{ order.phone.slice(-4) }}</view>
</view>
<view class="button" @click="telephone(order)">电话联系</view>
<view class="sure" @click="refund(order)">确认退款</view>
</view>
<view class="box2">
<view class="goods">1种商品共1件</view>
<view class="money">需退金额{{ order.totalPrice }}</view>
<uni-collapse-item title="订单详情" :show-animation="true">
<view v-for="(item, index) in order.orderDetailsVOList" :key="index" class="box3">
<text class="left3">{{ item.attributeNames || '未知菜品' }}</text>
<text class="right3">¥ {{ item.price }}</text>
</view>
</uni-collapse-item>
</view>
</view> -->
</block>
</view>
</scroll-view>
</view>
</template>
<script>
import { apiImageUrl } from '../../API/api';
export default {
data() {
return {
currentIndex: 0,
tabs: [
{ name: '待出餐' },
{ name: '已退款' },
{ name: '已完成' },
],
orderList: [],
refundOrderList: [],
currentPage: 1,
pageSize: 10,
total: 0,
};
},
onLoad() {
this.getLoginUser();
},
onShow() {
this.getLoginUser();
},
methods: {
getRefundReason(){
uni.request({
url:apiImageUrl+'/api/refund/list/business',
method:'POST',
header: {
'cookie': uni.getStorageSync("cookie")
},
success(res) {
console.log(res);
},
fail(err) {
console.log(err);
}
})
},
switchTab(index) {
this.currentIndex = index;
if (index === 0) {
this.getOrder();
} else if (index === 1) {
this.getRefundOrder();
}else if (index===2){
this.getRefundReason()
}
},
onPageChange(e) {
this.currentPage = e.current;
if (this.currentIndex === 0) {
this.getOrder();
} else if (this.currentIndex === 1) {
this.getRefundOrder();
}else if (this.currentIndex === 2) {
this.getRefundReason()
}
},
dinner(index) {
const currentOrder = this.orderList[index];
console.log('当前选择的订单信息:', currentOrder);
const orderInfo = encodeURIComponent(JSON.stringify(currentOrder));
uni.navigateTo({
url: `/pages/sendCommand/sendCommand?orderInfo=${orderInfo}`
});
},
refunddinner(index) {
const currentOrder = this.refundOrderList[index];
console.log('当前选择的订单信息:', currentOrder);
const orderInfo = encodeURIComponent(JSON.stringify(currentOrder));
uni.navigateTo({
url: `/pages/sendCommand/sendCommand?orderInfo=${orderInfo}`
});
},
telephone(order){
console.log("99999999999999999");
console.log(order.phone);
uni.makePhoneCall({
phoneNumber: order.phone
});
},
refund(order) {
console.log(order.pickupCode);
const pickupCodeNumber = order.pickupCode;
const _this = this;
uni.request({
url: apiImageUrl + '/api/Alipay/test/refund',
method: 'GET',
data: {
orderNo: pickupCodeNumber
},
header: {
'cookie': uni.getStorageSync("cookie")
},
success: (res) => {
console.log(res);
if (['10000', '40006', '20000'].includes(res.data.alipay_trade_refund_response.code)) {
uni.showModal({
title: '提示',
content: '退款成功',
showCancel: false,
success: () => {
if (_this.currentIndex === 0) {
_this.getOrder();
} else if (_this.currentIndex === 1) {
_this.getRefundOrder();
}
uni.reLaunch({ url: '/pages/order/order' });
}
});
} else {
uni.showModal({
title: '提示',
content: '退款失败',
showCancel: false,
});
}
},
fail() {
console.log("失败");
}
})
},
finish(order) {
console.log(order.id);
const _this = this;
uni.request({
url: apiImageUrl + '/api/orders/update',
method: 'POST',
data: {
id: order.id
},
header: {
'cookie': uni.getStorageSync("cookie")
},
success: (res) => {
console.log(res);
if (res.data.code === 0) {
uni.showModal({
title: '提示',
content: '确认出餐成功',
showCancel: false,
success: () => {
if (_this.currentIndex === 0) {
_this.getOrder();
}
_this.getFinishOrderList();
}
});
} else {
uni.showModal({
title: '提示',
content: '确认出餐失败',
showCancel: false,
});
}
},
fail: (err) => {
console.log(err);
uni.showModal({
title: '错误',
content: '网络请求失败',
showCancel: false
});
}
})
},
formatOrderTime(timeString) {
if (!timeString) return '';
const date = new Date(timeString);
const year = date.getFullYear();
const month = ('0' + (date.getMonth() + 1)).slice(-2);
const day = ('0' + date.getDate()).slice(-2);
const hour = ('0' + date.getHours()).slice(-2);
const minute = ('0' + date.getMinutes()).slice(-2);
const second = ('0' + date.getSeconds()).slice(-2);
return `${year}-${month}-${day} ${hour}:${minute}:${second}`;
},
getOrder() {
uni.request({
url: apiImageUrl + '/api/orders/my/page',
method: 'POST',
data: {
current: this.currentPage,
endTime: "",
id: "",
pageSize: this.pageSize,
pickupMethod: "",
sortField: "",
sortOrder: "",
startTime: "",
state: 1
},
header: {
'cookie': uni.getStorageSync("cookie")
},
success: (res) => {
console.log(res);
this.orderList = res.data.data.records.reverse();
this.total = res.data.data.total;
console.log(this.orderList);
},
fail: () => {
console.log('出错啦');
}
});
},
getRefundOrder() {
uni.request({
url: apiImageUrl + '/api/orders/my/page',
method: 'POST',
data: {
current: this.currentPage,
endTime: "",
id: "",
pageSize: this.pageSize,
pickupMethod: "",
sortField: "",
sortOrder: "",
startTime: "",
state: 2
},
header: {
'cookie': uni.getStorageSync("cookie")
},
success: (res) => {
console.log(res);
this.refundOrderList = res.data.data.records;
this.total = res.data.data.total;
console.log(this.refundOrderList);
},
fail: () => {
console.log('出错啦');
}
});
},
getFinishOrderList() {
uni.request({
url: apiImageUrl + '/api/orders/my/page',
method: 'POST',
data: {
current: this.currentPage,
endTime: "",
id: "",
pageSize: this.pageSize,
pickupMethod: "",
sortField: "",
sortOrder: "",
startTime: "",
state: 4
},
header: {
'cookie': uni.getStorageSync("cookie")
},
success: (res) => {
console.log(res);
this.finishOrderList = res.data.data.records.reverse();
this.total = res.data.data.total;
},
fail: () => {
console.log('出错啦');
}
});
}
},
getLoginUser() {
uni.request({
url: apiImageUrl + '/api/business/get/current',
method: 'POST',
header: {
'cookie': uni.getStorageSync("cookie")
},
success: (res) => {
console.log('用户信息:', res);
if (res.data && res.data.data) {
this.user = res.data.data;
const currentBusinessId = res.data.data.id;
uni.setStorageSync('currentBusinessId', currentBusinessId);
console.log('当前商家ID:', currentBusinessId);
}
uni.showToast({
title: '去蓝牙连接小票机',
duration: 2000,
icon: 'none'
});
},
fail: (err) => {
console.log('请求失败:', err);
uni.showToast({
title: '去登录',
duration: 2000,
icon: 'none'
});
uni.navigateTo({ url: '/pages/login/login' })
}
});
},
mounted() {
this.getOrder();
this.getRefundOrder();
this.getFinishOrderList();
}
};
</script>
<style scoped>
.container {
height: 100vh;
display: flex;
flex-direction: column;
}
.preview {
flex: 1;
overflow-y: auto;
}
.tab-menu {
display: flex;
justify-content: space-around;
background-color: #f8f8f8;
padding: 10px 0;
}
.tab-item {
padding: 10px 20px;
font-size: 16px;
}
.tab-item.active {
color: #007aff;
border-bottom: 2px solid #007aff;
}
.content {
padding: 10px;
}
.container1 {
margin-bottom: 20px;
background-color: #fff;
border-radius: 10px;
padding: 10px;
}
.box {
padding: 10px;
border-bottom: 1px solid #e0e0e0;
}
.numberState {
display: flex;
justify-content: space-between;
align-items: center;
}
.number {
font-weight: bold;
font-size: 20px;
}
.state {
color: #007aff;
font-size: 14px;
}
.time {
margin-top: 5px;
color: #757575;
font-size: 14px;
}
.message {
display: flex;
justify-content: space-between;
margin-top: 5px;
font-size: 14px;
}
.phone {
color: #757575;
}
.button {
background-color: #fdd835;
color: #000;
padding: 5px 10px;
margin-top: 5px;
border-radius: 5px;
font-size: 12px;
}
.sure {
background-color: #007aff;
color: #fff;
padding: 5px 10px;
margin-top: 5px;
border-radius: 5px;
font-size: 14px;
text-align: center;
}
.box2 {
padding: 10px;
font-size: 14px;
}
.beizhu {
font-size: 20px;
font-weight: 700;
padding-bottom: 15px;
padding-top: 10px;
background-color: linear-gradient(to bottom,#fdd835,#fff);
}
.beizhu, .goods, .money {
margin-top: 5px;
}
.km {
margin-top: 5px;
color: #757575;
font-size: 14px;
}
.box3 {
padding-top: 5px;
padding-bottom: 5px;
}
.left3,.right3 {
font-size: 30rpx;
}
.right3 {
float: right;
padding-right: 5px;
font-weight: 700;
}
.left3 {
padding-left: 5px;
}
.tag-view {
float: left;
margin-right: 10px;
}
</style>

View File

@ -0,0 +1,281 @@
<template>
<view class="normal-login-container">
<view class="logo-content align-center justify-center flex">
<image class="img-a" :src="apiImageUrl + '/static/images/b-1.png'" />
<image class="img-b" :src="apiImageUrl + '/static/images/b-2.png'" />
<view class="text">
<view class="t-b">校快送商家端</view>
<view class="t-b2">一款专为用户开发的点餐配送数字化平台</view>
</view>
</view>
<view class="login-form-content">
<view class="input-item flex align-center">
<view class="iconfont icon-user icon"></view>
<input v-model="loginForm.userAccount" class="input" type="text" placeholder="请输入账号" maxlength="30" />
</view>
<view class="input-item flex align-center">
<view class="iconfont icon-password icon"></view>
<input v-model="loginForm.userPassword" type="password" class="input" placeholder="请输入密码" maxlength="20" />
</view>
<view class="action-btn">
<button @click="handleLogin" class="login-btn cu-btn block bg-blue lg round">登录</button>
</view>
<p @click="goLogin" class="goLogin">去注册</p>
</view>
</view>
</template>
<script>
import { apiImageUrl } from '../../API/api';
export default {
data() {
return {
loginForm: {
userAccount: '',
userPassword: ''
},
//apiImageUrl: 'http://39.101.78.35:6448'
};
},
methods: {
// handleLogin() {
// console.log('userAccount:', this.loginForm.userAccount);
// console.log('userPassword:', this.loginForm.userPassword);
// // 检查表单字段是否已填充
// if (!this.loginForm.userAccount || !this.loginForm.userPassword) {
// uni.showToast({
// icon: 'error',
// title: '请输入账号和密码'
// });
// return;
// }
// uni.request({
// url: this.apiImageUrl + '/api/user/login',
// method: 'POST',
// data: {
// userAccount: this.loginForm.userAccount,
// userPassword: this.loginForm.userPassword
// },
// header:{
// 'cookie':uni.getStorageSync("cookie")
// },
// success: (res) => {
// console.log(res.data.code);
// if (res.data.code === 0) {
// uni.showToast({
// title: '登录成功',
// duration: 2000
// });
// uni.removeStorageSync('cookie');
// uni.setStorageSync('userInfo', res.data.data);
// uni.setStorageSync('cookie', res.header['Set-Cookie']);
// uni.switchTab({
// url: '/pages/index/index'
// });
// } else {
// uni.showToast({
// icon: 'error',
// title: '登录失败,请联系管理员'
// });
// return;
// }
// },
// fail: (err) => {
// console.error(err);
// uni.showToast({
// icon: 'error',
// title: '请求失败,请检查网络'
// });
// }
// });
// }
handleLogin() {
console.log('userAccount:', this.loginForm.userAccount);
console.log('userPassword:', this.loginForm.userPassword);
uni.showLoading({
title: '正在登录...',
mask: true
});
uni.request({
url: apiImageUrl + '/api/user/login',
method: 'POST',
data: {
appName:'business',
userAccount: this.loginForm.userAccount,
userPassword: this.loginForm.userPassword
},
header: {
'Content-Type': 'application/json',
'cookie': uni.getStorageSync("cookie") || ''
},
success: (res) => {
console.log('Response Data:', res);
if (res.statusCode === 200 && res.data.code === 0) {
uni.showToast({
title: '登录成功',
duration: 2000
});
uni.removeStorageSync('cookie');
uni.setStorageSync('userInfo', res.data.data);
if (res.header && res.header['Set-Cookie']) {
uni.setStorageSync("cookie", res.header['Set-Cookie']);
}
uni.switchTab({
url: '/pages/index/index'
});
} else {
uni.showToast({
icon: 'error',
title: "登录失败,请联系管理员"
});
}
},
fail: (err) => {
console.error('Request failed:', err);
uni.showToast({
icon: 'error',
title: "网络请求失败,请重试"
});
},
complete: () => {
uni.hideLoading();
}
});
},
goLogin(){
uni.navigateTo({
url:'/pages/signIn/signIn'
})
}
}
};
</script>
<style lang="scss">
page {
background: url('../../static/login.jpg') repeat fixed center;
}
.normal-login-container {
width: 100%;
.logo-content {
width: 100%;
font-size: 21px;
text-align: center;
padding-top: 15%;
image {
border-radius: 4px;
}
.title {
margin-left: 10px;
}
}
.login-form-content {
text-align: center;
margin: 20px auto;
width: 80%;
.input-item {
margin: 20px auto;
background-color: #f5f6f7;
height: 45px;
border-radius: 20px;
.icon {
font-size: 38rpx;
margin-left: 10px;
color: #999;
}
.input {
width: 80%;
font-size: 14px;
line-height: 20px;
text-align: left;
padding-left: 15px;
padding-top: 8px;
padding-bottom: 8px;
background-color: #f5f6f7;
}
}
.login-btn {
margin-top: 40px;
height: 45px;
border-radius: 30px;
}
.reg {
margin-top: 15px;
}
.xieyi {
color: #333;
margin-top: 20px;
}
.login-code {
height: 38px;
float: right;
.login-code-img {
height: 38px;
position: absolute;
margin-left: 10px;
width: 200rpx;
}
}
}
}
.img-a {
position: absolute;
width: 100%;
top: -74px;
right: 0;
z-index: 100;
}
.img-b {
position: absolute;
width: 50%;
bottom: 0;
left: -50rpx;
z-index: 100;
}
.text{
margin-left: -111px;
margin-top: 28px;
}
.t-b {
font-size: 29px;
color: #000;
padding: 60px 0 10px 0;
font-weight: bold;
}
.t-b2 {
text-align: center;
font-size: 32rpx;
color: #2a2a2a;
}
.goLogin {
float: right;
color: #444444;
padding: 10px;
}
</style>

View File

@ -0,0 +1,129 @@
<template>
<uni-list>
<uni-list-chat
v-for="(item, index) in historyList"
:key="index"
:title="item.title"
:avatar="item.imgUrl"
:note="item.message"
:time="item.time"
:badge-position="'left'"
:badge-text="item.unread"
clickable
@click="navigateToTalk"
/>
</uni-list>
</template>
<script>
export default {
data() {
return {
historyList: [
{
imgUrl: 'https://img.zcool.cn/community/0105ec5b5ac3cba801206a35cf08a8.jpg@1280w_1l_2o_100sh.jpg',
title: '普通用户01',
unread:'10',
time:'刚才',
message:'这次点的外卖真是超乎预期的好吃!【香辣鸡腿堡】外皮酥脆,鸡肉鲜嫩多汁,辣度适中,每一口都是满满的幸福感。【薯条】也是惊喜,又脆又香,完全没有油腻感。最棒的是配送员【小张】,准时送达,态度亲切,还特意提醒我餐品有点烫,小心食用。整体体验满分,下次还会再点!'
},
{
imgUrl: 'https://ts1.cn.mm.bing.net/th/id/R-C.63e4b0a881283cbd46f07e77c2bbd491?rik=vWq%2fKkimZ5n2XQ&riu=http%3a%2f%2fseopic.699pic.com%2fphoto%2f50014%2f5917.jpg_wh1200.jpg&ehk=KCX2DzgqaiIJnMJZUyFc%2btT9ILzKGslHE8oaSAKORdE%3d&risl=&pid=ImgRaw&r=0',
title: '普通用户02',
unread:'2',
time:'刚才',
message:'这次点的外卖真是超乎预期的好吃!【香辣鸡腿堡】外皮酥脆,鸡肉鲜嫩多汁,辣度适中,每一口都是满满的幸福感。【薯条】也是惊喜,又脆又香,完全没有油腻感。最棒的是配送员【小张】,准时送达,态度亲切,还特意提醒我餐品有点烫,小心食用。整体体验满分,下次还会再点!'
},
{
imgUrl: 'https://img.zcool.cn/community/0189d85c3c421aa80121fbb0284f6c.jpg@1280w_1l_2o_100sh.jpg',
title: '普通用户03',
unread:'',
time:'刚才',
message:'这次点的外卖真是超乎预期的好吃!【香辣鸡腿堡】外皮酥脆,鸡肉鲜嫩多汁,辣度适中,每一口都是满满的幸福感。【薯条】也是惊喜,又脆又香,完全没有油腻感。最棒的是配送员【小张】,准时送达,态度亲切,还特意提醒我餐品有点烫,小心食用。整体体验满分,下次还会再点!'
},
{
imgUrl: 'https://ts1.cn.mm.bing.net/th/id/R-C.b3a7697d2793ba094a861d546c31190d?rik=NevOIW4XmkUuMA&riu=http%3a%2f%2fseopic.699pic.com%2fphoto%2f50069%2f5445.jpg_wh1200.jpg&ehk=wuLPicg%2b9wXz8QAwp%2fAVFBtJQ6loBUiVfQZu2bbZODA%3d&risl=&pid=ImgRaw&r=0',
title: '普通用户04',
unread:'2',
time:'1分钟前',
message:'这次点的外卖真是超乎预期的好吃!【香辣鸡腿堡】外皮酥脆,鸡肉鲜嫩多汁,辣度适中,每一口都是满满的幸福感。【薯条】也是惊喜,又脆又香,完全没有油腻感。最棒的是配送员【小张】,准时送达,态度亲切,还特意提醒我餐品有点烫,小心食用。整体体验满分,下次还会再点!'
},
{
imgUrl: 'https://img.zcool.cn/community/0192885d01b363a801213ec27c862a.jpg@1280w_1l_2o_100sh.jpg',
title: '普通用户05',
unread:'3',
time:'12:10',
message:'这次点的外卖真是超乎预期的好吃!【香辣鸡腿堡】外皮酥脆,鸡肉鲜嫩多汁,辣度适中,每一口都是满满的幸福感。【薯条】也是惊喜,又脆又香,完全没有油腻感。最棒的是配送员【小张】,准时送达,态度亲切,还特意提醒我餐品有点烫,小心食用。整体体验满分,下次还会再点!'
},
{
imgUrl: 'https://img.zcool.cn/community/018aab5cc14900a801214168fdffc2.jpg@1280w_1l_2o_100sh.jpg',
title: '普通用户06',
unread:'',
time:'11:10',
message:'这次点的外卖真是超乎预期的好吃!【香辣鸡腿堡】外皮酥脆,鸡肉鲜嫩多汁,辣度适中,每一口都是满满的幸福感。【薯条】也是惊喜,又脆又香,完全没有油腻感。最棒的是配送员【小张】,准时送达,态度亲切,还特意提醒我餐品有点烫,小心食用。整体体验满分,下次还会再点!'
},
{
imgUrl: 'https://ts1.cn.mm.bing.net/th/id/R-C.68978afc71576a94a1d50ef5016dbd9e?rik=cDDsy5SLmDvDHQ&riu=http%3a%2f%2fseopic.699pic.com%2fphoto%2f50075%2f0779.jpg_wh1200.jpg&ehk=FG4Hd5S711LYcuLBIcDagQyk4KhcH1oIfqyk1MWUOyg%3d&risl=&pid=ImgRaw&r=0',
title: '普通用户07',
unread:'1',
time:'14:12',
message:'这次点的外卖真是超乎预期的好吃!【香辣鸡腿堡】外皮酥脆,鸡肉鲜嫩多汁,辣度适中,每一口都是满满的幸福感。【薯条】也是惊喜,又脆又香,完全没有油腻感。最棒的是配送员【小张】,准时送达,态度亲切,还特意提醒我餐品有点烫,小心食用。整体体验满分,下次还会再点!'
},
{
imgUrl: 'https://img95.699pic.com/photo/50093/6813.jpg_wh860.jpg',
title: '普通用户08',
unread:'2',
time:'14:50',
message:'这次点的外卖真是超乎预期的好吃!【香辣鸡腿堡】外皮酥脆,鸡肉鲜嫩多汁,辣度适中,每一口都是满满的幸福感。【薯条】也是惊喜,又脆又香,完全没有油腻感。最棒的是配送员【小张】,准时送达,态度亲切,还特意提醒我餐品有点烫,小心食用。整体体验满分,下次还会再点!'
},
{
imgUrl: 'https://bpic.588ku.com/back_origin_min_pic/23/04/19/05f178d63677c98d3db402d63fac38d2.jpg',
title: '普通用户09',
unread:'2',
time:'12:40',
message:'这次点的外卖真是超乎预期的好吃!【香辣鸡腿堡】外皮酥脆,鸡肉鲜嫩多汁,辣度适中,每一口都是满满的幸福感。【薯条】也是惊喜,又脆又香,完全没有油腻感。最棒的是配送员【小张】,准时送达,态度亲切,还特意提醒我餐品有点烫,小心食用。整体体验满分,下次还会再点!'
},
{
imgUrl: 'https://img95.699pic.com/photo/50093/6813.jpg_wh860.jpg',
title: '普通用户010',
unread:'1',
time:'18:48',
message:'这次点的外卖真是超乎预期的好吃!【香辣鸡腿堡】外皮酥脆,鸡肉鲜嫩多汁,辣度适中,每一口都是满满的幸福感。【薯条】也是惊喜,又脆又香,完全没有油腻感。最棒的是配送员【小张】,准时送达,态度亲切,还特意提醒我餐品有点烫,小心食用。整体体验满分,下次还会再点!'
},
]
};
},
methods: {
navigateToTalk() {
console.log('navigateToTalk called');
uni.navigateTo({
url: '/pages/talk/talk'
});
}
}
}
</script>
<style>
page {
background-color: #fff;
}
.chat-custom-right {
flex: 1;
/* #ifndef APP-NVUE */
display: flex;
/* #endif */
flex-direction: column;
justify-content: space-between;
align-items: flex-end;
}
.chat-custom-text {
font-size: 12px;
color: #999;
}
</style>

View File

@ -0,0 +1,460 @@
<template>
<view class="root">
<view class="bgImg">
<view class="orderSum">
<view class="orderSumLeft">
<view class="myShop">
本月盈利
</view>
<view class="monthMoney">
{{ monthMoney }}
</view>
<view class="addMoney">
+ {{ monthOrder }}
</view>
</view>
<!-- 登录 -->
<view class="orderSumRight" v-if="user.message==='ok'">
<view class="userImg">
<image :src="user.userAvatar" class="user"></image>
<view class="addOrder">
今日盈利
</view>
<view class="monthOrder">
{{ todayMoney }}
</view>
<view class="addOrder">
+{{todayOrder}}
</view>
</view>
</view>
<!-- 未登录 -->
<view class="orderSumRight" v-else>
<view class="userImg">
<image src="../../static/logo.png" class="user"></image>
</view>
</view>
</view>
</view>
<view class="feature">
<view class="square" v-for="(item, index) in featureList" :key="index">
<navigator class="imageContainer" :url="item.url">
<image :src="item.imgUrl" class="image"></image>
</navigator>
<view class="featureName">{{ item.name }}</view>
</view>
</view>
<view class="setting">
<view class="merchantSetting">
店铺设置
</view>
<view class="settingList">
<view class="state">
营业状态
&nbsp;&nbsp;&nbsp;
<switch
:checked="storeStatus === 1"
@change="handleSwitchChange"
color="#FFCC33"
style="transform:scale(0.7)"
/>
</view>
<view class="state">
账号管理
</view>
<view class="logout" @click="logout">
退出登录
</view>
</view>
</view>
</view>
</template>
<script>
import { apiImageUrl } from '../../API/api';
export default {
data() {
return {
user: {
userAvatar: '',
userName: '',
message: ''
},
featureList: [
{ url: '/pages/announcement/announcement', imgUrl: '../../static/Gourmet/meishi.png', name: '公告管理' },
{ url: '/pages/product/product', imgUrl: '../../static/Gourmet/meishi_caomei.png', name: '商品管理' },
{ url: '/pages/Statistics/Statistics', imgUrl: '../../static/Gourmet/meishi_hanbao.png', name: '数据统计' },
{ url: '/pages/orderManagement/orderManagement', imgUrl: '../../static/Gourmet/meishi_li.png', name: '订单管理' },
{ url: '/pages/bleConnect/bleConnect', imgUrl: '../../static/Gourmet/meishi_mangguo.png', name: '蓝牙服务' },
{ url: '/pages/evaluate/evaluate', imgUrl: '../../static/Gourmet/meishi_manyuemei.png', name: '评价管理' },
{ url: '/pages/distribution/distribution', imgUrl: '../../static/Gourmet/meishi_niunai.png', name: '配送服务' },
{ url: '/pages/more/more', imgUrl: '../../static/Gourmet/meishi_tusi.png', name: '更多功能' }
],
range: [],
storeStatus: 0,
monthMoney: '0.00',
monthOrder:'0',
todayMoney:'0.00',
todayOrder:'0'
};
},
onLoad() {
this.getLoginUser();
},
onShow() {
this.getLoginUser();
},
methods: {
getLoginUser() {
uni.request({
url: apiImageUrl + '/api/business/get/current',
method: 'POST',
header: {
'cookie': uni.getStorageSync("cookie")
},
success: (res) => {
console.log(res);
uni.setStorageSync('businessId', res.data.data.id);
uni.setStorageSync('businessName', res.data.data.businessName);
this.storeStatus = res.data.data.storeStatus;
console.log(res.data.data);
this.user.message = res.data.message;
if (this.user.message === 'ok') {
this.user.userName = res.data.data.businessName;
this.user.userAvatar = res.data.data.businessAvatar;
this.getMonthMoney();
this.getMonthOrder();
this.getDayMoney();
this.getDayOrder();
}
},
fail() {
console.log('出错啦');
}
});
},
async getMonthMoney() {
try {
const today = new Date();
const firstDayOfMonth = new Date(today.getFullYear(), today.getMonth(), 1);
const response = await uni.request({
url: apiImageUrl + '/api/orders/count/money',
method: 'POST',
header: {
'cookie': uni.getStorageSync("cookie")
},
data: {
businessId: uni.getStorageSync("businessId"),
businessName: uni.getStorageSync("businessName"),
businessState: 0,
categoryId: 1,
endTime: today.toISOString().split('T')[0],
startTime: firstDayOfMonth.toISOString().split('T')[0],
state: 1,
type: "1"
}
});
console.log(response[1].data.data);
this.monthMoney = `${response[1].data.data}`;
} catch (error) {
console.log(error);
}
},
async getMonthOrder() {
try {
const today = new Date();
const firstDayOfMonth = new Date(today.getFullYear(), today.getMonth(), 1);
const response = await uni.request({
url: apiImageUrl + '/api/orders/count/number',
method: 'POST',
header: {
'cookie': uni.getStorageSync("cookie")
},
data: {
businessId: uni.getStorageSync("businessId"),
businessName: uni.getStorageSync("businessName"),
businessState: 0,
categoryId: 1,
endTime: today.toISOString().split('T')[0],
startTime: firstDayOfMonth.toISOString().split('T')[0],
state: 1,
type: "1"
}
});
console.log(response[1].data.data);
this.monthOrder = `${response[1].data.data}`;
} catch (error) {
console.log(error);
}
},
async getDayMoney() {
try {
const today = new Date();
const startOfDay = new Date(today);
startOfDay.setHours(0, 0, 0, 0);
const endOfDay = new Date(today);
endOfDay.setHours(23, 59, 59, 999);
const response = await uni.request({
url: apiImageUrl + '/api/orders/count/money',
method: 'POST',
header: {
'cookie': uni.getStorageSync("cookie")
},
data: {
businessId: uni.getStorageSync("businessId"),
businessName: uni.getStorageSync("businessName"),
businessState: 0,
categoryId: 1,
endTime: endOfDay.toISOString().split('T')[0],
startTime: startOfDay.toISOString().split('T')[0],
state: 1,
type: "1"
}
});
console.log(response[1].data.data);
this.todayMoney = `${response[1].data.data}`;
} catch (error) {
console.log(error);
}
},
async getDayOrder() {
try {
const today = new Date();
const startOfDay = new Date(today);
startOfDay.setHours(0, 0, 0, 0);
const endOfDay = new Date(today);
endOfDay.setHours(23, 59, 59, 999);
const response = await uni.request({
url: apiImageUrl + '/api/orders/count/number',
method: 'POST',
header: {
'cookie': uni.getStorageSync("cookie")
},
data: {
businessId: uni.getStorageSync("businessId"),
businessName: uni.getStorageSync("businessName"),
businessState: 0,
categoryId: 1,
endTime: endOfDay.toISOString().split('T')[0],
startTime: startOfDay.toISOString().split('T')[0],
state: 1,
type: "1"
}
});
console.log(response[1].data.data);
this.todayOrder = `${response[1].data.data}`;
} catch (error) {
console.log(error);
}
},
orderSumRight() {
uni.navigateTo({
url: '/pages/money/money'
});
},
logout() {
uni.removeStorageSync('identify');
uni.removeStorageSync('cookie');
uni.removeStorageSync('userInfo');
uni.reLaunch({
url: '/pages/login/login'
});
uni.showToast({
title: '退出成功',
duration: 2000
});
},
handleSwitchChange(e) {
const newStatus = e.detail.value ? 1 : 0;
const businessId = uni.getStorageSync('businessId');
if (!businessId) {
uni.showToast({ title: '未找到商家信息', icon: 'none' });
return;
}
uni.request({
url: `${apiImageUrl}/api/business/update/my`,
method: 'POST',
header: {
'Content-Type': 'application/json',
'cookie': uni.getStorageSync("cookie")
},
data: {
storeStatus: newStatus
},
success: (res) => {
console.log(res);
if (res.data?.code === 0) {
this.storeStatus = newStatus;
uni.showToast({
title: `${newStatus ? '开业' : '打烊'}`,
icon: 'success'
});
} else {
uni.showToast({
title: res.data?.message || '操作失败',
icon: 'none'
});
}
},
fail: (error) => {
console.error('请求失败:', error);
uni.showToast({
title: '网络异常,请重试',
icon: 'none'
});
}
});
}
}
};
</script>
<style>
.bgImg {
width: 100%;
height: 500rpx;
background-image: url(../../static/myBgc.jpg);
background-size: cover;
background-position: center;
background-repeat: no-repeat;
border-radius: 0 0 50px 50px;
}
.orderSum {
width: 90%;
height: 150px;
margin: 0 auto;
display: flex;
align-items: center;
padding-top: 40px;
}
.orderSumLeft {
flex: 1.5;
height: 100%;
padding-left: 15px;
}
.myShop {
padding-top: 60rpx;
font-size: 20px;
color: #fff;
}
.monthMoney {
padding-top: 30rpx;
font-size: 30px;
color: #fff;
}
.addMoney {
padding-top: 20rpx;
font-size: 14px;
color: #fff;
}
.monthOrder {
padding-top: 24rpx;
font-size: 20px;
color: #fff;
}
.addOrder {
padding-top: 10rpx;
font-size: 14px;
color: #fff;
}
.orderSumRight {
flex: 1;
height: 100%;
}
.feature {
width: 100%;
display: flex;
flex-wrap: nowrap;
justify-content: space-between;
padding: 10px;
box-sizing: border-box;
margin: 0 auto;
border-radius: 15px;
border: 4px solid #ebebeb;
}
@media (max-width: 768px) {
.feature {
flex-wrap: wrap;
}
}
.square {
width: calc((100% - 20px*3) / 4);
height: 70px;
margin-bottom: 10px;
margin-top: 10px;
box-sizing: border-box;
}
.imageContainer {
width: 70%;
height: 70%;
margin: 0 auto;
}
.image {
width: 100%;
height: 100%;
}
.featureName {
font-size: 15px;
margin-top: 5px;
text-align: center;
}
.merchantSetting {
margin-top: 10px;
font-size: 35rpx;
font-weight: 700;
padding: 10px;
color: #fff;
background-color: #2237bf;
}
.settingList {
width: 70%;
margin: 0 auto;
}
.state {
font-size:35rpx;
font-weight: 700;
margin-top: 20px;
}
.time {
margin-top: 10px;
}
.logout {
width: 80%;
height: 100rpx;
line-height: 100rpx;
font-size: 35rpx;
text-align: center;
background-color: #2237bf;
border-radius: 15px;
margin: 0 auto;
color: #fff;
margin-top: 10px;
}
.userImg {
width: 60%;
height: 50%;
margin-top: 30px;
margin-left: 15px;
}
.user {
width: 120rpx;
height: 120rpx;
border-radius: 50%;
margin-left: 20px;
}
</style>

View File

@ -0,0 +1,227 @@
<template>
<view class="page">
<scroll-view scroll-y class="preview" :style="{ height: scrollHeight }">
<!-- 商品详情 -->
<view class="tab-menu">
<view
class="tab-item"
v-for="(tab, index) in tabs"
:key="index"
:class="{ active: currentIndex === index }"
@click="switchTab(index)"
>
{{ tab.name }}
</view>
</view>
<view class="content">
<block v-if="currentIndex === 0 || currentIndex === 1 || currentIndex === 2">
<view class="container">
<view
class="orderItem"
v-for="(order, index) in filteredOrders"
:key="index"
>
<view class="orderImg">
<image :src="orderImageUrl" class="img"></image>
</view>
<view class="orderMessage">
<text class="money">+{{ order.totalPrice }}</text>
<br />
<text class="time">下单时间:{{ formatDate(order.createTime) }}</text>
<br />
<text class="time">订单编号:{{ order.id }}</text>
</view>
</view>
</view>
</block>
</view>
</scroll-view>
</view>
</template>
<script>
import { apiImageUrl } from '../../API/api';
export default {
data() {
return {
currentIndex: 0,
tabs: [
{ name: '全部' },
{ name: '收入' },
{ name: '退款' }
],
orderList: [],
orderImageUrl: "https://tse4-mm.cn.bing.net/th/id/OIP-C.cDfrXgI1DKvU7OklwmBfewHaHa?rs=1&pid=ImgDetMain",
scrollHeight: 'calc(100vh - 60px)'
};
},
computed: {
filteredOrders() {
if (this.currentIndex === 0) {
return this.orderList;
} else {
return this.orderList.filter(order =>
(this.currentIndex === 1 && order.type === 'income') ||
(this.currentIndex === 2 && order.type === 'refund')
);
}
}
},
methods: {
switchTab(index) {
this.currentIndex = index;
},
getOrder() {
uni.request({
url: `${apiImageUrl}/api/orders/my/page`,
method: 'POST',
data: {
current: 1,
endTime: "",
id: "",
pageSize: 100,
pickupMethod: 0,
sortField: "",
sortOrder: "",
startTime: "",
state: 0
},
success: (res) => {
console.log(res);
this.orderList = res.data.data.records || [];
console.log(this.orderList);
},
fail: () => {
console.log('出错啦');
}
});
},
formatDate(dateStr) {
const date = new Date(dateStr);
const year = date.getFullYear();
const month = String(date.getMonth() + 1).padStart(2, '0');
const day = String(date.getDate()).padStart(2, '0');
return `${year}-${month}-${day}`;
}
},
mounted() {
this.getOrder();
}
};
</script>
<style lang="scss">
.tabs {
display: flex;
justify-content: space-around;
line-height: 60rpx;
margin: 0 10rpx;
background-color: #fff;
box-shadow: 0 4rpx 6rpx rgba(240, 240, 240, 0.6);
position: relative;
z-index: 9;
.item {
flex: 1;
text-align: center;
padding: 20rpx;
font-size: 28rpx;
color: #262626;
}
.cursor {
position: absolute;
left: 0;
bottom: 0;
width: 18%;
height: 6rpx;
padding: 0 50rpx;
background-color: #4095e5;
/* 过渡效果 */
transition: all 0.4s;
}
}
.preview image {
width: 100%;
}
.page {
height: 100%;
overflow: hidden;
background-color: #f5f5f5;
}
.tab-menu {
display: flex;
justify-content: space-around;
padding: 10px 0;
background-color: #f5f5f5;
}
.tab-item {
padding: 10px;
cursor: pointer;
}
.tab-item.active {
color: #4095e5;
font-weight: bold;
}
.scroll-view {
/* #ifndef APP-NVUE */
width: 100%;
height: 100%;
/* #endif */
flex: 1;
}
.orderItem {
width: calc(100% - 20px);
min-height: 80px;
margin-bottom: 10px;
margin-left: auto;
margin-right: auto;
background-color: #fff;
display: flex;
align-items: center;
border-radius: 10px;
box-shadow: 0 2px 5px rgba(0, 0, 0, 0.1), 0 2px 10px rgba(0, 0, 0, 0.08);
padding: 5px 10px 5px 10px;
}
.orderImg {
display: flex;
justify-content: center;
align-items: center;
width: 60px;
height: 60px;
margin-right: 10px;
}
.img {
width: 100%;
height: 100%;
border-radius: 50%;
object-fit: cover;
}
.orderMessage {
flex-grow: 1;
margin-top: 0;
}
.money {
font-size: 30rpx;
font-weight: 700;
}
.time {
font-size: 25rpx;
}
.container {
width: 90%;
margin: 0 auto;
}
</style>

View File

@ -0,0 +1,259 @@
<template>
<view>
<view class="item" v-for="(tab, index) in resultArray" :key="index" @click="showDrawer('showLeft', tab)">
{{ tab.groupName }}
</view>
<uni-drawer ref="showLeft" mode="left" :mask-click="true" @change="handleDrawerChange">
<view class="drawer-content">
<input class="styled-input" v-model="form.dishesName" placeholder="请输入菜品名" />
<button @click="chooseImage" class="styled-button">选择图片</button>
<view v-if="form.dishesImage">
<image :src="'http://'+form.dishesImage" style="width:30px; height:30px;" />
</view>
<input class="styled-input" v-model="form.dishesPrice" type="number" step="0.01" placeholder="请输入菜品价格" />
<button @click="addDishes" class="styled-button confirm">添加菜品</button>
<view v-if="result !== null">{{ result }}</view>
</view>
</uni-drawer>
</view>
</template>
<script>
import { apiImageUrl } from '../../API/api';
export default {
data() {
return {
businessId: '',
resultArray: [],
result: null,
currentGroupId: '',
form: {
dishesName: '',
dishesImage: '',
dishesPrice: '',
dishesGroup: '',
inventoryStatus: 0,
packPrice: 0,
specificationsIds: [],
status: 0,
}
};
},
mounted() {
this.loadCurrentBusinessId();
this.leftGroup();
},
methods: {
loadCurrentBusinessId() {
const storedBusinessId = uni.getStorageSync('businessId');
if (storedBusinessId) {
this.businessId = storedBusinessId;
} else {
console.error('currentBusinessId not found in storage');
}
},
leftGroup() {
const DishesGroupQueryRequest = {
businessId: this.businessId
};
uni.request({
url: apiImageUrl + '/api/dishesGroup/list/dishesGroup',
method: 'POST',
data: JSON.stringify(DishesGroupQueryRequest),
header: {
'Content-Type': 'application/json'
}
}).then((res) => {
console.log(res);
if (res[1] && res[1].data && res[1].data.code === 0) {
this.resultArray = res[1].data.data.map(item => ({
id: item.id,
groupName: item.groupName
}));
console.log(this.resultArray);
} else {
console.error('Unexpected response structure:', res);
}
}).catch((error) => {
console.error('Error fetching dishes groups:', error);
});
},
showDrawer(drawer, tab) {
this.currentGroupId = tab.id;
this.form.dishesGroup = tab.id;
this.$refs[drawer].open();
},
closeDrawer() {
this.$refs.showLeft.close();
},
chooseImage() {
console.log('选择图片按钮被点击');
uni.chooseImage({
count: 1,
sizeType: ['original', 'compressed'],
sourceType: ['album', 'camera'],
success: (res) => {
console.log('图片选择成功:', res);
const tempFilePaths = res.tempFilePaths;
const filePath = tempFilePaths[0];
this.uploadFile(filePath);
},
fail: (err) => {
console.error('选择图片失败:', err);
}
});
},
uploadFile(filePath) {
console.log('开始上传图片:', filePath);
uni.uploadFile({
url: apiImageUrl + '/api/file/upload/server',
filePath: filePath,
name: 'file',
formData: { biz: 'dishes' },
success: (uploadFileRes) => {
try {
const responseData = JSON.parse(uploadFileRes.data);
console.log('上传结果:', responseData);
if (responseData && responseData.data) {
this.form.dishesImage = responseData.data;
console.log('上传成功图片URL:', this.form.dishesImage);
} else {
console.error('未找到有效图片路径:', responseData);
}
} catch (e) {
console.error('解析上传结果失败:', e);
}
},
fail: (err) => {
console.error('上传文件失败:', err);
}
});
},
addDishes() {
const data = {
businessId: this.businessId,
dishesGroupId: parseInt(this.form.dishesGroup, 10),
dishesImage: this.form.dishesImage,
dishesName: this.form.dishesName,
dishesPrice: parseFloat(this.form.dishesPrice),
inventoryStatus: 0,
packPrice: 0,
specificationsIds: [],
status: 0,
};
uni.request({
url: apiImageUrl + '/api/dishes/add',
method: 'POST',
header: {
'content-type': 'application/json'
},
data: data,
success: (res) => {
console.log('成功返回:', res.data);
this.result = '菜品添加成功!';
this.closeDrawer();
uni.showModal({
title: '提示',
content: '菜品添加成功!',
showCancel: false
});
},
fail: (err) => {
console.error('请求失败:', err);
this.result = '菜品添加失败,请重试。';
uni.showModal({
title: '提示',
content: '菜品添加失败,请重试!',
showCancel: false
});
}
});
}
}
};
</script>
<style lang="scss">
.item {
font-size: 13px;
padding: 10px 20px;
display: inline-block;
background-color: rgba(245, 245, 220, 0.8);
margin: 10px;
border-radius: 20px;
box-shadow: 0 4px #ccc, 0 6px 10px rgba(0,0,0,0.1), inset 0 2px #fff, inset 0 -2px 2px rgba(0,0,0,0.1);
transition: transform 0.2s;
&:hover {
transform: translateY(-2px);
box-shadow: 0 6px #ccc, 0 8px 15px rgba(0,0,0,0.1), inset 0 4px #fff, inset 0 -2px 3px rgba(0,0,0,0.1);
}
}
.styled-input {
font-size: 14px;
width: calc(100% - 20px);
padding: 10px;
margin: 10px 0;
display: block;
background-color: rgba(245, 245, 220, 0.8);
border-radius: 20px;
box-shadow: 0 4px #ccc, 0 6px 10px rgba(0,0,0,0.1), inset 0 2px #fff, inset 0 -2px 2px rgba(0,0,0,0.1);
border: none;
outline: none;
transition: box-shadow 0.2s;
&:focus {
box-shadow: 0 6px #ccc, 0 8px 15px rgba(0,0,0,0.1), inset 0 4px #fff, inset 0 -2px 3px rgba(0,0,0,0.1);
}
}
.button-container {
display: flex;
justify-content: space-between;
}
.styled-button {
font-size: 14px;
flex: 1;
margin: 5px;
padding: 10px;
background-color: rgba(173, 216, 230, 0.8);
border: none;
border-radius: 15px;
box-shadow: 0 4px #ccc, 0 6px 10px rgba(0,0,0,0.1), inset 0 2px #fff, inset 0 -2px 2px rgba(0,0,0,0.1);
cursor: pointer;
transition: box-shadow 0.2s, background-color 0.2s;
&:hover {
background-color: rgba(173, 216, 230, 1);
box-shadow: 0 6px #ccc, 0 8px 15px rgba(0,0,0,0.1), inset 0 4px #fff, inset 0 -2px 3px rgba(0,0,0,0.1);
}
}
.confirm {
font-size: 14px;
background-color: rgba(135, 206, 235, 0.8);
}
.delete {
font-size: 14px;
background-color: rgba(255, 99, 71, 0.8);
}
</style>

View File

@ -0,0 +1,359 @@
<template>
<view>
<view class="navbar">
<view class="search">
<text class="icon-search">
<input type="text" placeholder="输入菜品组名称" class="transparent-input" v-model="form.groupName"/>
</text>
</view>
<button class="search-button" @click="addDishesGroup">添加</button>
</view>
<view class="item"
v-for="(tab, index) in resultArray"
:key="index"
@click="showDrawer('showLeft', tab)">
{{ tab.groupName }}
</view>
<uni-drawer ref="showLeft" mode="left" :mask-click="true" @change="change($event,'showLeft')">
<!-- 组件内部-->
<view class="edit-dishes-group">
<view class="drawer-content">
<input class="styled-input" type="text" v-model="newGroupName" placeholder="请输入新的菜品组名" />
</view>
<view class="button-container">
<button class="styled-button confirm" @click="updateDishesGroup">确认</button>
<button class="styled-button delete" @click="deleteDishesGroup(currentGroupId)">删除菜品组</button>
</view>
</view>
</uni-drawer>
</view>
</template>
<script>
import { apiImageUrl } from '../../API/api';
export default {
data() {
return {
businessId: '',
resultArray: [],
result: null,
currentGroupName: '',
currentGroupId: '',
newGroupName: '',
id: 0,
form: {
groupName: '',
isTopping: 0
}
};
},
mounted() {
this.loadCurrentBusinessId();
this.leftGroup();
},
methods: {
loadCurrentBusinessId() {
const storedBusinessId = uni.getStorageSync('businessId');
console.log(storedBusinessId);
if (storedBusinessId) {
this.businessId = storedBusinessId;
} else {
console.error('currentBusinessId not found in storage');
}
},
leftGroup() {
const DishesGroupQueryRequest = {
businessId: this.businessId
};
uni.request({
url: apiImageUrl + '/api/dishesGroup/list/dishesGroup',
method: 'POST',
data: JSON.stringify(DishesGroupQueryRequest),
header: {
'Content-Type': 'application/json'
}
}).then((res) => {
console.log(res);
if (res[1] && res[1].data && res[1].data.code === 0) {
this.resultArray = res[1].data.data.map(item => ({
id: item.id,
groupName: item.groupName
}));
console.log(this.resultArray);
} else {
console.error('Unexpected response structure:', res);
}
}).catch((error) => {
console.error('Error fetching dishes groups:', error);
});
},
showDrawer(drawer, tab) {
this.currentGroupName = tab.groupName;
this.currentGroupId = tab.id;
this.newGroupName = tab.groupName;
this.id = tab.id;
if (this.$refs.showLeft) {
this.$refs.showLeft.open();
}
},
closeDrawer() {
if (this.$refs.showLeft) {
this.$refs.showLeft.close();
}
},
change(e, type) {
console.log((type === 'showLeft' ? '左窗口' : '右窗口') + (e ? '打开' : '关闭'));
this[type] = e;
},
updateDishesGroup() {
if (!this.newGroupName || !this.id) return;
uni.request({
url: apiImageUrl + '/api/dishesGroup/update',
method: 'POST',
header: {
'Content-Type': 'application/json',
},
data: {
id: this.id,
groupName: this.newGroupName,
isTopping: 0,
},
}).then((res) => {
if (res[1] && res[1].data && res[1].data.code === 0) {
this.closeDrawer();
this.leftGroup();
uni.showModal({
title: '提示',
content: '菜品组更新成功',
showCancel: false
});
} else {
uni.showModal({
title: '提示',
content: '菜品组更新失败',
showCancel: false
});
}
}).catch((error) => {
console.error('Error updating dishes group:', error);
uni.showModal({
title: '提示',
content: '菜品组更新失败',
showCancel: false
});
});
},
removeGroupFromList(id) {
const index = this.resultArray.findIndex(item => item.id === id);
if (index > -1) {
this.resultArray.splice(index, 1);
}
},
deleteDishesGroup(id) {
uni.request({
url: `${apiImageUrl}/api/dishesGroup/delete`,
method: 'POST',
data: {
id: id
}
}).then((res) => {
if (res[1] && res[1].data && res[1].data.code === 0) {
uni.showModal({
title: '提示',
content: '成功删除菜品组',
showCancel: false
});
this.removeGroupFromList(id);
this.closeDrawer();
} else {
uni.showModal({
title: '提示',
content: '删除失败,请检查输入或联系管理员',
showCancel: false
});
}
}).catch((error) => {
console.error('Error:', error);
uni.showModal({
title: '提示',
content: '请求失败,请稍后重试',
showCancel: false
});
});
},
addDishesGroup() {
if (!this.form.groupName.trim()) {
uni.showToast({
title: '请输入菜品组名!',
icon: 'none'
});
return;
}
uni.request({
url: `${apiImageUrl}/api/dishesGroup/add`,
method: 'POST',
header: {
'Content-Type': 'application/json'
},
data: this.form,
}).then((res) => {
if (res[1] && res[1].data && res[1].data.code === 0) {
this.result = '添加成功!';
this.form.groupName = '';
this.leftGroup();
uni.showModal({
title: '提示',
content: '成功添加菜品组!',
showCancel: false
});
} else {
this.result = '添加失败,请检查输入或联系管理员';
uni.showModal({
title: '提示',
content: '添加失败,请检查输入或联系管理员!',
showCancel: false
});
}
}).catch((error) => {
console.error('Error:', error);
this.result = '请求失败,请稍后重试';
uni.showModal({
title: '提示',
content: '请求失败,请稍后重试!',
showCancel: false
});
});
}
}
};
</script>
<style lang="scss" scoped>
.item {
font-size: 13px;
padding: 10px 20px;
display: inline-block;
background-color: rgba(245, 245, 220, 0.8);
margin: 10px;
border-radius: 20px;
box-shadow: 0 4px #ccc, 0 6px 10px rgba(0,0,0,0.1), inset 0 2px #fff, inset 0 -2px 2px rgba(0,0,0,0.1);
transition: transform 0.2s;
&:hover {
transform: translateY(-2px);
box-shadow: 0 6px #ccc, 0 8px 15px rgba(0,0,0,0.1), inset 0 4px #fff, inset 0 -2px 3px rgba(0,0,0,0.1);
}
}
.navbar {
background-color: #4095e5;
display: flex;
flex-direction: row;
padding: 10px;
.search {
display: flex;
align-items: center;
padding: 0 10rpx 0 26rpx;
height: 50rpx;
color: #fff;
font-size: 28rpx;
border-radius: 32rpx;
background-color: rgba(255, 255, 255, 0.5);
width: 70%;
margin: 0 auto;
}
.icon-search {
margin-right: 10rpx;
}
.search-button {
margin-left: auto;
height: 50rpx;
background-color: #fff;
color: #4095e5;
border: none;
border-radius: 32rpx;
padding: 0 20rpx;
line-height: 50rpx;
font-size: 15px;
}
.transparent-input {
background-color: transparent;
border: none;
color: #fff;
outline: none;
width: 100%;
padding: 0 10rpx;
font-size: 28rpx;
}
}
.styled-input {
font-size: 14px;
width: calc(100% - 20px);
padding: 10px;
margin: 10px 0;
display: block;
background-color: rgba(245, 245, 220, 0.8);
border-radius: 20px;
box-shadow: 0 4px #ccc, 0 6px 10px rgba(0,0,0,0.1), inset 0 2px #fff, inset 0 -2px 2px rgba(0,0,0,0.1);
border: none;
outline: none;
transition: box-shadow 0.2s;
&:focus {
box-shadow: 0 6px #ccc, 0 8px 15px rgba(0,0,0,0.1), inset 0 4px #fff, inset 0 -2px 3px rgba(0,0,0,0.1);
}
}
.button-container {
display: flex;
justify-content: space-between;
}
.styled-button {
flex: 1;
margin: 5px;
padding: 10px;
background-color: rgba(173, 216, 230, 0.8);
border: none;
border-radius: 15px;
box-shadow: 0 4px #ccc, 0 6px 10px rgba(0,0,0,0.1), inset 0 2px #fff, inset 0 -2px 2px rgba(0,0,0,0.1);
cursor: pointer;
transition: box-shadow 0.2s, background-color 0.2s;
&:hover {
background-color: rgba(173, 216, 230, 1);
box-shadow: 0 6px #ccc, 0 8px 15px rgba(0,0,0,0.1), inset 0 4px #fff, inset 0 -2px 3px rgba(0,0,0,0.1);
}
}
.confirm {
background-color: rgba(135, 206, 235, 0.8);
font-size: 14px;
}
.delete {
background-color: rgba(255, 99, 71, 0.8);
font-size: 14px;
}
</style>

View File

@ -0,0 +1,139 @@
<template>
<scroll-view scroll-y class="viewport">
<view class="preview">
<swiper :circular="true" :autoplay="true" :interval="3000" indicator-dots>
<swiper-item>
<image
mode="aspectFill"
class="image"
src="https://ts1.cn.mm.bing.net/th/id/R-C.8f2db93b542db8adf6c850762c1cce4d?rik=erpuvqVy64IJzQ&riu=http%3a%2f%2fimg95.699pic.com%2fphoto%2f50044%2f9286.jpg_wh860.jpg&ehk=dnizwrPBuCaHnaxfih%2fryK7p%2fXZMbmolNORKknXvL%2bI%3d&risl=&pid=ImgRaw&r=0"
></image>
</swiper-item>
<swiper-item>
<image
mode="aspectFill"
class="image"
src="https://img95.699pic.com/photo/50127/2949.jpg_wh860.jpg"
></image>
</swiper-item>
<swiper-item>
<image
mode="aspectFill"
class="image"
src="https://img95.699pic.com/photo/50070/9636.jpg_wh860.jpg"
></image>
</swiper-item>
</swiper>
</view>
<view class="tab-menu">
<view
class="tab-item"
v-for="(tab, index) in tabs"
:key="index"
:class="{ active: currentIndex === index }"
@click="switchTab(index)"
>
{{ tab.name }}
</view>
</view>
<view class="content">
<block v-if="currentIndex === 0">
<sort></sort>
</block>
<block v-if="currentIndex === 1">
<groupVue></groupVue>
</block>
<block v-if="currentIndex === 2">
<addDishVue></addDishVue>
</block>
</view>
</scroll-view>
</template>
<script>
import { apiImageUrl } from '../../API/api';
import sort from './sort.vue'
import groupVue from './group.vue';
import addDishVue from './addDish.vue';
export default {
components: {
sort,
groupVue,
addDishVue
},
data(){
return {
businessId: '1830063677349658625',
currentIndex: 0,
resultArray: [],
historyList: [],
tabs: [
{ name: '总览' },
{ name: '菜品组操作' },
{ name: '新增菜品' },
],
};
},
methods: {
switchTab(index) {
this.currentIndex = index;
},
leftGroup(){
uni.request({
url:apiImageUrl+'/api/dishesGroup/list/dishesGroup',
method:'POST',
data: '1830063677349658625',
header: {
'cookie': uni.getStorageSync("cookie")
},
success(res) {
if(res.data.code===0){
console.log(res);
console.log("5555555555");
}
},
fail(res) {
console.log("失败啦");
}
});
},
}
}
</script>
<style lang="scss">
.viewport {
height: 100vh;
overflow: hidden;
image {
width: 100%;
}
}
.preview {
image {
width: 100%;
}
}
.tab-menu {
display: flex;
justify-content: space-around;
padding: 10px 0;
background-color: #f5f5f5;
}
.tab-item {
padding: 10px;
cursor: pointer;
&.active {
color: #4095e5;
font-weight: bold;
}
}
</style>

View File

@ -0,0 +1,585 @@
<template>
<view class="viewport">
<view class="categories">
<scroll-view class="primary" scroll-y>
<view
class="item"
v-for="(group, index) in resultArray"
:key="index"
:class="{ active: currentIndex === index }"
@click="switchTab(index)">
{{ group.groupName }}
</view>
</scroll-view>
<scroll-view class="secondary" scroll-y>
<view class="panel">
<view
class="container2"
v-for="(item, index) in filteredHistoryList"
:key="index"
@click="showDrawer('showLeft',item)">
<view class="box box-1">
<image :src="item.dishesImage" class="imageList"></image>
</view>
<view class="box box-2">
<view class="title">{{ item.dishesName }}</view>
<text class="sale">{{ item.dishesPrice }}</text>
<view class="money">{{ item.dishesPrice }}</view>
<view class="buttonList">
<view
class="button1"
@click.stop="deleteDish(item.id)">删除菜品</view>
<view
v-if="item.status === '0'"
class="button2"
@click.stop="toggleStatus(item, '1')">已上架</view>
<view
v-else
class="button2"
@click.stop="toggleStatus(item, '0')">已下架</view>
</view>
</view>
</view>
</view>
</scroll-view>
</view>
<uni-drawer ref="showLeft" mode="left" :mask-click="true" @change="change($event, 'showLeft')">
<view class="drawer-content">
<form>
<input v-model="editDish.dishesName" placeholder="菜品名称" />
<input v-model="editDish.dishesPrice" type="number" step="0.01" placeholder="价格" />
<button type="submit" @click.prevent="updateDish">保存</button>
</form>
</view>
</uni-drawer>
</view>
</template>
<script>
import { apiImageUrl } from '../../API/api';
export default {
data() {
return {
showLeft: false,
businessId: '',
currentIndex: 0,
newGroupName: '',
resultArray: [],
historyList: [],
editDish: {
businessId: '',
dishesGroupId: '',
dishesImage: '',
dishesName: '',
dishesPrice: 0,
},
loading: false,
};
},
created() {
this.getLoginUser();
},
methods: {
getLoginUser() {
uni.request({
url: `${apiImageUrl}/api/business/get/current`,
method: 'POST',
data: {},
header: {
'cookie': uni.getStorageSync("cookie")
},
success: (res) => {
if (res.data.code === 0) {
this.businessId = res.data.data.id;
this.leftGroup();
this.rightList();
}
},
fail: (error) => {
console.error('获取用户信息失败:', error);
uni.showModal({
title: '提示',
content: '获取用户信息失败!',
showCancel: false
});
}
});
},
leftGroup() {
uni.request({
url: `${apiImageUrl}/api/dishesGroup/list/dishesGroup`,
method: 'POST',
data: JSON.stringify({ businessId: this.businessId }),
header: {
'Content-Type': 'application/json',
'cookie': uni.getStorageSync("cookie")
},
success: (res) => {
if (res.data.code === 0) {
this.resultArray = res.data.data.map(item => ({ id: item.id, groupName: item.groupName }));
}
},
fail: (error) => {
console.error('获取菜品组失败:', error);
uni.showModal({
title: '提示',
content: '获取菜品组失败!',
showCancel: false
});
}
});
},
rightList() {
uni.request({
url: `${apiImageUrl}/api/dishes/list/dishes`,
method: 'POST',
data: JSON.stringify({ businessId: this.businessId }),
header: {
'Content-Type': 'application/json',
'cookie': uni.getStorageSync("cookie")
},
success: (res) => {
if (res.data.code === 0) {
this.historyList = res.data.data;
}
},
fail: (error) => {
console.error('获取菜品列表失败:', error);
uni.showModal({
title: '提示',
content: '获取菜品列表失败',
showCancel: false
});
}
});
},
switchTab(index) {
this.currentIndex = index;
const selectedGroupId = this.resultArray[index]?.id;
if (selectedGroupId) {
uni.request({
url: `${apiImageUrl}/api/dishes/list/dishesVO`,
method: 'POST',
data: JSON.stringify({ businessId: this.businessId, dishesGroupId: selectedGroupId }),
header: {
'Content-Type': 'application/json',
'cookie': uni.getStorageSync("cookie")
},
success: (res) => {
if (res.data.code === 0) {
this.historyList = res.data.data;
}
},
fail: (error) => {
console.error('Error fetching data:', error);
}
});
}
},
deleteDish(dishId) {
uni.request({
url: `${apiImageUrl}/api/dishes/delete`,
method: 'POST',
data: { id: dishId },
header: {
'cookie': uni.getStorageSync("cookie")
},
success: (res) => {
if (res.data.code === 0) {
this.rightList();
uni.showModal({
title: '提示',
content: '菜品删除成功',
showCancel: false
});
}
},
fail: (error) => {
console.error('删除菜品失败:', error);
uni.showModal({
title: '提示',
content: '菜品删除失败',
showCancel: false
});
}
});
},
// confirm() {},
// //打开窗口
// showDrawer(e) {
// this.$refs[e].open()
// },
// // 关闭窗口
// closeDrawer(e) {
// this.$refs[e].close()
// },
// // 抽屉状态发生变化触发
// change(e, type) {
// console.log((type === 'showLeft' ? '左窗口' : '右窗口') + (e ? '打开' : '关闭'));
// this[type] = e
// },
// showDrawer(drawer, item) {
// if (this.$refs[drawer]) {
// this.editDish = { ...item, businessId: this.businessId, dishesPrice: parseFloat(item.dishesPrice).toFixed(2) };
// this.$refs[drawer].open();
// }
// },
// closeDrawer() {
// if (this.$refs.showLeft) {
// this.$refs.showLeft.close();
// }
// this.editDish = {};
// },
showDrawer(drawer, item) {
if (this.$refs[drawer]) {
this.editDish = { ...item, businessId: this.businessId, dishesPrice: parseFloat(item.dishesPrice).toFixed(2) };
this.$refs[drawer].open();
}
},
// 关闭窗口
closeDrawer(e) {
if (this.$refs[e]) {
this.$refs[e].close();
}
this.editDish = {}; // 清空编辑菜品对象
},
// 抽屉状态发生变化触发
change(e, type) {
console.log((type === 'showLeft' ? '左窗口' : '右窗口') + (e ? '打开' : '关闭'));
this[type] = e;
},
// 显示侧边抽屉
/*updateDish() {
if (!this.editDish.dishesName || !this.editDish.dishesPrice || !this.editDish.dishesGroupId) {
console.error('请填写完整信息');
return;
}
this.editDish.dishesName = this.editDish.dishesName.trim();
this.editDish.dishesPrice = parseFloat(this.editDish.dishesPrice).toFixed(2);
uni.request({
url: `${apiImageUrl}/api/dishes/update`,
method: 'POST',
data: JSON.stringify(this.editDish),
header: {
'Content-Type': 'application/json',
'cookie': uni.getStorageSync("cookie")
},
success: (res) => {
if (res.data.code === 0) {
this.rightList();
this.closeDrawer();
} else {
console.error('菜品更新失败:', res.data.message);
}
},
fail: (error) => {
console.error('菜品更新请求失败:', error);
}
});
},
*/
toggleStatus(item, newStatus) {
uni.request({
url: `${apiImageUrl}/api/dishes/update/status`,
method: 'POST',
data: JSON.stringify({ id: item.id, status: newStatus }),
header: {
'Content-Type': 'application/json',
'cookie': uni.getStorageSync("cookie")
},
success: (res) => {
if (res.data.code !== 0) {
throw new Error(res.data.message);
}
item.status = newStatus;
uni.showModal({
title: '提示',
content: '菜品状态更新成功',
showCancel: false
});
},
fail: (error) => {
console.error('Update status failed:', error);
}
});
},
// 更新菜品
updateDish() {
if (!this.editDish.dishesName || !this.editDish.dishesPrice || !this.editDish.dishesGroupId) {
uni.showToast({
title: '请填写完整信息',
icon: 'none'
});
return;
}
// this.editDish.dishesName = this.editDish.dishesName.trim();
// this.editDish.dishesPrice = parseFloat(this.editDish.dishesPrice).toFixed(2);
uni.request({
url: `${apiImageUrl}/api/dishes/update`,
method: 'POST',
data: JSON.stringify(this.editDish),
header: {
'Content-Type': 'application/json',
'cookie': uni.getStorageSync("cookie")
},
success: (res) => {
if (res.data.code === 0) {
this.rightList(); // 刷新菜品列表
this.closeDrawer('showLeft'); // 关闭抽屉
uni.showToast({
title: '菜品更新成功',
icon: 'success'
});
} else {
uni.showToast({
title: res.data.message,
icon: 'none'
});
}
},
fail: (error) => {
console.error('菜品更新请求失败:', error);
uni.showToast({
title: '菜品更新失败',
icon: 'none'
});
}
});
},
},
computed: {
filteredHistoryList() {
const groupId = this.resultArray[this.currentIndex]?.id;
return groupId ? this.historyList.filter(item => item.dishesGroupId === groupId) : [];
}
}
};
</script>
<style lang="scss">
page {
height: 100%;
overflow: hidden;
}
.viewport {
height: 100%;
display: flex;
flex-direction: column;
}
.search {
padding: 0 30rpx 20rpx;
background-color: #fff;
.input {
display: flex;
align-items: center;
justify-content: space-between;
height: 64rpx;
padding-left: 26rpx;
color: #8b8b8b;
font-size: 28rpx;
border-radius: 32rpx;
background-color: #f3f4f4;
}
}
.icon-search {
&::before {
margin-right: 10rpx;
}
}
/* 分类 */
.categories {
flex: 1;
min-height: 400rpx;
display: flex;
}
/* 一级分类 */
.primary {
overflow: hidden;
width: 180rpx;
flex: none;
background-color: #f6f6f6;
.item {
display: flex;
justify-content: center;
align-items: center;
height: 96rpx;
font-size: 26rpx;
color: #595c63;
position: relative;
&::after {
content: '';
position: absolute;
left: 42rpx;
bottom: 0;
width: 96rpx;
border-top: 1rpx solid #e3e4e7;
}
}
.active {
background-color: #fff;
&::before {
content: '';
position: absolute;
left: 0;
top: 0;
width: 8rpx;
height: 100%;
background-color: #4095e5;
}
}
}
.primary .item:last-child::after,
.primary .active::after {
display: none;
}
/* 二级分类 */
.secondary {
background-color: #fff;
width: 100%;
.carousel {
height: 400rpx;
margin: 0 30rpx 20rpx;
border-radius: 4rpx;
overflow: hidden;
}
.panel {
margin: 0 30rpx 0rpx;
}
.container {
display: flex;
flex-direction: column;
align-items: center;
padding: 20rpx;
}
.history-list {
width: 100%;
}
.history-item {
display: flex;
margin-bottom: 20rpx;
flex-direction: row;
}
.history-img {
width: 200rpx;
height: 150rpx;
margin-right: 20rpx;
border-radius: 10px;
}
.history-info {
display: flex;
flex-direction: column;
justify-content: space-between;
width: 100px;
}
.history-title {
font-size: 32rpx;
font-weight: bold;
}
.history-description {
font-size: 28rpx;
}
.history-time{
font-size: 20rpx;
color: #999;
}
.history-money{
font-size: 30rpx;
color: black;
font-weight: 700;
}
}
.icon {
margin-top: 30rpx;
}
//内容区域
.container2 {
width: 100%;
}
.box-1 {
width: 30%;
height: 250rpx;
float: left;
padding: 10px;
box-sizing: border-box;
}
.box-2 {
width: 70%;
height: 250rpx;
float: left;
padding: 10px;
box-sizing: border-box;
}
.imageList {
height: 70%;
}
.title {
font-weight: 700;
}
.sale {
font-size: 25rpx;
color: #8b8b8b;
margin-top: 10px;
}
.inventory {
font-size: 25rpx;
color: #8b8b8b;
margin-left: 20px;
margin-top: 10px;
}
.money {
font-size: 35rpx;
color: #eb5354;
font-weight: 700;
margin-top: 17px;
}
.buttonList {
width: 100%;
height: 30%;
margin-top: 5px;
}
.button1 {
font-size: 24rpx;
display: inline-block;
border: 1px solid #999;
padding: 5px 10px;
border-radius: 5px;
}
.button2 {
font-size: 24rpx;
display: inline-block;
border: 1px solid #999;
margin-left: 10px;
padding: 5px 10px;
border-radius: 5px;
}
.button3 {
font-size: 24rpx;
display: inline-block;
border: 1px solid #999;
margin-left: 10px;
padding: 5px 10px;
border-radius: 5px;
}
</style>

View File

@ -0,0 +1,505 @@
<template>
<!-- <view class="content">
<view class="body"> --><!--
<view>
<textarea class="result" v-model="returnResult"></textarea>
</view>
<textarea class="input" @input="inputEvent" />
<button type="primary" @tap="sendData">发送(票据可使用)</button>
<view style='margin-top:4%;display: flex;flex-direction: row;'> -->
<button type='primary' @tap='receiptTest' :loading='isReceiptSend' :disabled='isReceiptSend'>票据测试</button>
<!-- <button type='primary' @tap='labelTest' :loading='isLabelSend' :disabled='isLabelSend'>标签测试</button>
</view>
<view style='margin-top:4%;display: flex;flex-direction: row;'>
hidden='true' -->
<!--<canvas canvas-id='edit_area_canvas' :style="{width:canvasWidth+'px',height:canvasHeight+'px'}"></canvas>
</view>
<picker style='margin:20px' mode='selector' :range='buffSize' :value='buffIndex' @change='buffBindChange'>
当前每次发送字节数为(点击可更换){{buffSize[buffIndex]}}
</picker>
<picker style='margin:20px' mode='selector' :range='printNum' :value='printNumIndex' @change='printNumBindChange'>
当前打印份数(点击可更换){{printNum[printNumIndex]}}
</picker>
</view>
<view>
<h1>订单详情</h1>
<view v-if="orderInfo">
<p>ID: {{ orderInfo.id }}</p>
<p>创建时间: {{ orderInfo.createTime }}</p>
<p>手机号: {{ orderInfo.phone }}</p>
<p>总价: {{ orderInfo.totalPrice }}</p>
</view>
</view>
</view> -->
</template>
<script>
var tsc = require("../../util/ble/tsc.js");
var esc = require("../../util/ble/esc.js");
var encode = require("../../util/ble/encoding.js");
import {
mapState
} from 'vuex';
export default {
data() {
return {
sendContent: "",
looptime: 0,
currentTime: 1,
lastData: 0,
oneTimeData: 0,
returnResult: "",
canvasWidth: 180,
canvasHeight: 180,
imageSrc: '../../static/logo.png',
buffSize: [],
buffIndex: 0,
printNum: [],
printNumIndex: 0,
printerNum: 1,
currentPrint: 1,
isReceiptSend: false,
isLabelSend: false,
orderInfo: null,
phoneNumber: "",
businessName:""
};
},
computed: mapState(['sysinfo', 'Bluetooth']),
onLoad(options) {
if (options.orderInfo) {
// 解码并解析订单信息
const orderInfo = decodeURIComponent(options.orderInfo);
this.orderInfo = JSON.parse(orderInfo);
// 从 orderInfo 中提取手机号
if (this.orderInfo && this.orderInfo.phone) {
this.phoneNumber = this.orderInfo.phone;
} else {
this.phoneNumber = '未提供手机号';
console.warn('没有从 orderInfo 中获取到 phoneNumber');
}
if (this.orderInfo && this.orderInfo.businessName) {
this.businessName = this.orderInfo.businessName;
} else {
this.businessName = '未提供商户名称';
console.warn('没有从 orderInfo 中获取到 .businessName');
}
} else {
this.phoneNumber = '未提供手机号';
console.warn('没有从 URL 参数中获取到 orderInfo');
}
let that = this;
let {
BLEInformation
} = that.Bluetooth;
// uni.notifyBLECharacteristicValueChange({
// deviceId: BLEInformation.deviceId,
// serviceId: BLEInformation.notifyServiceId,
// characteristicId: BLEInformation.notifyCharaterId,
// state: true,
// success(res) {
// uni.onBLECharacteristicValueChange(function(r) {
// console.log(`characteristic ${r.characteristicId} has changed, now is ${r}`)
// })
// },
// fail: function(e) {
// console.log(e)
// },
// complete: function(e) {
// console.log(e)
// }
// })
},
onReady(){
let list = []
let numList = []
let j = 0
for (let i = 20; i < 200; i += 10) {
list[j] = i;
j++
}
for (let i = 1; i < 10; i++) {
numList[i - 1] = i
}
this.buffSize = list;
this.oneTimeData = list[0];
this.printNum = numList;
this.printerNum = numList[0];
},
onShow(){
let that = this;
let width;
let height;
uni.getImageInfo({
src: that.imageSrc,
success(res) {
console.log(res.width)
console.log(res.height)
width = res.width
height = res.height
that.canvasWidth = res.width;
that.canvasHeight = res.height;
}
})
const ctx = uni.createCanvasContext("edit_area_canvas", this);
// if (app.globalData.platform == "android") {
// ctx.translate(width, height)
// ctx.rotate(180 * Math.PI / 180)
// }
ctx.drawImage(this.imageSrc, 0, 0, width, height);
ctx.draw();
},
onUnload() {
let that = this;
let {
BLEInformation
} = that.Bluetooth;
// uni.closeBLEConnection({
// deviceId: BLEInformation.deviceId,
// success: function(res) {
// console.log("关闭蓝牙成功")
// },
// })
},
methods:{
inputEvent(e){
this.sendContent = e.detail.value;
},
sendData(){
let data = this.sendContent + "\n"
this.looptime = 0;
var content = new encode.TextEncoder(
'gb18030', {
NONSTANDARD_allowLegacyEncoding: true
}).encode(data);
this.prepareSend(content);
},
labelTest(){
let that = this;
let canvasWidth = that.canvasWidth
let canvasHeight = that.canvasHeight
let command = tsc.jpPrinter.createNew()
command.setSize(48, 40)
command.setGap(0)
command.setCls()
command.setText(0, 30, "TSS24.BF2", 1, 1, "图片")
command.setQR(40, 120, "L", 5, "A", "www.smarnet.cc佳博智汇")
command.setText(60, 90, "TSS24.BF2", 1, 1, "佳博智汇")
command.setText(170, 50, "TSS24.BF2", 1, 1, "小程序测试")
command.setText(170, 90, "TSS24.BF2", 1, 1, "测试数字12345678")
command.setText(170, 120, "TSS24.BF2", 1, 1, "测试英文abcdefg")
command.setText(170, 150, "TSS24.BF2", 1, 1, "测试符号/*-+!@#$")
command.setBarCode(170, 180, "EAN8", 64, 1, 3, 3, "1234567")
uni.canvasGetImageData({
canvasId: 'edit_area_canvas',
x: 0,
y: 0,
width: canvasWidth,
height: canvasHeight,
success: function(res) {
command.setBitmap(60, 0, 1, res)
},
complete: function() {
command.setPagePrint()
that.isLabelSend = true;
that.prepareSend(command.getData())
}
})
},
//票据测试
receiptTest(){
var that = this;
var canvasWidth = that.canvasWidth
var canvasHeight = that.canvasHeight
var command = esc.jpPrinter.createNew()
command.init()
//取餐码
command.bold(1);//加粗
command.setFontSize(17);//字体大小
command.setSelectJustification(0)//居左
command.rowSpace(100);
//command.setText(`手机号: ${this.phoneNumber}`);
command.setText(`# ${this.orderInfo.id}`);
// command.setText(`# ${this.orderInfo.pickupCode.slice(-4)}`);
command.setPrint();
command.rowSpace(60);
command.bold(0);//取消加粗
command.setFontSize(0);//正常字体
// 标题
command.bold(1);//加粗
command.setFontSize(16);//字体大小
command.setSelectJustification(1)//居中
command.rowSpace(100);
//command.setText(`手机号: ${this.phoneNumber}`);
command.setText(` ${this.orderInfo.businessVO.businessName}`);
command.setPrint();
command.rowSpace(60);
command.bold(0);//取消加粗
command.setFontSize(0);//正常字体
const formattedCreateTime = this.formatCreateTime(this.orderInfo.createTime);
//食堂地址
command.setSelectJustification(0);//居左
command.setText(`哈尔滨华德学院:${this.orderInfo.businessVO.address}`);
command.setPrint();
//时间
command.setSelectJustification(0);//居左
command.setText(`创建时间: ${this.orderInfo.updateTime.slice(0, 19).replace('T', ' ')}`);
command.setPrint();
//编号
command.setSelectJustification(0);//居左
command.setText(`订单编号: ${this.orderInfo.pickupCode}`);
command.setPrintAndFeed(80);//打印并走纸feed个单位
//列表
command.rowSpace(80);//间距
command.bold(5);//加粗
command.setText("菜品");
command.setAbsolutePrintPosition(100);
// command.setText("大小");
// command.setAbsolutePrintPosition(180);
/* command.setText("口味");
command.setAbsolutePrintPosition(180); */
command.setText("单价");
command.setAbsolutePrintPosition(180);
command.setText("数量");
command.setAbsolutePrintPosition(270);
command.setText("金额");
command.setPrint()
command.bold(0);//加粗
// -------1
for (let item of this.orderInfo.orderDetailsVOList) {
command.setText(item.dishesVO?.dishesName);
command.setAbsolutePrintPosition(100);
// command.setText("大碗");
// command.setAbsolutePrintPosition(180);
/* command.setText("麻辣");
command.setAbsolutePrintPosition(180); */
command.setText(item.price);
command.setAbsolutePrintPosition(180);
command.setText(item.quantity);
command.setAbsolutePrintPosition(270);
command.setText(item.subtotal);
command.setPrint()
}
//合计
command.bold(5);//加粗
command.setAbsolutePrintPosition(0);
command.setText(`总数:${this.orderInfo.number}`);
command.setAbsolutePrintPosition(150);
command.setText(`合计:${this.orderInfo.totalPrice}`);
command.setPrint();
command.setPrint();
//提示
command.rowSpace(80);//间距
command.bold(2);//加粗
command.setSelectJustification(0);//居中
command.setText("用户需要餐具");
command.setPrint();
command.setText(`备注:${this.orderInfo.notes}`);
command.setPrint();
//电话
command.setSelectJustification(0);//居左
command.setText(`联系电话: ${this.orderInfo.phone}`);
command.setPrint();
command.setPrintAndFeedRow(3);
that.isReceiptSend = true;
that.prepareSend(command.getData());
},
formatCreateTime(createTime) {
const dateObj = new Date(createTime);
const year = dateObj.getFullYear();
const month = String(dateObj.getMonth() + 1).padStart(2, '0'); // 月份从 0 开始,需要加 1
const day = String(dateObj.getDate()).padStart(2, '0');
const hours = String(dateObj.getHours()).padStart(2, '0');
const minutes = String(dateObj.getMinutes()).padStart(2, '0');
const seconds = String(dateObj.getSeconds()).padStart(2, '0');
return `${year}-${month}-${day} ${hours}:${minutes}:${seconds}`;
},
prepareSend(buff){
console.log(buff);
let that = this
let time = that.oneTimeData
let looptime = parseInt(buff.length / time);
let lastData = parseInt(buff.length % time);
console.log(looptime + "---" + lastData)
this.looptime = looptime + 1;
this.lastData = lastData;
this.currentTime = 1;
that.Send(buff)
},
//查询打印机状态
queryStatus(){
let command = esc.jpPrinter.Query();
command.getRealtimeStatusTransmission(1);
},
//分包发送
Send(buff){
let that = this
let {currentTime,looptime:loopTime,lastData,oneTimeData:onTimeData,printerNum:printNum,currentPrint}=that;
let buf;
let dataView;
if (currentTime < loopTime) {
buf = new ArrayBuffer(onTimeData)
dataView = new DataView(buf)
for (var i = 0; i < onTimeData; ++i) {
dataView.setUint8(i, buff[(currentTime - 1) * onTimeData + i])
}
} else {
buf = new ArrayBuffer(lastData)
dataView = new DataView(buf)
for (var i = 0; i < lastData; ++i) {
dataView.setUint8(i, buff[(currentTime - 1) * onTimeData + i])
}
}
console.log("第" + currentTime + "次发送数据大小为:" + buf.byteLength)
let {
BLEInformation
} = that.Bluetooth;
plus.bluetooth.writeBLECharacteristicValue({
deviceId: BLEInformation.deviceId,
serviceId: BLEInformation.writeServiceId,
characteristicId: BLEInformation.writeCharaterId,
value: buf,
success: function(res) {
console.log(res)
},
fail: function(e) {
console.log(e)
},
complete: function() {
currentTime++
if (currentTime <= loopTime) {
that.currentTime = currentTime;
that.Send(buff)
} else {
uni.showToast({
title: '已打印第' + currentPrint + '张',
})
if (currentPrint == printNum) {
that.looptime = 0;
that.lastData = 0;
that.currentTime = 1;
that.isReceiptSend = false;
that.isLabelSend = false;
that.currentPrint = 1;
} else {
currentPrint++;
that.currentPrint = currentPrint;
that.currentTime = 1;
that.Send(buff)
}
}
}
})
},
buffBindChange: function(res) { //更改打印字节数
let index = res.detail.value
let time = this.buffSize[index]
this.buffIndex = index;
this.oneTimeData = time;
},
printNumBindChange: function(res) { //更改打印份数
let index = res.detail.value
let num = this.printNum[index]
this.printNumIndex = index;
this.printerNum = num;
},
}
}
</script>
<style lang="less">
.input{
text-align: top;
width: 90%;
height: 150px;
margin-left: 4%;
margin-right: 4%;
margin-top: 10px;
margin-bottom: 12px;
border: 1px solid slategray;
}
.receiver_info_scroll_view{
width: 90%;
height: 200px;
margin-left: 4%;
margin-right: 4%;
margin-top: 10px;
margin-bottom: 25px;
border: 1px solid black;
}
.result{
width: 90%;
height: 150px;
border: 1px solid black;
margin-left: 4%;
margin-bottom: 4%;
margin-top: 5%;
}
button{
width: 90%;
margin-left: 5%;
margin-right: 5%;
}
.switch{
float: right;
margin-right: 20px;
margin-bottom: 16px;
}
text{
color: #fff;
display: block;
}
input{
color: gainsboro;
float: left;
}
.v_net_ssid{
width: 100%;
background: #fff;
}
.v_net_passw{
width: 100%;
background: antiquewhite;
}
.swiper{
width: 100%;
height: 100%;
}
</style>

View File

@ -0,0 +1,373 @@
<template>
<view class="container">
<view class="header">
<view class="title">商家注册</view>
</view>
<view class="form">
<view class="input-group" v-for="(field, index) in fields" :key="index">
<view class="label">{{ field.label }}</view>
<view class="input">
<!-- 商家分类下拉选择器 -->
<template v-if="field.model === 'categoryId'">
<uni-data-select
v-model="formData.categoryId"
:localdata="range"
:clear="false"
placeholder="请选择商家分类"
class="distribution-select"
mode="selector"
></uni-data-select>
</template>
<!-- 普通输入框 -->
<input
v-else-if="!field.isFile"
v-model="formData[field.model]"
:placeholder="field.placeholder"
class="styled-input"
@blur="validateField(field)"
/>
<!-- 文件上传按钮 -->
<view v-else class="upload-container">
<button @click="handleUpload(field)" class="upload-button">
{{ formData[field.model] ? '已上传' : '点击上传' }}
</button>
<text v-if="formData[field.model]" class="upload-tip">已上传文件</text>
</view>
</view>
</view>
<view class="button">
<button @click="saveAddress" class="styled-button">点击注册</button>
</view>
</view>
</view>
</template>
<script>
import { apiImageUrl } from '../../API/api';
export default {
data() {
return {
formData: {
address: '',
backIdCard: '',
bankCard: '',
businessAvatar: '',
businessImages: '',
businessName: '',
businessPhone: '',
businessProfile: '',
categoryId: '',
endBusiness: '',
frontIdCard: '',
license: '',
shopkeeper: '',
startBusiness: '',
userAccount: '',
userPassword: ''
},
range: [
{ value: '1', text: '第一餐厅' },
{ value: '2', text: '第二餐厅' },
{ value: '3', text: '第三餐厅' },
{ value: '4', text: '第四餐厅' },
{ value: '5', text: '第五餐厅' }
],
fields: [
{ label: '商家地址', model: 'address', placeholder: '请输入地址' },
{
label: '身份证背面图片',
model: 'backIdCard',
isFile: true,
bizType: 'card'
},
{ label: '银行卡号', model: 'bankCard', placeholder: '请输入银行卡号', validation: (value) => value.length === 16, errorMsg: '银行卡号必须为16位' },
{
label: '商家头像',
model: 'businessAvatar',
isFile: true,
bizType: 'user_avatar'
},
{
label: '商家图片',
model: 'businessImages',
isFile: true,
bizType: 'user_avatar'
},
{ label: '商家名称', model: 'businessName', placeholder: '请输入商家名称' },
{ label: '商家手机号', model: 'businessPhone', placeholder: '请输入商家手机号', validation: (value) => value.length === 11, errorMsg: '手机号必须为11位' },
{ label: '商家门店简介', model: 'businessProfile', placeholder: '请输入商家简介' },
{
label: '商家分类',
model: 'categoryId',
},
{ label: '关店时间', model: 'endBusiness', placeholder: '关店时间' },
{
label: '身份证正面',
model: 'frontIdCard',
isFile: true,
bizType: 'card'
},
{
label: '营业执照正面',
model: 'license',
isFile: true,
bizType: 'card'
},
{
label: '店主姓名',
model: 'shopkeeper',
placeholder: '请输入店主姓名',
validation: (value) => /^[\u4e00-\u9fa5]+$/.test(value),
errorMsg: '姓名只能包含汉字'
},
{ label: '开店时间', model: 'startBusiness', placeholder: '开店时间' },
{ label: '账户', model: 'userAccount', placeholder: '账户' },
{ label: '密码', model: 'userPassword', placeholder: '密码', validation: (value) => value.length >= 8, errorMsg: '密码长度至少为8位' }
]
};
},
methods: {
handleUpload(field) {
uni.chooseImage({
count: 1,
sizeType: ['compressed'],
sourceType: ['album', 'camera'],
success: (res) => {
const tempFilePath = res.tempFilePaths[0];
this.uploadFile(tempFilePath, field);
}
});
},
uploadFile(filePath, field) {
uni.uploadFile({
url: apiImageUrl+'/api/file/upload/server/not_login',
filePath: filePath,
name: 'file',
formData: {
biz: field.bizType
},
success: (res) => {
try {
const response = JSON.parse(res.data);
if(response.code === 0) {
this.formData[field.model] = response.data;
uni.showToast({
title: '上传成功',
icon: 'success'
});
}
} catch(e) {
console.error('解析响应失败:', e);
}
},
fail: (err) => {
uni.showToast({
title: '上传失败',
icon: 'none'
});
}
});
},
validateField(field) {
if(field.isFile) return;
const value = this.formData[field.model].trim();
if (field.validation && !field.validation(value)) {
uni.showToast({
title: field.errorMsg,
icon: 'none',
duration: 2000
});
}
},
saveAddress() {
for (const field of this.fields) {
if(field.isFile) {
if(!this.formData[field.model]) {
uni.showToast({
title: `${field.label}必须上传`,
icon: 'none'
});
return;
}
continue;
}
const value = this.formData[field.model].trim();
if (!value) {
uni.showToast({
title: `${field.label}不能为空,请填写`,
icon: 'none',
duration: 2000
});
return;
}
if (field.validation && !field.validation(value)) {
uni.showToast({
title: field.errorMsg,
icon: 'none',
duration: 2000
});
return;
}
}
uni.request({
url: apiImageUrl+'/api/business/add',
method: 'POST',
data: this.formData,
header: {
'Content-Type': 'application/json',
'cookie': uni.getStorageSync("cookie") || ''
},
success: (res) => {
if(res.data.code === 0){
uni.showToast({
title: '注册成功!',
duration: 2000,
icon: "success"
})
} else if(res.data.code === 40000) {
uni.showToast({
title: res.data.description,
duration: 2000,
icon: "fail"
})
}
},
fail: (err) => {
console.log("请求失败", err);
uni.showToast({
title: '网络连接失败',
icon: 'none',
duration: 2000
});
}
});
}
}
};
</script>
<style lang="scss" scoped>
.container {
padding: 20px;
background-color: #fff;
border-radius: 8px;
box-shadow: 0 0 10px rgba(0, 0, 0, 0.1);
}
.header {
display: flex;
justify-content: space-between;
align-items: center;
margin-bottom: 20px;
.title {
font-size: 24px;
font-weight: bold;
}
}
.upload-container {
display: flex;
align-items: center;
gap: 10px;
}
.upload-button {
padding: 8px 15px;
background-color: #4CAF50;
color: white;
border-radius: 5px;
font-size: 14px;
}
.upload-tip {
color: #666;
font-size: 12px;
}
.form {
.input-group {
display: flex;
align-items: center;
margin-bottom: 20px;
.label {
flex: 1;
font-size: 14px;
margin-right: 20px;
}
.input {
flex: 3;
.styled-input {
font-size: 14px;
width: 100%;
padding: 10px;
background-color: rgba(255, 235, 59, 0.6);
border: none;
border-radius: 20px;
box-shadow: 0 4px 6px rgba(0, 0, 0, 0.1), 0 1px 3px rgba(0, 0, 0, 0.08);
outline: none;
transition: all 0.2s ease-in-out;
&:focus {
background-color: rgba(255, 235, 59, 0.8);
box-shadow: 0 6px 8px rgba(0, 0, 0, 0.15), 0 2px 4px rgba(0, 0, 0, 0.1);
}
}
}
}
.button {
margin-top: 20px;
.styled-button {
width: 100%;
padding: 10px;
background-color: #007bff;
color: #fff;
border: none;
border-radius: 15px;
cursor: pointer;
font-size: 16px;
line-height: inherit;
transition: background-color 0.2s;
&:hover {
background-color: #0056b3;
}
}
}
}
.distribution-select {
width: 100%;
.uni-select {
padding: 10px;
background-color: rgba(255, 235, 59, 0.6);
border-radius: 20px;
box-shadow: 0 4px 6px rgba(0, 0, 0, 0.1), 0 1px 3px rgba(0, 0, 0, 0.08);
&::after {
border-color: #5e7dec;
}
}
}
</style>

View File

@ -0,0 +1,259 @@
<template>
<view class="chat">
<scroll-view :style="{ height: `${windowHeight}rpx` }" id="scrollview" scroll-y="true" :scroll-top="scrollTop"
:scroll-with-animation="true" class="scroll-view">
<view id="msglistview" class="chat-body">
<view v-for="(item, index) in msgList" :key="index">
<view class="item self" v-if="item.userContent != ''">
<view class="content right">
{{ item.userContent }}
</view>
<view class="avatar">
</view>
</view>
<view class="item Ai" v-if="item.botContent != ''">
<view class="avatar">
</view>
<view class="content left">
{{ item.botContent }}
</view>
</view>
</view>
</view>
</scroll-view>
<view class="chat-bottom">
<view class="send-msg">
<view class="uni-textarea">
<textarea v-model="chatMsg" maxlength="300" :show-confirm-bar="false" auto-height></textarea>
</view>
<button @click="handleSend" class="send-btn">发送</button>
</view>
</view>
</view>
</template>
<script>
export default {
data() {
return {
scrollTop: 0,
userId: '',
chatMsg: "",
msgList: [
{
botContent: "商家正在积极出餐吗,请问有什么问题嘛?",
recordId: 0,
titleId: 0,
userContent: "",
userId: 0
},
{
botContent: "",
recordId: 0,
titleId: 0,
userContent: "不要香菜",
userId: 0
},
]
}
},
computed: {
windowHeight() {
return this.rpxTopx(uni.getSystemInfoSync().windowHeight)
}
},
methods: {
rpxTopx(px) {
let deviceWidth = uni.getSystemInfoSync().windowWidth
let rpx = (750 / deviceWidth) * Number(px)
return Math.floor(rpx)
},
handleSend() {
if (!this.chatMsg || !/^\s+$/.test(this.chatMsg)) {
let obj = {
botContent: "",
recordId: 0,
titleId: 0,
userContent: this.chatMsg,
userId: 0
}
this.msgList.push(obj);
this.chatMsg = '';
} else {
this.$modal.showToast('不能发送空白消息')
}
},
}
}
</script>
<style lang="scss" scoped>
$chatContentbgc: #4095e5;
$sendBtnbgc: #4095e5;
view,
button,
text,
input,
textarea {
margin: 0;
padding: 0;
box-sizing: border-box;
}
.chat {
.scroll-view {
::-webkit-scrollbar {
display: none;
width: 0 !important;
height: 0 !important;
-webkit-appearance: none;
background: transparent;
color: transparent;
}
background-color: #F6F6F6;
.chat-body {
display: flex;
flex-direction: column;
padding-top: 23rpx;
.self {
justify-content: flex-end;
}
.item {
display: flex;
padding: 23rpx 30rpx;
.right {
background-color: $chatContentbgc;
}
.left {
background-color: #FFFFFF;
}
.right::after {
position: absolute;
display: inline-block;
content: '';
width: 0;
height: 0;
left: 100%;
top: 10px;
border: 12rpx solid transparent;
border-left: 12rpx solid $chatContentbgc;
}
.left::after {
position: absolute;
display: inline-block;
content: '';
width: 0;
height: 0;
top: 10px;
right: 100%;
border: 12rpx solid transparent;
border-right: 12rpx solid #FFFFFF;
}
.content {
position: relative;
max-width: 486rpx;
border-radius: 8rpx;
word-wrap: break-word;
padding: 24rpx 24rpx;
margin: 0 24rpx;
border-radius: 5px;
font-size: 32rpx;
font-family: PingFang SC;
font-weight: 500;
color: #333;
line-height: 42rpx;
}
.avatar {
display: flex;
justify-content: center;
width: 78rpx;
height: 78rpx;
background-image: url("https://pic2.zhimg.com/v2-45e3ca228438d1e4c3e98e38c8f8e4a4_r.jpg?source=1940ef5c");
background-size: contain;
border-radius: 8rpx;
overflow: hidden;
image {
align-self: center;
}
}
}
}
}
.chat-bottom {
width: 100%;
height: 177rpx;
background: #F4F5F7;
.send-msg {
display: flex;
align-items: flex-end;
padding: 16rpx 30rpx;
width: 100%;
min-height: 177rpx;
position: fixed;
bottom: 0;
background: #EDEDED;
}
.uni-textarea {
padding-bottom: 70rpx;
textarea {
width: 537rpx;
min-height: 75rpx;
max-height: 500rpx;
background: #FFFFFF;
border-radius: 8rpx;
font-size: 32rpx;
font-family: PingFang SC;
color: #333333;
line-height: 43rpx;
padding: 5rpx 8rpx;
}
}
.send-btn {
display: flex;
align-items: center;
justify-content: center;
margin-bottom: 70rpx;
margin-left: 25rpx;
width: 128rpx;
height: 75rpx;
background: $sendBtnbgc;
border-radius: 8rpx;
font-size: 28rpx;
font-family: PingFang SC;
font-weight: 500;
color: #FFFFFF;
line-height: 28rpx;
}
}
}
</style>

View File

@ -0,0 +1,29 @@
<template>
<view>
<h1>订单详情</h1>
<view v-if="orderInfo">
<p>ID: {{ orderInfo.id }}</p>
<p>创建时间: {{ orderInfo.createTime }}</p>
<p>手机号: {{ orderInfo.phone }}</p>
<p>总价: {{ orderInfo.totalPrice }}</p>
<!-- 其他订单信息 -->
</view>
</view>
</template>
<script>
export default {
data() {
return {
orderInfo: null
};
},
onLoad(options) {
if (options.orderInfo) {
// 解码并解析订单信息
const orderInfo = decodeURIComponent(options.orderInfo);
this.orderInfo = JSON.parse(orderInfo);
}
}
};
</script>

View File

@ -0,0 +1,189 @@
<template>
<view>
<view class="item" v-for="(tab, index) in 10" :key="index">
zxt
</view>
<uni-drawer ref="showLeft" mode="left" :mask-click="true" @change="change($event, 'showLeft')">
<view class="drawer-content">
<input class="styled-input" placeholder="请输入菜品名" />
<input class="styled-input" placeholder="请输入菜品图片" />
<input class="styled-input" type="number" step="0.01" placeholder="请输入菜品价格" />
<view class="button-container">
<button class="styled-button confirm">确认</button>
<button class="styled-button delete">删除</button>
</view>
</view>
</uni-drawer>
</view>
</template>
<script>
import { apiImageUrl } from '../../API/api';
export default {
data() {
return {
businessId: '1830063677349658625',
resultArray: [],
result: null,
currentGroupId: '',
form: {
dishesName: '',
dishesImage: '',
dishesPrice: '',
dishesGroup: '',
inventoryStatus: 0,
packPrice: 0,
specificationsIds: [],
status: 0,
}
};
},
mounted() {
this.leftGroup();
},
methods: {
leftGroup() {
const DishesGroupQueryRequest = {
businessId: this.businessId
};
uni.request({
url: apiImageUrl + '/api/dishesGroup/list/dishesGroup',
method: 'POST',
data: JSON.stringify(DishesGroupQueryRequest),
header: {
'Content-Type': 'application/json'
}
}).then((res) => {
console.log(res); // 打印完整的响应对象
if (res[1] && res[1].data && res[1].data.code === 0) {
this.resultArray = res[1].data.data.map(item => ({
id: item.id,
groupName: item.groupName
}));
console.log(this.resultArray);
} else {
console.error('Unexpected response structure:', res);
}
}).catch((error) => {
console.error('Error fetching dishes groups:', error);
});
},
showDrawer(drawer, tab) {
this.currentGroupId = tab.id; // 保存当前菜品组的ID
this.form.dishesGroup = tab.id; // 设置新菜品组ID
this.$refs[drawer].open();
},
closeDrawer() {
this.$refs.showLeft.close();
},
addDishes() {
const data = {
businessId: this.businessId,
dishesGroupId: parseInt(this.form.dishesGroup, 10),
dishesImage: this.form.dishesImage,
dishesName: this.form.dishesName,
dishesPrice: parseFloat(this.form.dishesPrice),
inventoryStatus: 0,
packPrice: 0,
specificationsIds: [],
status: 0,
};
uni.request({
url: apiImageUrl+'/api/dishes/add',
method: 'POST',
header: {
'content-type': 'application/json' // 默认值
},
data: data,
success: (res) => {
console.log('成功返回:', res.data);
// 在这里处理成功的响应
this.result = '菜品添加成功!';
this.closeDrawer();
uni.showModal({
title: '提示',
content: '菜品添加成功!',
showCancel: false
});
},
fail: (err) => {
console.error('请求失败:', err);
// 在这里处理错误
this.result = '菜品添加失败,请重试。';
uni.showModal({
title: '提示',
content: '菜品添加失败,请重试!',
showCancel: false
});
}
});
}
}
};
</script>
<style lang="scss" scoped>
.item {
padding: 20px;
display: inline-block;
background-color: rgba(245, 245, 220, 0.8);
margin: 10px;
border-radius: 20px;
box-shadow: 0 4px #ccc, 0 6px 10px rgba(0,0,0,0.1), inset 0 2px #fff, inset 0 -2px 2px rgba(0,0,0,0.1);
transition: transform 0.2s;
&:hover {
transform: translateY(-2px);
box-shadow: 0 6px #ccc, 0 8px 15px rgba(0,0,0,0.1), inset 0 4px #fff, inset 0 -2px 3px rgba(0,0,0,0.1);
}
}
.styled-input {
width: calc(100% - 20px); /* 确保输入框宽度适应容器 */
padding: 10px;
margin: 10px 0; /* 设置上下间距为10px */
display: block;
background-color: rgba(245, 245, 220, 0.8);
border-radius: 20px;
box-shadow: 0 4px #ccc, 0 6px 10px rgba(0,0,0,0.1), inset 0 2px #fff, inset 0 -2px 2px rgba(0,0,0,0.1);
border: none;
outline: none;
transition: box-shadow 0.2s;
&:focus {
box-shadow: 0 6px #ccc, 0 8px 15px rgba(0,0,0,0.1), inset 0 4px #fff, inset 0 -2px 3px rgba(0,0,0,0.1);
}
}
.button-container {
display: flex;
justify-content: space-between;
}
.styled-button {
flex: 1;
margin: 5px;
padding: 10px;
background-color: rgba(173, 216, 230, 0.8); /* 浅蓝色半透明 */
border: none;
border-radius: 15px;
box-shadow: 0 4px #ccc, 0 6px 10px rgba(0,0,0,0.1), inset 0 2px #fff, inset 0 -2px 2px rgba(0,0,0,0.1);
cursor: pointer;
transition: box-shadow 0.2s, background-color 0.2s;
&:hover {
background-color: rgba(173, 216, 230, 1); /* 鼠标悬停时颜色更不透明 */
box-shadow: 0 6px #ccc, 0 8px 15px rgba(0,0,0,0.1), inset 0 4px #fff, inset 0 -2px 3px rgba(0,0,0,0.1);
}
}
.confirm {
background-color: rgba(135, 206, 235, 0.8); /* 确认按钮使用稍微深一点的浅蓝色 */
}
.delete {
background-color: rgba(255, 99, 71, 0.8); /* 删除按钮使用浅红色 */
}
</style>