更新订单列表详情,更新商品管理,更新代客下单

This commit is contained in:
2024-09-23 17:39:38 +08:00
parent 90e3866524
commit edcf844adb
36 changed files with 5301 additions and 949 deletions

View File

@@ -1,6 +1,7 @@
export const objToArrary = (obj) => { export const objToArrary = (obj,keyNewName) => {
return Object.entries(obj).map(([key, value]) => ({ return Object.entries(obj).map(([key, value]) => ({
key, key,
[keyNewName]:key,
...value, ...value,
})) }))
} }

View File

@@ -1,334 +0,0 @@
<template>
<view class="u-steps-item" ref="u-steps-item" :class="[`u-steps-item--${parentData.direction}`]">
<view class="u-steps-item__line" v-if="index + 1 < childLength"
:class="[`u-steps-item__line--${parentData.direction}`]" :style="[lineStyle]"></view>
<view class="u-steps-item__wrapper"
:class="[`u-steps-item__wrapper--${parentData.direction}`, parentData.dot && `u-steps-item__wrapper--${parentData.direction}--dot`]"
:style="[itemStyleInner]">
<slot name="icon">
<view class="u-steps-item__wrapper__dot" v-if="parentData.dot" :style="{
backgroundColor: statusColor
}">
</view>
<view class="u-steps-item__wrapper__icon" v-else-if="parentData.activeIcon || parentData.inactiveIcon">
<u-icon :name="index <= parentData.current ? parentData.activeIcon : parentData.inactiveIcon"
:size="iconSize"
:color="index <= parentData.current ? parentData.activeColor : parentData.inactiveColor">
</u-icon>
</view>
<view v-else :style="{
backgroundColor: statusClass === 'process' ? parentData.activeColor : 'transparent',
borderColor: statusColor
}" class="u-steps-item__wrapper__circle">
<text v-if="statusClass === 'process' || statusClass === 'wait'"
class="u-steps-item__wrapper__circle__text" :style="{
color: index == parentData.current ? '#ffffff' : parentData.inactiveColor
}">{{ index + 1}}</text>
<u-icon v-else :color="statusClass === 'error' ? 'error' : parentData.activeColor" size="12"
:name="statusClass === 'error' ? 'close' : 'checkmark'"></u-icon>
</view>
</slot>
</view>
<view class="u-steps-item__content" :class="[`u-steps-item__content--${parentData.direction}`]"
:style="[contentStyle]">
<u-text :text="title" :type="parentData.current == index ? 'primary' : 'content'" lineHeight="20px"
:size="parentData.current == index ? 14 : 13"></u-text>
<slot name="desc">
<view class="u-p-b-20">
<u-text :text="desc" :type="parentData.current == index ? 'primary' : 'content'" size="14"></u-text>
</view>
</slot>
</view>
<!-- <view
class="u-steps-item__line"
v-if="showLine && parentData.direction === 'column'"
:class="[`u-steps-item__line--${parentData.direction}`]"
:style="[lineStyle]"
></view> -->
</view>
</template>
<script>
import { props } from './prop/steps-item.js';
import { mpMixin } from './libs/mixin/mpMixin';
import { mixin } from './libs/mixin/mixin';
import { sleep, error } from './libs/function/index';
import color from './libs/config/color';
// #ifdef APP-NVUE
const dom = uni.requireNativePlugin('dom')
// #endif
/**
* StepsItem 步骤条的子组件
* @description 本组件需要和u-steps配合使用
* @tutorial https://uview-plus.jiangruyi.com/components/steps.html
* @property {String} title 标题文字
* @property {String} current 描述文本
* @property {String | Number} iconSize 图标大小 (默认 17 )
* @property {Boolean} error 当前步骤是否处于失败状态 (默认 false )
* @example <u-steps current="0"><u-steps-item title="已出库" desc="10:35" ></u-steps-item></u-steps>
*/
export default {
name: 'u-steps-item',
mixins: [mpMixin, mixin, props],
data() {
return {
index: 0,
childLength: 0,
showLine: false,
size: {
height: 0,
width: 0
},
parentData: {
direction: 'row',
current: 0,
activeColor: '',
inactiveColor: '',
activeIcon: '',
inactiveIcon: '',
dot: false
}
}
},
watch: {
'parentData'(newValue, oldValue) {
}
},
created() {
this.init()
},
// #ifdef MP-TOUTIAO
options: {
virtualHost: false
},
// #endif
computed: {
lineStyle() {
const style = {}
if (this.parentData.direction === 'row') {
style.width = this.size.width + 'px'
style.left = this.size.width / 2 + 'px'
} else {
style.height = this.size.height + 'px'
// style.top = this.size.height / 2 + 'px'
}
style.backgroundColor = this.parent.children?.[this.index + 1]?.error ? color.error : this.index <
this
.parentData
.current ? this.parentData.activeColor : this.parentData.inactiveColor
return style
},
itemStyleInner() {
return {
...this.itemStyle
}
},
statusClass() {
const {
index,
error
} = this
const {
current
} = this.parentData
if (current == index) {
return error === true ? 'error' : 'process'
} else if (error) {
return 'error'
} else if (current > index) {
return 'finish'
} else {
return 'wait'
}
},
statusColor() {
let colorTmp = ''
switch (this.statusClass) {
case 'finish':
colorTmp = this.parentData.activeColor
break
case 'error':
colorTmp = color.error
break
case 'process':
colorTmp = this.parentData.dot ? this.parentData.activeColor : 'transparent'
break
default:
colorTmp = this.parentData.inactiveColor
break
}
return colorTmp
},
contentStyle() {
const style = {}
if (this.parentData.direction === 'column') {
style.marginLeft = this.parentData.dot ? '2px' : '6px'
style.marginTop = this.parentData.dot ? '0px' : '6px'
} else {
style.marginTop = this.parentData.dot ? '2px' : '6px'
style.marginLeft = this.parentData.dot ? '2px' : '6px'
}
return style
}
},
mounted() {
this.parent && this.parent.updateFromChild()
sleep().then(() => {
this.getStepsItemRect()
})
},
methods: {
init() {
// 初始化数据
this.updateParentData()
if (!this.parent) {
return error('u-steps-item必须要搭配u-steps组件使用')
}
this.index = this.parent.children.indexOf(this)
this.childLength = this.parent.children.length
},
updateParentData() {
// 此方法在mixin中
this.getParentData('u-steps')
},
// 父组件数据发生变化
updateFromParent() {
this.init()
},
// 获取组件的尺寸,用于设置横线的位置
getStepsItemRect() {
// #ifndef APP-NVUE
this.$uGetRect('.u-steps-item').then(size => {
this.size = size
})
// #endif
// #ifdef APP-NVUE
dom.getComponentRect(this.$refs['u-steps-item'], res => {
const {
size
} = res
this.size = size
})
// #endif
}
}
}
</script>
<style lang="scss" scoped>
@import "./libs/css/components.scss";
.u-steps-item {
flex: 1;
@include flex;
&--row {
flex-direction: column;
align-items: center;
position: relative;
}
&--column {
position: relative;
flex-direction: row;
justify-content: flex-start;
padding-bottom: 5px;
}
&__wrapper {
@include flex;
justify-content: center;
align-items: center;
position: relative;
background-color: #fff;
border-radius: 50px;
&--column {
width: 20px;
height: 20px;
&--dot {
height: 20px;
width: 20px;
}
}
&--row {
width: 20px;
height: 20px;
&--dot {
width: 20px;
height: 20px;
}
}
&__circle {
width: 20px;
height: 20px;
/* #ifndef APP-NVUE */
box-sizing: border-box;
flex-shrink: 0;
/* #endif */
border-radius: 100px;
border-width: 1px;
border-color: $u-tips-color;
border-style: solid;
@include flex(row);
align-items: center;
justify-content: center;
transition: background-color 0.3s;
&__text {
color: $u-tips-color;
font-size: 11px;
@include flex(row);
align-items: center;
justify-content: center;
text-align: center;
line-height: 11px;
}
}
&__dot {
width: 10px;
height: 10px;
border-radius: 100px;
background-color: $u-content-color;
}
}
&__content {
@include flex;
flex: 1;
&--row {
flex-direction: column;
align-items: center;
}
&--column {
flex-direction: column;
margin-left: 6px;
}
}
&__line {
position: absolute;
background: $u-tips-color;
&--row {
top: 10px;
height: 1px;
}
&--column {
width: 1px;
left: 10px;
}
}
}
</style>

View File

@@ -1,90 +0,0 @@
<template>
<view
class="u-steps"
:class="[`u-steps--${direction}`]"
>
<slot></slot>
</view>
</template>
<script>
import { props } from './prop/steps.js';
import { mpMixin } from './libs/mixin/mpMixin';
import { mixin } from './libs/mixin/mixin';
import test from './libs/function/test';
/**
* Steps 步骤条
* @description 该组件一般用于完成一个任务要分几个步骤,标识目前处于第几步的场景。
* @tutorial https://uview-plus.jiangruyi.com/components/steps.html
* @property {String} direction row-横向column-竖向 (默认 'row' )
* @property {String | Number} current 设置当前处于第几步 (默认 0 )
* @property {String} activeColor 激活状态颜色 (默认 '#3c9cff' )
* @property {String} inactiveColor 未激活状态颜色 (默认 '#969799' )
* @property {String} activeIcon 激活状态的图标
* @property {String} inactiveIcon 未激活状态图标
* @property {Boolean} dot 是否显示点类型 (默认 false )
* @example <u-steps current="0"><u-steps-item title="已出库" desc="10:35" ></u-steps-item></u-steps>
*/
export default {
name: 'u-steps',
mixins: [mpMixin, mixin, props],
data() {
return {
}
},
watch: {
children() {
this.updateChildData()
},
parentData() {
this.updateChildData()
}
},
computed: {
// 监听参数的变化通过watch中手动去更新子组件的数据否则子组件不会自动变化
parentData() {
return [this.current, this.direction, this.activeColor, this.inactiveColor, this.activeIcon, this.inactiveIcon, this.dot]
}
},
methods: {
// 更新子组件的数据
updateChildData() {
this.children.map(child => {
// 先判断子组件是否存在对应的方法
test.func((child || {}).updateFromParent()) && child.updateFromParent()
})
},
// 接受子组件的通知,去修改其他子组件的数据
updateFromChild() {
this.updateChildData()
}
},
created() {
this.children = []
},
options: {
virtualHost: false
}
}
</script>
<style lang="scss" scoped>
@import "./libs/css/components.scss";
.u-steps {
@include flex;
&--column {
flex-direction: column
}
&--row {
flex-direction: row;
flex: 1;
/* #ifdef MP */
display: grid;
grid-template-columns: repeat(auto-fit, minmax(100px, 1fr));
/* #endif */
}
}
</style>

View File

@@ -128,4 +128,9 @@ export function $tbProductV2(data) {
export function $tbProskuConV2(data) { export function $tbProskuConV2(data) {
return http.req('/api/tbProskuCon/V2', data, 'POST') return http.req('/api/tbProskuCon/V2', data, 'POST')
} }
/* 修改商品相关(快捷接口) */
export function $updateProductData(data) {
return http.req('/api/stock/updateProductData', data, 'POST')
}
// v2 api end // v2 api end

25
http/yskApi/user.js Normal file
View File

@@ -0,0 +1,25 @@
import http from './http.js'
const request=http.request
/**
* 用户详情
* @returns
*/
export function tbShopInfo(shopId) {
const _shopId=uni.getStorageSync('shopId')
return request({
url: `/api/tbShopInfo/${shopId||_shopId}`,
method: 'get'
})
}
/**
* 修改店铺信息
* @returns
*/
export function tbShopInfoPut(data) {
return request({
url: `/api/tbShopInfo`,
method: 'put',
data
})
}

File diff suppressed because it is too large Load Diff

View File

@@ -1,7 +1,7 @@
<template> <template>
<view class="u-p-30 safe-page"> <view class="u-p-30 safe-page">
<up-sticky v-if="option.type==='edit'" offset-top="20" zIndex="99"> <up-sticky v-if="option.type==='edit'" offset-top="20" zIndex="99">
<myTabs :list="tabsList" @change="tabsChange"></myTabs> <myTabs :list="tabsList" v-model="tabsCurrent"></myTabs>
</up-sticky> </up-sticky>
<view class="box"> <view class="box">
@@ -11,19 +11,30 @@
err-show-type="toast" validateTrigger="submit" label-width="350" ref="Forms"> err-show-type="toast" validateTrigger="submit" label-width="350" ref="Forms">
<view class="block"> <view class="block">
<uni-forms-item label="商品类型" required showRequired> <uni-forms-item label="商品类型" required showRequired>
<view class="u-flex u-flex-wrap types " :class="{disabled:option.productId!==''}"> <up-radio-group
:disabled="option.type=='edit'"
v-model="FormData.typeEnum"
placement="row"
>
<up-radio
:customStyle="{marginRight: '30px'}"
v-for="(item, index) in pageData.types"
:key="index"
:label="item.name"
:name="item.value"
>
</up-radio>
</up-radio-group>
<!-- <view class="u-flex u-flex-wrap types " :class="{disabled:option.productId!==''}">
<view class="item" @tap="changeFormData('typeEnum',item.value)" <view class="item" @tap="changeFormData('typeEnum',item.value)"
:class="{active:FormData.typeEnum===item.value}" :class="{active:FormData.typeEnum===item.value}"
v-for="(item,index) in pageData.types" :key="index"> v-for="(item,index) in pageData.types" :key="index">
<!-- <view class="gou u-flex u-row-right u-col-top u-p-t-4 u-p-r-4">
<uni-icons type="checkmarkempty" :size="8" color="#fff"></uni-icons>
</view> -->
<view class="title">{{item.title}}</view> <view class="title">{{item.title}}</view>
<view class="u-font-24 color-999 u-m-t-10"> <view class="u-font-24 color-999 u-m-t-10">
{{item.desc}} {{item.desc}}
</view> </view>
</view> </view>
</view> </view> -->
</uni-forms-item> </uni-forms-item>
<uni-forms-item ref="fileItem" label="图片"> <uni-forms-item ref="fileItem" label="图片">
@@ -38,11 +49,6 @@
</uni-forms-item> </uni-forms-item>
<template v-if="FormData.typeEnum!='group'"> <template v-if="FormData.typeEnum!='group'">
<uni-forms-item label="所属分类" required showRequired name="categoryId"> <uni-forms-item label="所属分类" required showRequired name="categoryId">
<!-- <picker @change="bindPickerChange"
range-key="name"
:value="pageData.category" :range="pageData.category">
<view class="uni-input">请选择分类</view>
</picker> -->
<uni-data-picker :clear-icon="false" :map="{text:'name',value:'id'}" <uni-data-picker :clear-icon="false" :map="{text:'name',value:'id'}"
placeholder="请选择分类" popup-title="请选择分类" :localdata="pageData.category" placeholder="请选择分类" popup-title="请选择分类" :localdata="pageData.category"
v-model="FormData.categoryId"> v-model="FormData.categoryId">
@@ -50,10 +56,6 @@
</uni-forms-item> </uni-forms-item>
</template> </template>
<!-- <uni-forms-item label="产品编码">
<uni-easyinput :paddingNone="inputPaddingNone" :placeholderStyle="placeholderStyle"
:inputBorder="inputBorder" v-model="FormData.goodsCode" placeholder="请输入商品编码" />
</uni-forms-item> -->
<view class="border-top-0"> <view class="border-top-0">
<uni-forms-item label="商品描述"> <uni-forms-item label="商品描述">
<uni-easyinput :paddingNone="inputPaddingNone" :placeholderStyle="placeholderStyle" <uni-easyinput :paddingNone="inputPaddingNone" :placeholderStyle="placeholderStyle"
@@ -726,161 +728,27 @@
</uni-forms> </uni-forms>
<view style="height: 200rpx;"></view> <view style="height: 200rpx;"></view>
<view style="padding-left: 110rpx;padding-right: 110rpx;" class="u-m-t-20" v-if="option.type==='edit'" @click="delModelShow">
<my-button bgColor="#F9F9F9" shape="circle" type="cancel" >
<view class="color-red">删除该商品</view>
</my-button>
</view>
<view class="bootom"> <view class="bootom">
<view class="save-btn-box"> <view class="save-btn-box">
<my-button shape="circle" @tap="save">保存</my-button> <my-button shape="circle" @tap="save">保存</my-button>
</view> </view>
<!-- <view class="u-m-t-20" v-if="option.type==='edit'" @click="delModelShow">
<view class="u-m-t-20" v-if="option.type==='edit'" @click="delModelShow"> <my-button bgColor="#fff" shape="circle" type="cancel" >
<my-button shape="circle" type="cancel" bgColor="#fff">
<view class="color-red">删除该商品</view> <view class="color-red">删除该商品</view>
</my-button> </my-button>
<!-- <text>删除该商品</text> --> </view> -->
</view>
</view> </view>
</view> </view>
</template> </template>
<template v-if="tabsCurrent===1"> <template v-if="tabsCurrent===1">
<view class="stock"> <edit-haocai :goods="FormData" @cancel="changeTabsCurrent(0)"></edit-haocai>
<uni-forms :border="false" err-show-type="toast" validateTrigger="submit" ref="Forms1">
<!-- <view class="block ">
<uni-forms-item label="" required>
<view class="u-flex">
<view class="label-title">库存模式</view>
<view class="u-flex-1 u-p-l-100">
<uni-data-checkbox v-model="stockData.inventoryMode"
:localdata="InventoryModeData"></uni-data-checkbox>
</view>
</view>
</uni-forms-item>
</view> -->
<view class="block ">
<uni-forms-item label="">
<view class="u-flex u-row-between">
<view class="label-title">库存开关</view>
<my-switch v-model="FormData.isStock"
@change="updateProductStatus(FormData.id,'isStock')"></my-switch>
</view>
</uni-forms-item>
</view>
<view class="block ">
<uni-forms-item label="">
<view class="u-flex u-row-between">
<view class="label-title">共享库存</view>
<my-switch v-model="FormData.isDistribute"
@change="updateProductStatus(FormData.id,'isDistribute')"></my-switch>
</view>
</uni-forms-item>
</view>
<view class="block ">
<uni-forms-item label="">
<view class="u-flex u-row-between">
<view class="label-title">售罄</view>
<my-switch v-model="FormData.isPauseSale"
@change="updateProductStatus(FormData.id,'isPauseSale')"></my-switch>
</view>
</uni-forms-item>
</view>
<template v-if="FormData.typeEnum!=='sku'">
<view class="block ">
<uni-forms-item label="">
<view class="u-flex u-row-between">
<view class="label-title">上架</view>
<my-switch v-model="FormData.isGrounding"
@change="updateProductStatus(FormData.id,'isGrounding')"></my-switch>
</view>
</uni-forms-item>
</view>
<view class="block default-box-padding">
<view class="u-flex">
<view class="">
<my-button @tap="toRecoders" :height="60">库存记录</my-button>
</view>
<view class="u-m-l-40">
<my-button :height="60" @tap="toCheck">库存盘点</my-button>
</view>
</view>
</view>
</template>
<template v-else>
<view class="block default-box-padding">
<view class="u-flex">
<view class="">
<my-button @tap="toRecoders" :height="60">库存记录</my-button>
</view>
</view>
</view>
<view class="u-text-center block">
<view class="u-flex font-bold u-m-t-30 u-m-b-20">
<!-- <view class="u-flex-1">商品信息</view> -->
<view class="u-flex-1">规格</view>
<view class="u-flex-1">库存</view>
<view class="u-flex-1">售罄</view>
<view class="u-flex-1">上架</view>
<view class="u-flex-1">操作</view>
</view>
<view class="" v-for="(item,index) in pageData.skuList" :key="index">
<view class="u-flex u-p-b-12 u-p-t-12 ">
<view class="u-flex-1">{{item.specSnap}}</view>
<!-- <view class="u-flex-1">{{item.salePrice}}</view> -->
<view class="u-flex-1">{{item.stockNumber}}{{item.unitName}}</view>
<view class="u-flex-1 u-flex u-row-center"><my-switch v-model="item.isPauseSale"
@change="updateProductStatus(item.skuId,'isPauseSale')"></my-switch>
</view>
<view class="u-flex-1 u-flex u-row-center"><my-switch v-model="item.isGrounding"
@change="updateProductStatus(item.skuId,'isGrounding')"></my-switch>
</view>
<view class="u-flex u-row-center">
<my-button @tap="skuToCheck(item)" :width="120" :height="40">
<view class="u-font-24 no-wrap">库存盘点</view>
</my-button>
<!-- <my-button @tap="moreShow(item,index)" :width="100" :height="40">
<view class="u-font-24 no-wrap">更多</view>
</my-button> -->
</view>
</view>
</view>
</view>
</template>
<!-- <view class="block ">
<uni-forms-item label="" required>
<view class="u-flex">
<view class="label-title">剩余库存数量</view>
<view class="u-flex-1 u-p-l-40">
<uni-easyinput :paddingNone="inputPaddingNone"
:placeholderStyle="placeholderStyle" type="number"
:inputBorder="inputBorder" v-model="FormData.stockNumber"
placeholder="填写库存" />
</view>
</view>
</uni-forms-item>
</view> -->
<!-- <view class="block ">
<uni-forms-item label="" required>
<view class="u-flex">
<view class="label-title">库存模式</view>
<view class="u-flex-1 u-p-l-100">
<uni-data-checkbox v-model="stockData.inventoryReset"
:localdata="InventoryReset"></uni-data-checkbox>
</view>
</view>
</uni-forms-item>
</view> -->
</uni-forms>
<view class="btns">
<my-button shape="circle">保存</my-button>
<my-button shape="circle" type="default" @tap="back">取消</my-button>
</view>
</view>
</template> </template>
</view> </view>
@@ -894,11 +762,8 @@
</template> </template>
</my-model> </my-model>
</view>
<!-- 删除弹窗 --> <!-- 删除弹窗 -->
<my-model @confirm="delmodelConfirm" ref="delModel" desc="确认删除"> <my-model @confirm="delmodelConfirm" ref="delModel" desc="确认删除">
</my-model> </my-model>
@@ -906,6 +771,9 @@
<choose-goods ref="refChooseGoods" @confirm="refChooseGoodsConfirm" :category="pageData.category"></choose-goods> <choose-goods ref="refChooseGoods" @confirm="refChooseGoodsConfirm" :category="pageData.category"></choose-goods>
<!-- 更多操作 --> <!-- 更多操作 -->
<my-action-sheet @itemClick="actionSheetClick" ref="refMoreSheet" :list="actionSheet.list"></my-action-sheet> <my-action-sheet @itemClick="actionSheetClick" ref="refMoreSheet" :list="actionSheet.list"></my-action-sheet>
</view>
</template> </template>
<script setup> <script setup>
@@ -922,6 +790,7 @@
import myModel from '@/components/my-components/my-model' import myModel from '@/components/my-components/my-model'
import chooseGoods from './components/choose-goods' import chooseGoods from './components/choose-goods'
import editHaocai from './components/edit-haocai.vue'
import chooseGroupCategory from './components/choose-coupon-category' import chooseGroupCategory from './components/choose-coupon-category'
import myRadio from '@/components/my-components/my-radio' import myRadio from '@/components/my-components/my-radio'
import myUploadFile from '@/components/my-components/my-upload-file' import myUploadFile from '@/components/my-components/my-upload-file'
@@ -929,6 +798,7 @@
import myButton from '@/components/my-components/my-button' import myButton from '@/components/my-components/my-button'
import mySwitch from '@/components/my-components/my-switch.vue' import mySwitch from '@/components/my-components/my-switch.vue'
import infoBox from "@/commons/utils/infoBox.js" import infoBox from "@/commons/utils/infoBox.js"
import { import {
$types, $types,
$defaultSku $defaultSku
@@ -1274,7 +1144,13 @@
} }
const tabsList = ['基础设置', '库存设置'] const tabsList = ['基础设置', '耗材绑定']
let tabsCurrent = ref(0)
function changeTabsCurrent(newval){
tabsCurrent.value=newval
}
const Forms = ref(null) const Forms = ref(null)
@@ -1545,7 +1421,11 @@
//页面全部数据 //页面全部数据
const pageData = reactive({ const pageData = reactive({
// 商品类型 // 商品类型
types: $types, // types: $types,
types: [
{name:'单规格',value:'normal'},
{name:'多规格',value:'sku'}
],
// 单位 // 单位
units: [], units: [],
// 分类 // 分类
@@ -1597,14 +1477,7 @@
let tabsCurrent = ref(0)
function tabsChange(i) {
tabsCurrent.value = i
// if (tabsCurrent.value === 1 && option.type === 'add') {
// showModel('stockTips')
// }
}
let timer = null let timer = null
@@ -1809,7 +1682,7 @@
watchTimerSave(false) watchTimerSave(false)
}) })
onReady(() => { onReady(() => {
Forms.value.setRules(rules) Forms.value&&Forms.value.setRules(rules)
}) })
watch(() => pageData.types, (newval) => { watch(() => pageData.types, (newval) => {
Forms.value.setRules(rules) Forms.value.setRules(rules)
@@ -1884,13 +1757,13 @@
position: fixed; position: fixed;
left: 110rpx; left: 110rpx;
right: 110rpx; right: 110rpx;
bottom: 110rpx; bottom: 140rpx;
padding-bottom: env(safe-area-inset-bottom);
} }
.box { .box {
margin-top: 70rpx; margin-top: 36rpx;
font-size: 28rpx; font-size: 28rpx;
.block { .block {
background: #FFFFFF; background: #FFFFFF;
border-radius: 18rpx 18rpx 18rpx 18rpx; border-radius: 18rpx 18rpx 18rpx 18rpx;

View File

@@ -0,0 +1,159 @@
<template>
<view class="u-relative choose-haocai">
<view class="input u-flex" @click="toggle" >
<up-input @blur="blur" @change="filterHaocaiList" border="none" v-model="text" placeholder="请选择"></up-input>
<up-icon :size="10" name="arrow-down-fill"></up-icon>
</view>
<view class="u-absolute" v-if="popShow">
<scroll-view scroll-y="true" class="scroll">
<view class="item" v-for="(item,index) in $haocaiList" :key="index" @click="haocaiClick(item,index)">
{{item.name}}
</view>
<view class="item no-wrap" @click="toggle" v-if="text&&!$haocaiList.length">没有该单位</view>
</scroll-view>
</view>
</view>
</template>
<script setup>
import {
reactive,
ref,
watch,
onMounted
} from 'vue';
const props = defineProps({
listMap: {
type: Object,
default: () => {}
},
list: {
type: Array,
default: () => []
},
modelValue: {
type: [String, Number],
default: ''
},
show: {
type: Boolean,
default: false
},
})
let text = ref('')
let popShow = ref(props.show)
const emits = defineEmits(['update:show', 'close', 'confirm', 'update:modelValue'])
function close() {
popShow.value = false
}
function confirm() {
popShow.value = false
}
watch(() => props.show, (newval) => {
popShow.value = newval
})
watch(() => popShow.value, (newval) => {
console.log(newval);
emits('update:show', newval)
})
let $haocaiList = ref(props.list)
watch(() => props.list, (newval) => {
$haocaiList.value = newval
setText()
})
watch(() => props.modelValue, (newval) => {
console.log(newval);
setText()
})
function setText() {
// const item = props.listMap[props.modelValue]
// text.value = item ? item.name : ''
text.value=props.modelValue
}
function toggle(e) {
popShow.value = !popShow.value
}
function filterHaocaiList(e) {
if (e === '') {
return $haocaiList.value = props.list
}
const arr = props.list.filter(v => v.name.match(e))
$haocaiList.value = arr
}
function haocaiClick(item, index) {
console.log(item);
// if (item.id != props.modelValue) {
// emits('update:modelValue', item.id)
// }
if(item.name!=props.modelValue){
emits('update:modelValue', item.name)
}
popShow.value = false
}
function focus(){
console.log('focus');
popShow.value = true
}
function blur() {
console.log('blur');
setTimeout(()=>{
popShow.value = false
},100)
}
onMounted(() => {
setText()
})
</script>
<style lang="scss" scoped>
.choose-haocai {
.input {
width: 172rpx;
padding: 10rpx 16rpx;
height: 60rpx;
box-sizing: border-box;
background: #FFFFFF;
border-radius: 8rpx 8rpx 8rpx 8rpx;
display: flex;
align-items: center;
justify-content: space-between;
border: 2rpx solid #E5E5E5;
overflow: hidden;
}
.u-absolute {
top: calc(100% + 10rpx);
border: 1px solid #E5E5E5;
left: 0;
background-color: #fff;
z-index: 10;
right: 0;
border-radius: 8rpx;
.scroll {
$line-h: 60rpx;
max-height: calc($line-h * 4);
.item {
line-height: $line-h;
padding: 0 20rpx;
}
}
}
}
</style>

View File

@@ -0,0 +1,57 @@
<template>
<up-popup :round="10" :show="popShow" :closeable="true" @close="close">
<view class="u-text-center font-bold u-font-32 u-p-t-30">选择状态</view>
<view style="height: 20rpx;"></view>
<view class="u-p-30 all-list u-flex u-flex-wrap gap-20">
<view class="all-list-item" :class="{active:statusItemIndex==statusData.allListSel}" @click="changeAllListSel(statusItemIndex)" v-for="(statusItem,statusItemIndex) in statusData.allList" :key="statusItemIndex">
{{statusItem.label}}
</view>
</view>
<view class="u-flex u-p-t-30 u-p-b-30 u-p-l-20 u-p-r-20 gap-20">
<up-button @click="close">取消</up-button>
<up-button type="primary" @click="confirm">确定</up-button>
</view>
</up-popup>
</template>
<script setup>
import { ref, watch } from 'vue';
const props=defineProps({
show:{
type:Boolean,
default:false
}
})
let popShow=ref(props.show)
const emits=defineEmits(['update:show','close','confirm'])
function close(){
popShow.value=false
}
function confirm(){
popShow.value=false
}
watch(()=>props.show,(newval)=>{
popShow.value=newval
})
watch(()=>popShow.value,(newval)=>{
emits('update:show',newval)
})
</script>
<style lang="scss" scoped>
.all-list-item{
text-align: center;
width: 156rpx;
white-space: nowrap;
color: #666;
padding: 10rpx 20rpx;
border-radius: 8rpx;
transition: all .2s ease-in-out;
border: 1px solid #eee;
&.active {
color: $my-main-color;
border-color: $my-main-color;
}
}
</style>

View File

@@ -0,0 +1,149 @@
<template>
<view class="u-relative choose-haocai">
<view class="input u-flex" @click="toggle">
<!-- <view>
<text v-if="modelValue">{{modelValue}}</text>
<text v-else class="color-666">请选择</text>
</view> -->
<up-input @blur="blur" @change="filterHaocaiList" border="none" v-model="text" placeholder="请选择"></up-input>
<up-icon :size="10" name="arrow-down-fill"></up-icon>
</view>
<view class="u-absolute" v-if="popShow">
<scroll-view scroll-y="true" class="scroll">
<view class="item" v-for="(item,index) in $haocaiList" :key="index" @click="haocaiClick(item,index)">
{{item.conName}}
</view>
<view class="item no-wrap" @click="toggle" v-if="text&&!$haocaiList.length">没有该耗材</view>
</scroll-view>
</view>
</view>
</template>
<script setup>
import {
reactive,
ref,
watch,
onMounted
} from 'vue';
const props = defineProps({
listMap: {
type: Object,
default: () => {}
},
list: {
type: Array,
default: () => []
},
modelValue: {
type: [String, Number],
default: ''
},
show: {
type: Boolean,
default: false
},
})
let text = ref('')
let popShow = ref(props.show)
const emits = defineEmits(['update:show', 'close', 'confirm', 'update:modelValue','change'])
function close() {
popShow.value = false
}
function confirm() {
popShow.value = false
}
watch(() => props.show, (newval) => {
popShow.value = newval
})
watch(() => popShow.value, (newval) => {
emits('update:show', newval)
})
let $haocaiList = ref(props.list)
watch(() => props.list, (newval) => {
$haocaiList.value = newval
setText()
})
watch(() => props.modelValue, (newval) => {
setText()
})
function setText() {
const item = props.listMap[props.modelValue]
text.value = item ? item.conName : ''
}
function toggle(e) {
popShow.value = !popShow.value
}
function filterHaocaiList(e) {
if (e === '') {
return $haocaiList.value = props.list
}
const arr = props.list.filter(v => v.conName.match(e))
$haocaiList.value = arr
}
function haocaiClick(item, index) {
console.log(item);
if (item.consId != props.modelValue) {
emits('update:modelValue', item.consId)
emits('change', item)
}
popShow.value = false
}
function blur() {
setTimeout(()=>{
popShow.value = false
},100)
}
onMounted(() => {
setText()
})
</script>
<style lang="scss" scoped>
.choose-haocai {
.input {
width: 172rpx;
padding: 10rpx 16rpx;
height: 60rpx;
box-sizing: border-box;
background: #FFFFFF;
border-radius: 8rpx 8rpx 8rpx 8rpx;
display: flex;
align-items: center;
justify-content: space-between;
border: 2rpx solid #E5E5E5;
overflow: hidden;
}
.u-absolute {
top: calc(100% + 10rpx);
border: 1px solid #E5E5E5;
left: 0;
background-color: #fff;
z-index: 10;
right: 0;
border-radius: 8rpx;
.scroll {
$line-h: 60rpx;
max-height: calc($line-h * 4);
.item {
line-height: $line-h;
padding: 0 20rpx;
}
}
}
}
</style>

View File

@@ -0,0 +1,359 @@
<template>
<view>
<view class="default-box-padding bg-fff border-r-18">
<view class="u-flex u-row-between">
<view>商品名称</view>
<template v-if="isSku">
<view class="u-flex u-font-24 color-666">
<view class="u-m-r-20">绑定至规格</view>
<up-switch :size="18" v-model="isBindGuige" :disabled="!isSku">绑定至规格</up-switch>
</view>
</template>
</view>
<view class="border-bottom u-m-t-16 u-p-b-32">{{goods.name}}</view>
<view class="">
<template v-if="isBindGuige&&isSku">
<view class="list">
<view class="u-p-b-32 u-p-t-32 border-bottom" v-for="(item,index) in skuList" :key="index">
<view>规格名称</view>
<view class="u-m-t-16">{{item.specSnap}}</view>
<view class="color-666 u-m-t-24 u-flex">
<view class="xuhao">序号</view>
<view class="u-flex u-flex-1 u-p-l-32 gap-20">
<view class="u-flex-1">耗材名称</view>
<view class="u-flex-1">单位</view>
<view class="u-flex-1">用量</view>
</view>
</view>
<view class="u-m-t-32 color-666">
<view class="u-m-t-24" v-for="(haocai,haocaiIndex) in item.haoaiList"
:key="haocaiIndex">
<view class=" u-flex">
<view class="xuhao">{{haocaiIndex+1}}</view>
<view class="u-flex u-flex-1 u-p-l-32 gap-20">
<view class="u-flex-1 ">
<view class="u-flex input">
<view>{{item.name}}</view>
<up-icon :size="10" name="arrow-down-fill"></up-icon>
</view>
</view>
<view class="u-flex-1 ">
<view class="u-flex input">
<view>{{item.unit}}</view>
<up-icon :size="10" name="arrow-down-fill"></up-icon>
</view>
</view>
<view class="u-flex-1 ">
<view class="u-flex input">
<up-input border="none"></up-input>
<up-icon color="#EB4F4F" @click="delGuigeHaocao(index,haocaiIndex)"
:size="16" name="minus-circle-fill"></up-icon>
</view>
</view>
</view>
</view>
<view class="u-flex u-m-t-16 color-666 u-font-24">
<view class="xuhao">
</view>
<view class="u-flex u-flex-1 u-p-l-32 gap-20">库存{{item.stockNumber}}
</view>
</view>
</view>
</view>
<view class="u-flex">
<view class=" u-p-t-32 u-flex" @click="addGuigeHaocai(index)">
<up-icon :size="18" color="#318AFE" name="plus-circle-fill"></up-icon>
<view class="u-m-l-16">添加耗材</view>
</view>
</view>
</view>
</view>
</template>
<template v-else>
<view class="list">
<view class="u-p-b-32 u-p-t-32 border-bottom" v-for="(item,index) in conInfos" :key="index">
<view class="color-666 u-flex">
<view class="xuhao">序号</view>
<view class="u-flex u-flex-1 u-p-l-32 gap-20">
<view class="u-flex-1">耗材名称</view>
<view class="u-flex-1">单位</view>
<view class="u-flex-1">用量</view>
</view>
</view>
<view class="u-m-t-32 color-666">
<view class=" u-m-t-24 u-flex">
<view class="xuhao">{{index+1}}</view>
<view class="u-flex u-flex-1 u-p-l-32 gap-20">
<view class="u-flex-1 ">
<choose-haocai @change="conInfosChange($event,item)" :listMap="$haocaiMap"
:list="haoCaiList" v-model="item.conInfoId"></choose-haocai>
<!-- <view class="u-flex input">
<view>{{item.conName}}</view>
<up-icon :size="10" name="arrow-down-fill"></up-icon>
</view> -->
</view>
<view class="u-flex-1 ">
<choose-danwei :listMap="$danweiMap" :list="danweiList"
v-model="item.conUnit"></choose-danwei>
<!-- <view class="u-flex input">
<view>{{item.conUnit}}</view>
<up-icon :size="10" name="arrow-down-fill"></up-icon>
</view> -->
</view>
<view class="u-flex-1 ">
<view class="u-flex input">
<up-input border="none" v-model="item.surplusStock"></up-input>
<up-icon @click="delHaocai(index)" color="#EB4F4F" :size="16"
name="minus-circle-fill"></up-icon>
</view>
</view>
</view>
</view>
<view class="u-flex u-m-t-16 u-font-24" v-if="item.stockNumber">
<view class="xuhao">
</view>
<view class="u-flex u-flex-1 u-p-l-32 gap-20">库存{{item.stockNumber}}
{{item.conUnit}}
</view>
</view>
</view>
</view>
</view>
</template>
<template v-if="!isBindGuige">
<view class="u-flex">
<view class=" u-p-t-32 u-flex" @click="addHaocai">
<up-icon :size="18" color="#318AFE" name="plus-circle-fill"></up-icon>
<view class="u-m-l-16">添加耗材</view>
</view>
</view>
</template>
</view>
</view>
<view class="default-box-padding bg-fff border-r-18 u-flex u-row-between u-m-t-32">
<view>当某个耗材的使用库存不足时商品自动
售罄</view>
<view class="u-flex u-p-l-32">
<up-switch :size="20"></up-switch>
</view>
</view>
<view class="bottom">
<my-button type="primary" shape="circle" @click="save">保存</my-button>
<my-button bgColor="#F9F9F9" shape="circle" color="#999" @click="cancel">取消</my-button>
</view>
</view>
</template>
<script setup>
import {
ref,
reactive,
toRefs,
watch,
computed,
onMounted
}
from 'vue';
import {
getviewConSku,
gettbProductSpec,
gettbConsInfo,
posttbProskuCons,
puttbProskuCon,
deletetbProskuCon,
} from "@/http/yskApi/consumable.js";
import {
tbShopCurrencyGet,$hasPermission
} from '@/http/yskApi/shop.js'
import chooseHaocai from './choose-haocai.vue';
import chooseDanwei from './choose-danwei.vue';
import {
$tbProskuConV2
} from '@/http/yskApi/goods.js'
const emits=defineEmits(['cancel'])
function cancel(){
emits('cancel')
}
const props = defineProps({
goods: {
type: Object,
default: () => {
return {
conInfos: [],
skuList: [],
typeEnum: ''
}
}
}
})
const conInfos = ref(props.goods.conInfos)
watch(() => props.goods.conInfos, (newval) => {
console.log(newval);
conInfos.value = newval
})
function conInfosChange(newval, item) {
console.log(newval);
item.stockNumber = newval.balance
item.conUnit = newval.conUnit
}
const skuList = ref(props.goods.skuList)
watch(() => props.goods.skuList, (newval) => {
console.log(newval);
skuList.value = newval
})
function addHaocai() {
conInfos.value.push({
conInfoId: '',
conUnit: '',
surplusStock: ''
})
}
const popup = reactive({
haocai: {
show: true
}
})
function addGuigeHaocai(index) {
console.log(index);
}
function delHaocai(index) {
const item = conInfos.value[index]
uni.showModal({
title: '提示',
content: '是否删除该耗材',
success(res) {
if (res.confirm) {
if (item.id) {
deletetbProskuCon([item.id]).then(res1 => {
conInfos.value.splice(index, 1)
})
} else {
conInfos.value.splice(index, 1)
}
}
}
})
}
function delGuigeHaocao(guigeIndex, haocaiIndex) {
skuList.value[guigeIndex].haoaiList.splice(haocaiIndex, 1)
}
// 是否是多规格商品
const isSku = computed(() => {
return props.goods.typeEnum == 'sku'
})
let isBindGuige = ref(isSku.value)
watch(() => props.goods.typeEnum, (newval) => {
isBindGuige.value = isSku.value
})
function save() {
console.log('save');
const isPas= conInfos.value.every(v=>{
return v.conInfoId&&v.conUnit&&v.surplusStock>0
})
console.log(isPas);
return
let ajaxData = ''
if (!isBindGuige.value) {
//绑定至商品
ajaxData = conInfos.value.map(v => {
return {
conInfoId: v.conInfoId,
productId: props.goods.id,
shopId: uni.getStorageSync('shopId'),
productSkuId: 0,
surplusStock: v.surplusStock
}
})
} else {
}
console.log(ajaxData);
$tbProskuConV2(ajaxData)
}
let haoCaiList = ref([])
let $haocaiMap = reactive({})
let danweiList = ref([])
let $danweiMap = reactive({})
function init() {
gettbConsInfo({
page: 0,
size: 200
}).then(res => {
for (let i in res.content) {
const item = res.content[i]
$haocaiMap[item.consId] = item
}
haoCaiList.value = res.content
})
tbShopCurrencyGet({
page: 0,
size: 200
}).then(res => {
for (let i in res.content) {
const item = res.content[i]
$danweiMap[item.id] = item
}
danweiList.value = res.content
})
}
onMounted(() => {
init()
})
</script>
<style lang="scss" scoped>
.bottom {
padding: 84rpx 82rpx;
}
.xuhao {
width: 52rpx;
white-space: nowrap;
}
.input {
width: 172rpx;
padding: 10rpx 16rpx;
height: 60rpx;
box-sizing: border-box;
background: #FFFFFF;
border-radius: 8rpx 8rpx 8rpx 8rpx;
display: flex;
align-items: center;
justify-content: space-between;
border: 2rpx solid #E5E5E5;
overflow: hidden;
}
.list .border-bottom:last-child {
border: none;
}
</style>

View File

@@ -0,0 +1,499 @@
<template>
<view class="page">
<view class="box">
<view class="block border-top-0">
<uni-forms ref="nameFormRef" :model="specifications" :rules="rules" :label-width="350"
label-position="top" validateTrigger="blur">
<uni-forms-item label="模版名称" required name="name">
<uni-easyinput :placeholderStyle="placeholderStyle" :inputBorder="inputBorder"
v-model="specifications.name" placeholder="模版名称,如:衣服" />
</uni-forms-item>
</uni-forms>
</view>
<view v-for="(item,index) in specifications.list" :key="index">
<uni-forms :model="item" :rules="rules" err-show-type="undertext" validateTrigger="blur"
:ref="setFormRef(index)" :border="true" label-position="top" label-width="350">
<view class="block">
<view class="border-top-0">
<uni-forms-item label="规格组名" required name="name">
<uni-easyinput :placeholderStyle="placeholderStyle" :inputBorder="inputBorder"
v-model="item.name" placeholder="规格组名,如:尺码" />
</uni-forms-item>
</view>
<uni-forms-item label="规格值">
<view class="option">
<view class="">
<view class="u-flex option-item" v-for="(option,optionIndex) in item.options"
:key="optionIndex">
<view class="u-flex-1">
<uni-forms-item :key="optionIndex" :name="['options',optionIndex,'name']"
:ref="setFormInputRef(index,optionIndex)"
:rules="[{'required': true,errorMessage: '必填'}]" label-width="0"
label="" required :showRequired="false">
<uni-easyinput
v-model="specifications.list[index].options[optionIndex].name"
@input="inpuChange(index,optionIndex)"
:placeholderStyle="placeholderStyle" :inputBorder="inputBorder"
placeholder="请输入规格值,如:S、M" />
</uni-forms-item>
</view>
<view class=" u-flex">
<uni-forms-item :key="optionIndex" label-width="0" label=""
:showRequired="false">
<view class="u-flex">
<!-- <uni-easyinput v-model="specifications.list[index].options[optionIndex].optionPrice"
@input="inpuChange(index,optionIndex)"
:placeholderStyle="placeholderStyle" :inputBorder="inputBorder"
type="digit" placeholder="填写价格" /> -->
<view class="icon icon-reduce u-m-l-38"
@click="delOption(index,optionIndex)">
</view>
</view>
</uni-forms-item>
</view>
</view>
</view>
<view class="u-flex" @click="addOptions(index)">
<view class="icon icon-add u-m-r-22 ">
</view>
<view class="color-main">添加规格</view>
</view>
</view>
</uni-forms-item>
<view class="u-flex u-m-t-48 u-m-b-24" @click="delSpecificationsGroup(index)">
<view class="icon icon-reduce u-m-r-22 ">
</view>
<view class="color-red">删除规格组</view>
</view>
</view>
</uni-forms>
</view>
<view class="u-flex block u-p-l-20 u-p-r-20 u-p-t-28 u-p-b-28" @click="addSpecificationsGroup">
<view class="icon icon-add u-m-r-22 ">
</view>
<view class="color-main">添加规格组</view>
</view>
<view class="save-btn-box">
<button class="save-btn" hover-class="btn-hover-class" @click="save">保存</button>
</view>
</view>
<view class="bottom" ref="bottom"></view>
</view>
</template>
<script setup>
import go from '@/commons/utils/go.js';
import {
$productSpec
} from '@/http/yskApi/goods.js'
import {
onLoad,
onReady,
} from '@dcloudio/uni-app';
import infoBox from '@/commons/utils/infoBox.js'
import {
onMounted,
reactive,
nextTick,
ref,
onBeforeMount
} from 'vue';
const nameFormRef = ref(null)
// 表单样式
const placeholderStyle = ref('font-size:28rpx;')
//表单边框
const inputBorder = ref(false)
const form = ref(null)
const bottom = ref(null)
//表单验证
const rules = {
name: {
rules: [{
required: true,
errorMessage: '必填'
}]
},
MinOptional: {
rules: [{
required: true,
errorMessage: '必填'
}]
},
MaxOptional: {
rules: [{
required: true,
errorMessage: '必填'
}]
},
optionPrice: {
rules: [{
required: true,
errorMessage: '必填'
}]
}
}
// 构造规格的选项值的基础数据
const specificationsOptionsBasicData = {
name: '',
optionPrice: '0.00'
}
function returnOptionsBasicData() {
return {
...specificationsOptionsBasicData
}
}
// 构造规格的基础数据
const specificationsBasicData = {
name: '',
// MinOptional: 1,
// MaxOptional: 1,
options: []
}
function returnSpecificationsOptionsBasicData() {
return {
...specificationsBasicData,
options: [returnOptionsBasicData()]
}
}
function onFieldChange(e) {
console.log(e);
}
// 规格列表
const specifications = reactive({
name: '',
list: [returnSpecificationsOptionsBasicData()]
})
//添加规格组
function addSpecificationsGroup() {
specifications.list.push(returnSpecificationsOptionsBasicData())
scrollPageBottom()
}
//删除规格组
function delSpecificationsGroup(index) {
specifications.list.splice(index, 1)
}
// 向指定索引的规格组添加规格项
function addOptions(index) {
specifications.list[index].options.push(returnOptionsBasicData())
}
// 删除指定索引的规格组添加规格项
function delOption(index, optionIndex) {
specifications.list[index].options.splice(optionIndex, 1)
}
//页面滚动到最底部
function scrollPageBottom() {
nextTick(() => {
uni.pageScrollTo({
duration: 100, // 过渡时间
scrollTop: 100000, // 滚动的实际距离
})
})
}
//设置表单验证规则
function setFormRules() {
form.value.setRules(rules)
}
const formRefs = ref([]);
//绑定表单元素
function setFormRef(index) {
formRefs.value[index] = null;
return (el) => {
if (el) {
formRefs.value[index] = el;
}
};
}
// 绑定option input元素
const refFormInput = ref([])
function setFormInputRef(index, index1) {
const newIndex = index * 10000 + index1
return (el) => {
if (el) {
if (!refFormInput.value[newIndex]) {
refFormInput.value[newIndex] = el;
}
}
}
}
// 当表单内容输入变化根据配置的rules进行验证
function inpuChange(index, index1) {
const newIndex = index * 10000 + index1
console.log(refFormInput.value[newIndex]);
refFormInput.value[newIndex].onFieldChange()
}
const option = {
type: 'add',
id: undefined
}
onLoad(opt => {
console.log(opt);
if (opt && JSON.stringify(opt) !== '{}' && opt.type) {
option.type = opt.type
const data = uni.getStorageSync('spec')
uni.removeStorageSync('spec')
if(data){
specifications.name = data.name
specifications.id = data.id
specifications.list = data.specList.map(v => {
return {
...v,
options: v.value.map(v => {
return {
name: v
}
})
}
})
}
}
uni.setNavigationBarTitle({
title: option.type === 'edit' ? '编辑规格模版' : '添加规格模版'
})
})
function returnPromise(prosise, index) {
return new Promise((resolve, reject) => {
prosise.then(res => {
console.log(res);
resolve({
sucees: true
})
}).catch(err => {
console.log(err);
resolve({
sucees: false
})
})
})
}
let timer = null
function settimeoutBack(time) {
clearTimeout(timer)
timer = setTimeout(() => {
uni.navigateBack()
}, time)
}
async function save() {
let isAllPassForm = 0
const nameFormRes = await returnPromise(nameFormRef.value.validate())
console.log(nameFormRes);
if (!nameFormRes.sucees) {
isAllPassForm -= 1
}
for (let i in specifications.list) {
const res = await returnPromise(formRefs.value[i].validate(), i)
isAllPassForm += res.sucees ? 1 : 0
}
//判断验证是否通过
if (isAllPassForm === specifications.list.length) {
console.log('pass');
const data = {
name: specifications.name,
id:specifications.id,
specList: specifications.list.map(v => {
return {
...v,
value: v.options.map(v => v.name),
options: undefined
}
})
}
if (option.type === 'add') {
return $productSpec.add(data).then(res => {
infoBox.showSuccessToast('添加成功')
settimeoutBack(1500)
})
}
$productSpec.update(data).then(res => {
infoBox.showSuccessToast('修改成功')
settimeoutBack(1500)
})
}
}
</script>
<style scoped>
page {
background: #F9F9F9;
}
</style>
<style lang="scss" scoped>
$icon-size: 34rpx;
$icon-line-width: 20rpx;
$icon-line-height: 4rpx;
.page {
background: #F9F9F9;
padding: 30rpx;
padding-bottom: 200rpx;
}
.my-switch {
transform: scale(0.7);
}
::v-deep .uni-forms-item__error {
display: none !important;
}
::v-deep .option .uni-forms-item {
padding: 0;
min-height: inherit;
background-color: transparent;
border-top: none;
}
.icon {
width: $icon-size;
height: $icon-size;
position: relative;
border-radius: 50%;
&:before,
&::after {
position: absolute;
display: block;
content: '';
background-color: #fff;
}
}
.icon-add {
background-color: $my-main-color;
&::before {
width: $icon-line-height;
height: $icon-line-width;
top: calc(($icon-size /2) - ($icon-line-width / 2));
left: calc(($icon-size /2) - ($icon-line-height / 2));
}
&::after {
width: $icon-line-width;
height: 4rpx;
top: calc(($icon-size /2) - ($icon-line-height / 2));
left: calc(($icon-size /2) - ($icon-line-width / 2));
}
}
.icon-reduce {
background-color: $my-red-color;
&::after {
width: $icon-line-width;
height: $icon-line-height;
top: calc(($icon-size /2) - ($icon-line-height / 2));
left: calc(($icon-size /2) - ($icon-line-width / 2));
}
}
.label-title {
font-size: 28rpx;
font-weight: bold;
font-family: Source Han Sans CN, Source Han Sans CN;
}
.lh40 {
line-height: 40rpx;
}
.box {
margin-top: 70rpx;
font-size: 28rpx;
.block {
background: #FFFFFF;
border-radius: 18rpx 18rpx 18rpx 18rpx;
padding: 12rpx 24rpx;
margin-bottom: 32rpx;
}
}
.save-btn-box {
position: fixed;
left: 30rpx;
right: 30rpx;
bottom: 60rpx;
}
::v-deep.uni-forms-item {
align-items: inherit;
}
::v-deep .uni-forms-item .uni-forms-item__label {
text-indent: 0;
font-size: 28rpx !important;
font-weight: bold;
color: #333;
}
::v-deep .border-top-0 .uni-forms-item.is-direction-top {
border-color: transparent !important;
}
.save-btn {
background-color: $my-main-color;
color: #fff;
border-radius: 12rpx;
font-size: 28rpx;
}
.btn-hover-class {
opacity: .6;
}
.zuofa {
padding: 28rpx 0;
background: #F9F9F9;
padding-left: 42rpx;
border-radius: 14rpx 14rpx 14rpx 14rpx;
}
::v-deep .uni-input-placeholder {
font-size: 28rpx;
}
.option {
padding: 26rpx 30rpx 24rpx 24rpx;
background: #F9F9F9;
}
.option-item {
margin-bottom: 34rpx;
}
</style>

View File

@@ -1,53 +1,62 @@
<template> <template>
<view class="page"> <view class="page">
<view class="box"> <view class="box">
<view class="block border-top-0">
<uni-forms ref="nameFormRef" :model="specifications" :rules="rules" :label-width="350"
label-position="top" validateTrigger="blur">
<uni-forms-item label="模版名称" required name="name">
<uni-easyinput :placeholderStyle="placeholderStyle" :inputBorder="inputBorder"
v-model="specifications.name" placeholder="模版名称,如:衣服" />
</uni-forms-item>
</uni-forms>
</view>
<view v-for="(item,index) in specifications.list" :key="index"> <view v-for="(item,index) in specifications.list" :key="index">
<uni-forms :model="item" :rules="rules" err-show-type="undertext" validateTrigger="blur" <uni-forms :model="item" :rules="rules" err-show-type="undertext" validateTrigger="blur"
:ref="setFormRef(index)" :border="true" label-position="top" label-width="350"> :ref="setFormRef(index)" :border="true" label-position="top" label-width="350">
<view class="block"> <view class="block">
<view class="border-top-0"> <view class="border-top-0">
<uni-forms-item label="规格组名" required name="name"> <uni-forms-item label="规格组名" required name="name" >
<uni-easyinput :placeholderStyle="placeholderStyle" :inputBorder="inputBorder" <uni-easyinput :placeholderStyle="placeholderStyle" :inputBorder="inputBorder"
v-model="item.name" placeholder="规格组名,如:尺码" /> v-model="item.name" placeholder="规格组名" />
</uni-forms-item> </uni-forms-item>
</view> </view>
<uni-forms-item label="规格值"> <!-- <uni-forms-item label="最少可选" required name="MinOptional" >
<uni-easyinput :placeholderStyle="placeholderStyle" :inputBorder="inputBorder"
v-model="item.MinOptional" type="number" placeholder="填写最小数量" />
</uni-forms-item>
<uni-forms-item label="最大可选" required name="MaxOptional" >
<uni-easyinput :placeholderStyle="placeholderStyle" :inputBorder="inputBorder"
v-model="item.MaxOptional" type="number" placeholder="填写最大数量" />
</uni-forms-item> -->
<uni-forms-item label="选项值">
<view class="option"> <view class="option">
<view class=""> <view class="u-flex">
<view class="u-flex option-item" v-for="(option,optionIndex) in item.options" <view class="u-flex-1">名称</view>
:key="optionIndex"> <view class="u-flex-1 u-p-l-60">加价</view>
</view>
<view class="u-m-t-32">
<view class="u-flex option-item"
v-for="(option,optionIndex) in item.options"
:key="optionIndex"
>
<view class="u-flex-1"> <view class="u-flex-1">
<uni-forms-item :key="optionIndex" :name="['options',optionIndex,'name']" <uni-forms-item :key="optionIndex" :name="['options',optionIndex,'optionName']"
:ref="setFormInputRef(index,optionIndex)" :ref="setFormInputRef(index,optionIndex)"
:rules="[{'required': true,errorMessage: '必填'}]" label-width="0" :rules="[{'required': true,errorMessage: '必填'}]"
label="" required :showRequired="false"> label-width="0" label="" required :showRequired="false"
<uni-easyinput >
v-model="specifications.list[index].options[optionIndex].name" <uni-easyinput v-model="specifications.list[index].options[optionIndex].optionName"
@input="inpuChange(index,optionIndex)" @input="inpuChange(index,optionIndex)"
:placeholderStyle="placeholderStyle" :inputBorder="inputBorder" :placeholderStyle="placeholderStyle" :inputBorder="inputBorder"
placeholder="请输入规格值,如:S、M" /> placeholder="选项名" />
</uni-forms-item> </uni-forms-item>
</view> </view>
<view class=" u-flex"> <view class="u-p-l-60 u-flex-1 u-flex">
<uni-forms-item :key="optionIndex" label-width="0" label="" <uni-forms-item :key="optionIndex"
:showRequired="false"> :rules="[{'required': true,errorMessage: '必填'}]"
:ref="setFormInputRef(index,optionIndex)"
:name="['options',optionIndex,'optionPrice']" label-width="0" label="" required :showRequired="false"
>
<view class="u-flex"> <view class="u-flex">
<!-- <uni-easyinput v-model="specifications.list[index].options[optionIndex].optionPrice" <uni-easyinput v-model="specifications.list[index].options[optionIndex].optionPrice"
@input="inpuChange(index,optionIndex)" @input="inpuChange(index,optionIndex)"
:placeholderStyle="placeholderStyle" :inputBorder="inputBorder" :placeholderStyle="placeholderStyle" :inputBorder="inputBorder"
type="digit" placeholder="填写价格" /> --> type="digit" placeholder="填写价格" />
<view class="icon icon-reduce u-m-l-38" <view class="icon icon-reduce u-m-l-38"
@click="delOption(index,optionIndex)"> @click="delOption(index,optionIndex)">
@@ -70,7 +79,7 @@
</view> </view>
</uni-forms-item> </uni-forms-item>
<view class="u-flex u-m-t-48 u-m-b-24" @click="delSpecificationsGroup(index)"> <view class="u-flex u-m-t-48 u-m-b-24" @click="delSpecificationsGroup(index)">
<view class="icon icon-reduce u-m-r-22 "> <view class="icon icon-reduce u-m-r-22 ">
@@ -97,14 +106,10 @@
<script setup> <script setup>
import go from '@/commons/utils/go.js'; import go from '@/commons/utils/go.js';
import {
$productSpec
} from '@/http/yskApi/goods.js'
import { import {
onLoad, onLoad,
onReady, onReady
} from '@dcloudio/uni-app'; } from '@dcloudio/uni-app';
import infoBox from '@/commons/utils/infoBox.js'
import { import {
onMounted, onMounted,
reactive, reactive,
@@ -112,9 +117,8 @@
ref, ref,
onBeforeMount onBeforeMount
} from 'vue'; } from 'vue';
const nameFormRef = ref(null)
// 表单样式 // 表单样式
const placeholderStyle = ref('font-size:28rpx;') const placeholderStyle = ref('font-size:28rpx;')
//表单边框 //表单边框
const inputBorder = ref(false) const inputBorder = ref(false)
const form = ref(null) const form = ref(null)
@@ -139,6 +143,12 @@
errorMessage: '必填' errorMessage: '必填'
}] }]
}, },
optionName: {
rules: [{
required: true,
errorMessage: '必填'
}]
},
optionPrice: { optionPrice: {
rules: [{ rules: [{
required: true, required: true,
@@ -147,10 +157,10 @@
} }
} }
// 构造规格的选项值的基础数据 // 构造规格的选项值的基础数据
const specificationsOptionsBasicData = { const specificationsOptionsBasicData = {
name: '', optionName: '',
optionPrice: '0.00' optionPrice: '0.00'
} }
@@ -162,8 +172,8 @@
// 构造规格的基础数据 // 构造规格的基础数据
const specificationsBasicData = { const specificationsBasicData = {
name: '', name: '',
// MinOptional: 1, MinOptional: 1,
// MaxOptional: 1, MaxOptional: 1,
options: [] options: []
} }
@@ -179,7 +189,6 @@
} }
// 规格列表 // 规格列表
const specifications = reactive({ const specifications = reactive({
name: '',
list: [returnSpecificationsOptionsBasicData()] list: [returnSpecificationsOptionsBasicData()]
}) })
@@ -226,8 +235,7 @@
}; };
} }
// 绑定option input元素 // 绑定option input元素
const refFormInput = ref([]) const refFormInput=ref([])
function setFormInputRef(index, index1) { function setFormInputRef(index, index1) {
const newIndex = index * 10000 + index1 const newIndex = index * 10000 + index1
return (el) => { return (el) => {
@@ -244,104 +252,61 @@
console.log(refFormInput.value[newIndex]); console.log(refFormInput.value[newIndex]);
refFormInput.value[newIndex].onFieldChange() refFormInput.value[newIndex].onFieldChange()
} }
let emitName=''
function triggerEvent (emitName,data){
if(emitName){
const option = { uni.$emit(emitName,data)
type: 'add', }
id: undefined
} }
onLoad(opt => { onLoad(opt=>{
const arr=uni.getStorageSync('guige')
if(arr.length){
specifications.list=arr
console.log(arr);
}
console.log(opt); console.log(opt);
if (opt && JSON.stringify(opt) !== '{}' && opt.type) { if(opt&&JSON.stringify(opt)!=='{}'&&opt.emitName){
option.type = opt.type emitName=opt.emitName
const data = uni.getStorageSync('spec')
uni.removeStorageSync('spec')
if(data){
specifications.name = data.name
specifications.id = data.id
specifications.list = data.specList.map(v => {
return {
...v,
options: v.value.map(v => {
return {
name: v
}
})
}
})
}
} }
uni.setNavigationBarTitle({ uni.setNavigationBarTitle({
title: option.type === 'edit' ? '编辑规格模版' : '添加规格模版' title:emitName?'编辑规格模版':'添加规格模版'
}) })
}) })
function emitspecificationsSave(){
function returnPromise(prosise, index) { // emitspecificationsSave 触发规格保存事件将数据给到添加商品页面
return new Promise((resolve, reject) => { // guigeEdit 触发规格保存事件将数据给到添加规格页面
prosise.then(res => { uni.removeStorageSync('guige')
triggerEvent(emitName,specifications.list)
}
function returnPromise(index,prosise){
return new Promise((resolve,reject)=>{
prosise.then(res=>{
console.log(res); console.log(res);
resolve({ resolve({sucees:true})
sucees: true }).catch(err=>{
})
}).catch(err => {
console.log(err); console.log(err);
resolve({ resolve({sucees:false})
sucees: false
})
}) })
}) })
} }
async function save() {
let timer = null let isAllPassForm=0
function settimeoutBack(time) {
clearTimeout(timer)
timer = setTimeout(() => {
uni.navigateBack()
}, time)
}
async function save() {
let isAllPassForm = 0
const nameFormRes = await returnPromise(nameFormRef.value.validate())
console.log(nameFormRes);
if (!nameFormRes.sucees) {
isAllPassForm -= 1
}
for (let i in specifications.list) { for (let i in specifications.list) {
const res = await returnPromise(formRefs.value[i].validate(), i) const res=await returnPromise(i,formRefs.value[i].validate())
isAllPassForm += res.sucees ? 1 : 0 isAllPassForm+=res.sucees?1:0
} }
//判断验证是否通过 //判断验证是否通过
if (isAllPassForm === specifications.list.length) { if(isAllPassForm===specifications.list.length){
console.log('pass'); console.log('pass');
const data = { emitspecificationsSave()
name: specifications.name, go.back()
id:specifications.id,
specList: specifications.list.map(v => {
return {
...v,
value: v.options.map(v => v.name),
options: undefined
}
})
}
if (option.type === 'add') {
return $productSpec.add(data).then(res => {
infoBox.showSuccessToast('添加成功')
settimeoutBack(1500)
})
}
$productSpec.update(data).then(res => {
infoBox.showSuccessToast('修改成功')
settimeoutBack(1500)
})
} }
} }

View File

@@ -0,0 +1,134 @@
<template>
<up-popup :show="popShow" @close="close" @open="open" mode="center" :round="9" :zIndex="999">
<view class="u-p-32 box u-font-28">
<view class="u-flex u-relative u-row-center">
<view class="u-font-32">报损</view>
<view class="u-absolute close">
<up-icon @click="close" :size="16" color="#000" name="close-circle-fill"></up-icon>
</view>
</view>
<view class="u-m-t-48">
<view>商品名称</view>
<view class="u-m-t-16">{{data.name}}</view>
<view class="u-m-t-38">
<view class="u-m-b-32">
<view class="u-flex ">
报损数量
</view>
<view class="u-m-t-16">
<up-input v-model="form.number">
<template #suffix>
<view>{{data.unitName}}</view>
</template>
</up-input>
</view>
</view>
<view class="u-m-b-32">
<view class="u-flex u-row-between">
<view>备注</view>
</view>
<view class="u-m-t-16">
<up-textarea :height="42" v-model="form.note" placeholder="请输入备注"></up-textarea>
</view>
</view>
<view class="u-m-b-32">
<view class="u-flex u-row-between">
<view>上传图片</view>
</view>
<view class="u-m-t-16">
<scroll-view scroll-y="true" style="max-height: 300rpx;">
<my-up-upload v-model="form.images"></my-up-upload>
</scroll-view>
</view>
</view>
<view class="u-m-t-60">
<my-button type="primary" shape="circle" @tap="save">
<view class="u-font-32">
保存
</view>
</my-button>
</view>
</view>
</view>
</view>
</up-popup>
</template>
<script setup>
import {
reactive,
ref,
watch,
onMounted
} from 'vue';
import {
returnSkuSnap,
returnTypeEnum,
returnCategory
} from '@/pageProduct/util.js'
import {
$tbShopUnit
} from '@/http/yskApi/goods.js'
const props = defineProps({
show: {
type: Boolean,
default: false
},
category: {
type: Array,
default: () => []
},
goods: {
type: Object,
default: () => {
skuList: []
}
}
})
const data = ref(props.goods)
const emits = defineEmits(['update:show', 'save'])
const form = reactive({
note: '',
number: 1,
images: []
})
let popShow = ref(props.show)
watch(() => props.show, (newval) => {
popShow.value = newval
if (newval) {
data.value = props.goods
}
})
watch(() => popShow.value, (newval) => {
emits('update:show', newval)
})
function close() {
popShow.value = false
}
function open() {
}
function save() {
console.log(form.images);
}
</script>
<style lang="scss" scoped>
.box {
width: 556rpx;
border-radius: 18rpx 18rpx 18rpx 18rpx;
box-sizing: border-box;
}
.close {
position: absolute;
right: 0;
}
.number {
color: #EE4646;
}
</style>

View File

@@ -0,0 +1,141 @@
<template>
<up-popup :show="popShow" @close="close" @open="open" mode="center" :round="9">
<view class="u-p-32 box u-font-28">
<view class="u-flex u-relative u-row-center">
<view class="u-font-32">{{data.specSnap}}</view>
<view class="u-absolute close">
<up-icon @click="close" :size="16" color="#000" name="close-circle-fill"></up-icon>
</view>
</view>
<view class="u-m-t-48">
<view class="u-flex u-row-between border-bottom u-p-b-30">
<view>当前状态</view>
<view class="u-flex">
<up-radio-group v-model="isGrounding" placement="row" @change="isGroundingChange">
<up-radio :customStyle="{marginRight: '10px'}" v-for="(item, index) in status.list"
:key="index" :label="item.label" :name="item.name">
</up-radio>
</up-radio-group>
</view>
</view>
<view class=" u-flex u-row-between u-m-t-30">
<view>售罄</view>
<up-switch :size="20" @change="isPauseSaleChange" v-model="isPauseSale"></up-switch>
</view>
</view>
</view>
</up-popup>
</template>
<script setup>
import {
reactive,
ref,
watch
} from 'vue';
import {
returnSkuSnap,
returnTypeEnum,
returnCategory
} from '@/pageProduct/util.js'
import {
$updateGrounding, $updateProductStatus
} from '@/http/yskApi/goods.js'
import infoBox from '@/commons/utils/infoBox.js'
const props = defineProps({
show: {
type: Boolean,
default: false
},
category: {
type: Array,
default: () => []
},
goods: {
type: Object,
default: () => {
skuList: []
}
}
})
const status = reactive({
list: [{
name: 1,
label: '上架中'
}, {
name: 0,
label: '已下架'
}],
})
// 是否售罄
const isPauseSale = ref(false)
// 是否上架
const isGrounding = ref(1)
const data = ref(props.goods)
const emits = defineEmits(['update:show', 'save', 'isGroundingChange','isPauseSaleChange'])
const form = reactive({
note: ''
})
let popShow = ref(props.show)
watch(() => props.show, (newval) => {
popShow.value = newval
if (newval) {
console.log(props.goods);
data.value = props.goods
isPauseSale.value = props.goods.isPauseSale ? true : false
isGrounding.value = props.goods.isGrounding
}
})
watch(() => popShow.value, (newval) => {
emits('update:show', newval)
})
function close() {
popShow.value = false
}
function open() {
}
function save() {
emits('save')
}
async function isGroundingChange(e) {
console.log(e);
await $updateGrounding({
isGrounding: e ? true : false,
skuId: props.goods.id
})
emits('isGroundingChange', e)
infoBox.showToast('更新成功')
}
async function isPauseSaleChange(e) {
console.log(e);
await $updateProductStatus({
targetId: props.goods.id,
updateKey: "pauseSaleSku",
updateValue: e?1:0
})
emits('isPauseSaleChange', e)
infoBox.showToast('更新成功')
}
</script>
<style lang="scss" scoped>
.box {
width: 556rpx;
border-radius: 18rpx 18rpx 18rpx 18rpx;
box-sizing: border-box;
}
.close {
position: absolute;
right: 0;
}
.number {
color: #EE4646;
}
</style>

View File

@@ -0,0 +1,186 @@
<template>
<up-popup :show="popShow" @close="close" @open="open" mode="center" :round="9">
<view class="u-p-32 box u-font-28">
<view class="u-flex u-relative u-row-center">
<view class="u-font-32">修改价格</view>
<view class="u-absolute close">
<up-icon @click="close" :size="16" color="#000" name="close-circle-fill"></up-icon>
</view>
</view>
<view class="u-m-t-48">
<view>商品名称</view>
<view class="u-m-t-16" v-if="isSku">{{data.name}}</view>
<view class="u-m-t-38">
<template v-if="!isSku">
<view class="u-m-b-32">
<view class="u-flex u-row-between">
<view>{{data.name}}</view>
<view class="u-font-24">
<text>变动金额</text>
<text class="number">{{data.lowPrice-data._lowPrice}}</text>
</view>
</view>
<view class="u-m-t-16">
<up-input v-model="data.lowPrice">
<template #suffix>
<view></view>
</template>
</up-input>
</view>
</view>
<view class="u-m-b-32">
<view class="u-flex u-row-between">
<view>备注</view>
</view>
<view class="u-m-t-16">
<up-textarea :height="42" v-model="form.note" placeholder="请输入备注"></up-textarea>
</view>
</view>
</template>
<template v-else>
<scroll-view scroll-y="true" style="max-height: 50vh;">
<view class="u-m-b-32" v-for="(item,index) in data.skuList" :key="index">
<view class="u-flex u-row-between">
<view>{{item.name}}</view>
<view class="u-font-24">
<text>变动金额</text>
<text class="number">{{item.lowPrice-item._lowPrice}}</text>
</view>
</view>
<view class="u-m-t-16">
<up-input v-model="item.lowPrice">
<template #suffix>
<view></view>
</template>
</up-input>
</view>
</view>
<view class="u-m-b-32">
<view class="u-flex u-row-between">
<view>备注</view>
</view>
<view class="u-m-t-16">
<up-textarea :height="42" v-model="form.note" placeholder="请输入备注"></up-textarea>
</view>
</view>
</scroll-view>
</template>
<view class="u-m-t-60">
<my-button type="primary" shape="circle" @tap="save">
<view class="u-font-32">
保存
</view>
</my-button>
</view>
</view>
</view>
</view>
</up-popup>
</template>
<script setup>
import {
computed,
reactive,
ref,
watch
} from 'vue';
import {
returnSkuSnap,
returnTypeEnum,
returnCategory
} from '@/pageProduct/util.js'
const props = defineProps({
show: {
type: Boolean,
default: false
},
category: {
type: Array,
default: () => []
},
goods: {
type: Object,
default: () => {
return {
lowPrice:0,
skuList: []
}
}
}
})
const data = ref(props.goods)
const emits = defineEmits(['update:show', 'save'])
const form = reactive({
note: ''
})
let popShow = ref(props.show)
watch(() => props.show, (newval) => {
popShow.value = newval
if (newval) {
data.value = props.goods
}
})
const isSku=computed(()=>{
return data.value.typeEnum=='多规格'
})
watch(() => popShow.value, (newval) => {
emits('update:show', newval)
})
function close() {
popShow.value = false
}
function open() {
}
function save() {
emits('save', {
...data.value,
})
}
// function save() {
// const skuSnap = returnSkuSnap(data.value)
// let typeEnum = returnTypeEnum(data.value.typeEnum)
// let lowPrice = undefined
// typeEnum = typeEnum ? typeEnum : 'normal'
// const findCategory = returnCategory(data.value.categoryName, props.category)
// console.log(typeEnum);
// console.log(findCategory);
// const categoryId = findCategory ? findCategory.id : ''
// if (typeEnum == 'normal') {
// // 单规格
// lowPrice = data.value.skuList[0].salePrice
// }
// emits('save', {
// ...data.value,
// lowPrice,
// typeEnum,
// images: data.value.images ? data.value.images : [data.value.coverImg],
// categoryId,
// skuSnap: JSON.stringify(skuSnap)
// })
// }
</script>
<style lang="scss" scoped>
.box {
width: 556rpx;
border-radius: 18rpx 18rpx 18rpx 18rpx;
box-sizing: border-box;
}
.close {
position: absolute;
right: 0;
}
.number {
color: #EE4646;
}
</style>

View File

@@ -0,0 +1,235 @@
<template>
<up-popup :show="popShow" @close="close" @open="open" mode="center" :round="9">
<view class="u-p-32 box u-font-28">
<view class="u-flex u-relative u-row-center">
<view class="u-font-32">修改库存</view>
<view class="u-absolute close">
<up-icon @click="close" :size="16" color="#000" name="close-circle-fill"></up-icon>
</view>
</view>
<view class="u-m-t-48">
<view>商品名称</view>
<view class="u-m-t-16" v-if="isSku">{{data.name}}</view>
<view class="u-m-t-38">
<template v-if="!isSku">
<view class="u-m-b-32" >
<view class="u-flex u-row-between">
<view>{{data.name}}</view>
<view class="u-font-24">
<text>变动数量</text>
<text class="number">{{data.stockNumber-data._stockNumber}}</text>
</view>
</view>
<view class="u-m-t-16">
<up-input v-model="data.stockNumber">
<template #suffix>
<view>{{data.unitName||''}}</view>
</template>
</up-input>
</view>
</view>
<view class="u-m-b-32">
<view class="u-flex u-row-between">
<view>备注</view>
</view>
<view class="u-m-t-16">
<up-textarea :height="42" v-model="form.note" placeholder="请输入备注"></up-textarea>
</view>
</view>
</template>
<template v-else>
<scroll-view scroll-y="true" style="max-height: 30vh;">
<view class="u-m-b-32" v-for="(item,index) in data.skuList" :key="index">
<view class="u-flex u-row-between">
<view>{{item.name}}</view>
<view class="u-font-24">
<text>变动数量</text>
<text class="number">{{item.stockNumber-item._stockNumber}}</text>
</view>
</view>
<view class="u-m-t-16">
<up-input v-model="item.stockNumber">
<template #suffix>
<view>{{data.unitName||''}}</view>
</template>
</up-input>
</view>
</view>
<view class="u-m-b-32">
<view class="u-flex u-row-between">
<view>备注</view>
</view>
<view class="u-m-t-16">
<up-textarea :height="42" v-model="form.note" placeholder="请输入备注"></up-textarea>
</view>
</view>
</scroll-view>
</template>
<view class="u-m-t-60">
<my-button type="primary" shape="circle" @tap="save">
<view class="u-font-32">
保存
</view>
</my-button>
<view class="u-m-t-30">
<template v-if="!recoders.show">
<view class="color-999 u-font-24 u-flex u-row-center u-col-center">
<view class="u-flex" @click="changeShowRecoders(true)">
<view class="u-m-r-6">查看记录</view>
<up-icon name="arrow-down" :size="12"></up-icon>
</view>
</view>
</template>
<template v-else>
<scroll-view scroll-y="true" style="max-height: 30vh;">
<my-step :list="recoders.list"></my-step>
</scroll-view>
<view class="color-999 u-font-24 u-flex u-row-center u-col-center">
<view class="u-flex" @click="changeShowRecoders(false)">
<view class="u-m-r-6">收起记录</view>
<up-icon name="arrow-up" :size="12"></up-icon>
</view>
</view>
</template>
</view>
</view>
</view>
</view>
</view>
</up-popup>
</template>
<script setup>
import {
reactive,
ref,
watch,
onMounted,
computed
} from 'vue';
import {
returnSkuSnap,
returnTypeEnum,
returnCategory
} from '@/pageProduct/util.js'
import {
$tbShopUnit
} from '@/http/yskApi/goods.js'
const props = defineProps({
show: {
type: Boolean,
default: false
},
category: {
type: Array,
default: () => []
},
goods: {
type: Object,
default: () => {
skuList: []
}
}
})
function changeShowRecoders(show) {
recoders.show = show
}
const recoders = reactive({
list: [{
title: '2024-09-15 112030',
content: '开启了库存库存由0件修改为5件'
},
{
title: '2024-09-15 ',
content: '开启了库存库存由0件修改为4件'
},
{
title: '2024-09-15 ',
content: '开启了库存库存由0件修改为3件'
},
{
title: '2024-09-15 ',
content: '开启了库存库存由0件修改为2件'
},
],
show: false,
active: 0
})
const data = ref(props.goods)
const emits = defineEmits(['update:show', 'save'])
const form = reactive({
note: ''
})
let popShow = ref(props.show)
watch(() => props.show, (newval) => {
popShow.value = newval
if (newval) {
data.value = props.goods
}
})
const isSku = computed(() => {
// return data.value.typeEnum == '多规格'
return false
})
watch(() => popShow.value, (newval) => {
emits('update:show', newval)
})
function close() {
popShow.value = false
}
function open() {
}
function save() {
emits('save', {
...data.value,
})
}
// function save() {
// const skuSnap = returnSkuSnap(data.value)
// let typeEnum = returnTypeEnum(data.value.typeEnum)
// let lowPrice = undefined
// typeEnum = typeEnum ? typeEnum : 'normal'
// const findCategory = returnCategory(data.value.categoryName, props.category)
// console.log(typeEnum);
// console.log(findCategory);
// const categoryId = findCategory ? findCategory.id : ''
// if (typeEnum == 'normal') {
// // 单规格
// lowPrice = data.value.skuList[0].salePrice
// }
// emits('save', {
// ...data.value,
// lowPrice,
// typeEnum,
// images: data.value.images ? data.value.images : [data.value.coverImg],
// categoryId,
// skuSnap: JSON.stringify(skuSnap)
// })
// }
</script>
<style lang="scss" scoped>
.box {
width: 556rpx;
border-radius: 18rpx 18rpx 18rpx 18rpx;
box-sizing: border-box;
}
.close {
position: absolute;
right: 0;
}
.number {
color: #EE4646;
}
</style>

View File

@@ -7,55 +7,81 @@
<text class="u-m-l-20">{{data.sort}}</text> <text class="u-m-l-20">{{data.sort}}</text>
</view> </view>
<view class="color-333 u-m-l-42 u-flex"> <view class="color-333 u-m-l-42 u-flex">
<up-icon name="edit-pen" :size="16" :color="ColorMain"></up-icon> <up-icon @click="editStock" name="edit-pen" :size="16" :color="ColorMain"></up-icon>
<text class="stock">库存:</text> <text class="stock u-m-l-4">库存:{{data.stockNumber}}</text>
<text class="font-bold u-m-l-10">{{data.stockNumber}}</text>
</view> </view>
</view> </view>
<text class="u-font-28 color-666" @click="changeClick">修改</text> <view>
<!-- <text class="u-font-28 color-666" @click="changeClick">修改</text> -->
<text class="u-font-28 color-666" @click="changePrice">改价</text>
<text class="u-font-28 color-red u-m-l-24" @click="baosun">报损</text>
</view>
</view> </view>
<view class="u-m-t-48 u-flex"> <view class="u-m-t-48 u-flex u-col-top u-relative">
<view v-if="props.showChecked"> <view v-if="props.showChecked">
<label class="radio"> <label class="radio">
<radio :color="ColorMain" style="transform: scale(0.7);" @click="radioClick" <radio :color="ColorMain" style="transform: scale(0.7);" @click="radioClick"
:checked="props.data.checked" /><text></text> :checked="props.data.checked" /><text></text>
</label> </label>
</view> </view>
<image :src="data.coverImg" lazy-load class="img"></image> <view class="img">
<view class="h-100 u-p-l-16 u-flex-1 u-flex u-flex-col u-row-between"> <up--image :width="63" :height="63" :radius="3" :src="data.coverImg"></up--image>
<view class="color-333 w-full u-flex u-row-between"> </view>
<view class="w-full info">
<view class="info-p-l color-333 u-flex u-row-between">
<view class="u-flex"> <view class="u-flex">
<text class="u-m-r-24">{{data.name}}</text><uni-tag size="small" type="primary" <text class="u-m-r-24">{{data.name}}</text>
custom-style="background-color: #318AFE;" :text="data.typeEnum"></uni-tag> <!-- <uni-tag size="small" type="primary"
custom-style="background-color: #318AFE;" :text="data.typeEnum"></uni-tag> -->
</view>
<view class="u-font-32">
<text>{{data.lowPrice}}</text>
<!-- <text>¥</text>
<text>{{data.lowPrice}}</text>
<text v-if="data.typeEnum == '多规格'">~{{data.maxPrice }}</text> -->
</view> </view>
<view class="price">¥{{data.lowPrice}}</view>
</view> </view>
<view class="u-m-t-44">
<template v-if="data.skuList.length>=2">
<view class="u-flex u-flex-wrap w-full gap-10 u-col-top">
<view class="u-font-24 info-p-l u-m-t-14">规格</view>
<view class="skd" v-for="(item,index) in data.skuList" :key="index"
@click="guigeClick(index)">
<text>{{item.specSnap||item.name}}</text>
<view class="tag-primary tag" v-if="item.isGrounding">上架中</view>
<view class="tag-gray tag" v-else>已下架</view>
<!-- <template v-if="item.isPauseSale">
<view class="tag-gray tag" >已售罄</view>
</template>
<template v-else>
<view class="tag-primary tag" v-if="item.isGrounding">上架中</view>
<view class="tag-gray tag" v-else>已下架</view>
</template> -->
</view>
</view>
</template>
<template v-else>
<view style="height: 24rpx;">
</view>
</template>
</view>
</view> </view>
</view> </view>
<view class="u-m-t-16 skus u-text-center" v-if="data.skuList.length>=2"> <!-- <view class="u-m-t-16 skus u-text-center" v-if="data.skuList.length>=2">
<!-- <view class="u-flex u-row-between font-bold">
<view class="u-flex-1">商品信息</view>
<view class="u-flex-1">售价</view>
<view class="u-flex-1">库存</view>
</view>
<view v-for="(item,index) in data.skuList" :key="index">
<view class="u-flex u-m-t-10">
<view class="color-333 u-flex-1"> <text class="u-m-r-24">{{item.specSnap||''}}</text></view>
<view class="price u-flex-1">¥{{data.lowPrice||0}}</view>
<view class=" u-flex-1">{{item.stockNumber||0}} {{data.unitName||''}}</view>
</view>
</view> -->
<view class="u-flex u-flex-wrap skds"> <view class="u-flex u-flex-wrap skds">
<view class="skd" v-for="(item,index) in data.skuList" :key="index"><text>{{item.specSnap}}</text> <view class="skd" v-for="(item,index) in data.skuList" :key="index"><text>{{item.specSnap}}</text>
<view class="tag-primary tag">上架中</view> <view class="tag-primary tag">上架中</view>
</view> </view>
</view> </view>
</view> </view> -->
<view class="u-m-t-24 u-flex u-row-between"> <view class="u-m-t-24 u-flex u-row-between">
<view class="u-flex"> <view class="u-flex">
<view class="u-flex"> <view class="u-flex">
@@ -93,7 +119,7 @@
import { import {
ColorMain ColorMain
} from '@/commons/color.js' } from '@/commons/color.js'
const emits = defineEmits(['radioClick', 'changeClick', 'xiajia', 'del']) const emits = defineEmits(['radioClick', 'changeClick', 'xiajia', 'del', 'changePrice', 'baosun', 'guigeClick','editStock'])
const props = defineProps({ const props = defineProps({
index: { index: {
type: Number type: Number
@@ -113,7 +139,8 @@
default: false default: false
} }
}) })
function isHotChange(e) { function isHotChange(e) {
$goodsIsHot({ $goodsIsHot({
@@ -155,6 +182,20 @@
emits('del', props.index) emits('del', props.index)
} }
function changePrice() {
emits('changePrice', props.index)
}
function baosun() {
emits('baosun', props.index)
}
function guigeClick(guigeIndex) {
emits('guigeClick', props.index, guigeIndex)
}
function editStock(){
emits('editStock', props.index)
}
//携带参数type edit跳转到商品添加页面编辑与添加同一页面根据type值来判断 //携带参数type edit跳转到商品添加页面编辑与添加同一页面根据type值来判断
function toEdit() { function toEdit() {
go.to('PAGES_PRODUCT_ADD', { go.to('PAGES_PRODUCT_ADD', {
@@ -174,9 +215,12 @@
border: 2rpx solid transparent; border: 2rpx solid transparent;
} }
.gap-10 {
gap: 10rpx;
}
.btn-primary { .btn-primary {
border-color: $my-main-color; border-color: $my-main-color;
;
color: $my-main-color; color: $my-main-color;
} }
@@ -194,8 +238,15 @@
} }
.img { .img {
width: $imgSize; position: absolute;
height: $imgSize; left: 0;
top: 0;
// width: $imgSize;
// height: $imgSize;
}
.info-p-l {
padding-left: 71px;
} }
.icon-arrow-right { .icon-arrow-right {
@@ -219,6 +270,10 @@
// border: 2rpx solid #333333; // border: 2rpx solid #333333;
} }
.color-red {
color: #F0465B;
}
.goods { .goods {
border-radius: 10rpx 10rpx 10rpx 10rpx; border-radius: 10rpx 10rpx 10rpx 10rpx;
background-color: #fff; background-color: #fff;
@@ -239,33 +294,37 @@
.skds { .skds {
gap: 10rpx 50rpx; gap: 10rpx 50rpx;
} }
}
}
.skd { .skd {
padding: 14rpx 40rpx 14rpx 20rpx; padding: 14rpx 40rpx 14rpx 20rpx;
background: #F0F2F5; background: #F0F2F5;
border-radius: 4rpx; border-radius: 4rpx;
position: relative; position: relative;
color: #666; color: #666;
overflow: hidden; overflow: hidden;
margin-bottom: 10rpx; margin-bottom: 10rpx;
font-size: 24rpx;
.tag { .tag {
position: absolute; position: absolute;
right: 0; right: 0;
top: 0; top: 0;
font-size: 12rpx; font-size: 12rpx;
right: 0; right: 0;
padding: 2rpx 4rpx; padding: 2rpx 4rpx;
border-radius: 0rpx 4rpx 4rpx 4rpx; border-radius: 0rpx 4rpx 4rpx 4rpx;
} }
.tag-primary {
background-color: $my-main-color;
color: #fff;
}
}
.tag-primary {
background-color: $my-main-color;
color: #fff;
}
.tag-gray {
background-color: rgb(144, 147, 153);
color: #fff;
} }
} }
</style> </style>

View File

@@ -8,7 +8,8 @@
<view class="input-wrapper"> <view class="input-wrapper">
<view class="input-main"> <view class="input-main">
<view class="u-flex u-p-r-30 u-font-28" @click="onCategoryShowChange(true)"> <view class="u-flex u-p-r-30 u-font-28" @click="onCategoryShowChange(true)">
<text class="u-m-r-10 u-line-1" style="max-width: 100rpx;">{{pageData.categoryName||'分类' }}</text> <text class="u-m-r-10 u-line-1"
style="max-width: 100rpx;">{{pageData.categoryName||'分类' }}</text>
<up-icon name="arrow-down" size="16"></up-icon> <up-icon name="arrow-down" size="16"></up-icon>
</view> </view>
<uni-easyinput clearable class='jeepay-search' :inputBorder="false" <uni-easyinput clearable class='jeepay-search' :inputBorder="false"
@@ -40,8 +41,10 @@
<view class="goods-list u-p-30"> <view class="goods-list u-p-30">
<template v-if="pageData.goodsList.length"> <template v-if="pageData.goodsList.length">
<view class="u-m-b-32" v-for="(item,index) in pageData.goodsList" :key="index"> <view class="u-m-b-32" v-for="(item,index) in pageData.goodsList" :key="index">
<my-goods @changeClick="goodsChangeClick" @radioClick="goodsRadioClick" :index="index" :data="item" <my-goods @changePrice="changePriceShow" @changeClick="goodsChangeClick"
@del="goodsDel" :showChecked="showChecked" :showDetail="pageData.showGoodsDetail"></my-goods> @editStock="changeStockShow" @guigeClick="editGuigeShow" @baosun="baosunShow"
@radioClick="goodsRadioClick" :index="index" :data="item" @del="goodsDel"
:showChecked="showChecked" :showDetail="pageData.showGoodsDetail"></my-goods>
</view> </view>
</template> </template>
<template v-if="pageData.hasAjax&&!pageData.goodsList.length"> <template v-if="pageData.hasAjax&&!pageData.goodsList.length">
@@ -53,9 +56,8 @@
</view> </view>
<my-control ref="control" :categoryShow="pageData.categoryShow" :categoryName="pageData.categoryName" <my-control ref="control" :categoryShow="pageData.categoryShow" :categoryName="pageData.categoryName"
@categoryChange="categoryIdChange" @offShelf="offShelf" @allCheckedChange="allCheckedChange" @offShelf="offShelf" @allCheckedChange="allCheckedChange" @controlChange="controlChange"
@controlChange="controlChange" @toggleCategory="toggleCategory" @toggleCategory="toggleCategory" :bottom="pageData.componentBottom"></my-control>
:bottom="pageData.componentBottom"></my-control>
<!-- <my-category ref="category" @change="onCategoryShowChange" @cateClick="cateClick" <!-- <my-category ref="category" @change="onCategoryShowChange" @cateClick="cateClick"
:bottom="pageData.componentBottom+100"></my-category> --> :bottom="pageData.componentBottom+100"></my-category> -->
<!-- 下架弹窗 --> <!-- 下架弹窗 -->
@@ -113,7 +115,19 @@
</my-model> </my-model>
<!-- 分类 --> <!-- 分类 -->
<my-category v-model:isShow="pageData.categoryShow" @confirm="setCategory"></my-category> <my-category v-model:isShow="pageData.categoryShow" @confirm="setCategory"></my-category>
<!-- 修改价格弹窗 -->
<edit-price :category="pageData.categoryList" v-model:show="popup.price.show" @save="changePriceConfirm"
:goods="pageData.selGoods"></edit-price>
<!-- 修改库存弹窗 -->
<edit-stock :category="pageData.categoryList" v-model:show="popup.stock.show" @save="changeStockConfirm"
:goods="pageData.selGoods"></edit-stock>
<!-- 规格弹窗 -->
<edit-guige @isGroundingChange="isGroundingChange" v-model:show="popup.guige.show"
:goods="popup.guige.data"></edit-guige>
<!-- 报损 -->
<baosun-vue :category="pageData.categoryList" v-model:show="popup.baosun.show"
:goods="pageData.selGoods"></baosun-vue>
</view> </view>
</template> </template>
@@ -136,14 +150,25 @@
import myControl from './components/control.vue' import myControl from './components/control.vue'
import myCategory from './components/category.vue' import myCategory from './components/category.vue'
import infoBox from "@/commons/utils/infoBox.js" import infoBox from "@/commons/utils/infoBox.js"
import editPrice from './components/edit-price.vue';
import editGuige from './components/edit-guige.vue';
import editStock from './components/edit-stock.vue';
import baosunVue from './components/baosun.vue';
import { import {
$tbProduct, $tbProduct,
$upProSort, $upProSort,
$updateProduct, $updateProduct,
$getProductDetail, $getProductDetail,
$delProduct, $delProduct,
$updateProductStatus $tbShopCategory,
$updateProductStatus,
$tbProductV2,
$updateProductData
} from "@/http/yskApi/goods.js" } from "@/http/yskApi/goods.js"
import {
returnAllCategory
} from '@/pageProduct/util.js'
const pageData = reactive({ const pageData = reactive({
modelDesc: '是否下架', modelDesc: '是否下架',
stateCurrent: 0, stateCurrent: 0,
@@ -154,6 +179,7 @@
}, },
showGoodsDetail: false, showGoodsDetail: false,
selGoodsIndex: '', selGoodsIndex: '',
selGoods: {},
totalElements: 0, totalElements: 0,
totalPage: 0, totalPage: 0,
goodsList: [], goodsList: [],
@@ -164,24 +190,179 @@
name: '' name: ''
}, },
category: '', category: '',
categoryList: [], //分类列表
categoryShow: false, categoryShow: false,
categoryName: '', categoryName: '',
hasAjax: false hasAjax: false
}) })
watch(()=>pageData.query.categoryId,(newval)=>{ watch(() => pageData.query.categoryId, (newval) => {
getGoodsList() getGoodsList()
}) })
const popup = reactive({
price: {
show: false
},
guige: {
show: false,
data: {},
goodsIndex: '',
guigeIndex: '',
},
stock: {
show: false
},
baosun: {
show: false
}
})
//报损弹窗展示
function baosunShow(index) {
pageData.selGoodsIndex = index
const goods = pageData.goodsList[index]
pageData.selGoods = goods
popup.baosun.show = true
}
// 修改价格弹窗展示
function changePriceShow(index) {
pageData.selGoodsIndex = index
const goods = pageData.goodsList[index]
goods.skuList = goods.skuList.map(v => {
return {
...v,
_lowPrice: v.lowPrice
}
})
const lowPrice = goods.lowPrice.replace('¥', '') * 1
pageData.selGoods = {
...goods,
lowPrice,
_lowPrice: lowPrice
}
popup.price.show = true
}
async function changePriceConfirm(goods) {
let goodsArr = []
if (goods.typeEnum == '单规格') {
goodsArr = [{
shopId: uni.getStorageSync('shopId'),
isSku: false,
id: goods.id,
key: 'salePrice',
value: goods.lowPrice
}]
} else {
goodsArr = goods.skuList.map(v => {
return {
shopId: uni.getStorageSync('shopId'),
isSku: true,
id: v.id,
key: 'salePrice',
value: v.lowPrice
}
})
}
const res = await $updateProductData(goodsArr)
popup.price.show = false
getGoodsList()
}
// 修改库存弹窗展示
function changeStockShow(index) {
pageData.selGoodsIndex = index
const goods = pageData.goodsList[index]
goods.skuList = goods.skuList.map(v => {
return {
...v,
_stockNumber: v.stockNumber
}
})
const stockNumber = goods.stockNumber
pageData.selGoods = {
...goods,
stockNumber,
_stockNumber: stockNumber
}
popup.stock.show = true
}
async function changeStockConfirm(goods) {
let goodsArr = []
// if (goods.typeEnum == '单规格') {
// goodsArr = [{
// shopId: uni.getStorageSync('shopId'),
// isSku: false,
// id: goods.id,
// key: 'stockNumber',
// value: goods.stockNumber
// }]
// } else {
// goodsArr = goods.skuList.map(v => {
// return {
// shopId: uni.getStorageSync('shopId'),
// isSku: true,
// id: v.id,
// key: 'stockNumber',
// value: v.stockNumber
// }
// })
// }
goodsArr = [{
shopId: uni.getStorageSync('shopId'),
isSku: false,
id: goods.id,
key: 'stockNumber',
value: goods.stockNumber
}]
const res = await $updateProductData(goodsArr)
popup.stock.show = false
getGoodsList()
}
//修改规格上下架,售罄
function editGuigeShow(goodsIndex, guigeIndex) {
console.log(goodsIndex, guigeIndex);
const goodsGuige = pageData.goodsList[goodsIndex].skuList[guigeIndex]
popup.guige.data = goodsGuige
popup.guige.goodsIndex = goodsIndex
popup.guige.guigeIndex = guigeIndex
popup.guige.show = true
}
function isGroundingChange(e) {
const {
goodsIndex,
guigeIndex
} = popup.guige
pageData.goodsList[goodsIndex].skuList[guigeIndex].isGrounding = e
}
function isPauseSaleChange(e) {
const {
goodsIndex,
guigeIndex
} = popup.guige
pageData.goodsList[goodsIndex].skuList[guigeIndex].isPauseSale = e
}
function onCategoryShowChange(show) { function onCategoryShowChange(show) {
console.log(show); console.log(show);
pageData.categoryShow = show pageData.categoryShow = show
} }
function setCategory(category){
function setCategory(category) {
pageData.query.categoryId = category.id pageData.query.categoryId = category.id
pageData.categoryName = category.name pageData.categoryName = category.name
} }
function getGoodsList() { function getGoodsList() {
$tbProduct(pageData.query).then(res => { $tbProductV2(pageData.query).then(res => {
pageData.hasAjax = true pageData.hasAjax = true
console.log(res); console.log(res);
pageData.goodsList = res.content.map(v => { pageData.goodsList = res.content.map(v => {
@@ -198,9 +379,18 @@
onShow(() => { onShow(() => {
getGoodsList() getGoodsList()
}) })
onLoad(() => {
$tbShopCategory({
page: 0,
size: 200
}).then(res => {
pageData.categoryList = returnAllCategory(res.content)
console.log(pageData.categoryList);
})
})
const tabsList = ['简洁', '详情'] const tabsList = ['简洁', '详情']
const statesTabsList = ['全部', '已售罄','在售中', '已下架'] const statesTabsList = ['全部', '已售罄', '在售中', '已下架']
const control = ref(null) const control = ref(null)
const model = ref(null) const model = ref(null)
const goodsStockModel = ref(null) const goodsStockModel = ref(null)

41
pageProduct/util.js Normal file
View File

@@ -0,0 +1,41 @@
import {
$types
} from '@/pageProduct/goodsData.js'
export function returnSkuSnap(goods) {
const selectSpec = typeof goods.selectSpec === 'string' ? JSON.parse(goods.selectSpec) : goods.selectSpec
let result = selectSpec.map(v => {
return {
name: v.name,
value: v.selectSpecResult.join(',')
}
})
return result
}
export function returnTypeEnum(typeEnum) {
const item = $types.find(v => v.title == typeEnum)
let result = item ? item.value : undefined
return result
}
export function returnCategory(cateName, cateList) {
console.log(cateName);
console.log(cateList);
const item = cateList.find(v => v.name == cateName)
let result = item ? item : undefined
return result
}
export function returnAllCategory(arr) {
const result = arr.reduce((prve, cur) => {
prve.push(...[{
...cur,
name: '' + cur.name,
childrenList: undefined
}, ...cur.childrenList.map(v => {
return {
...v,
name: '' + v.name
}
})])
return prve
}, [])
return result
}

View File

@@ -125,11 +125,12 @@
function more() { function more() {
emits('more') emits('more')
} }
function diancan() { function diancan() {
go.to('PAGES_CREATE_ORDER', { go.to('PAGES_CREATE_ORDER', {
tableId: props.data.tableId, tableId: props.data.tableId,
tableName: props.data.name name: props.data.name
}) })
} }
@@ -140,14 +141,16 @@
name, name,
status, status,
amount, amount,
areaId areaId,
orderId
} = props.data } = props.data
go.to('PAGES_CRESATE_ORDER_DETAIL', { go.to('PAGES_ORDER_DETAIL', {
tableId, tableId,
name, name,
status, status,
amount, amount,
areaId areaId,
id:orderId
}) })
} }
} }

View File

@@ -1218,6 +1218,22 @@
{ {
"navigationBarTitleText" : "订单详情" "navigationBarTitleText" : "订单详情"
} }
},
{
"pageId": "PAGES_ORDER_PAY",
"path" : "pay-order/pay-order",
"style" :
{
"navigationBarTitleText" : "结账"
}
},
{
"pageId": "PAGES_ORDER_TUIKUAN",
"path" : "tuikuan/tuikuan",
"style" :
{
"navigationBarTitleText" : "退款"
}
} }
] ]

View File

@@ -144,8 +144,7 @@
{ {
title: '成员管理', title: '成员管理',
icon: '/static/indexImg/icon-staff.svg', icon: '/static/indexImg/icon-staff.svg',
pageUrl: 'PAGES_USER', pageUrl: 'PAGES_USER'
entId: 'ENT_UR_USER_LIST'
}, },
{ {
title: '数据中心', title: '数据中心',

View File

@@ -33,8 +33,10 @@
<template #btn> <template #btn>
<view class="u-p-30"> <view class="u-p-30">
<view class="u-m-t-10"> <view class="u-m-t-10">
<my-button @tap="confirm" shape="circle" showShadow>修改</my-button> <my-button @tap="confirm" shape="circle" >修改</my-button>
<my-button @tap="close" type="cancel" bgColor="#fff" >取消</my-button> <view class="">
<my-button @tap="close" type="cancel" bgColor="#fff" >取消</my-button>
</view>
</view> </view>
</view> </view>
</template> </template>
@@ -60,6 +62,10 @@
type: Array, type: Array,
default: [] default: []
}, },
discount:{
type: [Number,String],
default:100
},
price: { price: {
type: [Number,String], type: [Number,String],
default: 0 default: 0
@@ -119,6 +125,9 @@
function open() { function open() {
model.value.open() model.value.open()
form.price=props.price
form.currentPrice=props.price
form.discount=props.discount
} }
function close() { function close() {
@@ -127,11 +136,9 @@
const emits = defineEmits(['confirm']) const emits = defineEmits(['confirm'])
function confirm() { function confirm() {
const { console.log(form);
price, emits('confirm',{...form,currentPrice:Number(form.currentPrice).toFixed(2)})
} = form
close() close()
emits('confirm',form)
} }
defineExpose({ defineExpose({
open, open,

View File

@@ -6,9 +6,10 @@
<view class="u-m-t-24 u-flex u-row-between " @tap="chooseUser"> <view class="u-m-t-24 u-flex u-row-between " @tap="chooseUser">
<view v-if="!user">选择用户</view> <view v-if="!user">选择用户</view>
<view class="u-flex" v-else> <view class="u-flex" v-else>
<view class="headeimg"> <up-avatar :src="user.headImg" shape="square" :size="30"></up-avatar>
<!-- <view class="headeimg">
<image class="img" :src="user.headImg" mode=""></image> <image class="img" :src="user.headImg" mode=""></image>
</view> </view> -->
<view class="u-m-l-20">{{user.nickName}}</view> <view class="u-m-l-20">{{user.nickName}}</view>
<view class="color-main u-m-l-10 u-font-24">{{user.isVip?'会员':'' }}</view> <view class="color-main u-m-l-10 u-font-24">{{user.isVip?'会员':'' }}</view>
<view class="u-font-24 u-m-l-30"><text>余额</text><text class="color-main">{{user.amount}}</text> <view class="u-font-24 u-m-l-30"><text>余额</text><text class="color-main">{{user.amount}}</text>
@@ -16,69 +17,55 @@
<view class="u-font-24 u-m-l-30"><text>积分</text><text <view class="u-font-24 u-m-l-30"><text>积分</text><text
class="color-main">{{user.totalScore}}</text></view> class="color-main">{{user.totalScore}}</text></view>
</view> </view>
<uni-icons type="right" color="#999" size="22"></uni-icons> <uni-icons type="right" color="#999" size="16"></uni-icons>
</view> </view>
</view> </view>
<view class="u-p-b-24 u-m-b-24 border-bottom"> <view class="u-p-b-24 u-m-b-24 border-bottom">
<view>就餐类型</view> <view>就餐类型</view>
<view class="u-m-t-24 u-flex "> <view class="u-m-t-24 u-flex ">
<view class="u-flex color-666"> <view class="u-flex color-666">
<radio-group @change="radioGroupChange"> <up-radio-group v-model="eatTypes.active" placement="row">
<label class="radio u-m-r-60" v-for="(item,index) in eatTypes.list" :key="index"> <up-radio :customStyle="{marginRight: '30px'}" v-for="(item, index) in eatTypes.list"
<radio :value="''+item.value" :checked="item.value == eatTypes.active" :key="index" :label="item.name" :name="item.value">
class="scale7 " /> </up-radio>
<text>{{item.label}}</text> </up-radio-group>
</label>
</radio-group>
</view> </view>
</view> </view>
</view> </view>
<view class="u-p-b-24 u-m-b-24 border-bottom" @tap="chooseTable"> <view class=" " @tap="chooseTable">
<view>选择桌码</view> <view>选择桌码</view>
<view class="u-m-t-24 u-flex u-row-between "> <view class="u-m-t-24 u-flex u-row-between ">
<view> <view>
<text v-if="table">{{table.name}}</text> <text v-if="table">{{table.name}}</text>
<text v-else>不选择桌台</text> <text v-else>不选择桌台</text>
</view> </view>
<uni-icons type="right" color="#999" size="22"></uni-icons> <uni-icons type="right" color="#999" size="16"></uni-icons>
</view> </view>
</view> </view>
</view> </view>
<template v-if="user">
<view class="block"> <view class="block">
<template v-if="!user"> <view class="">
<view class="u-p-b-24 u-m-b-24 border-bottom"> <view class="u-flex border-bottom u-p-b-24 ">
<view>用餐人数</view> <up-avatar :src="user.headImg" shape="square" :size="60"></up-avatar>
<picker @change="userNumberChange" :value="userNumbers.defaultCateIndex" :range="userNumbers.list"> <!-- <image class="headeimg" src="@/static/uni.png" mode=""></image> -->
<view class="u-m-t-24 u-flex u-row-between ">
<view class="color-333">{{userNumbers.defaultCateIndex||''}}</view>
<uni-icons type="right" color="#999" size="22"></uni-icons>
</view>
</picker>
</view>
</template>
<template v-else>
<view>
<view class="u-flex border-bottom u-p-b-24">
<image class="headeimg" src="@/static/uni.png" mode=""></image>
<view class="u-m-l-32"> <view class="u-m-l-32">
<view class="">{{user.name}}</view> <view class="">{{user.nickName}}</view>
<view class="color-main u-font-24">{{user.isVip?'永久会员':'' }}</view> <view class="color-main u-font-24">{{user.isVip?'会员':'' }}</view>
</view> </view>
</view> </view>
<view class="u-flex u-m-t-24 u-row-between u-font-24 color-999"> <view class="u-flex u-m-t-24 u-row-between u-font-24 color-999">
<view class="u-flex"> <view class="u-flex">
<view>余额</view> <view>余额</view>
<view class="color-333 u-m-l-10"> 0.00</view> <view class="color-333 u-m-l-10"> {{user.amount}}</view>
</view> </view>
<view class="u-flex"> <view class="u-flex">
<view>积分</view> <view>积分</view>
<view class="color-333 u-m-l-10"> 0</view> <view class="color-333 u-m-l-10"> {{user.totalScore}}</view>
</view> </view>
<view class="u-flex"> <view class="u-flex">
<view>已消费</view> <view>已消费</view>
@@ -86,10 +73,23 @@
</view> </view>
</view> </view>
</view> </view>
</template> </view>
</template>
<template v-if="$shop.registerType!='restaurant'">
</view> <!-- 不免餐位费 -->
<view class="block">
<view class=" ">
<view>用餐人数</view>
<picker @change="userNumberChange" :value="userNumbers.defaultCateIndex" :range="userNumbers.list">
<view class="u-m-t-24 u-flex u-row-between ">
<view class="color-333">{{userNumbers.defaultCateIndex||''}}</view>
<uni-icons type="right" color="#999" size="16"></uni-icons>
</view>
</picker>
</view>
</view>
</template>
<view class="block"> <view class="block">
<view class="u-p-b-24 "> <view class="u-p-b-24 ">
@@ -150,9 +150,9 @@
<scroll-view scroll-x="true" v-if="index==goods.sel"> <scroll-view scroll-x="true" v-if="index==goods.sel">
<view class="u-m-t-32 u-flex no-wrap"> <view class="u-m-t-32 u-flex no-wrap">
<view class="u-flex u-m-r-20 u-m-b-20"> <!-- <view class="u-flex u-m-r-20 u-m-b-20">
<button class="tag" hover-class="hover-class" @tap="showModel('discount')">单品打折</button> <button class="tag" hover-class="hover-class" @tap="showModel('discount')">单品打折</button>
</view> </view> -->
<view class="u-flex u-m-r-20 u-m-b-20"> <view class="u-flex u-m-r-20 u-m-b-20">
<!-- <button class="tag" hover-class="hover-class" @tap="showModel('giveFood')">赠菜</button> --> <!-- <button class="tag" hover-class="hover-class" @tap="showModel('giveFood')">赠菜</button> -->
<button class="tag" hover-class="hover-class" <button class="tag" hover-class="hover-class"
@@ -177,7 +177,7 @@
<view class="u-flex u-row-between u-m-t-30 u-p-b-34 border-bottom"> <view class="u-flex u-row-between u-m-t-30 u-p-b-34 border-bottom">
<view> <view>
<text v-if="eatTypes.active==2">包装费</text> <text v-if="eatTypes.active=='takeout'">包装费</text>
<text v-else>桌位费</text> <text v-else>桌位费</text>
</view> </view>
<view>{{$seatFee.totalAmount||'0.00'}}</view> <view>{{$seatFee.totalAmount||'0.00'}}</view>
@@ -196,14 +196,16 @@
<view style="height: 300rpx;"></view> <view style="height: 300rpx;"></view>
<view class="safe-bottom fixed"> <view class="safe-bottom fixed">
<view> <!-- <view class="u-m-b-48">
<label class="radio"> <label class="radio">
<radio value="" class="scale7" /><text>打印预结算</text> <radio value="" class="scale7" /><text>打印预结算</text>
</label> </label>
</view> </view> -->
<view class="u-m-t-48 btn"> <view class="btn ">
<my-button shape="circle" @click="createOrder">提交</my-button> <my-button shape="circle" @click="createOrder">
{{$shop.registerType=='munchies'?'结算': '下单'}}
</my-button>
</view> </view>
</view> </view>
@@ -240,7 +242,12 @@
} from '@/commons/utils/format.js'; } from '@/commons/utils/format.js';
import color from '@/commons/color.js'; import color from '@/commons/color.js';
import * as Api from '@/http/yskApi/Instead.js' import * as Api from '@/http/yskApi/Instead.js'
import {getNowCart} from '@/pagesCreateOrder/util.js' import {
tbShopInfo
} from '@/http/yskApi/user.js'
import {
getNowCart
} from '@/pagesCreateOrder/util.js'
const models = new Map(); const models = new Map();
//备注 //备注
let note = ref('') let note = ref('')
@@ -270,16 +277,22 @@
defaultCateIndex: 1, defaultCateIndex: 1,
}) })
watch(() => userNumbers.defaultCateIndex, (newval) => { watch(() => userNumbers.defaultCateIndex, (newval) => {
console.log(newval);
updateChoseCount() updateChoseCount()
}) })
//更新就餐人数 //更新就餐人数
async function updateChoseCount(){ async function updateChoseCount() {
await Api.$choseCount({ console.log($shop.value);
masterId: option.masterId, if($shop.value.registerType!='restaurant'){
tableId: option.tableId, //不免餐位费
num: userNumbers.defaultCateIndex, await Api.$choseCount({
}) masterId: option.masterId,
tableId: option.tableId,
num: userNumbers.defaultCateIndex,
})
}
} }
function userNumberChange(e) { function userNumberChange(e) {
@@ -315,21 +328,17 @@
const eatTypes = reactive({ const eatTypes = reactive({
list: [{ list: [{
label: '堂食', name: "堂食",
value: 1 value: "dine-in",
}, },
{ {
label: '自取', name: "自取",
value: 2 value: "takeout",
}, }
], ],
active: 1 active: 'dine-in'
}) })
function radioGroupChange(e) {
eatTypes.active = e.detail.value
}
function chooseUser() { function chooseUser() {
go.to('PAGES_CHOOSE_USER') go.to('PAGES_CHOOSE_USER')
@@ -343,12 +352,24 @@
// 监听选择用户事件 // 监听选择用户事件
let user = ref(null) let user = ref(null)
//更新选择用户
function setUser(par) {
const submitPar = {
masterId: option.masterId,
tableId: option.tableId,
vipUserId: user.value.id ? user.value.id : '',
type: user.value.id ? 0 : 1 //0 设置 1 取消
}
Object.assign(submitPar, par)
return Api.$setUser(submitPar)
}
function watchChooseuser() { function watchChooseuser() {
uni.$off('choose-user') uni.$off('choose-user')
uni.$on('choose-user', (data) => { uni.$on('choose-user', (data) => {
console.log(data); console.log(data);
user.value = data user.value = data
setUser()
}) })
} }
let table = ref(null) let table = ref(null)
@@ -415,15 +436,24 @@
records, records,
seatFee seatFee
} = await Api.getCart(par) } = await Api.getCart(par)
goods.list =getNowCart(records) goods.list = getNowCart(records)
if(seatFee&&seatFee.totalNumber){ if (seatFee && seatFee.totalNumber) {
userNumbers.defaultCateIndex = seatFee.totalNumber || 1 userNumbers.defaultCateIndex = seatFee.totalNumber || 1
Object.assign($seatFee, seatFee) Object.assign($seatFee, seatFee)
} }
console.log(goods.list); console.log(goods.list);
} }
let $shop = ref()
// 获取账号信息
async function getTbShopInfo() {
const res = await tbShopInfo()
$shop.value = res
console.log(res);
return res
}
// 创建订单 // 创建订单
async function createOrder(par = { async function createOrder(par = {
masterId: option.masterId, masterId: option.masterId,
@@ -435,6 +465,13 @@
}) { }) {
updateChoseCount() updateChoseCount()
const res = await Api.$createOrder(par) const res = await Api.$createOrder(par)
console.log($shop.value);
if($shop.value.registerType=='munchies'){
//先付
return go.to('PAGES_ORDER_DETAIL',{
id:res.id
})
}
uni.showToast({ uni.showToast({
title: '提交成功', title: '提交成功',
icon: 'none' icon: 'none'
@@ -453,10 +490,36 @@
if (opt) { if (opt) {
table.value = { table.value = {
tableId: opt.tableId, tableId: opt.tableId,
name: opt.tableName name: opt.name
} }
} }
getCart() getCart()
getTbShopInfo()
updateChoseCount()
})
async function changeUseType() {
const {
registerType
} = $shop.value
//munchies 先付 restaurant 后付
const isPayAfter = registerType == "munchies" ? false : true;
let useType = "takeout";
if (eatTypes.active == "takeout") {
uni.setStorageSync("useType", "takeout");
} else {
//堂食
useType = `dine-in-${isPayAfter? "after" : "before"}`;
uni.setStorageSync("useType", useType);
}
const res = await Api.$changeUseType({
useType,
cartIds: goods.list.map((v) => v.id),
})
return res
}
watch(() => eatTypes.active, (newval) => {
changeUseType()
}) })
onBeforeUnmount(() => { onBeforeUnmount(() => {

View File

@@ -2,7 +2,18 @@
<view class="u-wrap"> <view class="u-wrap">
<view class="top bg-fff w-full"> <view class="top bg-fff w-full">
<view class="u-flex u-row-between choose-user" @tap="chooseUser"> <view class="u-flex u-row-between choose-user" @tap="chooseTable">
<view>
<view v-if="!data.table.tableId">选择桌台</view>
<view class="u-flex" v-else>
<view class="u-m-l-20">{{data.table.name}}</view>
</view>
</view>
<view class="u-flex">
<uni-icons type="right" size="20" color="#999"></uni-icons>
</view>
</view>
<!-- <view class="u-flex u-row-between choose-user" @tap="chooseUser">
<view> <view>
<view v-if="!data.vipUser.id">选择用户</view> <view v-if="!data.vipUser.id">选择用户</view>
<view class="u-flex" v-else> <view class="u-flex" v-else>
@@ -20,7 +31,7 @@
<view class="u-flex"> <view class="u-flex">
<uni-icons type="right" size="20" color="#999"></uni-icons> <uni-icons type="right" size="20" color="#999"></uni-icons>
</view> </view>
</view> </view> -->
<view class="search u-flex u-col-center "> <view class="search u-flex u-col-center ">
<view class="u-flex-1"> <view class="u-flex-1">
<uni-search-bar bgColor="#F9F9F9" cancelButton="none" placeholder="搜索店内商品" @confirm="search" <uni-search-bar bgColor="#F9F9F9" cancelButton="none" placeholder="搜索店内商品" @confirm="search"
@@ -86,6 +97,7 @@
<script setup> <script setup>
import _ from 'lodash'; import _ from 'lodash';
import * as Api from '@/http/yskApi/Instead.js' import * as Api from '@/http/yskApi/Instead.js'
import {$table} from '@/http/yskApi/table.js'
import { import {
$tbShopCategory $tbShopCategory
} from '@/http/yskApi/goods.js' } from '@/http/yskApi/goods.js'
@@ -107,12 +119,15 @@
computed, computed,
reactive, reactive,
ref, ref,
nextTick nextTick,
watch
} from 'vue'; } from 'vue';
import myCar from './components/car' import myCar from './components/car'
import go from '@/commons/utils/go.js'; import go from '@/commons/utils/go.js';
import infoBox from '@/commons/utils/infoBox.js'; import infoBox from '@/commons/utils/infoBox.js';
import {getNowCart} from '@/pagesCreateOrder/util.js' import {
getNowCart
} from '@/pagesCreateOrder/util.js'
const cars = reactive([]) const cars = reactive([])
const data = reactive({ const data = reactive({
scrollTop: 0, //tab标题的滚动条位置 scrollTop: 0, //tab标题的滚动条位置
@@ -294,16 +309,23 @@
} }
//获取台桌信息
async function getTableInfo(){
const res=await $table.get({qrcode:data.table.tableId})
console.log(res);
if(res&&res.content[0]){
// data.table=res.content[0]
}
}
async function init() { async function init() {
getTableInfo()
const { const {
masterId masterId
} = await getMasterId() } = await getMasterId()
data.masterId = masterId data.masterId = masterId
const cartRes = await getCart() const cartRes = await getCart()
cars.length = 0 cars.length = 0
const cartArr =getNowCart(cartRes.records) const cartArr = getNowCart(cartRes.records)
for (let i in cartArr) { for (let i in cartArr) {
cars.push(cartArr[i]) cars.push(cartArr[i])
} }
@@ -351,13 +373,27 @@
let searchValue = ref('') let searchValue = ref('')
function search() { function search() {
console.log(searchValue.value);
console.log(data.tabbar );
} }
function chooseUser() { function chooseUser() {
go.to('PAGES_CHOOSE_USER') go.to('PAGES_CHOOSE_USER')
} }
function chooseTable() {
go.to('PAGES_CHOOSE_TABLE', {
...data.table
})
}
function watchChooseTable() {
uni.$off('choose-table')
uni.$on('choose-table', (tableData) => {
data.table = tableData
})
}
function toLinshi() { function toLinshi() {
go.to('PAGES_ADD_TEMP_CUISINE') go.to('PAGES_ADD_TEMP_CUISINE')
} }
@@ -499,7 +535,7 @@
prve[i] = matchArr prve[i] = matchArr
.filter((v) => v.specSnap.match(i)) .filter((v) => v.specSnap.match(i))
.every((v) => { .every((v) => {
return util.isCanBuy(v) return !util.isCanBuy(v)
}); });
} }
} }
@@ -801,9 +837,14 @@
setUser() setUser()
}) })
} }
watch(()=>data.table.tableId,(newval)=>{
console.log(newval);
init()
})
onBeforeUnmount(() => {}) onBeforeUnmount(() => {})
onShow(() => { onShow(() => {
watchChooseuser() // watchChooseuser()
watchChooseTable()
}) })
onLoad((opt) => { onLoad((opt) => {
console.log(opt) console.log(opt)

View File

@@ -12,7 +12,7 @@
<view class="item u-m-b-20" v-for="(item,index) in order.info" :key="index"> <view class="item u-m-b-20" v-for="(item,index) in order.info" :key="index">
<view class="u-flex u-col-top"> <view class="u-flex u-col-top">
<view> <view>
<image class="img" :src="item.coverImg" mode=""></image> <image class="img" :src="item.coverImg||item.productImg" mode=""></image>
</view> </view>
<view class="u-p-l-30 u-flex-1"> <view class="u-p-l-30 u-flex-1">
<view class="u-flex u-row-between u-col-top"> <view class="u-flex u-row-between u-col-top">
@@ -21,20 +21,27 @@
<view class="tui" v-if="item.status=='return'"> <view class="tui" v-if="item.status=='return'">
已退 已退
</view> </view>
<view :class="{'line-th':item.status=='return'}">{{item.name}}</view> <view :class="{'line-th':item.status=='return'}">{{item.name||item.productName}}</view>
</view> </view>
<view class="u-text-right"> <view class="u-text-right">
<view>{{item.salePrice}}</view> <view>{{item.salePrice||item.price}}</view>
<view v-if="item.status=='return'" class="line-th color-666 u-font-24">{{item.salePrice}}</view> <view v-if="item.status=='return'" class="line-th color-666 u-font-24">{{item.salePrice||item.price}}</view>
<view class="u-m-t-10 u-font-24">X{{item.number}}</view> <view class="u-m-t-10 u-font-24">X{{item.number||item.num}}</view>
</view> </view>
</view> </view>
</view> </view>
</view> </view>
<view class="u-flex u-row-right gap-20 u-m-t-20" v-if="item.status!='return'"> <template v-if="orderInfo.status=='unpaid'">
<!-- <my-button :height="60" color="#333" plain type="cancel" shape="circle">更多操作</my-button> --> <view class="u-flex u-row-right gap-20 u-m-t-20" v-if="item.status!='return'">
<my-button :width="168" :height="60" plain shape="circle" @tap="tuicai(item,index)">退菜</my-button> <!-- <my-button :height="60" color="#333" plain type="cancel" shape="circle">更多操作</my-button> -->
</view> <my-button :width="168" :height="60" plain shape="circle" @tap="tuicai(item,index)">退菜</my-button>
</view>
</template>
<template v-if="orderInfo.status=='closed'">
<view class="u-flex u-row-right gap-20 u-m-t-20" v-if="item.status!='return'">
<my-button :width="168" :height="60" plain shape="circle" @tap="tuikuan(item,index)">退款</my-button>
</view>
</template>
</view> </view>
</view> </view>
<view class="bg-gray u-p-20 u-m-t-20"> <view class="bg-gray u-p-20 u-m-t-20">
@@ -45,9 +52,15 @@
<view class="u-m-t-40"> <view class="u-m-t-40">
<view class="u-flex u-row-between border-bottom u-p-b-20"> <view class="u-flex u-row-between border-bottom u-p-b-20">
<view class="tag no-pay"> <view>
未支付 <template v-if="orderInfo.status=='unpaid'">
<view class="tag no-pay">
未支付
</view>
</template>
</view> </view>
<view> <view>
<text>小计</text> <text>小计</text>
<text class="font-bold u-font-32">{{allPrice}}</text> <text class="font-bold u-font-32">{{allPrice}}</text>
@@ -73,11 +86,21 @@
computed computed
} from 'vue'; } from 'vue';
import color from '@/commons/color.js' import color from '@/commons/color.js'
const emits=defineEmits(['tuicai']) const emits=defineEmits(['tuicai','tuikuan','printOrder'])
function tuicai(item,index){ function tuicai(item,index){
emits('tuicai',item,index) emits('tuicai',item,index)
} }
function tuikuan(item,index){
emits('tuikuan',item,index)
}
function printOrder(){
emits('printOrder')
}
const props = defineProps({ const props = defineProps({
orderInfo:{
type: Object,
default: () => {}
},
data: { data: {
type: Array, type: Array,
default: () => [] default: () => []
@@ -90,7 +113,7 @@
const allPrice = computed(() => { const allPrice = computed(() => {
return props.data.reduce((prve, cur) => { return props.data.reduce((prve, cur) => {
const curTotal=cur.info.filter(v=>v.isGift !== "true"&& v.status !== "return").reduce((a,b)=>{ const curTotal=cur.info.filter(v=>v.isGift !== "true"&& v.status !== "return").reduce((a,b)=>{
return a+b.salePrice * b.number return a+(b.salePrice||b.price) * (b.number||b.num)
},0) },0)
return prve + curTotal return prve + curTotal
}, 0).toFixed(2) }, 0).toFixed(2)
@@ -100,15 +123,13 @@
let result = 0 let result = 0
result = props.data.reduce((a, b) => { result = props.data.reduce((a, b) => {
const bTotal = b.info.reduce((prve, cur) => { const bTotal = b.info.reduce((prve, cur) => {
return prve + cur.number * 1; return prve + (cur.number||cur.num) * 1;
}, 0); }, 0);
return a + bTotal return a + bTotal
}, 0) }, 0)
return result return result
}) })
function printOrder(){
}
</script> </script>
<style lang="scss" scoped> <style lang="scss" scoped>

View File

@@ -10,15 +10,15 @@
</view> </view>
<view class="u-flex u-row-between u-m-t-20"> <view class="u-flex u-row-between u-m-t-20">
<view>桌位号</view> <view>桌位号</view>
<view>{{table.name}}</view> <view>{{table.name||data.tableName}}</view>
</view> </view>
<view class="u-flex u-row-between u-m-t-20"> <view class="u-flex u-row-between u-m-t-20">
<view>就餐人数</view> <view>就餐人数</view>
<view>{{seatFee.totalNumber}}</view> <view>{{seatFee.number||''}}</view>
</view> </view>
<view class="u-flex u-row-between u-m-t-20"> <view class="u-flex u-row-between u-m-t-20">
<view>支付方式</view> <view>支付方式</view>
<view></view> <view>{{data.payType||''}}</view>
</view> </view>
<view class="u-flex u-row-between u-m-t-20"> <view class="u-flex u-row-between u-m-t-20">
<view>预约时间</view> <view>预约时间</view>

View File

@@ -1,11 +1,12 @@
<template> <template>
<view class="default-box-padding bg-fff border-r-12 u-m-t-20"> <view class="default-box-padding bg-fff border-r-12 u-m-t-20">
<up-steps :dot="true" current="0" direction="column"> <my-step :list="recoders.list"></my-step>
<!-- <up-steps :dot="true" current="0" direction="column">
<up-steps-item title="2024-09-02 09:19" :itemStyle="itemStyle" desc="[东风(id:124413)]使用代客下单提交。(未打印预结单)"> <up-steps-item title="2024-09-02 09:19" :itemStyle="itemStyle" desc="[东风(id:124413)]使用代客下单提交。(未打印预结单)">
</up-steps-item> </up-steps-item>
<up-steps-item title="2024-09-02 09:19" desc="[东风(id:124413)]使用代客下单提交。(未打印预结单)"> <up-steps-item title="2024-09-02 09:19" desc="[东风(id:124413)]使用代客下单提交。(未打印预结单)">
</up-steps-item> </up-steps-item>
</up-steps> </up-steps> -->
</view> </view>
@@ -19,7 +20,14 @@
const itemStyle = reactive({ const itemStyle = reactive({
color: 'rgb(255,0,0)' color: 'rgb(255,0,0)'
}) })
const recoders = reactive({
list:[
{title:'2024-09-15 112030',content:'[东风(id:124413)]使用代客下单提交。(未打印预结单)'},
{title:'2024-09-15 ',content:'[东风(id:124413)]使用代客下单提交。(未打印预结单)'},
{title:'2024-09-15 ',content:'[东风(id:124413)]使用代客下单提交。(未打印预结单)'}
],
active:0
})
</script> </script>
<style> <style>

View File

@@ -1,6 +1,8 @@
<template> <template>
<view class="u-font-28 default-box-padding u-relative bg-fff border-r-12 u-overflow-hide"> <view class="u-font-28 default-box-padding u-relative bg-fff border-r-12 u-overflow-hide">
<view class="change u-absolute my-bg-main color-fff left-top" >切换</view> <template v-if="orderInfo.status=='unpaid'">
<view class="change u-absolute my-bg-main color-fff left-top" @click="chooseUser">切换</view>
</template>
<view class="u-flex u-row-between u-m-t-20 border-bottom u-p-b-20"> <view class="u-flex u-row-between u-m-t-20 border-bottom u-p-b-20">
<view class="u-flex"> <view class="u-flex">
<up-avatar :size="30"></up-avatar> <up-avatar :size="30"></up-avatar>
@@ -27,14 +29,28 @@
</view> </view>
</template> </template>
<script> <script setup>
import go from '@/commons/utils/go.js'
const props = defineProps({
orderInfo: {
type: Object,
default: () => {}
},
user: {
type: Object,
default: () => {}
}
})
function chooseUser() {
go.to('PAGES_CHOOSE_USER')
}
</script> </script>
<style lang="scss" scoped> <style lang="scss" scoped>
.change{ .change {
padding: 4rpx 16rpx; padding: 4rpx 16rpx;
border-radius: 0 0 16rpx 0; border-radius: 0 0 16rpx 0;
z-index: 2; z-index: 2;
} }
</style> </style>

View File

@@ -1,11 +1,11 @@
<template> <template>
<view class="min-page bg-gray u-font-28 u-p-30"> <view class="min-page bg-gray u-font-28 u-p-30">
<user-vue></user-vue> <user-vue :orderInfo="orderDetail.info"></user-vue>
<view class="default-box-padding bg-fff border-r-12 u-m-t-20"> <view class="default-box-padding bg-fff border-r-12 u-m-t-20">
<text class="color-666">桌位号</text> <text class="color-666">桌位号</text>
<text class="font-bold">{{options.name}}</text> <text class="font-bold">{{orderDetail.info.tableName}}</text>
</view> </view>
<goods-list :data="orderDetail.goodsList" :seatFee="orderDetail.seatFee.totalAmount" <goods-list @printOrder="onPrintOrder" @tuikuan="onTuikuan" :orderInfo="orderDetail.info" :data="orderDetail.goodsList" :seatFee="orderDetail.seatFee.totalAmount"
@tuicai="onTuiCai"></goods-list> @tuicai="onTuiCai"></goods-list>
<extra-vue :data="orderDetail.seatFee"></extra-vue> <extra-vue :data="orderDetail.seatFee"></extra-vue>
<order-vue :data="orderDetail.info" :table="options" :seatFee="orderDetail.seatFee"></order-vue> <order-vue :data="orderDetail.info" :table="options" :seatFee="orderDetail.seatFee"></order-vue>
@@ -23,7 +23,7 @@
type="primary">结账</my-button> type="primary">结账</my-button>
</view> </view>
</template> </template>
</view> </view>
</view> </view>
@@ -34,6 +34,9 @@
<script setup> <script setup>
import * as Api from '@/http/yskApi/Instead.js' import * as Api from '@/http/yskApi/Instead.js'
import * as orderApi from '@/http/yskApi/order.js' import * as orderApi from '@/http/yskApi/order.js'
import {
objToArrary
} from '@/commons/utils/returrn-data.js'
import userVue from './components/user.vue'; import userVue from './components/user.vue';
import orderVue from './components/order.vue'; import orderVue from './components/order.vue';
import goodsList from './components/list.vue'; import goodsList from './components/list.vue';
@@ -41,13 +44,14 @@
import extraVue from './components/extra.vue'; import extraVue from './components/extra.vue';
import tuicaiVue from './components/tuicai.vue'; import tuicaiVue from './components/tuicai.vue';
import go from '@/commons/utils/go.js' import go from '@/commons/utils/go.js'
import infoBox from '@/commons/utils/infoBox.js'
import { import {
onLoad, onLoad,
onShow, onShow,
onHide onHide
} from '@dcloudio/uni-app'; } from '@dcloudio/uni-app';
import { import {
reactive reactive, ref
} from 'vue'; } from 'vue';
import OrderDetail from './page.js' import OrderDetail from './page.js'
const tuicai = reactive({ const tuicai = reactive({
@@ -59,13 +63,42 @@
tuicai.show = true tuicai.show = true
tuicai.selGoods = goods tuicai.selGoods = goods
} }
async function printDishes(){
try{
const res= await Api.$printDishes({
tableId:orderDetail.info.tableId
})
infoBox.showToast('已发送打印请求')
}catch(e){
infoBox.showToast('发送打印请求失败')
//TODO handle the exception
}
}
function onPrintOrder(){
uni.showModal({
title:'提示',
content:'是否打印当前台桌菜品',
success(res) {
if(res.confirm){
printDishes()
}
}
})
}
function onTuikuan(goods, index){
go.to('PAGES_ORDER_TUIKUAN',{
})
}
async function tuicaiConfirm() { async function tuicaiConfirm() {
const res=await Api.$returnCart({ const res = await Api.$returnCart({
cartId: tuicai.selGoods.id, cartId: tuicai.selGoods.cartId,
tableId:options.tableId, tableId: orderDetail.info.tableId,
}) })
tuicai.selGoods.status='return' tuicai.selGoods.status = 'return'
tuicai.show = false tuicai.show = false
} }
const uiPage = new OrderDetail() const uiPage = new OrderDetail()
@@ -84,7 +117,7 @@
} }
function toPay() { function toPay() {
go.to('PAGES_CRESATE_ORDER_PAY', { go.to('PAGES_ORDER_PAY', {
tableId: options.tableId, tableId: options.tableId,
tableName: options.name, tableName: options.name,
masterId: options.masterId, masterId: options.masterId,
@@ -102,22 +135,48 @@
}) })
const options = reactive({}) const options = reactive({})
async function init() { async function init() {
const res= await orderApi.tbOrderInfoDetail(options.id) const res = await orderApi.tbOrderInfoDetail(options.id)
const masterId=res.masterId const masterId = res.masterId
options.masterId = res.masterId options.masterId = res.masterId
if(res.status=='unpaid'){ if (res.status == 'unpaid') {
// if (false) {
const { const {
records, records,
seatFee seatFee
} = await Api.getCart({ } = await Api.getCart({
masterId, masterId,
tableId:res.tableId tableId: res.tableId,
page: 1,
size: 200
}) })
orderDetail.goodsList = records orderDetail.goodsList = records
orderDetail.seatFee = seatFee orderDetail.seatFee = seatFee ? seatFee : orderDetail.seatFee
}else{ } else {
orderDetail.goodsList = res.detailList const goodsMap = {}
for (let i in res.detailList) {
const goods = res.detailList[i]
if (goods.productName != '客座费') {
if (goodsMap.hasOwnProperty(goods.placeNum)) {
goodsMap[goods.placeNum].push(goods)
} else {
goodsMap[goods.placeNum] = [goods]
}
}
}
orderDetail.seatFee = {
name: '餐位费',
number: res.seatCount,
totalNumber: res.seatCount,
totalAmount: res.seatAmount
}
orderDetail.goodsList = Object.entries(goodsMap).map(([key, value]) => ({
info: value,
placeNum: key
}))
console.log(orderDetail.goodsList);
} }
console.log(orderDetail);
orderDetail.info = res orderDetail.info = res
} }
@@ -128,8 +187,32 @@
init() init()
}) })
} }
// 监听选择用户事件
let user = ref(null)
//更新选择用户
function setUser(par) {
const submitPar = {
masterId: option.masterId,
tableId: option.tableId,
vipUserId: user.value.id ? user.value.id : '',
type: user.value.id ? 0 : 1 //0 设置 1 取消
}
Object.assign(submitPar, par)
return Api.$setUser(submitPar)
}
function watchChooseuser() {
uni.$off('choose-user')
uni.$on('choose-user', (data) => {
console.log(data);
user.value = data
setUser()
})
}
onShow(() => { onShow(() => {
watchEmit() watchEmit()
watchChooseuser()
}) })
onLoad((opt) => { onLoad((opt) => {
Object.assign(options, opt) Object.assign(options, opt)

View File

@@ -22,7 +22,7 @@
<view class="u-m-l-16">{{formatTime(data.createdAt)}}</view> <view class="u-m-l-16">{{formatTime(data.createdAt)}}</view>
</view> </view>
<view class="u-m-t-32"> <view class="u-m-t-32">
<view class="u-font-32">1种商品共1</view> <view class="u-font-32">{{goosZhonglei}}种商品{{goodsNumber}}</view>
<view class="border-bottom u-p-b-32"> <view class="border-bottom u-p-b-32">
<view class="u-flex u-row-between u-m-t-24" v-for="(item,index) in data.detailList" :key="index"> <view class="u-flex u-row-between u-m-t-24" v-for="(item,index) in data.detailList" :key="index">
<view> <view>
@@ -32,12 +32,12 @@
</view> </view>
</view> </view>
<view class="u-flex"> <view class="u-flex">
<view>×1</view> <view>×{{item.num}}</view>
<view class="u-m-l-24">15.00</view> <view class="u-m-l-24">{{item.price}}</view>
</view> </view>
</view> </view>
</view> </view>
</view> </view>
<view class="u-flex u-row-between border-bottom u-m-t-32 u-p-b-32"> <view class="u-flex u-row-between border-bottom u-m-t-32 u-p-b-32">
<view>订单备注</view> <view>订单备注</view>
@@ -49,7 +49,7 @@
<text class="font-bold u-font-32">{{data.orderAmount}}</text> <text class="font-bold u-font-32">{{data.orderAmount}}</text>
</view> </view>
<view class="u-flex u-row-right u-m-t-24"> <view class="u-flex u-row-right u-m-t-24">
<view class="print">重新打印</view> <view class="print" @click.stop="print(item)">重新打印</view>
</view> </view>
</view> </view>
</view> </view>
@@ -60,19 +60,51 @@
import dayjs from 'dayjs'; import dayjs from 'dayjs';
import orderEnum from '@/commons/orderEnum.js' import orderEnum from '@/commons/orderEnum.js'
import go from '@/commons/utils/go.js' import go from '@/commons/utils/go.js'
import {
computed,
reactive,
ref,
watch
} from 'vue';
const emits=defineEmits(['printOrder'])
const props = defineProps({ const props = defineProps({
data: { data: {
type: Object, type: Object,
default: () => {} default: () => {
detailList: []
}
}, },
index: { index: {
type: [String, Number], type: [String, Number],
default: 0 default: 0
} }
}) })
function formatTime(time){ let $goodsMap = {}
let goosZhonglei =ref(0)
let goodsNumber = ref(0)
function goodsMapInit(){
for (let i in props.data.detailList) {
const goods = props.data.detailList[i]
if ($goodsMap.hasOwnProperty(goods.productId)) {
$goodsMap[goods.productId] += goods.num*1
goodsNumber.value+=goods.num*1
} else {
$goodsMap[goods.productId] = goods.num*1
goosZhonglei.value+=1
goodsNumber.value+=goods.num*1
}
}
}
goodsMapInit()
watch(() => props.data.detailList, (newval) => {
goodsMapInit()
})
function formatTime(time) {
return dayjs(time).format('YYYY-MM-DD HH:mm:ss'); return dayjs(time).format('YYYY-MM-DD HH:mm:ss');
} }
function returnStatus(status) { function returnStatus(status) {
const item = orderEnum.status.find(v => v.key == status) const item = orderEnum.status.find(v => v.key == status)
return item ? item.label : '' return item ? item.label : ''
@@ -85,11 +117,15 @@
return t; return t;
} }
} }
function toDetail(){
go.to('PAGES_ORDER_DETAIL',{ function toDetail() {
id:props.data.id go.to('PAGES_ORDER_DETAIL', {
id: props.data.id
}) })
} }
function print(item) {
emits('printOrder',props.data)
}
</script> </script>
<style lang="scss" scoped> <style lang="scss" scoped>
@@ -110,10 +146,11 @@
.unpaid { .unpaid {
color: #FD7B49; color: #FD7B49;
} }
.print{
.print {
padding: 6rpx 14rpx 8rpx 18rpx; padding: 6rpx 14rpx 8rpx 18rpx;
border:1px solid $my-main-color; border: 1px solid $my-main-color;
color:$my-main-color; color: $my-main-color;
font-size: 24rpx; font-size: 24rpx;
border-radius: 100rpx; border-radius: 100rpx;
} }

View File

@@ -1,7 +1,7 @@
<template> <template>
<view class="list"> <view class="list">
<view v-for="(item,index) in list" :key="index"> <view v-for="(item,index) in list" :key="index">
<order-item :data="item" :index="index"></order-item> <order-item @printOrder="print" :data="item" :index="index"></order-item>
</view> </view>
<view v-if="hasAjax&&!list.length"> <view v-if="hasAjax&&!list.length">
<my-img-empty tips="亲,你还没有订单哦~"></my-img-empty> <my-img-empty tips="亲,你还没有订单哦~"></my-img-empty>
@@ -21,7 +21,10 @@
default:false default:false
} }
}) })
const emits=defineEmits(['printOrder'])
function print(item) {
emits('printOrder',item)
}
</script> </script>
<style lang="scss" scoped> <style lang="scss" scoped>

View File

@@ -6,14 +6,18 @@
</view> </view>
<filter-vue v-model:time="pageData.order.query.createdAt"></filter-vue> <filter-vue v-model:time="pageData.order.query.createdAt"></filter-vue>
</view> </view>
<order-list :hasAjax="pageData.order.hasAjax" :list="pageData.order.list"></order-list> <order-list @printOrder="onPrintOrder" :hasAjax="pageData.order.hasAjax" :list="pageData.order.list"></order-list>
<my-pagination :totalElements="pageData.order.totalElements"></my-pagination>
<view style="height: 100rpx;"></view>
</view> </view>
</template> </template>
<script setup> <script setup>
import * as Api from '@/http/yskApi/order.js' import * as Api from '@/http/yskApi/order.js'
import {$printOrder} from '@/http/yskApi/Instead.js'
import filterVue from './compoents/filter.vue'; import filterVue from './compoents/filter.vue';
import orderList from './compoents/order-list.vue'; import orderList from './compoents/order-list.vue';
import infoBox from '@/commons/utils/infoBox.js'
import { import {
reactive, watch reactive, watch
} from 'vue'; } from 'vue';
@@ -28,10 +32,11 @@
textAlign: 'right' textAlign: 'right'
} }
}) })
const pageData = reactive({ const pageData = reactive({
order: { order: {
list: [], list: [],
totalElements:0,
hasAjax:false, hasAjax:false,
query: { query: {
createdAt: [], createdAt: [],
@@ -50,12 +55,40 @@
init() init()
}) })
async function init() { async function init() {
const {content}=await Api.tbOrderInfoData(pageData.order.query) const {content,totalElements}=await Api.tbOrderInfoData(pageData.order.query)
pageData.order.hasAjax=true pageData.order.hasAjax=true
pageData.order.totalElements=totalElements
pageData.order.list=content pageData.order.list=content
console.log(content); console.log(content);
} }
init() init()
async function printOrder(item){
try{
console.log(item);
const res= await $printOrder({
tableId:item.tableId
})
infoBox.showToast('已发送打印请求')
}catch(e){
console.log(e);
infoBox.showToast('发送打印请求失败')
//TODO handle the exception
}
}
function onPrintOrder(e){
console.log(e);
uni.showModal({
title: '提示',
content: '是否打印该订单',
success(res) {
if (res.confirm) {
printOrder(e)
}
}
})
}
</script> </script>
<style> <style>

View File

@@ -0,0 +1,320 @@
<template>
<view class="bg-gray min-page u-p-30 u-font-28">
<view class="u-p-t-60 u-p-b-60 u-text-center">
<view class="u-font-32 ">
<text class="price-fuhao"></text>
<text class="font-bold price">{{discount.currentPrice?discount.currentPrice:order.amount}}</text>
</view>
<view class="u-m-t-10 color-999 old-price">
<text class=""></text>
<text class=" ">{{order.amount}}</text>
</view>
<view class="u-m-t-10 u-flex u-row-center color-main">
<view @click="showModel('editMoney',true)">修改</view>
</view>
</view>
<view class="content bg-fff box-shadow border-r-12">
<view class=" u-p-t-30 u-p-l-26 u-p-r-26 card top u-m-t-30">
<view class="u-flex u-p-l-24 u-p-r-24 border-bottom-dashed u-row-between u-p-b-30">
<view>优惠券</view>
<view class="color-999 u-flex u-col-center">
<text>选择优惠券</text>
<view class="u-flex u-col-center">
<uni-icons type="right" color="#999"></uni-icons>
</view>
</view>
</view>
<view class="u-flex u-p-l-24 u-p-r-24 border-bottom u-row-between u-p-t-30 u-p-b-30"
v-if="discount.price&&discount.currentPrice!=order.amount">
<view>服务员改价</view>
<view class=" u-flex u-col-center">
<text style="color: rgb(255, 95, 46);">-{{order.amount- discount.currentPrice}}</text>
</view>
</view>
</view>
<view class="bg-fff border-r-12 ">
<view class="u-p-t-30 u-p-l-50 u-p-r-50 card bottom">
<my-tabs :list="pays.list" v-model="pays.selIndex"></my-tabs>
<template v-if="pays.selIndex==0">
<view class="list">
<view class="item" @click="changePayType(index)" v-for="(item,index) in pays.payTypes.list"
:key="index">
<view class="u-flex u-row-between u-p-t-30 u-p-b-30 border-bottom">
<view class="u-flex">
<image class="icon" :src="item.icon" mode=""></image>
<text class="u-m-l-10">{{item.payName}}</text>
</view>
<view class="u-flex color-999 u-font-24">
<!-- <view class="u-m-r-20">
<text>余额</text>
<text>0.00</text>
</view> -->
<my-radio @click="changePayType(index)" :modelValue="index==pays.payTypes.selIndex">
</my-radio>
</view>
</view>
</view>
</view>
<view class="u-m-t-60 u-p-b-30">
<my-button @click="payOrder">确认付款</my-button>
</view>
</template>
<template v-else>
<view class="">
<view class="u-font-32 u-m-t-40 u-text-center">请让顾客使用微信扫码</view>
<view class="u-flex u-row-center u-m-t-40 ">
<up-qrcode :size="140" val="uview-plus"></up-qrcode>
</view>
</view>
</template>
</view>
<!-- 二维码支付扫码 -->
<template v-if="pays.selIndex==1">
<view class="card border-bottom top u-m-t-32">
</view>
<view class="bg-fff card bottom border-r-12 u-p-32">
<view class="font-bold u-font-32 u-text-center">
{{discount.currentPrice?discount.currentPrice: order.amount}}</view>
<view class="u-flex u-row-center u-m-t-24">
<up-loading-icon size="14" text="等待支付"></up-loading-icon>
<view class="u-flex pay-success">
<up-icon color="#5CBB6F" name="checkmark-circle-fill"></up-icon>
<view class="u-m-l-6">支付成功</view>
</view>
</view>
</view>
</template>
</view>
</view>
<edit-discount @confirm="editDiscountConfirm" title="优惠金额" :ref="setModel" name="editMoney"
:price="order.amount"></edit-discount>
</view>
</template>
<script setup>
import {
reactive,
onMounted,
watch,
ref
} from 'vue';
import {
onLoad
} from '@dcloudio/uni-app'
import * as Api from '@/http/yskApi/Instead.js'
import * as orderApi from '@/http/yskApi/order.js'
import infoBox from '@/commons/utils/infoBox.js'
import editDiscount from '@/pagesCreateOrder/components/edit-discount.vue'
let payStatus = ref(null) //loading success
const pays = reactive({
list: ['扫码收款', '二维码收款'],
selIndex: 0,
payTypes: {
list: [],
selIndex: 0
}
})
const models = new Map();
function setModel(el) {
if (el && el.$attrs['name']) {
models.set(el.$attrs['name'], el);
}
}
function showModel(key) {
const model = models.get(key)
model && model.open()
}
//打折相关数据
const discount = reactive({
})
function editDiscountConfirm(form) {
console.log(form);
Object.assign(discount, form)
}
async function getPayType() {
const payTypeList = await Api.$getPayType()
pays.payTypes.list = payTypeList
}
function changePayType(i) {
pays.payTypes.selIndex = i
}
//支付成功回调
function paySuccess() {
infoBox.showToast('支付成功')
setTimeout(() => {
// uni.$emit('orderDetail:update')
uni.navigateBack({
delta: 2
})
}, 500)
}
async function payOrder() {
const payType = pays.payTypes.list[pays.payTypes.selIndex].payType
await Api.$payOrder({
tableId: order.tableId,
masterId: order.masterId,
orderId: order.id || order.orderId,
payType,
vipUserId: order.userId,
discount: 1,
code: ''
})
paySuccess()
}
onMounted(() => {
getPayType()
})
const order = reactive({
amount: 0
})
function saomaPay() {
const item = pays.payTypes.list[pays.payTypes.selIndex]
uni.scanCode({
onlyFromCamera: true,
success: function(res) {
console.log('条码类型:' + res.scanType);
console.log('条码内容:' + res.result);
Api.$payOrder({
"orderId": order.orderId, // 订单id
"payType": item.payType, //
"discount": order.discount,
"code": res.result
}).then(res => {
console.log(res);
paySuccess()
})
}
});
}
watch(() => pays.payTypes.selIndex, (newval) => {
const item = pays.payTypes.list[newval]
if (item.payType == "vipPay") {
return
}
if (item.payType == "deposit") {
//储值卡支付
return saomaPay('deposit')
}
if (item.payType == "scanCode") {
//扫码支付
return saomaPay('scanCode')
}
})
async function init() {
const res = await orderApi.tbOrderInfoDetail(order.orderId)
Object.assign(order, res)
}
onLoad((opt) => {
Object.assign(order, opt)
init()
})
</script>
<style lang="scss" scoped>
.box-shadow {
box-shadow: 0 0 5px #E5E5E5;
}
.pay-success {
color: #5CBB6F;
}
.icon {
width: 40rpx;
height: 40rpx;
}
.border-bottom-dashed {
border-bottom: 1px dashed #bbb;
}
.border-bottom {
border-color: rgb(240, 240, 240);
}
.list {
.item:last-child {
.border-bottom {
border-bottom: none;
}
}
}
.old-price {
text-decoration: line-through;
}
.price-fuhao {
font-size: 24px;
}
.price {
font-size: 32px;
}
$dotSize: 20rpx;
$position: calc($dotSize / (-2));
.card {
position: relative;
&::after,
&:before {
content: '';
display: block;
position: absolute;
background-color: #F9F9F9;
width: $dotSize;
height: $dotSize;
border-radius: 50%;
}
&.top {
&::after {
right: $position;
bottom: $position;
}
&:before {
left: $position;
bottom: $position;
}
}
&.bottom {
&::after {
right: $position;
top: $position;
}
&:before {
left: $position;
top: $position;
}
}
}
</style>

View File

@@ -0,0 +1,22 @@
<template>
<view>
</view>
</template>
<script>
export default {
data() {
return {
}
},
methods: {
}
}
</script>
<style>
</style>