This commit is contained in:
GaoHao
2024-12-11 10:41:26 +08:00
31 changed files with 3949 additions and 570 deletions

6
.vscode/settings.json vendored Normal file
View File

@@ -0,0 +1,6 @@
{
"files.associations": {
"*.ttml": "xml",
"*.ttss": "css"
}
}

View File

@@ -0,0 +1,268 @@
<template>
<view class="mask u-fixed position-all u-flex u-col-bottom u-font-28" v-if="show" @tap="close">
<view class="bg-fff w-full " @tap.stop="nullFunction">
<view class="u-p-30">
<view class="font-bold u-text-center">选择商品</view>
<view class="u-m-t-32 u-flex">
<view class=" ">
<uni-data-picker :clear-icon="false" :map="{text:'name',value:'id'}" placeholder="请选择分类"
popup-title="请选择分类" :localdata="category" v-model="goods.query.categoryId">
<view class="u-flex u-font-28" >
<text class=" u-line-1"
style="max-width: 100rpx;">{{goods.query.categoryId||'分类' }}</text>
<up-icon name="arrow-down" size="16"></up-icon>
</view>
</uni-data-picker>
</view>
<view class="u-flex-1 u-p-l-16">
<up-search @custom="getGoods" v-model="goods.query.name" placeholder="请输入商品名称" @search="getGoods" @clear="getGoods"></up-search>
</view>
</view>
</view>
<scroll-view :scroll-x="false" scroll-y="true" :style="computedStyle()">
<view class="u-p-l-30 u-p-r-30 table">
<view class="u-flex u-row-between no-wrap title">
<view>
<my-radio @change="radioAllChange" v-model="goods.allChecked" shape="square"
:size="20"></my-radio>
</view>
<view>商品信息</view>
<view>规格</view>
<!-- <view>是否售尽</view> -->
<!-- <view>是否分销</view> -->
<view>售价</view>
<view>销量/库存</view>
<view>分类名称</view>
</view>
<view @click="changeChecked(item)" class="u-m-t-12 u-flex u-p-24 u-row-between row" v-for="(item,index) in goods.list" :key="index">
<view class="">
<my-radio @change="radioChange($event,item)" v-model="item.checked" shape="square" :size="20"></my-radio>
</view>
<view class="u-text-left u-flex-1 u-p-l-20">
<!-- <view class="u-flex">
<image lazy-load class="coverImg" :src="item.coverImg" mode=""></image>
</view> -->
<view class="">{{item.name}}</view>
</view>
<view class="u-flex-1 u-p-l-4 u-p-r-4 box-size-border">
{{item.typeEnum}}
</view>
<view class="u-flex-1">
{{ item.lowPrice }}
</view>
<view class="u-flex-1">
<!-- {{ item.realSalesNumber }}/{{ item.stockNumber }} -->
{{ item.stockNumber }}
</view>
<view class="u-flex-1">
{{item.categoryName}}
</view>
</view>
</view>
</scroll-view>
<view class="u-p-30">
<my-pagination :totalElements="goods.totalElements" :size="goods.query.size"
@change="pageChange"></my-pagination>
<view class="u-m-t-20 u-flex">
<view class="u-flex-1 u-p-r-16">
<my-button type="cancel" plain @tap="close">取消</my-button>
</view>
<view class="u-flex-1 u-p-l-16">
<my-button @tap="confrim">确定</my-button>
</view>
</view>
</view>
</view>
</view>
</template>
<script setup>
import {
$tbProductList
} from '@/http/yskApi/goods.js';
import {
reactive,
onMounted,
ref,
watch
} from 'vue';
const props = defineProps({
modelValue: {
type: Boolean,
default: false
},
height: {
type: [Number, String],
default: '50vh'
},
category: {
type: Array,
default: () => {
return []
}
}
})
function changeChecked(item){
item.checked=!item.checked
if(!item.checked&&$selGoodsMap[item.id]){
delete $selGoodsMap[item.id]
}else{
$selGoodsMap[item.id]=item
}
goods.allChecked = goods.list.filter(v => v.checked).length != 0
}
function nullFunction() {
}
const show = ref(props.modelValue)
let selArr=[]
let $selGoodsMap={}
async function open(arr) {
show.value = true
selArr=arr
console.log(arr);
for(let i in arr){
$selGoodsMap[arr[i].proId
]=arr[i]
}
getGoods()
}
function close() {
show.value = false
resetQuery()
$selGoodsMap={}
}
function resetQuery() {
Object.assign(goods.query, $quey)
}
function computedStyle() {
return `height:${typeof props.height==='string'?props.height:props.height+'rpx'};`
}
const emits = defineEmits(['update:modelValue', 'confirm'])
const $quey = {
categoryId: "",
createdAt: [],
id: "",
name: "",
sort: "createdAt,desc",
type: "",
page: 0,
size: 10,
}
const query = reactive({
...$quey
})
const goods = reactive({
list: [],
allChecked: false,
totalElements: 0,
query: {
...$quey
}
})
getGoods()
function getGoods() {
const arr=selArr
$tbProductList(goods.query).then(res => {
let selLen=0;
goods.list = res.content.map(v => {
const checked=$selGoodsMap[v.id]?true:false
selLen+=(checked?1:0)
return {
...v,
checked
}
})
goods.allChecked = selLen==res.content.length?true:false
goods.totalElements = res.totalElements
})
}
function pageChange(page) {
goods.query.page = page - 1
getGoods()
}
function radioChange(newval,item) {
if(!newval&&$selGoodsMap[item.id]){
delete $selGoodsMap[item.id]
}else{
$selGoodsMap[item.id]=item
}
goods.allChecked = goods.list.filter(v => v.checked).length != 0
}
function radioAllChange(newval) {
goods.list.forEach(i => {
i.checked = newval
if($selGoodsMap[i.id]&&!newval){
delete $selGoodsMap[i.id]
}else{
$selGoodsMap[i.id]=i
}
})
}
function confrim() {
for(let i in goods.list){
const item=goods.list[i]
if($selGoodsMap[item.id]&&!item.checked){
delete $selGoodsMap[item.id]
}
}
console.log($selGoodsMap);
const arr = Object.values($selGoodsMap)
emits('confirm', arr)
}
defineExpose({
open,
close
})
</script>
<style lang="scss" scoped>
.bg-fff{
border-radius: 24rpx 24rpx 0 0 ;
}
.mask {
background: rgba(51, 51, 51, 0.5);
z-index: 900;
}
.box-size-border{
box-sizing: border-box;
}
.coverImg {
width: 60rpx;
height: 60rpx;
border-radius: 10rpx;
}
.table {
background: #F9F9F9;
border-radius: 8rpx;
overflow: hidden;
.title {
padding: 12rpx 24rpx 12rpx 24rpx;
background: #AEBAD2;
border-radius: 8rpx 8rpx 0rpx 0rpx;
color: #fff;
}
.row:nth-of-type(2n+1) {
background: #F0F0F0;
}
}
</style>

View File

@@ -0,0 +1,8 @@
<template>
</template>
<script>
</script>
<style>
</style>

View File

@@ -0,0 +1,76 @@
<template>
<view class=" table u-font-28">
<view class="u-flex u-row-between no-wrap title">
<slot name="title">
<view>
<my-radio @change="radioAllChange" v-model="allChecked" shape="square" :size="20"></my-radio>
</view>
<view>商品信息</view>
<view>规格</view>
<view>售价</view>
<view>销量/库存</view>
<view>分类名称</view>
</slot>
</view>
<view @click="changeChecked(item)" class="u-m-t-12 u-flex u-p-24 u-row-between row"
v-for="(item,index) in list" :key="index">
<view class="">
<my-radio @change="radioChange($event,item)" v-model="item.checked" shape="square"
:size="20"></my-radio>
</view>
<view class="u-text-left u-flex-1 u-p-l-20">
<view class="">{{item.name}}</view>
</view>
<view class="u-flex-1 u-p-l-4 u-p-r-4 box-size-border">
{{item.typeEnum}}
</view>
<view class="u-flex-1">
{{ item.lowPrice }}
</view>
<view class="u-flex-1">
<!-- {{ item.realSalesNumber }}/{{ item.stockNumber }} -->
{{ item.stockNumber }}
</view>
<view class="u-flex-1">
{{item.categoryName}}
</view>
</view>
</view>
</template>
<script setup>
import {
reactive, ref
} from 'vue';
const props=defineProps({
list:{
type:Array,
default:()=>[]
}
})
let allChecked=ref(false)
const emits=defineEmits(['selectAllChange'])
function radioAllChange(e){
emits('selectAllChange')
console.log('selectAllChange');
}
</script>
<style lang="scss">
.table {
background: #F9F9F9;
border-radius: 8rpx;
overflow: hidden;
.title {
padding: 12rpx 24rpx 12rpx 24rpx;
background: #AEBAD2;
border-radius: 8rpx 8rpx 0rpx 0rpx;
color: #fff;
}
.row:nth-of-type(2n+1) {
background: #F0F0F0;
}
}
</style>

33
http/php/api.ts Normal file
View File

@@ -0,0 +1,33 @@
import { request } from './request'
// 会员签入 登录
export const douyincheckIn = (data : object | any) => {
return request('douyin/checkIn', 'POST', data, true)
}
// 登出
export const userlogout = () => {
return request('user/logout', 'POST', '', true)
}
// 查询绑定状态
export const searchstorestatus = (data : object) => {
return request('meituan/searchstorestatus', 'POST', data, true)
}
// 团购核销准备
export const fulfilmentcertificateprepare = (data : object) => {
return request('douyin/fulfilmentcertificateprepare', 'POST', data, true)
}
// 获取uisdk 绑定 链接
export const getuisdk = (data : object) => {
return request('douyin/getuisdk', 'POST', data, true)
}
// 团购核销
export const certificateprepares = (data : object) => {
return request('douyin/certificateprepare', 'POST', data, true)
}
// 团购核销记录
export const orderlist = (data : object) => {
return request('douyin/orderlist', 'POST', data, true)
}
// 团购核销撤销
export const fulfilmentcertificatecanceles = (data : object) => {
return request('douyin/fulfilmentcertificatecancel', 'POST', data, true)
}

80
http/php/request.ts Normal file
View File

@@ -0,0 +1,80 @@
//服务器接口地址
const baseURL : string = 'https://czgdoumei.sxczgkj.com/index.php/api/'
// 封装公共请求方法
function request(url : string, method : "GET" | "POST" | undefined, data : object | any, toast : boolean) {
let networkType = ''
uni.getNetworkType({
success: (res) => {
networkType = res.networkType
}
});
if (networkType == 'none') {
uni.showToast({
title: '网络异常,请检查网络',
icon: 'none'
})
return false;
}
if (toast) {
uni.showLoading({
title: '加载中',
mask: true
})
}
return new Promise(async (resolve, reject) => {
let header : any
header = {
'content-type': 'application/json',
'clinttype':uni.getStorageSync('clint_type'),
'bausertoken': uni.getStorageSync('phpuserinfo').token
};
uni.request({
url: baseURL + url,
method: method,
data: data,
header: header,
success(res : any) {
if (res.data.code != 1) {
//是否提示错误
if (toast) {
uni.showToast({
title: res.data.msg || res.data.message,
icon: 'none'
})
setTimeout(() => {
uni.hideLoading()
}, 1000)
}
if (res.data.code == 401) {
uni.showToast({
title: res.message || res.msg,
icon: "none",
success: () => {
// uni.removeStorageSync('logintoken');
// uni.removeStorageSync('token');
uni.reLaunch({
url: '/pages/index/index'
})
}
})
}
uni.hideLoading()
reject(res.message | res.msg);
} else {
uni.hideLoading()
resolve(res.data.data);
}
},
fail(err) {
uni.hideLoading()
//请求失败
uni.showToast({
title: '无法连接到服务器',
icon: 'none'
})
reject(err)
}
})
})
}
export { request, baseURL }

View File

@@ -389,4 +389,27 @@ export function $calcDeDuctionPoints(data) {
...data
}
});
}
}
//购物车-临时菜添加
export function $temporaryDishes(data) {
return request({
url: '/api/place/temporaryDishes',
method: "post",
data:{
shopId: uni.getStorageSync("shopId"),
...data
}
});
}
//单品改价
export function $updatePrice(data) {
return request({
url: '/api/place/updatePrice',
method: "put",
data:{
shopId: uni.getStorageSync("shopId"),
...data
}
});
}

View File

@@ -119,7 +119,10 @@ export const $productSpec=new $API('/api/tbProductSpec',http.req)
// v2 api start
// 商品列表 后台查询
export function $tbProductList(data) {
return http.req('/api/tbProduct/list', {...data,shopId:uni.getStorageSync('shopId')}, 'GET')
}
/* 商品列表 V2 */
export function $tbProductV2(data) {
return http.req('/api/tbProduct/list/v2', {...data,shopId:uni.getStorageSync('shopId')}, 'post')

File diff suppressed because it is too large Load Diff

View File

@@ -1,36 +1,33 @@
<template>
<view class="mask u-fixed position-all u-flex u-col-bottom" v-if="show" @tap="close">
<view class="bg-fff w-full" @tap.stop="nullFunction">
<view class="mask u-fixed position-all u-flex u-col-bottom u-font-28" v-if="show" @tap="close">
<view class="bg-fff w-full " @tap.stop="nullFunction">
<view class="u-p-30">
<view class="font-bold u-text-center">选择商品</view>
<view class="u-m-t-32 u-flex">
<view class="u-flex-1 u-p-r-16">
<view class="u-m-b-12">商品名称</view>
<uni-easyinput v-model="goods.query.name" placeholder="请输入商品名称" />
</view>
<view class="u-flex-1 u-p-l-16">
<view class="u-m-b-12">商品分类</view>
<view class=" ">
<uni-data-picker :clear-icon="false" :map="{text:'name',value:'id'}" placeholder="请选择分类"
popup-title="请选择分类" :localdata="category" v-model="goods.query.categoryId">
<view class="u-flex u-font-28" >
<text class=" u-line-1"
style="max-width: 100rpx;">{{goods.query.categoryId||'分类' }}</text>
<up-icon name="arrow-down" size="16"></up-icon>
</view>
</uni-data-picker>
</view>
</view>
<view class="u-m-t-32 u-flex u-row-right">
<view class="u-flex-1 u-p-r-16">
<my-button type="cancel" plain @tap="resetQuery">重置</my-button>
</view>
<view class="u-flex-1 u-p-l-16">
<my-button @tap="getGoods">查询</my-button>
<up-search @custom="getGoods" v-model="goods.query.name" placeholder="请输入商品名称" @search="getGoods" @clear="getGoods"></up-search>
</view>
</view>
</view>
<scroll-view :scroll-x="false" scroll-y="true" :style="computedStyle()">
<view class="u-p-l-30 u-p-r-30">
<view class="u-flex u-row-between no-wrap">
<view class="u-p-l-30 u-p-r-30 table">
<view class="u-flex u-row-between no-wrap title">
<view>
<my-radio @change="radioAllChange" v-model="goods.allChecked" shape="square" :size="20"></my-radio>
<my-radio @change="radioAllChange" v-model="goods.allChecked" shape="square"
:size="20"></my-radio>
</view>
<view>商品信息</view>
<view>规格</view>
@@ -40,29 +37,35 @@
<view>销量/库存</view>
<view>分类名称</view>
</view>
<view class="u-m-t-12 u-flex u-row-between" v-for="(item,index) in goods.list" :key="index">
<my-radio @change="radioChange" v-model="item.checked" shape="square" :size="20"></my-radio>
<view class="u-flex u-flex-col u-row-center u-col-center">
<image lazy-load class="coverImg" :src="item.coverImg" mode=""></image>
<view class="u-m-t-10">{{item.name}}</view>
<view @click="changeChecked(item)" class="u-m-t-12 u-flex u-p-24 u-row-between row" v-for="(item,index) in goods.list" :key="index">
<view class="">
<my-radio @change="radioChange($event,item)" v-model="item.checked" shape="square" :size="20"></my-radio>
</view>
<view>
<view class="u-text-left u-flex-1 u-p-l-20">
<!-- <view class="u-flex">
<image lazy-load class="coverImg" :src="item.coverImg" mode=""></image>
</view> -->
<view class="">{{item.name}}</view>
</view>
<view class="u-flex-1 u-p-l-4 u-p-r-4 box-size-border">
{{item.typeEnum}}
</view>
<view>
<view class="u-flex-1">
{{ item.lowPrice }}
</view>
<view>
{{ item.realSalesNumber }}/{{ item.stockNumber }}
<view class="u-flex-1">
<!-- {{ item.realSalesNumber }}/{{ item.stockNumber }} -->
{{ item.stockNumber }}
</view>
<view>
{{item.categoryName}}
<view class="u-flex-1">
{{item.categoryName}}
</view>
</view>
</view>
</scroll-view>
<view class="u-p-30">
<my-pagination :totalElements="goods.totalElements" :size="goods.query.size" @change="pageChange"></my-pagination>
<my-pagination :totalElements="goods.totalElements" :size="goods.query.size"
@change="pageChange"></my-pagination>
<view class="u-m-t-20 u-flex">
<view class="u-flex-1 u-p-r-16">
<my-button type="cancel" plain @tap="close">取消</my-button>
@@ -77,11 +80,8 @@
</template>
<script setup>
import myButton from '@/components/my-components/my-button';
import myRadio from '@/components/my-components/my-radio';
import myPagination from '@/components/my-components/my-pagination'
import {
$tbProduct
$tbProductList
} from '@/http/yskApi/goods.js';
import {
reactive,
@@ -96,7 +96,7 @@
},
height: {
type: [Number, String],
default: '40vh'
default: '50vh'
},
category: {
type: Array,
@@ -105,29 +105,42 @@
}
}
})
function changeChecked(item){
item.checked=!item.checked
if(!item.checked&&$selGoodsMap[item.id]){
delete $selGoodsMap[item.id]
}else{
$selGoodsMap[item.id]=item
}
goods.allChecked = goods.list.filter(v => v.checked).length != 0
}
function nullFunction() {
}
const show = ref(props.modelValue)
function open(arr) {
let selArr=[]
let $selGoodsMap={}
async function open(arr) {
show.value = true
if(arr){
for(let i in goods.list){
console.log(arr.includes(goods.list[i].id));
goods.list[i].checked=arr.includes(goods.list[i].id)
}
selArr=arr
console.log(arr);
for(let i in arr){
$selGoodsMap[arr[i].proId
]=arr[i]
}
getGoods()
}
function close() {
show.value = false
resetQuery()
$selGoodsMap={}
}
function resetQuery() {
Object.assign(goods.query, $quey)
@@ -137,61 +150,119 @@
return `height:${typeof props.height==='string'?props.height:props.height+'rpx'};`
}
const emits = defineEmits(['update:modelValue','confirm'])
const emits = defineEmits(['update:modelValue', 'confirm'])
const $quey = {
categoryId: '',
name: '',
categoryId: "",
createdAt: [],
id: "",
name: "",
sort: "createdAt,desc",
type: "",
page: 0,
size: 10,
}
const query = reactive({
...$quey
})
const goods=reactive({
list:[],
allChecked:false,
totalElements:0,
query:{
const goods = reactive({
list: [],
allChecked: false,
totalElements: 0,
query: {
...$quey
}
})
getGoods()
function getGoods() {
$tbProduct(goods.query).then(res=>{
goods.list=res.content.map(v=>{
return {...v,checked:false}
const arr=selArr
$tbProductList(goods.query).then(res => {
let selLen=0;
goods.list = res.content.map(v => {
const checked=$selGoodsMap[v.id]?true:false
selLen+=(checked?1:0)
return {
...v,
checked
}
})
goods.allChecked=false
goods.totalElements=res.totalElements
goods.allChecked = selLen==res.content.length?true:false
goods.totalElements = res.totalElements
})
}
getGoods()
function pageChange(page){
goods.query.page=page-1
function pageChange(page) {
goods.query.page = page - 1
getGoods()
}
function radioChange(newval){
goods.allChecked=goods.list.filter(v=>v.checked).length!=0
function radioChange(newval,item) {
if(!newval&&$selGoodsMap[item.id]){
delete $selGoodsMap[item.id]
}else{
$selGoodsMap[item.id]=item
}
goods.allChecked = goods.list.filter(v => v.checked).length != 0
}
function radioAllChange(newval){
goods.list.forEach(i=>{i.checked=newval})
function radioAllChange(newval) {
goods.list.forEach(i => {
i.checked = newval
if($selGoodsMap[i.id]&&!newval){
delete $selGoodsMap[i.id]
}else{
$selGoodsMap[i.id]=i
}
})
}
function confrim(){
const arr= goods.list.filter(v=>v.checked)
emits('confirm',arr)
function confrim() {
for(let i in goods.list){
const item=goods.list[i]
if($selGoodsMap[item.id]&&!item.checked){
delete $selGoodsMap[item.id]
}
}
console.log($selGoodsMap);
const arr = Object.values($selGoodsMap)
emits('confirm', arr)
}
defineExpose({open,close})
defineExpose({
open,
close
})
</script>
<style lang="scss" scoped>
.bg-fff{
border-radius: 24rpx 24rpx 0 0 ;
}
.mask {
background: rgba(51, 51, 51, 0.5);
z-index: 900;
}
.coverImg{
.box-size-border{
box-sizing: border-box;
}
.coverImg {
width: 60rpx;
height: 60rpx;
border-radius: 10rpx;
}
.table {
background: #F9F9F9;
border-radius: 8rpx;
overflow: hidden;
.title {
padding: 12rpx 24rpx 12rpx 24rpx;
background: #AEBAD2;
border-radius: 8rpx 8rpx 0rpx 0rpx;
color: #fff;
}
.row:nth-of-type(2n+1) {
background: #F0F0F0;
}
}
</style>

View File

@@ -0,0 +1,164 @@
<template>
<view class="mask u-fixed position-all u-flex u-col-bottom u-font-28" v-if="show" @tap="close">
<view class="bg-fff w-full " @tap.stop="nullFunction">
<view class="u-p-30">
<view class="font-bold u-text-center">选择规格</view>
</view>
<scroll-view :scroll-x="false" scroll-y="true" :style="computedStyle()">
<view class="u-p-l-30 u-p-r-30 ">
<view class="u-flex u-flex-wrap w-full gap-10 u-col-top">
<view class="skd" v-for="(item,index) in skuList" :key="index"
:class="{active:sel.id==item.id}"
@click="guigeClick(item,index)">
<text>{{item.specSnap||item.name}}</text>
<view class="tag-primary tag" v-if="item.isGrounding">上架中</view>
<view class="tag-gray tag" v-if="item.isPauseSale">已售罄</view>
<view class="tag-gray tag" v-if="!item.isGrounding">已下架</view>
</view>
</view>
</view>
</scroll-view>
<view class="u-p-30">
<view class="u-m-t-20 u-flex">
<view class="u-flex-1 u-p-r-16">
<my-button type="cancel" plain @tap="close">取消</my-button>
</view>
<view class="u-flex-1 u-p-l-16">
<my-button @tap="confrim">确定</my-button>
</view>
</view>
</view>
</view>
</view>
</template>
<script setup>
import {
$tbProduct
} from '@/http/yskApi/goods.js';
import {
reactive,
onMounted,
ref,
watch
} from 'vue';
import infoBox from '@/commons/utils/infoBox.js'
const props = defineProps({
modelValue: {
type: Boolean,
default: false
}
})
let skuList=ref([])
function nullFunction() {
}
const show = ref(props.modelValue)
async function open(arr,sel) {
show.value = true
skuList.value=arr
}
function close() {
show.value = false
sel.value={}
}
let sel=ref({
})
function guigeClick(item,index){
if(sel.value.id==item.id){
return sel.value={}
}
sel.value=item
}
function computedStyle() {
return `height:${typeof props.height==='string'?props.height:props.height+'rpx'};`
}
const emits = defineEmits(['update:modelValue', 'confirm'])
function confrim() {
if(!sel.value.id){
return infoBox.showToast('请选择选择一个规格')
}
emits('confirm', sel.value)
close()
}
defineExpose({
open,
close
})
</script>
<style lang="scss" scoped>
.bg-fff{
border-radius: 24rpx 24rpx 0 0 ;
}
.mask {
background: rgba(51, 51, 51, 0.5);
z-index: 900;
}
.skd {
padding: 10rpx 38rpx 8rpx 40rpx;
background: #F0F2F5;
border-radius: 4rpx;
position: relative;
color: #666;
overflow: hidden;
margin-bottom: 10rpx;
font-size: 24rpx;
border: 1px solid transparent;
&.active{
border-color: $my-main-color;
}
.tag {
position: absolute;
right: 0;
top: 0;
font-size: 12rpx;
height: 18rpx;
line-height: 18rpx;
right: 0;
border-radius: 0rpx 2rpx 2rpx 8rpx;
}
.tag-primary {
background-color: $my-main-color;
color: #fff;
}
.tag-gray {
background-color: rgb(144, 147, 153);
color: #fff;
}
}
.coverImg {
width: 60rpx;
height: 60rpx;
border-radius: 10rpx;
}
.table {
background: #F9F9F9;
border-radius: 8rpx;
overflow: hidden;
.title {
padding: 12rpx 24rpx 12rpx 24rpx;
background: #AEBAD2;
border-radius: 8rpx 8rpx 0rpx 0rpx;
color: #fff;
}
.row:nth-of-type(2n+1) {
background: #F0F0F0;
}
}
</style>

View File

@@ -0,0 +1,109 @@
<template>
<view class="u-flex number-box">
<view class="u-flex u-flex-1">
<up-input @blur="priceFormat" border="none" v-model="number" :type="inputType" :placeholder="placeholder"></up-input>
</view>
<view class="u-flex u-flex-col right">
<view class="u-flex-1 u-p-l-8 u-p-r-8" @click="changeNumber('add')">
<up-icon name="arrow-up" color="#E5E5E5"></up-icon>
</view>
<view class="line"></view>
<view class="u-flex-1 u-p-l-8 u-p-r-8" @click="changeNumber('reduce')">
<up-icon name="arrow-down" color="#E5E5E5"></up-icon>
</view>
</view>
</view>
</template>
<script setup>
import {
formatPrice
} from "@/commons/utils/format.js";
import {
ref,
watch,nextTick
} from 'vue';
const props = defineProps({
inputType:{
type:String,
default:'digit'
},
modelValue: {
type: [String, Number]
},
min: {
type: Number,
default: 0
},
max: {
type: Number,
default: 999999999
},
step: {
type: Number,
default: 1
},
placeholder: {
type: String,
default: '请输入'
}
})
let number = ref(props.modelValue)
function changeNumber(type) {
const newval = number.value + props.step * (type == 'add' ? 1 : -1)
if (newval < props.min) {
number.value = props.min
}
if (newval > props.max) {
number.value = props.max
}
priceFormat(newval)
}
function priceFormat(e) {
nextTick(() => {
const min = props
.min;
const max = props.max;
if (e === '') {
return
}
const newval = formatPrice(e, min, max, true)
if (typeof newval !== 'number') {
number.value = newval.value
uni.showToast({
title: `请输入${min}${max}范围内的数字`,
icon: 'none'
})
} else {
number.value = newval
}
})
}
watch(() => props.modelValue, (newval) => {
number.value = newval
})
const emits = defineEmits(['update:modelValue'])
watch(() => number.value, (newval) => {
emits('update:modelValue', newval)
})
</script>
<style lang="scss" scoped>
.line {
width: 100%;
height: 1px;
background-color: #E5E5E5;
}
.number-box {
border: 1px solid #E5E5E5;
border-radius: 8rpx 8rpx 8rpx 8rpx;
padding-left: 24rpx;
.right {
border-left: 1px solid #E5E5E5;
}
}
</style>

View File

@@ -0,0 +1,224 @@
<template>
<view class="u-p-30 min-page u-font-28">
<!-- <view class="u-flex">
<view style="width: 210rpx;">
<my-button shape="circle" @click="addTimer">添加定时器</my-button>
</view>
</view> -->
<view class="list u-m-t-20" v-if="list.length">
<view class="block" v-for="(item,index) in list" :key="index">
<!-- <view class="u-flex u-row-between">
<view>定时器{{index+1}}</view>
<uni-icons @click="delTimer(index)" type="trash"></uni-icons>
</view> -->
<view class="u-flex u-row-between">
<view>周期</view>
<view class="color-main" @click="selectAllClick(index)">
{{isAllChecked?'取消全选':'全选'}}
</view>
</view>
<view class="u-m-t-24">
<uni-data-checkbox :selectedColor="color.ColorMain" multiple v-model="item.cycleChecked" :localdata="cycle"></uni-data-checkbox>
</view>
<view class="u-m-t-24">
<view class="u-flex">
<view>上架时间:</view>
<view class="u-flex-1 u-m-l-10">
<picker mode="multiSelector" @change="listingTimeChange($event,index)"
:value="item.listingTime.index" :range="times">
<view class="bg-gray u-p-l-20 u-p-t-6 u-p-b-6 u-p-r-20 ">
{{item.listingTime.value}}
</view>
</picker>
</view>
</view>
<view class="u-flex u-m-t-16">
<view>下架时间:</view>
<view class="u-flex-1 u-m-l-10">
<picker mode="multiSelector" @change="offShelfChange($event,index)"
:value="item.offShelf.index" :range="times">
<view class="bg-gray u-p-l-20 u-p-t-6 u-p-b-6 u-p-r-20 ">
{{item.offShelf.value}}
</view>
</picker>
</view>
</view>
</view>
</view>
</view>
<view class="u-flex u-row-center u-m-t-60">
<my-button width="580" shape="circle" @click="save">保存</my-button>
</view>
</view>
</template>
<script setup>
import {
onLoad,
onReady
} from '@dcloudio/uni-app';
import {
computed,
ref
} from 'vue';
import go from '@/commons/utils/go.js';
import color from '@/commons/color.js'
import {
$getProductDetail,
} from '@/http/yskApi/goods.js'
//返回一天的时间 时分格式
function returnDayTime() {
return new Array(2).fill(1).map((v, index) => {
if (index === 0) {
return new Array(24).fill(1).map((hour, index) => {
return `0${index}`.slice(-2)
})
}
if (index === 1) {
return new Array(60).fill(1).map((hour, index) => {
return `0${index}`.slice(-2)
})
}
})
}
const times = ref(returnDayTime())
let defaultTimeIndex = ref(0)
function getTime(indexArr) {
const hour = times.value[0][indexArr[0]]
const month = times.value[1][indexArr[1]]
return `${hour}:${month}`
}
//获取$event.detail.value
function getEnentDetailValue(e) {
return e.detail.value
}
function setListTimeValue(index, key, time) {
list.value[index][key].value = time
}
function listingTimeChange(e, index) {
const indexArr = getEnentDetailValue(e)
const time = getTime(indexArr)
setListTimeValue(index, 'listingTime', time)
}
function offShelfChange(e, index) {
const indexArr = getEnentDetailValue(e)
const time = getTime(indexArr)
setListTimeValue(index, 'offShelf', time)
}
const cycle = [{
value: 0,
text: '星期一'
},
{
value: 1,
text: '星期二'
},
{
value: 2,
text: '星期三'
},
{
value: 3,
text: '星期四'
},
{
value: 4,
text: '星期五'
},
{
value: 5,
text: '星期六'
},
{
value: 6,
text: '星期日'
}
]
const ListDataconstructor = {
cycleChecked: [0, 1, 2, 3, 4, 5, 6],
}
function returnBasicTimeConstructor() {
return {
listingTime: {
value: '00:00',
index: [0, 0]
},
offShelf: {
value: '00:00',
index: [0, 0]
}
}
}
const list = ref([returnBasicDataConstructor()])
function returnBasicDataConstructor() {
return {
...ListDataconstructor,
...returnBasicTimeConstructor()
}
}
function addTimer() {
list.value.push(returnBasicDataConstructor())
}
function delTimer(index) {
list.value.splice(index,1)
}
const isAllChecked=computed(()=>{
return list.value[0].cycleChecked.length==cycle.length?true:false
})
function selectAllClick(index){
if(isAllChecked.value){
list.value[index].cycleChecked=[]
}else{
list.value[index].cycleChecked=ListDataconstructor.cycleChecked
}
}
// 触发定时器保存事件将数据给到添加商品页面
function emitTimerSave(){
uni.$emit('timerSave',list.value)
go.back()
}
function save(){
console.log(list.value);
emitTimerSave()
}
let goodsDetail=ref({})
function returnTimer(res){
return []
}
onLoad(async(opt)=>{
let res=null
if(opt.productId){
res=await $getProductDetail(opt.productId)
goodsDetail.value=res
}
const arr=res?returnTimer(res):[]
if(arr.length){
list.value=arr
}
})
</script>
<style lang="scss">
.min-page {
background-color: #F9F9F9;
}
.block {
background: #FFFFFF;
border-radius: 18rpx 18rpx 18rpx 18rpx;
padding: 32rpx 28rpx;
margin-bottom: 32rpx;
}
</style>

View File

@@ -1,42 +1,45 @@
<template>
<view class="u-p-30 min-page">
<view class="u-flex">
<view class="u-p-30 min-page u-font-28">
<!-- <view class="u-flex">
<view style="width: 210rpx;">
<my-button shape="circle" @click="addTimer">添加定时器</my-button>
</view>
</view>
</view> -->
<view class="list u-m-t-20" v-if="list.length">
<view class="block" v-for="(item,index) in list" :key="index">
<view class="u-flex u-row-between">
<!-- <view class="u-flex u-row-between">
<view>定时器{{index+1}}</view>
<uni-icons @click="delTimer(index)" type="trash"></uni-icons>
</view>
<view class="u-flex u-m-t-20 u-row-between">
</view> -->
<view class="u-flex u-row-between">
<view>周期</view>
<view @click="selectAllClick(index)">全选</view>
<view class="color-main" @click="selectAllClick(index)">
{{isAllChecked?'取消全选':'全选'}}
</view>
</view>
<view class="u-m-t-20">
<uni-data-checkbox multiple v-model="item.cycleChecked" :localdata="cycle"></uni-data-checkbox>
<view class="u-m-t-24">
<uni-data-checkbox :selectedColor="color.ColorMain" multiple v-model="item.cycleChecked"
:localdata="cycle"></uni-data-checkbox>
</view>
<view class="u-m-t-20">
<view class="u-m-t-24">
<view class="u-flex">
<view>上架时间:</view>
<view class="u-flex-1 u-m-l-10">
<picker mode="multiSelector" @change="listingTimeChange($event,index)"
:value="item.listingTime.index" :range="times">
<picker mode="multiSelector" @change="startTimeChange($event,index)"
:value="item.startTime.index" :range="times">
<view class="bg-gray u-p-l-20 u-p-t-6 u-p-b-6 u-p-r-20 ">
{{item.listingTime.value}}
{{item.startTime.value}}
</view>
</picker>
</view>
</view>
<view class="u-flex u-m-t-20">
<view class="u-flex u-m-t-16">
<view>下架时间:</view>
<view class="u-flex-1 u-m-l-10">
<picker mode="multiSelector" @change="offShelfChange($event,index)"
:value="item.offShelf.index" :range="times">
<picker mode="multiSelector" @change="endTimeChange($event,index)"
:value="item.endTime.index" :range="times">
<view class="bg-gray u-p-l-20 u-p-t-6 u-p-b-6 u-p-r-20 ">
{{item.offShelf.value}}
{{item.endTime.value}}
</view>
</picker>
</view>
@@ -58,19 +61,23 @@
onReady
} from '@dcloudio/uni-app';
import {
computed,
ref
} from 'vue';
import go from '@/commons/utils/go.js';
import myButton from '@/components/my-components/my-button.vue'
import color from '@/commons/color.js'
import {
$getProductDetail,
} from '@/http/yskApi/goods.js'
//返回一天的时间 时分格式
function returnDayTime() {
return new Array(2).fill(1).map((v, index) => {
return new Array(3).fill(1).map((v, index) => {
if (index === 0) {
return new Array(24).fill(1).map((hour, index) => {
return `0${index}`.slice(-2)
})
}
if (index === 1) {
if (index === 1 || index === 2) {
return new Array(60).fill(1).map((hour, index) => {
return `0${index}`.slice(-2)
})
@@ -83,6 +90,8 @@
function getTime(indexArr) {
const hour = times.value[0][indexArr[0]]
const month = times.value[1][indexArr[1]]
const s = times.value[2][indexArr[2]]
// return `${hour}:${month}:${s}`
return `${hour}:${month}`
}
//获取$event.detail.value
@@ -94,66 +103,67 @@
list.value[index][key].value = time
}
function listingTimeChange(e, index) {
function startTimeChange(e, index) {
const indexArr = getEnentDetailValue(e)
const time = getTime(indexArr)
setListTimeValue(index, 'listingTime', time)
setListTimeValue(index, 'startTime', time)
}
function offShelfChange(e, index) {
function endTimeChange(e, index) {
const indexArr = getEnentDetailValue(e)
const time = getTime(indexArr)
setListTimeValue(index, 'offShelf', time)
setListTimeValue(index, 'endTime', time)
}
const cycle = [{
value: 0,
value: 'Monday',
text: '星期一'
},
{
value: 1,
value: 'Tuesday',
text: '星期二'
},
{
value: 2,
value: 'Wednesday',
text: '星期三'
},
{
value: 3,
value: 'Thursday',
text: '星期四'
},
{
value: 4,
value: 'Friday',
text: '星期五'
},
{
value: 5,
value: 'Saturday',
text: '星期六'
},
{
value: 6,
value: 'Sunday',
text: '星期日'
}
]
const ListDataconstructor = {
cycleChecked: [0, 1, 2, 3, 4, 5, 6],
cycleChecked: ['Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday', 'Sunday'],
}
function returnBasicTimeConstructor() {
return {
listingTime: {
value: '09:00',
index: [9, 0]
startTime: {
value: '00:00',
index: [0, 0, 0]
},
offShelf: {
value: '18:00',
index: [18, 0]
endTime: {
value: '23:59',
index: [0, 0, 0]
}
}
}
const list = ref([returnBasicDataConstructor()])
function returnBasicDataConstructor() {
return {
...ListDataconstructor,
@@ -164,25 +174,68 @@
function addTimer() {
list.value.push(returnBasicDataConstructor())
}
function delTimer(index) {
list.value.splice(index,1)
list.value.splice(index, 1)
}
function selectAllClick(index){
list.value[index].cycleChecked=ListDataconstructor.cycleChecked
const isAllChecked = computed(() => {
return list.value[0].cycleChecked.length == cycle.length ? true : false
})
function selectAllClick(index) {
if (isAllChecked.value) {
list.value[index].cycleChecked = []
} else {
list.value[index].cycleChecked = ListDataconstructor.cycleChecked
}
}
// 触发定时器保存事件将数据给到添加商品页面
function emitTimerSave(){
uni.$emit('timerSave',list.value)
function emitTimerSave() {
const par = {
days: list.value[0].cycleChecked.join(','),
startTime: list.value[0].startTime.value,
endTime: list.value[0].endTime.value
}
console.log(par);
uni.$emit('timerSave', par)
go.back()
}
function save(){
console.log(list.value);
function save() {
emitTimerSave()
}
onLoad(()=>{
const arr=uni.getStorageSync('timer')
if(arr.length){
list.value=arr
let goodsDetail = ref({})
function returnTimeIndex(time) {
console.log(time);
return time.split(':').map(v => {
return v * 1
})
}
function returnTimer(res) {
return [{
cycleChecked: res.days ? res.days.split(',').filter(v => v) : [],
startTime: res.startTime ? {
value: res.startTime,
index: returnTimeIndex(res.startTime)
} : returnBasicTimeConstructor.startTime,
endTime: res.endTime ? {
value: res.endTime,
index: returnTimeIndex(res.endTime)
} : returnBasicTimeConstructor.endTime
}]
}
onLoad(async (opt) => {
let res = null
if (opt.productId) {
res = await $getProductDetail(opt.productId)
goodsDetail.value = res
}
const arr = res ? returnTimer(res) : [];
console.log(arr);
if (arr.length) {
list.value = arr
}
})
</script>
@@ -195,7 +248,7 @@
.block {
background: #FFFFFF;
border-radius: 18rpx 18rpx 18rpx 18rpx;
padding: 30rpx;
margin-bottom: 20rpx;
padding: 32rpx 28rpx;
margin-bottom: 32rpx;
}
</style>

View File

@@ -8,8 +8,7 @@
"^u-([^-].*)": "uview-plus/components/u-$1/u-$1.vue"
}
},
"pages": [
{
"pages": [{
"pageId": "PAGES_INDEX",
"path": "pages/index/index",
"style": {
@@ -639,7 +638,7 @@
}
},
{
"pageId": "PAGES_ADD_TEMP_CUISINE",
"pageId": "PAGES_CHOOSE_ADD_TEMP_CUISINE",
"path": "add-temp-cuisine/add-temp-cuisine",
"style": {
"navigationBarTitleText": "添加临时菜"
@@ -760,13 +759,28 @@
{
"root": "pageBwc",
"pages": [{
"pageId": "PAGES_BWC",
"path": "index/index",
"style": {
"navigationBarTitleText": "霸王餐"
}
"pageId": "PAGES_BWC",
"path": "index/index",
"style": {
"navigationBarTitleText": "霸王餐"
}
]
}]
},
{
"root": "pagewriteoff",
"pages": [{
"pageId": "PAGES_WEITEOFF",
"path": "index/index",
"style": {
"navigationBarTitleText": "核销列表"
}
}, {
"pageId": "PAGES_WEITEOFF_RECORD",
"path": "index/record",
"style": {
"navigationBarTitleText": "核销记录"
}
}]
},
{
"root": "pageBooking",
@@ -877,11 +891,10 @@
}
},
{
"path" : "quan/quan",
"path": "quan/quan",
"pageId": "PAGES_ORDER_QUAN",
"style" :
{
"navigationBarTitleText" : "券包"
"style": {
"navigationBarTitleText": "券包"
}
}
@@ -1094,44 +1107,42 @@
{
"root": "pageNotification",
"pages": [{
"pageId": "PAGES_NOTIFICATION_INDEX",
"path": "index",
"style": {
"navigationBarTitleText": "订阅通知"
}
"pageId": "PAGES_NOTIFICATION_INDEX",
"path": "index",
"style": {
"navigationBarTitleText": "订阅通知"
}
]
}]
},
{
"root": "pageCreditBuyer",
"pages": [{
"pageId": "PAGES_CREDIT_BUYER_INDEX",
"path": "index",
"style": {
"navigationBarTitleText": "挂账管理"
}
},{
"pageId": "PAGES_CREDIT_BUYER_ADDDEBTOR",
"path": "addDebtor",
"style": {
"navigationBarTitleText": "挂账人"
}
},{
"pageId": "PAGES_CREDIT_BUYER_REPAYMENTRECORD",
"path": "rePaymentRecord",
"style": {
"navigationBarTitleText": "账单付款记录"
}
},{
"pageId": "PAGES_CREDIT_BUYER_DETAIL",
"path": "creditDetail",
"style": {
"navigationBarTitleText": "查看明细"
}
"pageId": "PAGES_CREDIT_BUYER_INDEX",
"path": "index",
"style": {
"navigationBarTitleText": "挂账管理"
}
]
}, {
"pageId": "PAGES_CREDIT_BUYER_ADDDEBTOR",
"path": "addDebtor",
"style": {
"navigationBarTitleText": "挂账人"
}
}, {
"pageId": "PAGES_CREDIT_BUYER_REPAYMENTRECORD",
"path": "rePaymentRecord",
"style": {
"navigationBarTitleText": "账单付款记录"
}
}, {
"pageId": "PAGES_CREDIT_BUYER_DETAIL",
"path": "creditDetail",
"style": {
"navigationBarTitleText": "查看明细"
}
}]
}
],
"globalStyle": {
"navigationBarTextStyle": "black",

View File

@@ -284,8 +284,11 @@
// pageUrl: 'PAGES_RED_INDEX',
// entId: 'ENT_MCH_MEMBER'
// },
{
title: '核销管理',
icon: '/static/indexImg/pagewriteoff.svg',
pageUrl: 'PAGES_WEITEOFF'
},
{
title: '退出登录',
icon: '/static/indexImg/icon-login-out.svg',
@@ -373,6 +376,7 @@
/* #endif */
/* #ifndef H5 */
padding-top: calc(84rpx + 44px);
/* #endif */
>view {
text-align: center;

View File

@@ -1,5 +1,5 @@
<template>
<view class="min-page bg-gray u-p-30">
<view class="min-page bg-gray u-p-30 u-font-28">
<view class="u-font-24">
<text class="color-red">*</text>
<text class="color-999">将临时菜添加至购物车不会影响总商品库</text>
@@ -14,20 +14,20 @@
<text class="color-red">*</text>
</view>
</template>
<view class="border-bottom u-p-t-10 u-p-b-10">
<view class="border-bottom ">
<uni-easyinput :inputBorder="false" paddingNone v-model="form.name"
placeholder="填写菜品名称"></uni-easyinput>
</view>
</uni-forms-item>
<uni-forms-item required label="" name="category">
<template #label>
<view class="u-text-left u-m-t-24">
<view class="u-text-left ">
<text class="color-333">菜品分类</text>
<text class="color-red">*</text>
</view>
</template>
<picker @change="categoryChange" :value="categoryCurrent" range-key="name" :range="category">
<view class="u-m-t-14 u-p-t-10 u-flex u-row-between border-bottom u-p-b-10 u-relative ">
<view class=" u-flex u-row-between border-bottom u-relative ">
<view class="zhezhao u-absolute position-all" style="z-index: 1;"></view>
<!-- <view>
<text class="" v-if="form.category!==''">{{category[form.category].name}}</text>
@@ -46,25 +46,25 @@
<uni-forms-item required label="" name="price">
<template #label>
<view class="u-m-t-24 u-text-left">
<view class=" u-text-left">
<text class="color-333">价格()</text>
<text class="color-red">*</text>
</view>
</template>
<view class="border-bottom u-p-t-10 u-p-b-10">
<view class="border-bottom ">
<uni-easyinput :inputBorder="false" paddingNone v-model="form.price" placeholder="输入价格"
type="digit"></uni-easyinput>
</view>
</uni-forms-item>
<uni-forms-item required label="" name="unit">
<template #label>
<view class="u-text-left u-m-t-24">
<view class="u-text-left ">
<text class="color-333">单位</text>
<text class="color-red">*</text>
</view>
</template>
<picker @change="unitChange" :value="units.current" range-key="name" :range="units.list">
<view class="u-m-t-14 u-p-t-10 u-flex u-row-between border-bottom u-p-b-10 u-relative ">
<view class=" u-flex u-row-between border-bottom u-relative ">
<view class="zhezhao u-absolute position-all" style="z-index: 1;"></view>
<view class="u-flex-1">
<uni-easyinput :inputBorder="false" paddingNone v-model="form.unit"
@@ -76,21 +76,33 @@
</picker>
</uni-forms-item>
<uni-forms-item required label="" name="price">
<uni-forms-item required label="" name="num">
<template #label>
<view class="u-m-t-24 u-text-left">
<view class=" u-text-left">
<text class="color-333">下单数量</text>
<text class="color-red">*</text>
</view>
</template>
<view class="border-bottom u-p-t-10 u-p-b-10">
<uni-easyinput :inputBorder="false" paddingNone v-model="form.number" placeholder="填写数量"
<view class="border-bottom ">
<uni-easyinput :inputBorder="false" paddingNone v-model="form.num" placeholder="填写数量"
type="digit"></uni-easyinput>
</view>
</uni-forms-item>
<uni-forms-item required label="" name="note">
<template #label>
<view class=" u-text-left">
<text class="color-333">备注</text>
</view>
</template>
<view class="border u-m-t-16">
<uni-easyinput :inputBorder="false" paddingNone v-model="form.note" placeholder="请输入自定义备注"
type="textarea"></uni-easyinput>
</view>
</uni-forms-item>
</uni-forms>
</view>
<view style="height: 200rpx;"></view>
</view>
<view class="fixed-b">
@@ -99,40 +111,31 @@
</template>
<script setup>
import myButton from '../../components/my-components/my-button';
import {
returnAllCategory
} from '@/pageProduct/util.js'
import {
$tbShopCategory,
$tbShopUnit
} from '@/http/yskApi/goods.js'
import {
$temporaryDishes
} from '@/http/yskApi/Instead.js'
import {
reactive,
ref
onMounted,
ref,
onBeforeMount,
} from 'vue';
import {
onLoad,
onShow
} from '@dcloudio/uni-app'
const units = reactive({
list: [{
name: '件',
value: 1
},
{
name: '杯',
value: 2
},
{
name: '个',
value: 3
}
],
current:''
list: [],
current: ''
})
const category = reactive([{
name: '分类1',
value: 1
},
{
name: '分类2',
value: 2
},
{
name: '分类3',
value: 3
}
])
let category = reactive([])
let categoryCurrent = ref('')
function categoryChange(e) {
@@ -140,7 +143,8 @@
categoryCurrent.value = e.detail.value
form.category = category[e.detail.value].name
}
function unitChange(e){
function unitChange(e) {
units.current = e.detail.value
form.unit = units.list[e.detail.value].name
}
@@ -149,9 +153,9 @@
const form = reactive({
name: '',
category: '',
price: 0,
unit:'',
number:0
price: '',
unit: '',
num: ''
})
// 校验规则
const rules = {
@@ -167,7 +171,7 @@
errorMessage: '请选择菜品分类'
}]
},
price: {
num: {
rules: [{
required: true,
errorMessage: '请输入价格'
@@ -186,17 +190,103 @@
}]
},
}
let timer = null
function submit() {
refform.value.validate(res => {
console.log(res)
if (!res) {
$temporaryDishes({
"useType": option.useType,
"masterId": option.masterId,
"tableId": option.tableId,
"name": form.name,
"categoryId": category[categoryCurrent.value].id,
"price": form.price,
"num": form.num,
unit: units.list[units.current].id,
"note": form.note,
"vipUserId": option.vipUserId
}).then(r => {
uni.$emit('add:cashCai')
clearInterval(timer)
timer = setTimeout(() => {
uni.navigateBack()
}, 500)
})
}
}).catch(err => {
console.log(err);
})
}
//获取单位数据
async function getTbShopUnit() {
const res = await $tbShopUnit({
page: 0,
size: 200,
sort: "id"
})
units.list = res.content.map(v => {
return {
...v,
value: v.id
}
})
}
async function getCategory() {
const res = await $tbShopCategory({
page: 0,
size: 600
})
const arr = forList(res.content).map(v => {
return {
...v,
value: v.id
}
})
category.length = arr.length
for (let i in arr) {
category[i] = arr[i]
}
}
function forList(arr) {
let arrs = []
arr.forEach(ele => {
arrs.push(ele)
if (ele.childrenList.length) {
ele.childrenList.forEach(res => {
arrs.push(res)
})
}
})
return arrs
}
async function init() {
getTbShopUnit()
getCategory()
}
// onMounted(() => {
// init()
// })
onLoad((opt) => {
Object.assign(option, opt)
setTimeout(() => {
init()
}, 600)
})
onBeforeMount(() => {
clearInterval(timer)
})
const option = reactive({
})
</script>
<style lang="scss" scoped>
.u-text-left {}
.form {
margin-top: 32rpx;
background-color: #fff;
@@ -205,6 +295,13 @@
// background-color: transparent;
}
.border {
border: 1px solid #F4F4F4;
border-radius: 12rpx;
overflow: hidden;
padding-left: 24rpx;
}
::v-deep.uni-forms-item {
align-items: inherit;
}
@@ -213,6 +310,16 @@
display: none;
}
::v-deep .uni-easyinput__content-input {
height: inherit;
padding-top: 16rpx;
padding-bottom: 24rpx;
}
::v-deep .uni-forms-item:not(:first-child) {
margin-top: 24rpx;
}
.fixed-b {
position: fixed;
left: 100rpx;

View File

@@ -1,9 +1,9 @@
<template>
<my-model ref="model" :title="title" iconColor="#000" @close="resetForm">
<template #desc>
<view class="u-m-t-48 tab">
<!-- <view class="u-m-t-48 tab">
<my-tabs :list="tabs" @change="tabsChange"></my-tabs>
</view>
</view> -->
<view class="u-text-left u-p-30 ">
<template v-if="!current">
<view>
@@ -34,7 +34,6 @@
<view class="u-flex-1">
<input @input="discountMoneyInput" v-model="form.discountMoney" type="digit"
placeholder-class="placeholder-class" placeholder="减8.55元请输入8.55" />
</view>
<view class="color-999 u-p-l-48 u-p-r-48 u-flex u-row-center u-col-center">
<view></view>
@@ -46,19 +45,22 @@
</view>
</template>
<view class="u-m-t-48">
<view class="u-font-24">
<text class="color-999">打折原因</text>
<text class="color-red">*</text>
</view>
<view class="u-font-24">
<text class="color-999">当前单品价格{{price}}</text>
</view>
<view class="u-font-24">
<text class="color-999">打折原因</text>
<text class="color-red">*</text>
</view>
<view class="u-flex u-m-t-24">
<view class="u-flex" v-for="(item,index) in causes" :key="index">
<button @tap="changeCauses(item)" class="tag u-m-r-20"
<button @tap="changeCauses(item,index)" class="tag u-m-r-20"
:class="{active:item.checked}">{{item.name}}</button>
</view>
</view>
</view>
<view class="u-m-t-32 u-flex ">
<uni-easyinput type="textarea" v-model="value" placeholder="自定义内容"></uni-easyinput>
<uni-easyinput type="textarea" v-model="form.note" placeholder="自定义内容"></uni-easyinput>
</view>
</view>
@@ -67,7 +69,10 @@
<view class="u-p-30">
<view class="u-m-t-10">
<my-button @tap="confirm" shape="circle" showShadow>确认</my-button>
<my-button type="cancel" bgColor="#fff" @tap="confirm">取消</my-button>
<view style="height: 20rpx;">
</view>
<!-- <my-button type="cancel" bgColor="#fff" @tap="confirm">取消</my-button> -->
</view>
</view>
</template>
@@ -86,7 +91,7 @@
import myTabs from '@/components/my-components/my-tabs.vue'
const props = defineProps({
price: {
type: [Number,String],
type: [Number, String],
default: 0
},
title: {
@@ -98,12 +103,10 @@
default: []
}
})
function changeCauses(item) {
item.checked = !item.checked
}
const discounts = [95, 90, 85, 80]
const causes = reactive([{
@@ -120,6 +123,11 @@
}
])
function changeCauses(item, index) {
item.checked = !item.checked
form.notes = causes
}
function discountInput(e) {
if (e.detail.value >= 100) {
nextTick(() => {
@@ -127,8 +135,9 @@
})
}
}
function discountMoneyInput(e) {
const max=100
const max = 100
if (e.detail.value >= max) {
nextTick(() => {
form.discountMoney = 100
@@ -142,7 +151,7 @@
const tabs = ['打折', '减免']
let current = ref(0)
let current = ref(1)
function tabsChange(i) {
console.log(i);
@@ -158,11 +167,12 @@
const form = reactive({
...$form
})
watch(()=>props.price,(newval)=>{
watch(() => props.price, (newval) => {
console.log(newval);
form.price=newval
form.currentPrice=newval
form.price = newval
form.currentPrice = newval
})
function resetForm() {
Object.assign(form, {
...$form
@@ -182,22 +192,23 @@
function confirm() {
const {
discount,discountMoney
discount,
discountMoney
} = form
if (current.value===0&& discount==='') {
if (current.value === 0 && discount === '') {
return uni.showToast({
icon: 'none',
title: '请输入有效折扣!'
})
}
if (current.value===1&& discountMoney==='') {
if (current.value === 1 && discountMoney === '') {
return uni.showToast({
icon: 'none',
title: '请输入有效减免价格!'
})
}
close()
emits('confirm', form)
close()
}
defineExpose({
open,

View File

@@ -136,10 +136,15 @@
:key="index">
<view class="u-flex u-row-between ">
<view class="u-flex">
<image class="img" :src="item.coverImg" mode=""></image>
<image class="img" v-if="item.coverImg" :src="item.coverImg" mode=""></image>
<view
style="background-color: #3f9eff; width: 84rpx;height: 84rpx;line-height: 84rpx;text-align: center;color: #fff;"
v-else>
临时菜
</view>
<view class="u-m-l-32">
<view class="u-flex">
<view class="u-flex u-m-r-20" v-if="item.isWait">
<view class="u-flex u-m-r-20" v-if="item.isWaitCall">
<uni-tag text="等叫"
custom-style="background-color: #FFF0DF; border-color: #FFF0DF; color: #FF9F2E;">
</uni-tag>
@@ -154,6 +159,11 @@
custom-style="background-color: #E6F0FF; border-color: #E6F0FF; color: #318AFE;"
size="small" text="打包" inverted type="success" />
</view>
<view class="u-m-r-20 u-flex" v-if="item.isPrint">
<uni-tag
custom-style="background-color: #E6F0FF; border-color: #E6F0FF; color: #318AFE;"
size="small" text="打印" inverted type="success" />
</view>
<view>
{{item.name}}
</view>
@@ -174,7 +184,8 @@
<text
class="line-th color-999">{{formatPrice(item.salePrice*item.number) }}</text>
<view class="u-absolute" style="right: 0;bottom: 100%;">
<text class="font-bold">{{formatPrice(item.memberPrice*item.number) }}</text>
<text
class="font-bold">{{formatPrice(item.memberPrice*item.number) }}</text>
</view>
</template>
<template v-else>
@@ -196,9 +207,10 @@
</template>
<scroll-view class="u-m-t-32" scroll-x="true" v-if="index==goods.sel">
<view class=" u-flex no-wrap ">
<!-- <view class="u-flex u-m-r-20 u-m-b-20">
<button class="tag" hover-class="hover-class" @tap="showModel('discount')">单品打折</button>
</view> -->
<view class="u-flex u-m-r-20 " v-if="!item.isGift">
<button class="tag" hover-class="hover-class"
@tap="showModel('discount',index)">单品打折</button>
</view>
<view class="u-flex u-m-r-20 ">
<!-- <button class="tag" hover-class="hover-class" @tap="showModel('giveFood')">赠菜</button> -->
<button class="tag" hover-class="hover-class"
@@ -208,10 +220,14 @@
<button class="tag" hover-class="hover-class"
@tap="toggleGoodsItemKey(item,index,'isPack')">{{item.isPack?'取消打包':'打包'}}</button>
</view>
<!-- <view class="u-flex u-m-r-20 u-m-b-20">
<view class="u-flex u-m-r-20 ">
<button class="tag" hover-class="hover-class"
@tap="toggleWait(item)">{{item.isWait?'取消等叫':'等叫'}}</button>
</view> -->
@tap="toggleWait(item)">{{item.isWaitCall?'取消等叫':'等叫'}}</button>
</view>
<view class="u-flex u-m-r-20 ">
<button class="tag" hover-class="hover-class"
@tap="toggisPrint(item)">{{item.isPrint?'免厨打':'打印'}}</button>
</view>
<view class="u-flex u-m-r-20 ">
<button class="tag" hover-class="hover-class"
@tap="showModel('remark',index)">单品备注</button>
@@ -251,7 +267,7 @@
<view class="font-bold u-font-32">{{formatPrice(youhui) }}</view>
</view>
</view>
<view class="u-flex price u-m-l-32">
<view class="">实收金额</view>
<view class="font-bold u-font-32">{{formatPrice(allPrice) }}</view>
@@ -278,8 +294,8 @@
</view>
</view>
<model-discount title="菜品打折/减免" :ref="setModel" name="discount" :price="allPrice"></model-discount>
<model-discount title="菜品减免" :ref="setModel" name="discount" :price="modelData.data.salePrice"
@confirm="discountconfirm"></model-discount>
<give-food title="赠菜" :ref="setModel" name="giveFood"></give-food>
<one-remark @confirm="goodsOneRemarkConfirm" title="单品备注" :ref="setModel" name="remark"></one-remark>
<edit-discount title="优惠金额" :ref="setModel" name="editMoney" :price="allPrice"></edit-discount>
@@ -351,7 +367,26 @@
return Number(n).toFixed(2)
}
// 单品打折
async function discountconfirm(form) {
if (form.discountMoney != '.') {
let str = ''
if (form.notes) {
form.notes.forEach(ele => {
if (ele.checked) {
str = str + ele.name + ','
}
})
}
let obj = {
saleAmount: form.discountMoney,
note: str + form.note,
cartId: modelData.data.id
}
const res = await Api.$updatePrice(obj)
getCart()
}
}
//用餐人数
const userNumbers = reactive({
@@ -416,18 +451,46 @@
skuId
}
par[key] = !item[key]
const res = await Api.$updateCart(par)
goods.list[index][key] = returnBoolean(res[key])
if (key == 'isPack') {
getCart()
}
getCart()
}
//等叫
function toggleWait(item) {
item.isWait = !item.isWait
async function toggleWait(item) {
item.isWaitCall = !item.isWaitCall
let obj = {
cartId: item.id,
isGift: item.isGift,
isPack: item.isPack,
isPrint: item.isPrint,
isWaitCall: item.isWaitCall,
masterId: option.masterId,
num: item.number, // 0会删除此商品
productId: item.productId,
skuId: item.skuId,
vipUserId: '',
}
let res = await Api.$updateCart(obj)
}
// 打印
async function toggisPrint(item) {
item.isPrint = !item.isPrint
let obj = {
cartId: item.id,
isGift: item.isGift,
isPack: item.isPack,
isPrint: item.isPrint,
isWaitCall: item.isWaitCall,
masterId: option.masterId,
num: item.number, // 0会删除此商品
productId: item.productId,
skuId: item.skuId,
vipUserId: '',
}
let res = await Api.$updateCart(obj)
}
const eatTypes = reactive({
list: [{
@@ -479,7 +542,6 @@
function watchChooseuser() {
uni.$off('choose-user')
uni.$on('choose-user', (data) => {
console.log(data);
user.value = data
setUser()
})
@@ -520,20 +582,25 @@
totalNumber: 0,
totalAmount: 0,
})
const isVip=computed(()=>{
return $shop.value.isMemberPrice&& user.value&&user.value.id&&user.value.isVip
const isVip = computed(() => {
return $shop.value.isMemberPrice && user.value && user.value.id && user.value.isVip
})
const discountSaleAmount = computed(() => {
return goods.list.filter((v) => v.discountSaleAmount && v.discountSaleAmount > 0)
.reduce((a, b) => {
return a + b.number * b.discountSaleAmount;
}, 0);
})
const goodsPrice = computed(() => {
const goodsTotalPrice = goods.list.reduce((prve, cur) => {
const memberPrice=cur.memberPrice?cur.memberPrice:cur.salePrice
const tPrice = (isVip.value? memberPrice:cur.salePrice) * cur.number
const memberPrice = cur.memberPrice ? cur.memberPrice : cur.salePrice
const tPrice = (isVip.value ? memberPrice : cur.salePrice) * cur.number
const tpackFee = cur.isPack ? cur.packFee * 1 : 0
return prve + (cur.isGift ? 0 : tPrice) + tpackFee
}, 0)
return (goodsTotalPrice || 0).toFixed(2)
return ((goodsTotalPrice - discountSaleAmount.value) || 0).toFixed(2)
})
const allPrice = computed(() => {
console.log(goodsPrice.value);
const n = goodsPrice.value * 1 + $seatFee.totalAmount
return n.toFixed(2)
// const goodsTotalPrice = goods.list.reduce((prve, cur) => {
@@ -541,18 +608,21 @@
// }, 0)
// return (goodsTotalPrice + ($seatFee.totalAmount || 0)).toFixed(2)
})
const youhui=computed(()=>{
if(user.value&&user.value.id&&user.value.isVip){
const goodsTotalPrice = goods.list.reduce((prve, cur) => {
const youhui = computed(() => {
let goodsTotalPrice = 0
if (user.value && user.value.id && user.value.isVip) {
goodsTotalPrice = goods.list.reduce((prve, cur) => {
const tPrice = cur.salePrice * cur.number
const tpackFee = cur.isPack ? cur.packFee * 1 : 0
return prve + tPrice + tpackFee
}, 0)
return goodsTotalPrice-allPrice.value
}else{
return 0
return goodsTotalPrice - allPrice.value
} else {
console.log(discountSaleAmount.value,'优惠金额')
return (discountSaleAmount.value)
}
return goodsTotalPrice
console.log(discountSaleAmount.value,'优惠金额1')
return (goodsTotalPrice + discountSaleAmount.value * 1).toFixed(2)
})
function setGoodsItem(key, val) {
@@ -573,16 +643,16 @@
records,
seatFee
} = await Api.getCart(par)
let useType=''
let useType = ''
if (seatFee && seatFee.useType) {
useType=seatFee.useType
useType = seatFee.useType
$storageManage.useType(useType)
}else{
useType=records[0].info[0].useType
} else {
useType = records[0].info[0].useType
$storageManage.useType(useType)
}
console.log(useType);
eatTypes.active =useType == 'takeout' ? useType : useType.replace(
eatTypes.active = useType == 'takeout' ? useType : useType.replace(
/-after|-before/g, '');
goods.list = getNowCart(records)
if (seatFee && seatFee.totalNumber) {

View File

@@ -6,7 +6,7 @@
<view class="u-absolute goods bg-fff">
<view
class="u-p-t-32 color-666 border-bottom bg-fff u-absolute total u-p-r-28 u-p-b-32 u-p-l-28 u-flex u-row-between">
<view>已添加{{goodsNumber}}件商品</view>
<view>已添加{{goodsNumber.toFixed(0)}}件商品</view>
<view class="color-666">
<uni-icons color="#666" type="trash"></uni-icons>
<text class="u-m-l-10" @tap="setModalShow('clear',true)">清空</text>
@@ -36,7 +36,7 @@
</image>
</view>
<view class="u-m-l-30 u-m-r-30 color-333">
{{item.number}}
{{(item.number).toFixed(2)}}
</view>
<view class="u-flex" @tap="updateNumber(true,index,item)">
<image src="/pagesCreateOrder/static/images/icon-add-black.svg" class="icon" mode="">

View File

@@ -1,30 +1,34 @@
<template>
<view class="u-relative u-flex item">
<up-image :src="data.coverImg" mode="aspectFill" :width="img.width" :height="img.height"></up-image>
<up-image :src="data.coverImg" mode="aspectFill" :width="img.width" :height="img.height"></up-image>
<!-- <image lazy-load class="img" :src="data.coverImg" mode="aspectFill" :style="computedImgStyle()"></image> -->
<view class="info u-flex u-row-between u-col-top u-flex-col" @tap="emitEvent('add')">
<view class="info u-flex u-row-between u-col-top u-flex-col">
<view>
<view>
<text class="u-line-2">{{data.name}}</text>
<text class="u-line-2">{{data.name}}
</text>
</view>
<view class="u-font-32 font-bold u-m-t-16">
{{data.price}}
</view>
<template v-if="data.type=='weigh'">
<view class="btnweigh">称重</view>
</template>
</view>
<view class="u-flex">
<template v-if="!isSellout">
<template v-if="!data.isDan">
<template v-if="!data.isDan||data.groupType==1">
<button class="btn" hover-class="btn-hover-class" @tap="emitEvent('chooseGuige')">选规格</button>
</template>
<template v-else>
<view class="u-flex icon-btn">
<view class="u-flex" @tap.stop="emitEvent('add')">
<view class="u-flex" @tap.stop="emitEvent(data.type=='weigh'?'tapweigh':'add')">
<image src="/pagesCreateOrder/static/images/icon-add.svg" class="icon" mode=""></image>
</view>
<template v-if="data.chooseNumber">
<view class="u-font-32">
{{data.chooseNumber}}
{{(data.chooseNumber).toFixed(2)}}
</view>
<view class="u-flex" @tap.stop="emitEvent('reduce')">
<image src="/pagesCreateOrder/static/images/icon-reduce.svg" class="icon" mode="">
@@ -55,20 +59,20 @@
} from 'vue';
import util from '../util.js';
const props = defineProps({
img:{
type:Object,
default:{
width:'250rpx',
height:'272rpx'
img: {
type: Object,
default: {
width: '250rpx',
height: '272rpx'
}
},
index: {
type: [Number,String],
type: [Number, String],
},
isSeatFee:{
isSeatFee: {
//是否为餐位费
type:Boolean,
default:false
type: Boolean,
default: false
},
data: {
type: Object,
@@ -79,36 +83,36 @@
}
}
})
function computedImgStyle(){
function computedImgStyle() {
return {
width:props.img.width,
height:props.img.height
width: props.img.width,
height: props.img.height
}
}
//判断是否是菜品
function isGoods(){
function isGoods() {
return props.data.hasOwnProperty('id')
}
//判断商品是否售尽
const isSellout = computed(() => {
const item = props.data
if(!isGoods()){
if (!isGoods()) {
return false
}
return (
item.isPauseSale ||
(item.typeEnum !== "sku" && item.isStock==1&& item.stockNumber <= 0)
(item.typeEnum !== "sku" && item.isStock == 1 && item.stockNumber <= 0)
);
})
const emits = defineEmits(['add', 'reduce', 'chooseGuige'])
function emitEvent(emitName){
if(isGoods()){
const emits = defineEmits(['add', 'reduce', 'chooseGuige','tapweigh'])
function emitEvent(emitName) {
if (isGoods()) {
emits(emitName, props.index)
}
}
@@ -133,10 +137,24 @@
color: #fff;
}
.btnweigh {
margin: 5rpx 0;
width: 100rpx;
background: linear-gradient(124deg, #73c969 6%, #27921b 93%);
border-radius: 10rpx;
font-size: 24rpx;
padding: 6rpx 0;
text-align: center;
}
.btn-hover-class {
opacity: .6;
}
image{will-change: transform}
image {
will-change: transform
}
.item {
// width: 250rpx;
// height: 272rpx;

View File

@@ -0,0 +1,180 @@
<template>
<my-model ref="model" borderRadius="12" :title="datas.title">
<template #desc>
<scroll-view scroll-y="true" style="height: 50vh;" class="u-p-30 guigeModel">
<view class="u-m-b-40" v-for="(item,index) in datas.skus" :key="index">
<view class="u-text-left">
<view class="color-333">{{item.title}} <text
style="color:#999">({{item.count}}{{item.number}})</text> </view>
</view>
<view class="u-flex u-m-t-20 u-flex-wrap">
<view class="item" @tap="chooseSkd(skd,item)" :class="{active:skd.select==true}"
v-for="(skd,skdIndex) in item.goods" :key="skdIndex">
{{skd.proName}}
</view>
</view>
</view>
</scroll-view>
</template>
<template #btn>
<view class="u-p-30 border-top ">
<view class="u-flex u-p-b-30 u-row-between">
<view class="price">
<text></text>
<text>{{datas.price}}</text>
</view>
</view>
<view class="u-m-t-10">
<my-button @tap="confirm">添加</my-button>
</view>
</view>
</template>
</my-model>
<uni-popup ref="popup" type="message">
<uni-popup-message type="info" message="请选择套餐" :duration="2000"></uni-popup-message>
</uni-popup>
</template>
<script setup>
import {
computed,
getCurrentInstance,
reactive,
ref,
watch
} from 'vue';
import util from '../util.js';
import infobox from '@/commons/utils/infoBox.js'
import myModel from '@/components/my-components/my-model.vue'
import myButton from '@/components/my-components/my-button.vue'
import {
onShow,
} from '@dcloudio/uni-app';
const props = defineProps({
goodsData: {
type: Object,
default: () => {}
},
})
let datas = reactive({
item: "",
title: "",
price: "",
skus: [],
// 几选几,的和
selectNumber: 0,
})
// const selSku = computed(() => {
// return props.skus.reduce((prve, cur) => {
// prve.push(cur.sel)
// return prve
// }, []).join()
// })
// const goods = computed(() => {
// return props.skuMap[selSku.value]
// })
watch(() => props.goodsData, (newval) => {
newval.proGroupVo.forEach(ele => {
ele.selectData = []
})
datas.item = newval
datas.title = newval.name
datas.price = newval.price
datas.skus = newval.proGroupVo
datas.skus.forEach(ele => {
datas.selectNumber += ele.number
})
})
const emits = defineEmits(['confirm', 'updateSku'])
function chooseSkd(skd, item) {
if (item.selectData.includes(skd.proId)) {
skd.select = false
let indexs = item.selectData.indexOf(skd.proId)
item.selectData.splice(indexs, 1)
} else {
if (item.selectData.length < item.number) {
skd.select = true
item.selectData.push(skd.proId)
}
}
}
const model = ref(null)
function open() {
model.value.open()
}
function close() {
model.value.close()
}
const instance = getCurrentInstance();
function confirm() {
// 将数据保存进对应的值
let arr = []
datas.item.proGroupVo.forEach(ele => {
arr.push(...ele.selectData)
})
if (arr.length == datas.selectNumber) {
emits('confirm', arr, datas.item)
close()
} else {
instance.ctx.$refs.popup.open()
}
}
defineExpose({
open,
close
})
</script>
<style lang="scss">
.border-top {}
.icon {
width: 40rpx;
height: 40rpx;
}
.guigeModel {
.item {
color: #666;
font-size: 24rpx;
padding: 4rpx 28rpx;
border: 1px solid #E5E5E5;
border-radius: 8rpx;
margin-right: 20rpx;
margin-bottom: 20rpx;
transition: all .2s ease-in-out;
&.active {
border-color: $my-main-color;
color: $my-main-color;
}
&.disabled {
color: #ccc;
border-color: #eee;
}
}
}
.price {
color: #EB4F4F;
}
.border-top {
border-top: 1px solid #E5E5E5;
}
</style>

View File

@@ -0,0 +1,290 @@
<template>
<view class="">
<up-overlay :show="overlayshow" @click="overlayshow = false">
<view class="boxoverlay">
<view class="rect" @tap.stop>
<view class="title">
<view>
标题
</view>
<view class="" @click="overlayshow = false">
<up-icon name="close" color="#93969b" size="20"></up-icon>
</view>
</view>
<view class="inputtop">
<view class="dj">
<view class="text">单价</view>
<view class="jg">{{form.goods.lowPrice}}/{{form.goods.unitName}}</view>
</view>
<view class="inputdj">
<view>重量</view>
<view class="inputdjbox">
<view class="inputdisplay">{{ currentInput }}</view>
<text>{{ form.goods.unitName }}</text>
</view>
</view>
</view>
<view class="keyboard">
<button v-for="(num, index) in numberButtons" :key="index" @click="handleClick(num)">
{{ num }}
</button>
<button @click="deleteLast"></button>
</view>
<view class="classmoney">
{{ (form.goods.lowPrice * currentInput).toFixed(2) }}
</view>
<view class="classconfirm" @click="clickconfirm">
确认
</view>
</view>
</view>
</up-overlay>
</view>
</template>
<script setup>
import {
onLoad,
onShow,
onReachBottom
} from '@dcloudio/uni-app';
import {
computed,
reactive,
ref,
watch,
defineExpose,
defineEmits
} from 'vue';
const emit = defineEmits(['refresh'])
const currentInput = ref('');
const numberButtons = ['1', '2', '3', '4', '5', '6', '7', '8', '9', '0', '.'];
const handleClick = (value) => {
// 首位不能输入0
if (currentInput.value === '') {
if (value === '0') {
return;
}
}
if (value === '.' && currentInput.value.indexOf('.') !== -1) {
return; // 如果已经存在小数点,不再添加
}
if (value === '.' && currentInput.value === '') {
currentInput.value = '0.';
} else {
currentInput.value += value;
}
// 限制小数点后两位
const parts = currentInput.value.split('.');
if (parts.length > 1 && parts[1].length > 2) {
currentInput.value = currentInput.value.slice(0, -1);
}
};
const deleteLast = () => {
currentInput.value = currentInput.value.slice(0, -1);
};
const clickconfirm = () => {
// 首位不能输入0
if (currentInput.value === '') {
uni.showToast({
title: '请输入',
icon: 'none'
})
return false;
}
emit('weighgoodsUpdate', form.foodsindex, form.index, true, undefined, currentInput.value)
overlayshow.value = false
}
//显示
const overlayshow = ref(false);
const form = reactive({})
const open = (foodsindex, index, goods) => {
currentInput.value = ''
Object.assign(form, {
foodsindex,
index,
goods
})
overlayshow.value = true
}
defineExpose({
open
})
</script>
<style lang="scss" scoped>
page {
background: #F9F9F9;
}
.boxoverlay {
width: 100%;
display: flex;
align-items: center;
justify-content: center;
height: 100%;
.rect {
padding: 32rpx 28rpx;
width: 80%;
background-color: #fff;
border-radius: 18rpx;
.title {
display: flex;
justify-content: space-between;
align-items: center;
padding-bottom: 20rpx;
font-size: 40rpx;
border-bottom: 1rpx solid #ccc;
}
.inputtop {
margin-top: 20rpx;
width: 100%;
display: flex;
justify-content: space-between;
align-items: center;
flex-wrap: wrap;
.dj {
width: 32%;
display: flex;
flex-direction: column;
justify-content: center;
align-items: flex-start;
.text {
font-weight: 300;
font-size: 24rpx;
}
.jg {
margin-top: 16rpx;
background-color: #e8f4ff;
color: #1890ff;
height: 60rpx;
line-height: 60rpx;
padding: 0 20rpx;
font-size: 24rpx;
color: #1890ff;
border-radius: 10rpx;
}
}
.inputdj {
width: 66%;
display: flex;
flex-direction: column;
justify-content: center;
align-items: flex-start;
font-weight: 300;
font-size: 24rpx;
.inputdjbox {
margin-top: 16rpx;
width: 100%;
display: flex;
justify-content: space-between;
align-items: center;
border: 1rpx solid #ccc;
border-radius: 10rpx;
padding-left: 20rpx;
height: 60rpx;
line-height: 60rpx;
background: #fff;
.inputdisplay {
width: auto;
}
text {
border: 1rpx solid #ccc;
border-radius: 10rpx;
border-radius: 10rpx;
padding: 0 20rpx;
background: #f5f7fa;
color: #a7aaaf;
}
}
}
}
.keyboard {
margin-top: 20rpx;
display: flex;
justify-content: space-between;
align-items: center;
flex-wrap: wrap;
button {
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
width: 28%;
margin: 10rpx;
}
.keyboard-button {
width: 28%;
margin: 10rpx;
border: none;
border-radius: 5rpx;
box-shadow: 0 0 5rpx rgba(0, 0, 0, 0.3), 0 0 10rpx rgba(0, 0, 0, 0.2);
cursor: pointer;
transition: all 0.3s ease;
}
// .keyboard-button:hover {
// box-shadow: 0 0 10rpx rgba(255, 0, 0, 0.5), 0 0 20px rgba(255, 0, 0, 0.3);
// transform: translateY(-2rpx);
// }
.dot-button {
// background-color: #FFC107;
}
.clear-button {
// background-color: #FF5733;
}
.clear-button:hover {
box-shadow: 0 0 10px rgba(255, 87, 51, 0.5), 0 0 20px rgba(255, 87, 51, 0.3);
}
.delete-button {
// background-color: #33FF57;
}
.delete-button:hover {
// box-shadow: 0 0 10px rgba(51, 255, 87, 0.5), 0 0 20px rgba(51, 255, 87, 0.3);
}
}
.classmoney {
margin-top: 16rpx;
width: 100%;
font-size: 40rpx;
text-align: left;
color: #ff5152;
font-weight: 600;
}
.classconfirm {
width: 100%;
margin: 30rpx auto 0 auto;
border-radius: 16rpx;
text-align: center;
background: #1890ff;
color: #fff;
padding: 10rpx 0;
}
}
}
</style>

View File

@@ -60,7 +60,7 @@
<view class="page-view u-p-l-24">
<view class="list-tight-top">
<template v-if="lingshi.show">
<view id="lingshi" class="lingshi" @tap="toLinshi">
<view id="lingshi" class="lingshi u-m-b-32" @tap="toLinshi">
<uni-icons type="plus-filled" size="24" :color="color.ColorMain"></uni-icons>
<view class="u-m-t-24 color-main">临时菜</view>
</view>
@@ -78,7 +78,8 @@
<view class="thumb-box" v-for="(goodsItem, goodsIndex) in item.foods" :key="goodsIndex">
<list-goods-item @chooseGuige="chooseGuige($event,index)"
@add="goodsUpdate($event,index,true)" @reduce="goodsUpdate($event,index,false)"
:index="goodsIndex" :data="goodsItem"></list-goods-item>
@tapweigh="tapweigh($event,index)" :index="goodsIndex"
:data="goodsItem"></list-goods-item>
</view>
<!-- <template v-if="item.name==='附加费'">
@@ -104,8 +105,8 @@
@chooseGuige="chooseGuige(goodsItem.goodsIndex,goodsItem.index)"
@add="searchGoodsUpdate(goodsItem,goodsIndex,true)"
@reduce="searchGoodsUpdate(goodsItem,goodsIndex,false)"
@tapweigh="tapweigh(goodsItem.goodsIndex,goodsItem.index)"
:index="goodsItem.goodsIndex" :data="goodsItem"></list-goods-item>
</view>
</view>
<my-img-empty v-if="!searchResult.length" tips="未搜索到相关商品"></my-img-empty>
@@ -120,15 +121,16 @@
<my-car :isCreateOrderToDetail="isCreateOrderToDetail" @updateNumber="carsNumberChange" :user="data.vipUser"
:masterId="data.masterId" :table="data.table" :data="cars" @clear="onClearCart"></my-car>
</view>
<!-- 套餐选择规格 -->
<taocanModel ref="taocanModelRef" @confirm="taocanConfirm" :goodsData="selGoods"></taocanModel>
<!-- 选择规格 -->
<guige-model @update-sku="updateSkuSel" @confirm="guigeConfirm" ref="chooseGuigeModel" :goodsData="selGoods"
:title="guigeModelData.title" :sku-map="guigeModelData.chooseGoods.skuMap"
:skus="guigeModelData.chooseGoods.skus"></guige-model>
<!-- 添加附加费 -->
<my-surcharge @confirm="surchargeConfirm" ref="surcharge" title="添加附加费"></my-surcharge>
<!-- 称重 -->
<weigh-item ref="refweighitem" @weighgoodsUpdate='goodsUpdate'></weigh-item>
</view>
<up-modal title="提示" content="该台桌购物车里有商品,是否清除该台桌里的商品?" :show="modal.clear" showCancelButton closeOnClickOverlay
@confirm="confirmModelConfirm" @cancel="confirmModelConfirm('cancel')" @close="setModalShow('clear',false)"
@@ -150,6 +152,8 @@
import util from './util.js';
import color from '@/commons/color.js';
import guigeModel from './components/guige'
import taocanModel from './components/taocanModel.vue'
import weighItem from './components/weigh.vue'
import listGoodsItem from './components/list-goods-item.vue'
import mySurcharge from './components/surcharge'
import {
@@ -224,7 +228,7 @@
xiadanClick()
//临时菜
const lingshi = reactive({
show: false
show: true
})
//附加费
const extraFee = reactive({
@@ -277,6 +281,26 @@
}
return obj
}
// 添加套餐
async function taocanConfirm(d, item) {
const cartGoods = await addCart({
num: 1,
groupProductIdList: d,
productId: item.id,
skuId: item.specList[0].id
})
infoBox.showToast('添加成功')
// guigeConfirm(item, 1)
// updateCartGoods({
// productId: item.id,
// skuId: item.specList[0].id,
// cartId: cartGoods.id
// })
cars.push({
...cartGoods,
specSnap: item.specSnap
})
}
function scanCode() {
// 只允许通过相机扫码
@@ -671,7 +695,12 @@
}
function toLinshi() {
go.to('PAGES_ADD_TEMP_CUISINE')
go.to('PAGES_CHOOSE_ADD_TEMP_CUISINE', {
masterId: data.masterId,
tableId: data.table.tableId,
vipUserId: option.vipUserId ? option.vipUserId : '',
useType: uni.getStorageSync('useType')
})
}
const chooseGuigeModel = ref(null)
@@ -828,7 +857,14 @@
}
let selGoods = ref({})
let selGoods = ref({});
// 称重
const refweighitem = ref(null)
const tapweigh = (foodsindex, index) => {
const goods = data.tabbar[index].foods[foodsindex]
refweighitem.value.open(foodsindex, index, goods)
}
function chooseGuige(foodsindex, index) {
if (!canAddGoods()) {
@@ -838,13 +874,19 @@
}
const $goods = data.tabbar[index].foods[foodsindex]
selGoods.value = $goods
guigeModelData.title = $goods.name
const specList = $goods.specList;
const tagSnap = JSON.parse($goods.skuResult.tagSnap)
const skuMap = returnSelGoodsSkuMap(specList)
const skuList = returnSelGoodsSkuList(tagSnap)
setSkugoodsDefaultInit($goods, skuList, skuMap, specList)
chooseGuigeModel.value.open()
if ($goods.groupType == 1) {
instance.ctx.$refs.taocanModelRef.open()
} else {
guigeModelData.title = $goods.name
const specList = $goods.specList;
const skuMap = returnSelGoodsSkuMap(specList)
// 多规格,和套餐规格区分.groupType=1 套餐多规格
let tagSnap = JSON.parse($goods.skuResult.tagSnap)
const skuList = returnSelGoodsSkuList(tagSnap)
setSkugoodsDefaultInit($goods, skuList, skuMap, specList)
chooseGuigeModel.value.open()
}
}
async function guigeConfirm(sku, num) {
@@ -897,10 +939,15 @@
categoryId,
skuId
} = goods
const cartId = goods.id
const tabbarIndex = data.tabbar.findIndex(v => v.id == categoryId)
const $goods = data.tabbar[tabbarIndex].foods.find(v => v.id == productId)
const $sku = $goods.specList.find(v => v.id == skuId)
//临时菜没有对应商品数据
const $goods = !productId ? undefined : data.tabbar[tabbarIndex].foods.find(v => v.id == productId)
//临时菜没有skuList
const $sku = !productId ? {
suit: 1
} : $goods.specList.find(v => v.id == skuId)
if (num === 0 || num < $sku.suit) {
//移除
@@ -950,7 +997,8 @@
searchResult.value[index].chooseNumber = chooseNumber
}
}
async function goodsUpdate(foodsindex, index, isAdd, searchGoodsIndex) {
async function goodsUpdate(foodsindex, index, isAdd, searchGoodsIndex, showCurrentInput) { // showCurrentInput 称重才会传的参数
// if (!canAddGoods()) {
// return infoBox.showToast('请先选择桌台', 0.5).then(res => {
// chooseTable()
@@ -964,13 +1012,13 @@
});
const productId = $goods.id
const skuId = $goods.specList[0].id
const suit = $goods.specList[0].suit || 1
let suit = $goods.specList[0].suit || 1
if (goodsInCarIndex !== -1) {
//更新
const carGoods = cars[goodsInCarIndex]
const cartId = carGoods.id
const step = isAdd ? 1 : -1
const num = carGoods.number * 1 + step
let num = carGoods.number * 1 + step
if (num === 0 || num < suit) {
//移除
cars.splice(goodsInCarIndex, 1)
@@ -980,6 +1028,10 @@
cartId
})
}
// 不影响之前的代码 称重num单独处理
if ($goods.type == 'weigh' && showCurrentInput) {
num = carGoods.number * 1 + Number(showCurrentInput)
}
const {
number
} = await updateCartGoods({
@@ -992,16 +1044,23 @@
$goods.chooseNumber = number
setSearchGoods(searchGoodsIndex, number)
} else {
//增加
const num = suit
const cartGoods = await addCart({
num,
productId,
skuId
})
infoBox.showToast('添加成功')
$goods.chooseNumber = num
cars.push(cartGoods)
// 不影响之前的代码 称重suit单独处理
if ($goods.type == 'weigh' && showCurrentInput) {
suit = showCurrentInput
}
// 套餐和单规格
if ($goods.groupType != 1) {
//增加
const num = suit
const cartGoods = await addCart({
num,
productId,
skuId
})
infoBox.showToast('添加成功')
$goods.chooseNumber = Number(num)
cars.push(cartGoods)
}
}
return
}
@@ -1129,7 +1188,7 @@
}
if (e.detail.scrollTop == 0) {
isTabClickOver = true
return swichMenu(0)
// return swichMenu(0)
}
setTimeout(() => { // 节流
data.timer = null;
@@ -1184,6 +1243,7 @@
function watchUpdate() {
uni.$off('update:createOrderIndex')
uni.$off('get:table')
uni.$off('add:cashCai')
uni.$on('update:createOrderIndex', () => {
// data.table = {
// tableId: ""
@@ -1192,6 +1252,15 @@
console.log('update:createOrderIndex');
init()
})
uni.$on('add:cashCai', async () => {
console.log('add:cashCai');
const cartRes = await getCart()
cars.length = 0
const cartArr = getNowCart(cartRes.records)
for (let i in cartArr) {
cars.push(cartArr[i])
}
})
uni.$on('get:table', () => {
console.log('get:table');
if (data.table.tableId) {

View File

@@ -9,7 +9,10 @@ export function getNowCart(records) {
const arr = []
for (let i in Cart) {
const item=Cart[i]
const key = item.productId + '_' + item.skuId
const productId=item.productId
const skuId=item.skuId
const isLinShiCai=!productId&&!skuId?true:false
const key =isLinShiCai?item.name: (item.productId + '_' + item.skuId)
if (goodsMap.hasOwnProperty(key)) {
const index = goodsMap[key]
arr[index].number = arr[index].number * 1 + item.number

View File

@@ -219,7 +219,8 @@
tableId: options.tableId || orderDetail.info.tableId,
name: options.name || orderDetail.info.tableName,
masterId:orderDetail.info.masterId,
type: 'add'
type: 'add',
vipUserId:orderDetail.memberId?orderDetail.memberId:''
})
}

View File

@@ -0,0 +1,255 @@
<template>
<view class="">
<up-overlay :show="overlayshow" @click="overlayshow = false">
<view class="boxoverlay">
<view class="rect" @tap.stop>
<!-- 抖音 -->
<view class="bottomconstant">
<view class="itemlist">
<!-- <view class="ordernumber">
订单号111
</view> -->
<view class="title">
请选择商品
</view>
<view class="itemlists" v-for="(item,index) in form.goods" :key="index">
<view class="top">
<view class="tag">
{{item.title}}
</view>
<view class="date">
¥{{item.amount}}
</view>
</view>
<!-- <view class="bottom">
核销
</view> -->
<view v-if="item.type" @click="item.type =!item.type">
<up-icon name="checkmark-circle" color="#2979ff" size="22"></up-icon>
</view>
<view class="icon" v-else @click="item.type =!item.type"></view>
</view>
<view class="bouttonbox">
<view class="keep" @click="confirms">
确定核销
</view>
<view class="cancel" @click="overlayshow = false">
取消
</view>
</view>
</view>
</view>
</view>
</view>
</up-overlay>
</view>
</template>
<script setup>
import {
onLoad,
onShow,
onReachBottom
} from '@dcloudio/uni-app';
import {
computed,
reactive,
ref,
watch,
defineExpose
} from 'vue';
const form = reactive({
id: "",
number: '',
sum_pay_amount: '',
goods: [],
verify_token: '',
});
import {
certificateprepares
} from '@/http/php/api.ts';
//显示
const overlayshow = ref(false);
const open = (val) => {
Object.assign(form, val)
form.goods.map((item) => {
item.type = true
})
overlayshow.value = true
}
let confirms = async () => {
// 判断是否选择商品
if (form.goods.filter(i => i.type).length == 0) {
uni.showToast({
title: '请选择商品',
icon: 'none'
})
return false
}
let data = null
if (uni.getStorageSync('clint_type') == 1) {
data = {
couponCode: form.couponCode,
num: form.goods.length
}
} else {
let encrypted_codes = form.goods.filter(i => i.type).map((obj, index) => {
return obj.encrypted_code;
})
data = {
verify_token: form.verify_token,
encrypted_codes: encrypted_codes.toString(),
id: form.id
}
}
await certificateprepares(data)
uni.showToast({
title: '验证成功',
icon: 'none'
})
overlayshow.value = false
}
defineExpose({
open
})
</script>
<style lang="scss" scoped>
page {
background: #F9F9F9;
}
.boxoverlay {
width: 100%;
display: flex;
align-items: center;
justify-content: center;
height: 100%;
.rect {
padding: 32rpx 28rpx;
width: 80%;
background-color: #fff;
border-radius: 18rpx;
.bottomconstant {
padding: 0 28rpx;
width: 100%;
border-radius: 18rpx 18rpx 18rpx 18rpx;
.itemlist:nth-child(1) {
margin-top: 0;
}
.itemlist {
// margin-top: 16rpx;
width: 100%;
background: #FFFFFF;
border-radius: 18rpx 18rpx 18rpx 18rpx;
.ordernumber {
font-family: Source Han Sans CN, Source Han Sans CN;
font-weight: 400;
font-size: 24rpx;
color: #999999;
}
.title {
margin-top: 16rpx;
padding-bottom: 16rpx;
font-family: Source Han Sans CN, Source Han Sans CN;
font-weight: bold;
font-size: 28rpx;
color: #333333;
border-bottom: 1rpx solid #E5E5E5;
}
.itemlists {
padding-top: 16rpx;
display: flex;
justify-content: space-between;
align-items: center;
.top {
display: flex;
flex-direction: column;
justify-content: center;
align-items: flex-start;
.date {
margin-top: 10rpx;
font-family: Source Han Sans CN, Source Han Sans CN;
font-weight: 400;
font-size: 24rpx;
color: #999999;
}
.tag {
width: 350rpx;
overflow: hidden; //超出的文本隐藏
text-overflow: ellipsis; //溢出用省略号显示
white-space: nowrap; //溢出不换行
font-family: Source Han Sans CN, Source Han Sans CN;
font-weight: 500;
font-size: 28rpx;
color: #333333;
}
}
.icon {
width: 40rpx;
height: 40rpx;
border: 1px solid #909399;
border-radius: 50%;
}
.bottom {
background: #EAF4FD;
border-radius: 4rpx 4rpx 4rpx 4rpx;
padding: 6rpx 12rpx;
font-family: Source Han Sans CN, Source Han Sans CN;
font-weight: 400;
font-size: 20rpx;
color: #318AFE;
}
}
.bouttonbox {
margin-top: 80rpx;
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
.keep {
width: 490rpx;
height: 80rpx;
background: #318AFE;
border-radius: 40rpx 40rpx 40rpx 40rpx;
font-family: Source Han Sans CN, Source Han Sans CN;
font-weight: 500;
font-size: 32rpx;
color: #FFFFFF;
text-align: center;
line-height: 80rpx;
}
.cancel {
text-align: center;
width: 490rpx;
height: 80rpx;
background: #ffffff;
border-radius: 40rpx 40rpx 40rpx 40rpx;
font-family: Source Han Sans CN, Source Han Sans CN;
font-weight: 400;
font-size: 24rpx;
color: #999999;
line-height: 80rpx;
}
}
}
}
}
}
</style>

View File

@@ -0,0 +1,155 @@
<template>
<view class="">
<up-overlay :show="overlayshow" @click="overlayshow = false">
<view class="boxoverlay">
<view class="rect" @tap.stop>
<!-- 抖音 -->
<view class="bottomconstant">
<view class="itemlist">
<!-- <view class="ordernumber">
订单号111
</view> -->
<view class="title">
绑定门店
</view>
<view class="itemlists" v-for="(item,index) in 4" :key="index">
<view class="top">
<view class="tag">
名称qqqqqqqqq
</view>
<view class="date">
地址qqqqqqq
</view>
</view>
<view class="bottom">
操作
</view>
</view>
</view>
</view>
</view>
</view>
</up-overlay>
</view>
</template>
<script setup>
import {
onLoad,
onShow,
onReachBottom
} from '@dcloudio/uni-app';
import {
computed,
reactive,
ref,
watch,
defineExpose
} from 'vue';
//显示
const overlayshow = ref(false);
const open = () => {
overlayshow.value = true
}
defineExpose({
open
})
</script>
<style lang="scss" scoped>
page {
background: #F9F9F9;
}
.boxoverlay {
width: 100%;
display: flex;
align-items: center;
justify-content: center;
height: 100%;
.rect {
padding: 32rpx 28rpx;
width: 80%;
background-color: #fff;
border-radius: 18rpx;
.bottomconstant {
padding: 0 28rpx;
width: 100%;
border-radius: 18rpx 18rpx 18rpx 18rpx;
.itemlist:nth-child(1) {
margin-top: 0;
}
.itemlist {
// margin-top: 16rpx;
width: 100%;
background: #FFFFFF;
border-radius: 18rpx 18rpx 18rpx 18rpx;
.ordernumber {
font-family: Source Han Sans CN, Source Han Sans CN;
font-weight: 400;
font-size: 24rpx;
color: #999999;
}
.title {
margin-top: 16rpx;
padding-bottom: 16rpx;
font-family: Source Han Sans CN, Source Han Sans CN;
font-weight: bold;
font-size: 28rpx;
color: #333333;
border-bottom: 1rpx solid #E5E5E5;
}
.itemlists {
padding-top: 16rpx;
display: flex;
justify-content: space-between;
align-items: center;
.top {
display: flex;
flex-direction: column;
justify-content: center;
align-items: flex-start;
.date {
margin-top: 10rpx;
font-family: Source Han Sans CN, Source Han Sans CN;
font-weight: 400;
font-size: 24rpx;
color: #999999;
}
.tag {
width: 350rpx;
overflow: hidden; //超出的文本隐藏
text-overflow: ellipsis; //溢出用省略号显示
white-space: nowrap; //溢出不换行
font-family: Source Han Sans CN, Source Han Sans CN;
font-weight: 500;
font-size: 28rpx;
color: #333333;
}
}
.bottom {
background: #EAF4FD;
border-radius: 4rpx 4rpx 4rpx 4rpx;
padding: 6rpx 12rpx;
font-family: Source Han Sans CN, Source Han Sans CN;
font-weight: 400;
font-size: 20rpx;
color: #318AFE;
}
}
}
}
}
}
</style>

View File

@@ -0,0 +1,267 @@
<template>
<view class="constant">
<view class="constantitem" @click="object_id =null,overlayshow = true">
<view>扫码核销</view>
<view>
<up-icon name="arrow-right" color="#909399" size="20"></up-icon>
</view>
</view>
<view class="constantitem" @click="clickpath('PAGES_WEITEOFF_RECORD',1)">
<view>美团记录</view>
<view>
<up-icon name="arrow-right" color="#909399" size="20"></up-icon>
</view>
</view>
<view class="constantitem" @click="clickpath('PAGES_WEITEOFF_RECORD',2)">
<view>抖音记录</view>
<view>
<up-icon name="arrow-right" color="#909399" size="20"></up-icon>
</view>
</view>
<!-- 核销准备 -->
<up-overlay :show="overlayshow">
<view class="boxoverlay">
<view class="rect" @tap.stop>
<view class="top">
团购卷核销
</view>
<view class="subsection">
<up-subsection :list="subsectionlist" :current="subsectioncurrent" @change="sectionChange">
</up-subsection>
</view>
<view class="search">
<up-search :show-action="false" searchIcon="scan" :clearabled="true" @clickIcon='clickIcon'
placeholder="请扫码或者输入卷码" v-model="object_id"></up-search>
</view>
<view class="search">
<up-alert fontSize='10' :show-icon="true" title="请使用相机识别扫码" type="warning"
:closable="true"></up-alert>
</view>
<view class="bouttonbox">
<view class="keep" @click="confirms">
确认
</view>
<view class="cancel" @click="overlayshow = false">
取消
</view>
</view>
</view>
</view>
</up-overlay>
<!-- 绑定门店 -->
<dialogs ref="dialogsref"></dialogs>
<!-- 选择商品 -->
<commodity ref="refcommodity"></commodity>
<!-- 二维码 -->
<up-overlay :show="qrcodes.show" @click="qrcodes.show = false">
<view class="boxoverlay">
<view class="rect" @tap.stop
style="display: flex; flex-direction: column; align-items: center; justify-content: center;">
<!-- <view>{{subsectioncurrent==0?'请用美团':'抖音'}}</view> -->
<view style="padding-bottom:40rpx;font-weight: 600;">请进行手机扫码</view>
<!-- <up-qrcode :size="200" :val="qrcodes.val" :icon='qrcodes.icon'></up-qrcode> -->
<up-qrcode :size="200" :val="qrcodes.val"></up-qrcode>
</view>
</view>
</up-overlay>
</view>
</template>
<script setup>
import {
onLoad,
onShow,
onUnload,
} from '@dcloudio/uni-app';
import {
computed,
reactive,
ref,
watch
} from 'vue';
import {
userlogout,
douyincheckIn,
fulfilmentcertificateprepare, //准备核销
searchstorestatus, //状态查询
getuisdk //获取uisdk 绑定 链接
} from '@/http/php/api.ts';
import go from '@/commons/utils/go.js'
import dialogs from '../components/dialogs.vue'
import commodity from '../components/commodity.vue'
onLoad(async () => {
// 登录 会员入签
let res = await douyincheckIn({
token: uni.getStorageSync("iToken"),
loginName: uni.getStorageSync("shopId"),
clientType: 'ADMIN'
})
uni.setStorageSync('phpuserinfo', res.userInfo)
uni.setStorageSync('clint_type', 1)
})
//显示
const overlayshow = ref(false);
// 切换
const subsectioncurrent = ref(0);
const subsectionlist = ref(['美团', '抖音']);
const sectionChange = (index) => {
subsectioncurrent.value = index;
uni.setStorageSync('clint_type', index + 1)
}
// 二维码或者条形码
const object_id = ref(null)
// 扫码
const clickIcon = () => {
uni.scanCode({ // 允许从相机和相册扫码
success: (res) => {
console.log('条码类型:' + res.scanType);
console.log('条码内容:' + res.result);
object_id.value = res.result
}
});
}
// 二维码
const qrcodes = reactive({
val: 'www.baidu.com',
icon: '@/static/logo.png',
show: false
})
// 首先获取状态
let confirms = async () => {
if (object_id.value == null) {
uni.showToast({
title: '请扫码或者输入卷码',
icon: 'none'
})
return false;
}
let res = await searchstorestatus()
// status == 0 则需要显示二维码 ==1 去核销
if (res.status == 0) {
qrcodes.val = await getuisdk()
overlayshow.value = false
qrcodes.show = true
} else {
clickkeep()
}
}
// 点击确定
const clickkeep = async () => {
let data = null
if (uni.getStorageSync('clint_type') == 1) {
data = {
code: object_id.value
}
} else {
data = {
object_id: object_id.value
}
}
let res = await fulfilmentcertificateprepare(data)
overlayshow.value = false
refcommodity.value.open(res)
}
// 这是选择门店
// const dialogsref = ref(null)
// const dialogconfirm = () => {
// dialogsref.value.open()
// }
// 选择商品
const refcommodity = ref(null)
// 跳转
const clickpath = (URL, title) => {
uni.setStorageSync('clint_type', title)
go.to(URL)
}
onShow(async () => {})
// 销毁组件
onUnload(async () => {
// 退出
await userlogout()
})
</script>
<style lang="scss" scoped>
page {
background: #F9F9F9;
}
.constant {
.constantitem {
display: flex;
justify-content: space-between;
align-items: center;
background: #fff;
padding: 24rpx 32rpx;
}
.boxoverlay {
width: 100%;
display: flex;
align-items: center;
justify-content: center;
height: 100%;
.rect {
padding: 32rpx 28rpx;
width: 80%;
background-color: #fff;
border-radius: 18rpx;
.top {
font-size: 32rpx;
font-weight: 600;
}
.subsection {
margin-top: 24rpx;
}
.search {
margin-top: 24rpx;
}
.bouttonbox {
margin-top: 80rpx;
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
.keep {
width: 490rpx;
height: 80rpx;
background: #318AFE;
border-radius: 40rpx 40rpx 40rpx 40rpx;
font-family: Source Han Sans CN, Source Han Sans CN;
font-weight: 500;
font-size: 32rpx;
color: #FFFFFF;
text-align: center;
line-height: 80rpx;
}
.cancel {
text-align: center;
width: 490rpx;
height: 80rpx;
background: #ffffff;
border-radius: 40rpx 40rpx 40rpx 40rpx;
font-family: Source Han Sans CN, Source Han Sans CN;
font-weight: 400;
font-size: 24rpx;
color: #999999;
line-height: 80rpx;
}
}
}
}
}
</style>

View File

@@ -0,0 +1,360 @@
<template>
<view class="constant">
<!-- <view class="topbox">
<view class="left">
<view class="">
筛选
</view>
<view class=""></view>
</view>
<view class="right">
<up-input class="input" placeholder="搜索订单号" v-model="value"
@change="change"></up-input>
</view>
</view> -->
<!-- 抖音 -->
<view v-if="form.type == 2">
<view class="bottomconstant" v-for="(item,index) in form.list" :key="index">
<view class="itemlist">
<view class="ordernumber">
{{item.d_order_id}}
</view>
<view class="title">
{{item.title}}
</view>
<view class="itemlists" v-for="(item1,index1) in item.douyinCodeGoods" :key="item1.id">
<view class="top">
<view class="date">
{{item1.create_time}}
</view>
<view class="tag" v-if="item1.status == 1" @click="clickcancel(item1)"
style="background: #318AFE;color: #fff; border-radius: 10rpx;">
撤销核销
</view>
<view class="tag" v-if="item1.status == 0">
等待验券
</view>
<view class="tag" v-if="item1.status == 2">
失败
</view>
</view>
<view class="bottom">
<view class="bottomtitle">
{{item1.title}}
</view>
<view class="price">
<view class="prices">
{{item1.pay_amount}}
</view>
<!-- <view class="pricees">
{{item1.market_price}}
</view> -->
</view>
</view>
</view>
</view>
</view>
</view>
<!-- 美团 -->
<view class="bottomconstant" v-else>
<view class="itemlist" v-for="(item,index) in form.list" :key="index">
<view class="itemlists" style="padding: 0;">
<view class="top">
<view class="date">
{{item.couponUseTime}}
</view>
<view class="tag" :style="!item.type?'background: #318AFE;color: #fff; border-radius: 10rpx;':''"
@click="clickcancel(item)">
{{item.type ? item.couponStatusDesc:'撤销核销'}}
</view>
</view>
<view class="bottom">
<view class="bottomtitle">
{{item.dealTitle}}
</view>
<view class="price">
<view class="prices">
¥{{item.couponBuyPrice}}
</view>
<!-- <view class="pricees">
156
</view> -->
</view>
</view>
</view>
</view>
</view>
<up-loadmore :status="form.status" />
</view>
</template>
<script setup>
import {
onLoad,
onShow,
onReachBottom
} from '@dcloudio/uni-app';
import {
computed,
reactive,
ref,
watch
} from 'vue';
import dayjs from "dayjs";
import {
orderlist,
fulfilmentcertificatecanceles
} from '@/http/php/api.ts';
// 下拉加载
onReachBottom(() => {
if (form.status != 'nomore') {
form.page = ++form.page;
getlist()
}
})
onLoad(async (e) => {
form.type = uni.getStorageSync('clint_type')
initial()
})
const dropdownvalue = ref(1)
const optionsdropdown = [{
label: '等待验证',
value: 1,
},
{
label: '成功',
value: 2,
},
{
label: '失败',
value: 3,
}
]
// 初始化
const initial = () => {
form.page = 1
form.status = 'loadmore'
form.d_order_id = ''
form.querystatus = ''
getlist()
}
//
const form = reactive({
type: '',
d_order_id: '',
querystatus: '',
page: 1,
status: '',
list: [],
count: '',
date: ''
});
const getlist = async () => {
let data = null
if (uni.getStorageSync('clint_type') == 1) {
data = {
page: form.page,
date: form.date
}
} else {
data = {
page: form.page,
status: form.querystatus,
d_order_id: form.d_order_id
}
}
let res = await orderlist(data)
form.count = res.count
form.status = 'loading';
if (form.page == 1 && res.list.length == 0) {
form.status = 'nomore'
return false;
} else {
setTimeout(() => {
if (form.page == 1) {
form.list = res.list
} else {
form.list = [...form.list, ...res.list];
}
if (form.list.length >= form.count && res.list.length < 10) {
form.status = 'nomore';
} else {
form.status = 'loadmore';
}
// 这是美团处理的数据
if (uni.getStorageSync('clint_type') == 1) {
form.list = form.list.map(item => {
// 计算60天后
item.couponUseTimes = dayjs(item.couponUseTime).add(60, 'day').format(
'YYYY-MM-DD HH:mm:ss')
item.type = dayjs().isAfter(dayjs(item.couponUseTime).add(60, 'day'),
'year')
return item
});
}
}, 500)
}
}
const clickcancel = async (item) => {
uni.showModal({
title: '确认撤销吗?',
success: async (res) => {
if (res.confirm) {
let data = null
if (uni.getStorageSync('clint_type') == 1) {
data = {
couponCode: item.couponCode
}
} else {
data = {
verify_id: item.verify_id,
certificate_id: item.certificate_id
}
}
await fulfilmentcertificatecanceles(data)
uni.showToast({
title: '撤销核销成功',
icon: 'success'
})
setTimeout(() => {
initial()
}, 1000)
} else if (res.cancel) {
console.log('用户点击取消');
}
}
})
}
</script>
<style lang="scss" scoped>
page {
background: #F9F9F9;
}
.constant {
padding-bottom: 32rpx;
.topbox {
width: 100%;
padding: 32rpx 28rpx;
background: #fff;
display: flex;
justify-content: space-between;
align-items: center;
flex-wrap: wrap;
.left {}
.right {
width: 80%;
.input {
width: 100%;
}
}
}
.bottomconstant {
padding: 0 28rpx;
width: 100%;
border-radius: 18rpx 18rpx 18rpx 18rpx;
.itemlist {
margin-top: 32rpx;
padding: 32rpx 24rpx;
width: 100%;
background: #FFFFFF;
border-radius: 18rpx 18rpx 18rpx 18rpx;
.ordernumber {
font-family: Source Han Sans CN, Source Han Sans CN;
font-weight: 400;
font-size: 24rpx;
color: #999999;
}
.title {
margin-top: 16rpx;
padding-bottom: 24rpx;
font-family: Source Han Sans CN, Source Han Sans CN;
font-weight: bold;
font-size: 28rpx;
color: #333333;
border-bottom: 1rpx solid #E5E5E5;
}
.itemlists {
padding-top: 24rpx;
.top {
display: flex;
justify-content: space-between;
align-items: center;
flex-wrap: wrap;
.date {
font-family: Source Han Sans CN, Source Han Sans CN;
font-weight: 400;
font-size: 24rpx;
color: #999999;
}
.tag {
background: #EAF4FD;
border-radius: 4rpx 4rpx 4rpx 4rpx;
padding: 6rpx 12rpx;
font-family: Source Han Sans CN, Source Han Sans CN;
font-weight: 400;
font-size: 20rpx;
color: #318AFE;
}
}
.bottom {
display: flex;
justify-content: space-between;
align-items: center;
.bottomtitle {
width: 350rpx;
overflow: hidden; //超出的文本隐藏
text-overflow: ellipsis; //溢出用省略号显示
white-space: nowrap; //溢出不换行
font-family: Source Han Sans CN, Source Han Sans CN;
font-weight: 500;
font-size: 28rpx;
color: #333333;
}
.price {
margin-top: 16rpx;
display: flex;
justify-content: flex-start;
align-items: center;
.prices {
font-family: Source Han Sans CN, Source Han Sans CN;
font-weight: 500;
font-size: 28rpx;
color: #333333;
}
.pricees {
margin-left: 12rpx;
font-family: Source Han Sans CN, Source Han Sans CN;
font-weight: 500;
font-size: 24rpx;
color: #999999;
text-decoration-line: line-through;
}
}
}
}
}
}
}
</style>

View File

@@ -0,0 +1,20 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px" width="96px" height="96px" viewBox="0 0 96 96" enable-background="new 0 0 96 96" xml:space="preserve"> <image id="image0" width="96" height="96" x="0" y="0"
xlink:href="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAGAAAABgCAMAAADVRocKAAAAIGNIUk0AAHomAACAhAAA+gAAAIDo
AAB1MAAA6mAAADqYAAAXcJy6UTwAAABRUExURQAAAFCf/0uZ/0yZ/kyY/kuY/UyZ/0yZ/kuY/k2Z
/0yZ/UqX/0uZ/0uY/kuZ/kyZ/kyY/UuZ/UiX/0uZ/kuZ/UyX/0yY/kqa/0uZ/kyZ/v///7LMcjEA
AAAZdFJOUwAQX6+/n3/v31CAYHCwz8CQoCDwj0DQMODQpj2tAAAAAWJLR0QadWfkMgAAAAd0SU1F
B+gMBQIoEmmNJfAAAAHtSURBVGje7ZnZloMgDEChm63RKlK3///RsXVciTUBOmdmDnkF7wVTSU4R
IgQr5OF4ap3idD684V8iN3of19vW8o8+8M844wJv/A1D7I/ftoC8IC/vf4hIGoLEJx/bQupXkBqC
u19BZgj88ts2CH5KkEoh8w8K1OtR1OBF0PNF8SmBevesB8HI/9AORr5Ai6CzYOKf0XFXwR7fVbDL
pwp0ZsknChKBllICnyaIXyNgw6cJvgsrWPBpgmEM+HyaoEAMRD5NcBSGgcon/opgbSDzqd/BykDn
k7/khYHBpx8VMwOHzziLkD6WwOccdmDDZ52mYMHnHdfA5zPrAbD53IIDXD67ogGTzy+Zl26OpPMt
avL18bjS+X+muw6CIAiC3y5QJTmUjQAp9tsBfEHF4QtRsQUxT5CzBSlPkLIFUcHh1xFb0N5rBt+s
dfuCrkieiIGVUorAKYIgCIIgCILgnwneXk9VjaNAq0LU2RZEJ11H1DgIdNz/75holJH1fUGZWQqa
qbcrEIaehmub1jFb3grDehPp4rayyPWeYLlGVa7H5SLZjXEpLeNFMsybwNnzz8wicZsIucQmzPNt
NoZjfzxk1ozhQqspNybM8p2Yg9U6sxjgucbNBczyXSFzZFytM4tO2usou3w3SooQIfzFFziLPvqM
MV6wAAAAJXRFWHRkYXRlOmNyZWF0ZQAyMDI0LTEyLTA1VDAyOjQwOjE4KzAwOjAwFHedYwAAACV0
RVh0ZGF0ZTptb2RpZnkAMjAyNC0xMi0wNVQwMjo0MDoxOCswMDowMGUqJd8AAAAodEVYdGRhdGU6
dGltZXN0YW1wADIwMjQtMTItMDVUMDI6NDA6MTgrMDA6MDAyPwQAAAAAAElFTkSuQmCC" />
</svg>

After

Width:  |  Height:  |  Size: 1.7 KiB