This commit is contained in:
duan 2024-10-10 15:22:48 +08:00
commit 82ad5973fb
21 changed files with 743 additions and 205 deletions

View File

@ -0,0 +1,163 @@
import {
$hasPermission
} from '@/http/yskApi/shop.js'
import infoBox from '@/commons/utils/infoBox.js'
const $PermissionObj = {
data: [{
key: 'yun_xu_cha_kan_jing_ying_shu_ju',
text: '允许查看经营数据'
},
{
key: 'yun_xu_cha_kan_suo_you_jiao_ban_ji_lu',
text: '允许查看所有交班记录'
}
],
default: [{
key: 'yun_xu_xia_dan',
text: '允许下单'
},
{
key: 'yun_xu_shou_kuan',
text: '允许收款'
},
{
key: 'yun_xu_tui_kuan',
text: '允许退款'
},
{
key: 'yun_xu_jiao_ban',
text: '允许交班'
}
],
goods: [{
key: 'yun_xu_xiu_gai_shang_pin',
text: '允许修改商品'
},
{
key: 'yun_xu_shang_xia_jia_shang_pin',
text: '允许上下架商品'
},
{
key: 'yun_xu_xiu_gai_fen_lei',
text: '允许修改分类'
},
{
key: 'yun_xu_xiu_gai_fen_zu',
text: '允许修改分组'
}
],
discount:[
{
key: 'yun_xu_da_zhe',
text: '允许打折'
}
],
vip:[
{
key: '允许管理会员信息',
text: 'yun_xu_guan_li_hui_yuan_xin_xi'
},
{
key: 'yun_xu_xiu_gai_hui_yuan_yu_e',
text: '允许修改会员余额'
}
],
stock:[
{
text: '允许提交报损',
key: 'yun_xu_ti_jiao_bao_sun'
},
{
text: '允许沽清',
key: 'yun_xu_gu_qing'
},
{
text: '允许售罄商品',
key: 'yun_xu_shou_qing_shang_pin'
},
{
text:'允许修改商品库存',
key:'yun_xu_xiu_gai_shang_pin_ku_cun'
},
{
text: '允许耗材入库',
key: 'yun_xu_hao_cai_ru_ku'
},
{
text: '允许耗材出库',
key: 'yun_xu_hao_cai_chu_ku'
},
{
text: '允许耗材盘点',
key: 'yun_xu_hao_cai_pan_dian'
}
]
}
function isChinese(str) {
for (var i = 0; i < str.length; i++) {
if (str.charCodeAt(i) >= 0x4E00 && str.charCodeAt(i) <= 0x9FFF) {
return true; // 是中文
}
}
return false; // 不是中文,全是英文或其他
}
function isObjectButNotArray(value) {
return typeof value === 'object' && Array.isArray(value) === false;
}
function findPermissionObj(str) {
for (let i in $PermissionObj) {
const obj = $PermissionObj[i].find(v => v.key == str || v.text == str)
if (obj) {
return obj
break
}
}
console.error('未找到相关权限配置请检查权限配置文件commons/utils/hasPermission.js文件进行修改或增加')
return false
}
function returnFormatParams(params) {
if (typeof params === 'string') {
return findPermissionObj(params)
} else {
if (isObjectButNotArray(params)) {
const obj=findPermissionObj(params.key || params.text)
return {...params,...obj}
} else {
console.error('参数只能是字符串或者对象,不能是数组')
}
}
}
/**
* 判断是否有某权限
* @param {Object|String} params
*/
export async function hasPermission(params) {
//如果是商户默认拥有全部权限
const loginType=uni.getStorageSync('loginType')
if(loginType=='merchant'){
return true
}
params = returnFormatParams(params)
if (!params) {
return infoBox.showToast('未找到相关权限请检查代码或在权限配置文件commons/utils/hasPermission.js文件进行修改或增加')
}
const option = Object.assign({
tips: true,
key: '',
text: ''
}, params)
const res = await $hasPermission({
code: params.key
})
if (!res && option.tips) {
infoBox.showToast('您没有' + params.text + '权限!')
}
return res
}

View File

@ -23,6 +23,7 @@ const model = {
uni.setStorageSync('shopName',res.shopName) uni.setStorageSync('shopName',res.shopName)
uni.setStorageSync('logo',res.logo) uni.setStorageSync('logo',res.logo)
uni.setStorageSync('loginType',res.loginType) uni.setStorageSync('loginType',res.loginType)
uni.setStorageSync('shopUserId',res.user.user.id)
}, },
// 退出清空所有的缓存数据。 (不包含 环境相关) // 退出清空所有的缓存数据。 (不包含 环境相关)
cleanByLogout: () => { cleanByLogout: () => {
@ -79,6 +80,27 @@ const model = {
return appCache.shopId return appCache.shopId
} }
}, },
// 获取和放置店铺员工id
shopUserId: (val, isDelete = false) => {
if (isDelete) {
appCache.shopUserId = ""
return uni.removeStorageSync('shopUserId')
}
if (val) {
// 有值,为放置
appCache.shopUserId = val
uni.setStorageSync('shopUserId', val)
} else {
// 否则为获取
if (!appCache.shopUserId) {
//缓存取不到,获取应用本地信息
appCache.shopUserId = uni.getStorageSync('shopUserId')
}
return appCache.shopUserId
}
},
// 获取和放置useType就餐类型 // 获取和放置useType就餐类型
useType: (val, isDelete = false) => { useType: (val, isDelete = false) => {
if (isDelete) { if (isDelete) {

View File

@ -6,7 +6,7 @@
height: height, height: height,
borderRadius: `calc(${height} / 2)`, borderRadius: `calc(${height} / 2)`,
}" @click.stop="changeSwitch" }" @click.stop="changeSwitch"
:class="{disabled:disabled}" :class="{disabled:disabled&&openDisabledClass}"
> >
<view v-show="!modelValue" class="before" :style="{ <view v-show="!modelValue" class="before" :style="{
left: `calc(${margin} * 2)`, left: `calc(${margin} * 2)`,
@ -40,6 +40,10 @@
type:Boolean, type:Boolean,
default:false default:false
}, },
openDisabledClass:{
type:Boolean,
default:true
},
height: { height: {
type: String, type: String,
default: '40rpx', default: '40rpx',
@ -82,10 +86,11 @@
default: false, default: false,
}, },
}) })
const emits = defineEmits(['update:modelValue', 'change']) const emits = defineEmits(['update:modelValue', 'change','click'])
// switch // switch
function changeSwitch() { function changeSwitch() {
if(props.disabled){ if(props.disabled){
emits('click')
return return
} }
let currentVal=props.modelValue let currentVal=props.modelValue

View File

@ -4,19 +4,17 @@
<view class="u-flex tabs zhanwei u-relative"> <view class="u-flex tabs zhanwei u-relative">
<view class="active-block" :style="computedBlockStyle"> <view class="active-block" :style="computedBlockStyle">
</view> </view>
<view class="u-flex-1 u-text-center item" <view class="u-flex-1 u-text-center item" :class="[index===current?'':'active',size]" @tap="changeCurrent(index)"
:class="{active:index===current}" v-for="(item,index) in props.list" :key="index">
@tap="changeCurrent(index)" v-for="(item,index) in props.list" :key="index"> {{textKey?item[textKey]:item}}
{{item}}
</view> </view>
</view> </view>
<view class="u-flex tabs u-absolute position-all"> <view class="u-flex tabs u-absolute position-all">
<view class="u-flex-1 u-text-center item" <view class="u-flex-1 u-text-center item" :class="{active:index===current}" @tap="changeCurrent(index)"
:class="{active:index===current}" v-for="(item,index) in props.list" :key="index">
@tap="changeCurrent(index)" v-for="(item,index) in props.list" :key="index"> {{textKey?item[textKey]:item}}
{{item}}
</view> </view>
</view> </view>
@ -25,56 +23,75 @@
</template> </template>
<script setup> <script setup>
import { computed, ref, watch } from 'vue'; import {
const props=defineProps({ computed,
padding:{type:String}, ref,
list:{type:Array}, watch
defaultIndex:{ } from 'vue';
type:Number, const props = defineProps({
default:0 size:{
type: String,
default:''
}, },
modelValue:{ padding: {
type:Number, type: String
default:0 },
list: {
type: Array
},
textKey: {
type: String,
default: ''
},
defaultIndex: {
type: Number,
default: 0
},
modelValue: {
type: Number,
default: 0
} }
}) })
const emit=defineEmits(['change','update:modelValue']) const emit = defineEmits(['change', 'update:modelValue'])
let current=ref(props.modelValue||props.defaultIndex||0) let current = ref(props.modelValue || props.defaultIndex || 0)
function changeCurrent(index){
current.value=index
}
const computedBlockStyle=computed(()=>{
const oneWidth= 100/props.list.length
const left= current.value*oneWidth
return{
width:oneWidth+'%',
left:left+'%'
}
})
watch(()=>props.modelValue,(newval)=>{
current.value=newval
})
watch(()=>current.value,(newval)=>{
emit('update:modelValue',newval)
emit('change',newval)
})
function changeCurrent(index) {
current.value = index
}
const computedBlockStyle = computed(() => {
const oneWidth = 100 / props.list.length
const left = current.value * oneWidth
return {
width: oneWidth + '%',
left: left + '%'
}
})
watch(() => props.modelValue, (newval) => {
current.value = newval
})
watch(() => current.value, (newval) => {
emit('update:modelValue', newval)
emit('change', newval)
})
</script> </script>
<style lang="scss" scoped> <style lang="scss" scoped>
.zhanwei{ .zhanwei {
.item{ .item {
opacity: 0; opacity: 0;
} }
} }
.bg{
.bg {
background: #E6F0FF; background: #E6F0FF;
padding: 4rpx 10rpx; padding: 4rpx 10rpx;
} }
.border-r-16{
.border-r-16 {
border-radius: 16rpx; border-radius: 16rpx;
} }
.active-block{
.active-block {
background-color: $my-main-color; background-color: $my-main-color;
color: #fff; color: #fff;
top: 4rpx; top: 4rpx;
@ -86,12 +103,14 @@ import { computed, ref, watch } from 'vue';
overflow: hidden; overflow: hidden;
z-index: 1; z-index: 1;
} }
.tabs{
.tabs {
border-radius: 16rpx; border-radius: 16rpx;
font-size: 28rpx; font-size: 28rpx;
color: #318AFE; color: #318AFE;
z-index: 2; z-index: 2;
.active-block{
.active-block {
background-color: $my-main-color; background-color: $my-main-color;
color: #fff; color: #fff;
top: 4rpx; top: 4rpx;
@ -103,14 +122,19 @@ import { computed, ref, watch } from 'vue';
overflow: hidden; overflow: hidden;
z-index: 1; z-index: 1;
} }
.item{
.item {
padding: 8rpx 0; padding: 8rpx 0;
transition: all .2s ease-in-out; transition: all .2s ease-in-out;
position: relative; position: relative;
background-color: transparent; background-color: transparent;
z-index: 2; z-index: 2;
&.large{
padding: 16rpx 0;
}
} }
.item.active{
.item.active {
border-radius: 8rpx; border-radius: 8rpx;
// background-color: $my-main-color; // background-color: $my-main-color;
color: #fff; color: #fff;

View File

@ -319,3 +319,15 @@ export function $changeUseType(data) {
} }
}); });
} }
// 退款
export function $returnOrder(data) {
return request({
url: '/api/place/returnOrder',
method: "post",
data:{
shopId: uni.getStorageSync("shopId"),
...data
}
});
}

View File

@ -122,7 +122,7 @@ export const $productSpec=new $API('/api/tbProductSpec',http.req)
/* 商品列表 V2 */ /* 商品列表 V2 */
export function $tbProductV2(data) { export function $tbProductV2(data) {
return http.req('/api/tbProduct/list/v2', {...data,shopId:uni.getStorageSync('shopId')}, 'GET') return http.req('/api/tbProduct/list/v2', {...data,shopId:uni.getStorageSync('shopId')}, 'post')
} }
/* 耗材与商品绑定关系 */ /* 耗材与商品绑定关系 */
export function $tbProskuConV2(data) { export function $tbProskuConV2(data) {

View File

@ -727,7 +727,7 @@ export function $hasPermission(params) {
url: '/api/tbShopPermission/hasPermission', url: '/api/tbShopPermission/hasPermission',
method: "get", method: "get",
params:{ params:{
shopId: uni.getStorageSync("shopId"), userId: uni.getStorageSync("shopUserId"),
...params ...params
} }
}); });

View File

@ -118,7 +118,7 @@
tbProductGroupPost tbProductGroupPost
} from "@/http/yskApi/shop.js" } from "@/http/yskApi/shop.js"
import {hasPermission} from '@/commons/utils/hasPermission.js';
import { import {
returnAllCategory returnAllCategory
@ -260,6 +260,10 @@
} }
async function save() { async function save() {
const res=await hasPermission('允许修改分组')
if(!res){
return
}
console.log(pageData.goodsList); console.log(pageData.goodsList);
await tbProductGroupPut({ await tbProductGroupPut({
...option, ...option,
@ -275,7 +279,11 @@
} }
// //
function goodsDel(index) { async function goodsDel(index) {
const res=await hasPermission('允许修改分组')
if(!res){
return
}
const goods = pageData.bindGoodsList[index] const goods = pageData.bindGoodsList[index]
uni.showModal({ uni.showModal({
title: '提示', title: '提示',

View File

@ -8,11 +8,11 @@
</view> </view>
</view> </view>
<view class="u-m-t-36"> <view class="u-m-t-36">
<view>修改排序</view> <view>修改分组名称</view>
<view class="u-m-t-38"> <view class="u-m-t-38">
<view class="u-m-b-32"> <view class="u-m-b-32">
<view class="u-m-t-16"> <view class="u-m-t-16">
<up-input v-model="sort"> <up-input v-model="name">
</up-input> </up-input>
</view> </view>
</view> </view>
@ -59,7 +59,7 @@
item: { item: {
type: Object, type: Object,
default: () => { default: () => {
sort:'' name:''
} }
} }
}) })
@ -74,10 +74,10 @@
note: '' note: ''
}) })
let popShow = ref(props.show) let popShow = ref(props.show)
let sort=ref('') let name=ref('')
watch(()=>props.item.sort,(newval)=>{ watch(()=>props.item.name,(newval)=>{
sort.value=newval name.value=newval
}) })
watch(() => props.show, (newval) => { watch(() => props.show, (newval) => {
@ -105,7 +105,7 @@
function save() { function save() {
emits('save', { emits('save', {
...data.value, ...data.value,
sort:sort.value name:name.value
}) })
} }
</script> </script>

View File

@ -4,6 +4,7 @@
<view class="u-m-b-32" v-for="(item,index) in pageData.list" :key="index"> <view class="u-m-b-32" v-for="(item,index) in pageData.list" :key="index">
<my-category @del="categoryDel" @useTypeClick="categoryUseTypeClick" <my-category @del="categoryDel" @useTypeClick="categoryUseTypeClick"
@editName="popupShow($event,'name',true)"
@editSort="popupShow($event,'sort',true)" @edit="actionsShow" @radioClick="goodsRadioClick" @editSort="popupShow($event,'sort',true)" @edit="actionsShow" @radioClick="goodsRadioClick"
@isShowChange="isSHowChange" :index="index" :data="item" :showChecked="showChecked" @isShowChange="isSHowChange" :index="index" :data="item" :showChecked="showChecked"
:showDetail="pageData.showGoodsDetail"></my-category> :showDetail="pageData.showGoodsDetail"></my-category>
@ -23,6 +24,7 @@
</view> </view>
<edit-sort @save="updataGroup" :item="popup.selData" v-model:show="popup.sort.show"></edit-sort> <edit-sort @save="updataGroup" :item="popup.selData" v-model:show="popup.sort.show"></edit-sort>
<edit-name @save="updataGroup" :item="popup.selData" v-model:show="popup.name.show"></edit-name>
<up-action-sheet :round="10" @select="actionSelect" @close="actionsHide" cancelText="取消" :actions="actions.list" <up-action-sheet :round="10" @select="actionSelect" @close="actionsHide" cancelText="取消" :actions="actions.list"
:show="actions.show"></up-action-sheet> :show="actions.show"></up-action-sheet>
@ -41,6 +43,7 @@
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 editSort from './components/edit-sort.vue'; import editSort from './components/edit-sort.vue';
import editName from './components/edit-name.vue';
import { import {
tbProductGroupGet, tbProductGroupGet,
tbProductGroupDelete, tbProductGroupDelete,
@ -100,6 +103,9 @@
}, },
sort: { sort: {
show: false show: false
},
name:{
show: false
} }
}) })
@ -112,6 +118,7 @@
console.log(e); console.log(e);
const res = await $productCategory.update(e) const res = await $productCategory.update(e)
popup.sort.show = false; popup.sort.show = false;
popup.name.show = false;
pageData.list[popup.selIndex] = e pageData.list[popup.selIndex] = e
infoBox.showToast('更新成功') infoBox.showToast('更新成功')
} }

View File

@ -1,7 +1,7 @@
<template> <template>
<view class="u-p-30 safe-page min-page"> <view class="u-p-30 safe-page min-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" v-model="tabsCurrent"></myTabs> <my-tabs :list="tabsList" v-model="tabsCurrent"></my-tabs>
</up-sticky> </up-sticky>
<view class="box"> <view class="box">
@ -11,8 +11,7 @@
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>
<up-radio-group :disabled="option.type=='edit'" v-model="FormData.typeEnum" <up-radio-group v-model="FormData.typeEnum" placement="row">
placement="row">
<up-radio :customStyle="{marginRight: '30px'}" <up-radio :customStyle="{marginRight: '30px'}"
v-for="(item, index) in pageData.types" :key="index" :label="item.name" v-for="(item, index) in pageData.types" :key="index" :label="item.name"
:name="item.value"> :name="item.value">
@ -40,21 +39,28 @@
<uni-easyinput :paddingNone="inputPaddingNone" :placeholderStyle="placeholderStyle" <uni-easyinput :paddingNone="inputPaddingNone" :placeholderStyle="placeholderStyle"
:inputBorder="inputBorder" v-model="FormData.name" placeholder="请输入商品名称" /> :inputBorder="inputBorder" v-model="FormData.name" placeholder="请输入商品名称" />
</uni-forms-item> </uni-forms-item>
<template v-if="FormData.typeEnum!='group'">
<uni-forms-item label="所属分类" required showRequired name="categoryId">
<uni-data-picker :clear-icon="false" :map="{text:'name',value:'id'}"
placeholder="请选择分类" popup-title="请选择分类" :localdata="pageData.category"
v-model="FormData.categoryId">
</uni-data-picker>
</uni-forms-item>
</template>
<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"
type="textarea" v-model="FormData.shortTitle" placeholder="请填写商品简述" /> type="textarea" v-model="FormData.shortTitle" placeholder="请填写商品简述" />
</uni-forms-item> </uni-forms-item>
</view> </view>
<template v-if="FormData.typeEnum!='group'">
<view class="u-relative">
<uni-forms-item label="所属分类" required showRequired name="categoryId">
<uni-data-picker :clear-icon="false" :map="{text:'name',value:'id'}"
placeholder="请选择分类" popup-title="请选择分类" :localdata="pageData.category"
v-model="FormData.categoryId">
</uni-data-picker>
</uni-forms-item>
<view class="zhezhao u-absolute position-all" @click="canEditGoodsCategory(true)" v-if="option.type=='edit'&&disabledChangeCategory">
</view>
</view>
</template>
<view class="border-top-0"> <view class="border-top-0">
<uni-forms-item label="单位" required showRequired name="categoryId"> <uni-forms-item label="单位" required showRequired name="categoryId">
@ -115,13 +121,13 @@
<template v-if="skuList.list.length"> <template v-if="skuList.list.length">
<view class="u-text-center"> <view class="u-text-center">
<view class="u-flex font-bold u-m-b-12"> <view class="u-flex font-bold u-m-b-12">
<view class="u-flex-1">组合名称</view> <view class="u-flex-1 u-text-left">组合名称</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>
<view class="u-flex u-p-b-12 u-p-t-12" v-for="(item,index) in skuList.list" <view class="u-flex u-p-b-12 u-p-t-12" v-for="(item,index) in skuList.list"
:key="index"> :key="index">
<view class="u-flex-1">{{item.specSnap}}</view> <view class="u-flex-1 u-text-left">{{item.specSnap}}</view>
<view class="u-flex-1">{{item.salePrice}}</view> <view class="u-flex-1">{{item.salePrice}}</view>
<view class="u-flex-1">{{item.stockNumber}}</view> <view class="u-flex-1">{{item.stockNumber}}</view>
</view> </view>
@ -207,7 +213,7 @@
</template> </template>
<template v-if="FormData.typeEnum!='sku'"> <template v-if="FormData.typeEnum!='sku'">
<view class="u-m-t-32 u-font-32 u-m-l-10 u-m-b-32">规格属性</view> <!-- <view class="u-m-t-32 u-font-32 u-m-l-10 u-m-b-32">规格属性</view> -->
<view class="block" v-for="(sku,index) in skuList.list" :key="index"> <view class="block" v-for="(sku,index) in skuList.list" :key="index">
<view class="border-top-0"> <view class="border-top-0">
<uni-forms-item label="售价"> <uni-forms-item label="售价">
@ -224,7 +230,7 @@
:inputBorder="inputBorder" v-model="sku.memberPrice" type="digit" :inputBorder="inputBorder" v-model="sku.memberPrice" type="digit"
placeholder="请输入会员价(元)" /> placeholder="请输入会员价(元)" />
</uni-forms-item> </uni-forms-item>
<!-- <uni-forms-item label="成本价(元)"> <!-- <uni-forms-item label="成本价(元)">
<uni-easyinput @blur="priceFormat(sku,'costPrice')" :paddingNone="inputPaddingNone" <uni-easyinput @blur="priceFormat(sku,'costPrice')" :paddingNone="inputPaddingNone"
:placeholderStyle="placeholderStyle" :inputBorder="inputBorder" :placeholderStyle="placeholderStyle" :inputBorder="inputBorder"
v-model="sku.costPrice" type="digit" placeholder="请输入成本价(元)" /> v-model="sku.costPrice" type="digit" placeholder="请输入成本价(元)" />
@ -240,12 +246,12 @@
:placeholderStyle="placeholderStyle" :inputBorder="inputBorder" :placeholderStyle="placeholderStyle" :inputBorder="inputBorder"
v-model="sku.suit" type="digit" placeholder="请输入起售数量" /> v-model="sku.suit" type="digit" placeholder="请输入起售数量" />
</uni-forms-item> </uni-forms-item>
<uni-forms-item label="库存数量"> <!-- <uni-forms-item label="库存数量">
<uni-easyinput @blur="priceFormat(sku,'stockNumber')" <uni-easyinput @blur="priceFormat(sku,'stockNumber')"
:paddingNone="inputPaddingNone" :placeholderStyle="placeholderStyle" :paddingNone="inputPaddingNone" :placeholderStyle="placeholderStyle"
:inputBorder="inputBorder" v-model="sku.stockNumber" type="digit" :inputBorder="inputBorder" v-model="sku.stockNumber" type="digit"
placeholder="请输入库存数量" /> placeholder="请输入库存数量" />
</uni-forms-item> </uni-forms-item> -->
<uni-forms-item label="分销金额"> <uni-forms-item label="分销金额">
<uni-easyinput :paddingNone="inputPaddingNone" <uni-easyinput :paddingNone="inputPaddingNone"
@blur="priceFormat(sku,'firstShared')" :placeholderStyle="placeholderStyle" @blur="priceFormat(sku,'firstShared')" :placeholderStyle="placeholderStyle"
@ -384,7 +390,7 @@
<template v-if="FormData.typeEnum!='group'"> <template v-if="FormData.typeEnum!='group'">
<view class="block"> <view class="block">
<view class="border-top-0"> <!-- <view class="border-top-0">
<uni-forms-item label="上架区域"> <uni-forms-item label="上架区域">
<view class="u-flex"> <view class="u-flex">
<view class="u-m-r-30"> <view class="u-m-r-30">
@ -393,6 +399,15 @@
<my-radio text="小程序商城" v-model="FormData.isShowMall"></my-radio> <my-radio text="小程序商城" v-model="FormData.isShowMall"></my-radio>
</view> </view>
</uni-forms-item> </uni-forms-item>
</view> -->
<view class="border-top-0">
<uni-forms-item label="">
<view class="u-flex u-row-between">
<view class="label-title">上架</view>
<my-switch disabled :openDisabledClass="false" @click="isGroundingChange"
v-model="FormData.isGrounding"></my-switch>
</view>
</uni-forms-item>
</view> </view>
<uni-forms-item label=""> <uni-forms-item label="">
<view class="u-flex u-row-between"> <view class="u-flex u-row-between">
@ -401,6 +416,21 @@
</view> </view>
<view class="color-999 u-m-t-16 u-font-24">关闭则不计算出入库数据</view> <view class="color-999 u-m-t-16 u-font-24">关闭则不计算出入库数据</view>
</uni-forms-item> </uni-forms-item>
<template v-if="FormData.isStock">
<uni-forms-item label="库存数量">
<uni-easyinput :paddingNone="inputPaddingNone"
:disabled="disabledStock"
:placeholderStyle="placeholderStyle" :inputBorder="inputBorder"
v-model="FormData.stockNumber" type="digit" placeholder="请输入库存数量" />
</uni-forms-item>
</template>
<uni-forms-item label="">
<view class="u-flex u-row-between">
<view class="label-title">设为推荐</view>
<my-switch v-model="FormData.isHot"></my-switch>
</view>
</uni-forms-item>
<uni-forms-item label=""> <uni-forms-item label="">
<view class="u-flex u-row-between"> <view class="u-flex u-row-between">
<view class="label-title">标签打印</view> <view class="label-title">标签打印</view>
@ -414,12 +444,12 @@
:inputBorder="inputBorder" v-model="FormData.packFee" type="digit" :inputBorder="inputBorder" v-model="FormData.packFee" type="digit"
placeholder="请输入打包费" /> placeholder="请输入打包费" />
</uni-forms-item> </uni-forms-item>
<uni-forms-item label="虚拟销量"> <!-- <uni-forms-item label="虚拟销量">
<uni-easyinput @blur="priceFormat(FormData,'baseSalesNumber')" <uni-easyinput @blur="priceFormat(FormData,'baseSalesNumber')"
:paddingNone="inputPaddingNone" :placeholderStyle="placeholderStyle" :paddingNone="inputPaddingNone" :placeholderStyle="placeholderStyle"
:inputBorder="inputBorder" v-model="FormData.baseSalesNumber" type="digit" :inputBorder="inputBorder" v-model="FormData.baseSalesNumber" type="digit"
placeholder="请输入虚拟销量" /> placeholder="请输入虚拟销量" />
</uni-forms-item> </uni-forms-item> -->
<template v-if="option.type==='edit'"> <template v-if="option.type==='edit'">
<uni-forms-item label="排序"> <uni-forms-item label="排序">
<uni-easyinput @blur="priceFormat(FormData,'sort')" <uni-easyinput @blur="priceFormat(FormData,'sort')"
@ -448,7 +478,8 @@
</template> </template>
<template v-if="tabsCurrent===1"> <template v-if="tabsCurrent===1">
<edit-haocai @updateGoods="updateGoodsDetail" :goods="FormData" @cancel="changeTabsCurrent(0)"></edit-haocai> <edit-haocai @updateGoods="updateGoodsDetail" :goods="FormData"
@cancel="changeTabsCurrent(0)"></edit-haocai>
</template> </template>
</view> </view>
@ -489,17 +520,15 @@
import go from '@/commons/utils/go.js'; import go from '@/commons/utils/go.js';
import color from '@/commons/color.js'; import color from '@/commons/color.js';
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 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 myUploadFile from '@/components/my-components/my-upload-file'
import myTabs from '@/components/my-components/my-tabs'
import myButton from '@/components/my-components/my-button'
import mySwitch from '@/components/my-components/my-switch.vue'
import infoBox from "@/commons/utils/infoBox.js" import infoBox from "@/commons/utils/infoBox.js"
import {
hasPermission
} from '@/commons/utils/hasPermission.js';
import { import {
$types, $types,
$defaultSku $defaultSku
@ -513,7 +542,10 @@
$delProduct, $delProduct,
$productSpec, $productSpec,
$updateProductStatus, $updateProductStatus,
$updateGrounding $updateGrounding,
$goodsIsHot,
$tbProskuConV2,
$updateProductData
} from '@/http/yskApi/goods.js' } from '@/http/yskApi/goods.js'
import { import {
@ -535,6 +567,50 @@
nextTick nextTick
} from 'vue'; } from 'vue';
async function upDateGoods(par) {
const res = await $updateProductData([{
id: FormData.id,
isSku: 0,
shopId: uni.getStorageSync('shopId'),
...par
}])
uni.showToast({
title: '修改成功',
icon: 'none'
})
}
async function isPauseSaleChange(e) {
if (option.type == 'add') {
FormData.isPauseSale = FormData.isPauseSale ? 0 : 1
return
}
const res = await hasPermission('允许售罄商品')
if (!res) {
return
}
await upDateGoods({
key: 'pauseSale',
value: FormData.isPauseSale ? 0 : 1
})
FormData.isPauseSale = FormData.isPauseSale ? 0 : 1
}
async function isGroundingChange(e) {
if (option.type == 'add') {
FormData.isGrounding = FormData.isGrounding ? 0 : 1
return
}
const res = await hasPermission('允许上下架商品')
if (!res) {
return
}
await upDateGoods({
key: 'grounding',
value: FormData.isGrounding ? 0 : 1
})
FormData.isGrounding = FormData.isGrounding ? 0 : 1
}
function toRecoders() { function toRecoders() {
go.to('PAGES_PRODUCT_INVOICING_LIST', { go.to('PAGES_PRODUCT_INVOICING_LIST', {
productId: FormData.id productId: FormData.id
@ -932,9 +1008,11 @@
isShowMall: 1, isShowMall: 1,
isShowCash: 1, isShowCash: 1,
isStock: 0, isStock: 0,
isStock: 0,
isHot: 0,
packFee: 0, packFee: 0,
specId: "", specId: "",
baseSalesNumber: 0, // baseSalesNumber: 0,
sort: 0, sort: 0,
groupSnap: [], groupSnap: [],
specInfo: [], specInfo: [],
@ -942,6 +1020,8 @@
specTableHeaders: [], specTableHeaders: [],
skuSnap: "", skuSnap: "",
groupCategoryId: [], groupCategoryId: [],
isGrounding: 1,
stockNumber: 0,
notices: { notices: {
availableTime: "", availableTime: "",
bookingType: "", bookingType: "",
@ -1001,14 +1081,14 @@
url: v url: v
} }
}) })
for(let i in res.conInfos){ for (let i in res.conInfos) {
const con=res.conInfos[i] const con = res.conInfos[i]
const item=res.skuList.find(v=>v.id==con.productSkuId) const item = res.skuList.find(v => v.id == con.productSkuId)
if(item){ if (item) {
if(item.hasOwnProperty('haoCaiList')){ if (item.hasOwnProperty('haoCaiList')) {
item.haoCaiList.push(con) item.haoCaiList.push(con)
}else{ } else {
item.haoCaiList=[con] item.haoCaiList = [con]
} }
} }
} }
@ -1054,7 +1134,7 @@
}, },
names, names,
specSnap: v.specSnap, specSnap: v.specSnap,
coverImg:v.coverImg coverImg: v.coverImg
} }
}), }),
specList: [], specList: [],
@ -1161,9 +1241,10 @@
pageData.skuList = res pageData.skuList = res
}) })
} }
function updateGoodsDetail(){
function updateGoodsDetail() {
getGoodsDetail() getGoodsDetail()
getProductSku() // getProductSku()
} }
onLoad((params) => { onLoad((params) => {
if (isEmpty(params)) { if (isEmpty(params)) {
@ -1173,14 +1254,13 @@
// getGoodsDetail() // getGoodsDetail()
// getProductSku() // getProductSku()
} }
canEditGoodsCategory()
console.log(option.type);
uni.setNavigationBarTitle({ uni.setNavigationBarTitle({
title: option.type === 'add' ? '添加商品' : '编辑商品' title: option.type === 'add' ? '添加商品' : '编辑商品'
}) })
if (option.type === 'edit') { if (option.type === 'edit') {
getGoodsDetail() getGoodsDetail()
getProductSku() // getProductSku()
} }
defaultValueInit() defaultValueInit()
getCategory() getCategory()
@ -1212,12 +1292,18 @@
function settimeoutBack(time) { function settimeoutBack(time) {
clearTimeout(timer) clearTimeout(timer)
timer = setTimeout(() => { timer = setTimeout(() => {
uni.$emit('update:productIndex')
uni.navigateBack() uni.navigateBack()
}, time) }, time)
} }
// //
function save() { async function save() {
const bol = await hasPermission('允许修改商品')
if (!bol) {
return
}
Forms.value.validate().then(res => { Forms.value.validate().then(res => {
const { const {
typeEnum, typeEnum,
@ -1231,7 +1317,7 @@
// return infoBox.showErrorToast('') // return infoBox.showErrorToast('')
// } // }
const images = refFile.value.getFileList() const images = refFile.value.getFileList()
if(images.length<=0){ if (images.length <= 0) {
return infoBox.showToast('请上传商品图片') return infoBox.showToast('请上传商品图片')
} }
const skuSnap = [] const skuSnap = []
@ -1239,8 +1325,8 @@
...$defaultSku, ...$defaultSku,
barCode: `${uni.getStorageSync("shopId")}${dayjs().valueOf()}` barCode: `${uni.getStorageSync("shopId")}${dayjs().valueOf()}`
}]; }];
if(typeEnum=='normal'){ if (typeEnum == 'normal') {
submitSkuList=skuList.list ; submitSkuList = skuList.list;
} }
console.log(submitSkuList); console.log(submitSkuList);
if (FormData.specificationsGroup) { if (FormData.specificationsGroup) {
@ -1253,6 +1339,16 @@
} }
} }
} }
console.log(FormData.specificationsGroup);
const selectSpec = FormData.typeEnum != 'sku' ? '' : JSON.stringify(FormData.specificationsGroup
.selectSpec.map(spe => {
return {
...spe,
value: spe.value.map(v => {
return typeof v === 'string' ? v : v.text || v.value
})
}
}))
const submitData = { const submitData = {
...FormData, ...FormData,
images: images, images: images,
@ -1261,13 +1357,7 @@
specInfo: JSON.stringify(submitSkuList), specInfo: JSON.stringify(submitSkuList),
lowPrice: submitSkuList[0].salePrice, lowPrice: submitSkuList[0].salePrice,
specificationsGroup: undefined, specificationsGroup: undefined,
selectSpec: JSON.stringify(FormData.specificationsGroup.selectSpec.map(spe=>{ selectSpec,
return {
...spe,value:spe.value.map(v=>{
return typeof v==='string'?v:v.text||v.value
})
}
})),
skuSnap: JSON.stringify(skuSnap) skuSnap: JSON.stringify(skuSnap)
} }
// //
@ -1420,15 +1510,46 @@
} }
} }
}) })
/**
* 权限start
*/
//
let disabledStock=ref(false)
async function canEditGoodsStock() {
if (option.type === 'edit') {
const res=await hasPermission({text:'允许修改商品库存',tips:false})
disabledStock.value=!res
}
}
watch(() => FormData.isStock, (newval) => {
if (newval) {
canEditGoodsStock()
}
})
//
let disabledChangeCategory=ref(false)
async function canEditGoodsCategory(tips=false) {
if (option.type === 'edit') {
const res=await hasPermission({text:'允许修改分类',tips})
disabledChangeCategory.value=!res
}
}
/**
* 权限end
*/
watch(() => pageData.types, (newval) => {
Forms.value.setRules(rules)
})
onShow(() => { onShow(() => {
watchSpecificationsSave() watchSpecificationsSave()
}) })
onReady(() => { onReady(() => {
Forms.value && Forms.value.setRules(rules) Forms.value && Forms.value.setRules(rules)
}) })
watch(() => pageData.types, (newval) => {
Forms.value.setRules(rules)
})
</script> </script>
<style scoped> <style scoped>
page { page {

View File

@ -26,8 +26,7 @@
</view> </view>
</view> </view>
<view class="u-m-t-32 color-666"> <view class="u-m-t-32 color-666">
<view class="u-m-t-24" v-for="(item,haocaiIndex) in sku.haoCaiList" <view class="u-m-t-24" v-for="(item,haocaiIndex) in sku.haoCaiList" :key="haocaiIndex">
:key="haocaiIndex">
<view class=" u-flex"> <view class=" u-flex">
<view class="xuhao">{{haocaiIndex+1}}</view> <view class="xuhao">{{haocaiIndex+1}}</view>
<view class="u-flex u-flex-1 u-p-l-32 gap-20"> <view class="u-flex u-flex-1 u-p-l-32 gap-20">
@ -42,8 +41,8 @@
</view> </view>
<view class="u-flex input"> <view class="u-flex input">
<up-input border="none" v-model="item.surplusStock"></up-input> <up-input border="none" v-model="item.surplusStock"></up-input>
<up-icon @click="delGuigeHaocao(index,haocaiIndex)" color="#EB4F4F" :size="16" <up-icon @click="delGuigeHaocao(index,haocaiIndex)" color="#EB4F4F"
name="minus-circle-fill"></up-icon> :size="16" name="minus-circle-fill"></up-icon>
</view> </view>
</view> </view>
</view> </view>
@ -178,7 +177,13 @@
import { import {
$tbProskuConV2 $tbProskuConV2
} from '@/http/yskApi/goods.js' } from '@/http/yskApi/goods.js'
import { cloneWith } from 'lodash'; import {
cloneWith
} from 'lodash';
import {
hasPermission
} from '@/commons/utils/hasPermission.js';
const emits = defineEmits(['cancel', 'updateGoods']) const emits = defineEmits(['cancel', 'updateGoods'])
function cancel() { function cancel() {
@ -276,7 +281,7 @@ import { cloneWith } from 'lodash';
content: '是否删除该耗材', content: '是否删除该耗材',
success(res) { success(res) {
if (res.confirm) { if (res.confirm) {
if (item&&item.id) { if (item && item.id) {
deletetbProskuCon([item.id]).then(res1 => { deletetbProskuCon([item.id]).then(res1 => {
skuList.value[guigeIndex].haoCaiList.splice(haocaiIndex, 1) skuList.value[guigeIndex].haoCaiList.splice(haocaiIndex, 1)
}) })
@ -298,19 +303,25 @@ import { cloneWith } from 'lodash';
isBindGuige.value = isSku.value isBindGuige.value = isSku.value
}) })
async function save() { async function save() {
const bol = await hasPermission('允许修改商品')
if (!bol) {
return
}
console.log('save'); console.log('save');
let isPas=false let isPas = false
if(!isBindGuige.value){ if (!isBindGuige.value) {
// //
isPas = conInfos.value.every(v => { isPas = conInfos.value.every(v => {
return v.conInfoId && v.conUnit && v.surplusStock > 0 return v.conInfoId && v.conUnit && v.surplusStock > 0
}) })
}else{ } else {
// //
isPas = skuList.value.filter(v=>v.haoCaiList&&v.haoCaiList.length).every(sku => { isPas = skuList.value.filter(v => v.haoCaiList && v.haoCaiList.length).every(sku => {
console.log(sku.haoCaiList); console.log(sku.haoCaiList);
return sku.haoCaiList.every(v=>{ return sku.haoCaiList.every(v => {
return v.conInfoId && v.conUnit && v.surplusStock > 0 return v.conInfoId && v.conUnit && v.surplusStock > 0
}) })
}) })
@ -337,10 +348,10 @@ import { cloneWith } from 'lodash';
} }
}) })
} else { } else {
for(let i in skuList.value){ for (let i in skuList.value) {
const haocaiList=skuList.value[i].haoCaiList||[] const haocaiList = skuList.value[i].haoCaiList || []
for(let k in haocaiList){ for (let k in haocaiList) {
const v=haocaiList[k] const v = haocaiList[k]
ajaxData.cons.push({ ajaxData.cons.push({
id: v.id || '', id: v.id || '',
conInfoId: v.conInfoId, conInfoId: v.conInfoId,

View File

@ -548,7 +548,7 @@
} }
.box { .box {
margin-top: 70rpx; // margin-top: 70rpx;
font-size: 28rpx; font-size: 28rpx;
.block { .block {

View File

@ -87,11 +87,11 @@
<view class="u-flex"> <view class="u-flex">
<view class="u-flex"> <view class="u-flex">
<view class="u-m-r-18 color-999">售罄</view> <view class="u-m-r-18 color-999">售罄</view>
<my-switch v-model="isPauseSale" @change="isPauseSaleChange"></my-switch> <my-switch disabled v-model="isPauseSale" :openDisabledClass="false" @click="isPauseSaleChange"></my-switch>
</view> </view>
<view class="u-flex u-m-l-30"> <view class="u-flex u-m-l-30">
<view class="u-m-r-18 color-999">{{data.isGrounding?'下架产品':'上架产品' }}</view> <view class="u-m-r-18 color-999">{{data.isGrounding?'下架产品':'上架产品' }}</view>
<my-switch v-model="isGrounding" @change="isGroundingChange"></my-switch> <my-switch disabled v-model="isGrounding" :openDisabledClass="false" @click="isGroundingChange"></my-switch>
</view> </view>
</view> </view>
<view class="u-flex"> <view class="u-flex">
@ -117,8 +117,8 @@
$goodsIsHot, $goodsIsHot,
$tbProskuConV2,$updateProductData $tbProskuConV2,$updateProductData
} from '@/http/yskApi/goods.js' } from '@/http/yskApi/goods.js'
import mySwitch from '@/components/my-components/my-switch.vue'
import go from '@/commons/utils/go.js'; import go from '@/commons/utils/go.js';
import {hasPermission} from '@/commons/utils/hasPermission.js';
import { import {
ColorMain ColorMain
} from '@/commons/color.js' } from '@/commons/color.js'
@ -171,17 +171,24 @@
isGrounding.value=newval isGrounding.value=newval
}) })
function isPauseSaleChange(e) { async function isPauseSaleChange(e) {
const res=await hasPermission('允许售罄商品')
if(!res){
return
}
upDateGoods({ upDateGoods({
key: 'pauseSale', key: 'pauseSale',
value: e value: isPauseSale.value?0:1
}) })
} }
async function isGroundingChange(e) {
function isGroundingChange(e) { const res=await hasPermission('允许上下架商品')
if(!res){
return
}
upDateGoods({ upDateGoods({
key: 'grounding', key: 'grounding',
value: e value: isGrounding.value?0:1
}) })
} }
@ -208,7 +215,11 @@
emits('del', props.index) emits('del', props.index)
} }
function changePrice() { async function changePrice() {
const res=await hasPermission('允许修改商品')
if(!res){
return
}
emits('changePrice', props.index) emits('changePrice', props.index)
} }
@ -225,10 +236,11 @@
} }
//type edittype //type edittype
function toEdit() { function toEdit() {
go.to('PAGES_PRODUCT_ADD', { emits('edit', props.data.id)
type: 'edit', // go.to('PAGES_PRODUCT_ADD', {
productId: props.data.id // type: 'edit',
}) // productId: props.data.id
// })
} }
</script> </script>

View File

@ -42,6 +42,7 @@
<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 :key="item.id" @update="getGoodsList" @changePrice="changePriceShow" @changeClick="goodsChangeClick" <my-goods :key="item.id" @update="getGoodsList" @changePrice="changePriceShow" @changeClick="goodsChangeClick"
@edit="toGoodsDetail"
@editStock="changeStockShow" @guigeClick="editGuigeShow" @baosun="baosunShow" @editStock="changeStockShow" @guigeClick="editGuigeShow" @baosun="baosunShow"
@radioClick="goodsRadioClick" :index="index" :data="item" @del="goodsDel" @radioClick="goodsRadioClick" :index="index" :data="item" @del="goodsDel"
:showChecked="showChecked" :showDetail="pageData.showGoodsDetail"></my-goods> :showChecked="showChecked" :showDetail="pageData.showGoodsDetail"></my-goods>
@ -149,6 +150,7 @@
watch watch
} from 'vue'; } from 'vue';
import go from '@/commons/utils/go.js'; import go from '@/commons/utils/go.js';
import {hasPermission} from '@/commons/utils/hasPermission.js';
import myGoods from './components/goods.vue' import myGoods from './components/goods.vue'
import myControl from './components/control.vue' import myControl from './components/control.vue'
import myCategory from './components/category.vue' import myCategory from './components/category.vue'
@ -285,7 +287,11 @@
// //
function changeStockShow(index) { async function changeStockShow(index) {
const res= await hasPermission('允许修改商品库存')
if(!res){
return
}
pageData.selGoodsIndex = index pageData.selGoodsIndex = index
const goods = pageData.goodsList[index] const goods = pageData.goodsList[index]
goods.skuList = goods.skuList.map(v => { goods.skuList = goods.skuList.map(v => {
@ -387,8 +393,15 @@
pageData.totalElements = res.totalElements pageData.totalElements = res.totalElements
}) })
} }
function watchEmitInit(){
uni.$off('update:productIndex')
uni.$on('update:productIndex',(data)=>{
getGoodsList()
})
}
onShow(() => { onShow(() => {
// getGoodsList() // getGoodsList()
watchEmitInit()
}) })
onLoad(() => { onLoad(() => {
getGoodsList() getGoodsList()
@ -485,6 +498,17 @@
pageData.query.page=0; pageData.query.page=0;
} }
async function toGoodsDetail(id){
const res= await hasPermission('允许修改商品')
if(!res){
return
}
go.to('PAGES_PRODUCT_ADD', {
type: 'edit',
productId: id
})
}
function statesTableClick(index) { function statesTableClick(index) {
pageData.stateCurrent = index; pageData.stateCurrent = index;
resetQuery() resetQuery()

View File

@ -13,8 +13,21 @@
<!-- 不需要label, 需要修改 label-width="0" --> <!-- 不需要label, 需要修改 label-width="0" -->
<uni-forms ref="loginFormRef" label-width="0" :model="vdata.formData" :rules="rules"> <uni-forms ref="loginFormRef" label-width="0" :model="vdata.formData" :rules="rules">
<view class="u-p-b-30">
<my-tabs size="large" @change="accountTypeChange" v-model="accountType.sel" :list="accountType.list" textKey="label"></my-tabs>
</view>
<view v-if="vdata.loginType == 'pwd' "> <view v-if="vdata.loginType == 'pwd' ">
<template v-if="accountType.sel==1">
<uni-forms-item name="merchantName">
<uni-easyinput class='jeepay-easyinput' placeholder="请输入商户号"
v-model="vdata.formData.merchantName" :clearable="false">
<template #prefixIcon>
<image src="@/static/login/icon-user.svg" class="input-icon" />
</template>
</uni-easyinput>
</uni-forms-item>
</template>
<uni-forms-item name="username"> <uni-forms-item name="username">
<uni-easyinput class='jeepay-easyinput' placeholder="请输入登录名/手机号" <uni-easyinput class='jeepay-easyinput' placeholder="请输入登录名/手机号"
v-model="vdata.formData.username" :clearable="false"> v-model="vdata.formData.username" :clearable="false">
@ -159,6 +172,15 @@
login, login,
getCodeImg getCodeImg
} from '@/http/yskApi/login.js'; } from '@/http/yskApi/login.js';
const accountType=reactive({
list:[
{label:'商户',value:'merchant'},
{label:'员工',value:'staff'},
],
sel:0
})
const loginFormRef = ref() const loginFormRef = ref()
const envChangeTipsRef = ref() const envChangeTipsRef = ref()
const refAgr = ref() const refAgr = ref()
@ -169,6 +191,9 @@
} from "@/commons/utils/pushmsg/wxTextToSpeach.js" } from "@/commons/utils/pushmsg/wxTextToSpeach.js"
// #endif // #endif
const rules = { const rules = {
merchantName:{
rules: [formUtil.rules.requiredInputShowToast('商户号')],
},
username: { username: {
rules: [formUtil.rules.requiredInputShowToast('用户名')], rules: [formUtil.rules.requiredInputShowToast('用户名')],
}, },
@ -223,6 +248,14 @@
vdata.formData.pwd = 'qwer1234' vdata.formData.pwd = 'qwer1234'
// #endif // #endif
function accountTypeChange(e){
// #ifdef H5
if(e==1){
vdata.formData.merchantName = '18049104914'
vdata.formData.username = '13666666666'
}
// #endif
}
const getCode = () => { const getCode = () => {
getCodeImg().then(res => { getCodeImg().then(res => {
@ -268,7 +301,7 @@
code: vdata.formData.code, code: vdata.formData.code,
uuid: vdata.formData.uuid, uuid: vdata.formData.uuid,
merchantName: vdata.formData.merchantName, merchantName: vdata.formData.merchantName,
loginType: vdata.formData.loginType loginType: accountType.list[accountType.sel].value
}) })
} else if (vdata.loginType == 'sms') { // } else if (vdata.loginType == 'sms') { //
@ -313,6 +346,7 @@
storageManage.setLogin(loginBizData) storageManage.setLogin(loginBizData)
storageManage.token(loginBizData.token) storageManage.token(loginBizData.token)
storageManage.shopId(loginBizData.shopId) storageManage.shopId(loginBizData.shopId)
storageManage.shopUserId(loginBizData.user.user.id)
storageManage.userInfo(loginBizData) storageManage.userInfo(loginBizData)
// //
go.to("PAGES_INDEX", { go.to("PAGES_INDEX", {

View File

@ -18,7 +18,9 @@
<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" showShadow>确认</my-button>
<my-button type="cancel" bgColor="#fff" @tap="confirm">取消</my-button> <view class="u-m-t-10">
<my-button type="cancel" bgColor="#fff" @tap="confirm">取消</my-button>
</view>
</view> </view>
</view> </view>
</template> </template>
@ -31,9 +33,6 @@
nextTick, nextTick,
ref ref
} from 'vue'; } from 'vue';
import myModel from '@/components/my-components/my-model.vue'
import myButton from '@/components/my-components/my-button.vue'
import myTabs from '@/components/my-components/my-tabs.vue'
const props = defineProps({ const props = defineProps({
title: { title: {
type: String, type: String,
@ -47,7 +46,7 @@
function changeCauses(item) { function changeCauses(item) {
let prve=form.remark.length?',':'' let prve=form.remark?',':''
form.remark +=prve+item.name form.remark +=prve+item.name
} }
@ -88,7 +87,8 @@
const model = ref(null) const model = ref(null)
function open() { function open(data) {
Object.assign(form,data)
model.value.open() model.value.open()
} }
@ -100,11 +100,12 @@
function confirm() { function confirm() {
const {remark const {remark
} = form } = form
close()
emits('confirm', { emits('confirm', {
name, remark
price
}) })
console.log(remark);
close()
} }
defineExpose({ defineExpose({
open, open,

View File

@ -13,7 +13,8 @@
</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>
</view> </view>
<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>
@ -80,7 +81,8 @@
<view class="block"> <view class="block">
<view class=" "> <view class=" ">
<view>用餐人数</view> <view>用餐人数</view>
<picker @change="userNumberChange" :value="userNumbers.defaultCateIndex" :range="userNumbers.list"> <picker @change="userNumberChange" :value="userNumbers.defaultCateIndex"
:range="userNumbers.list">
<view class="u-m-t-24 u-flex u-row-between "> <view class="u-m-t-24 u-flex u-row-between ">
<view class="color-333">{{userNumbers.defaultCateIndex||''}}</view> <view class="color-333">{{userNumbers.defaultCateIndex||''}}</view>
<uni-icons type="right" color="#999" size="16"></uni-icons> <uni-icons type="right" color="#999" size="16"></uni-icons>
@ -147,7 +149,11 @@
<view class="color-999 u-text-right u-font-24 u-m-t-12">×{{item.number}}</view> <view class="color-999 u-text-right u-font-24 u-m-t-12">×{{item.number}}</view>
</view> </view>
</view> </view>
<template v-if="item.note">
<view class="u-p-20 bg-gray u-m-t-10">
{{item.note}}
</view>
</template>
<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 u-p-b-12"> <view class="u-m-t-32 u-flex no-wrap u-p-b-12">
<!-- <view class="u-flex u-m-r-20 u-m-b-20"> <!-- <view class="u-flex u-m-r-20 u-m-b-20">
@ -167,7 +173,8 @@
@tap="toggleWait(item)">{{item.isWait?'取消等叫':'等叫'}}</button> @tap="toggleWait(item)">{{item.isWait?'取消等叫':'等叫'}}</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('remark')">单品备注</button> <button class="tag" hover-class="hover-class"
@tap="showModel('remark',index)">单品备注</button>
</view> </view>
</view> </view>
</scroll-view> </scroll-view>
@ -214,7 +221,7 @@
<model-discount title="菜品打折/减免" :ref="setModel" name="discount" :price="allPrice"></model-discount> <model-discount title="菜品打折/减免" :ref="setModel" name="discount" :price="allPrice"></model-discount>
<give-food title="赠菜" :ref="setModel" name="giveFood"></give-food> <give-food title="赠菜" :ref="setModel" name="giveFood"></give-food>
<my-remark title="单品备注" :ref="setModel" name="remark"></my-remark> <my-remark @confirm="goodsOneRemarkConfirm" title="单品备注" :ref="setModel" name="remark"></my-remark>
<edit-discount title="优惠金额" :ref="setModel" name="editMoney" :price="allPrice"></edit-discount> <edit-discount title="优惠金额" :ref="setModel" name="editMoney" :price="allPrice"></edit-discount>
</view> </view>
@ -252,6 +259,10 @@
getNowCart getNowCart
} from '@/pagesCreateOrder/util.js' } from '@/pagesCreateOrder/util.js'
const models = new Map(); const models = new Map();
const modelData = reactive({
data: {},
selIndex: -1
})
// //
let note = ref('') let note = ref('')
@ -261,9 +272,11 @@
} }
} }
function showModel(key) { function showModel(key, index) {
modelData.data =goods.list[index]
modelData.selIndex =index
const model = models.get(key) const model = models.get(key)
model && model.open() model && model.open({remark:modelData.data.note})
} }
function formatPrice(n) { function formatPrice(n) {
@ -497,7 +510,9 @@
}) })
} else { } else {
// //
uni.navigateBack({delta:2}) uni.navigateBack({
delta: 2
})
// return go.to('PAGES_ORDER_DETAIL', { // return go.to('PAGES_ORDER_DETAIL', {
// id: res.id // id: res.id
// }) // })
@ -514,7 +529,21 @@
// }, 500) // }, 500)
} }
function init(){ //
async function goodsOneRemarkConfirm(e) {
const cart=goods.list[modelData.selIndex]
await Api.$updateCart({
cartId: cart.id,
productId: cart.productId,
skuId: cart.skuId,
tableId: option.tableId,
note: e.remark,
num: cart.number // 0
})
cart.note= e.remark
}
function init() {
} }
@ -548,7 +577,7 @@
useType = `dine-in-${isPayAfter? "after" : "before"}`; useType = `dine-in-${isPayAfter? "after" : "before"}`;
uni.setStorageSync("useType", useType); uni.setStorageSync("useType", useType);
} }
const tableId = useType=='takeout'?undefined: table.value.tableId; const tableId = useType == 'takeout' ? undefined : table.value.tableId;
const res = await Api.$changeUseType({ const res = await Api.$changeUseType({
useType, useType,
tableId, tableId,

View File

@ -49,6 +49,8 @@
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 infoBox from '@/commons/utils/infoBox.js'
import {$hasPermission} from '@/http/yskApi/shop.js'
import {hasPermission} from '@/commons/utils/hasPermission.js'
import { import {
onLoad, onLoad,
onShow, onShow,
@ -70,9 +72,18 @@
tuicai.isSeatFee = seatFee tuicai.isSeatFee = seatFee
tuicai.selGoods = seatFee tuicai.selGoods = seatFee
} }
//退
async function hasTuiKuan(){
const isHas=await hasPermission('允许退款')
return isHas
}
function onSeatFeeTuiKuan(seatFee) { async function onSeatFeeTuiKuan(seatFee) {
console.log(seatFee); console.log(seatFee);
const canTuikuan=await hasTuiKuan()
if(!canTuikuan){
return
}
const { const {
id, id,
productId, productId,
@ -139,7 +150,12 @@
}) })
} }
function onTuikuan(goods, index) {
async function onTuikuan(goods, index) {
const canTuikuan=await hasTuiKuan()
if(!canTuikuan){
return
}
const { const {
id, id,
productId, productId,
@ -147,6 +163,7 @@
productName, productName,
productSkuName, productSkuName,
cartId, cartId,
orderId,
num, num,
priceAmount, priceAmount,
price price
@ -154,6 +171,7 @@
go.to('PAGES_ORDER_TUIKUAN', { go.to('PAGES_ORDER_TUIKUAN', {
id, id,
cartId, cartId,
orderId,
productId, productId,
productSkuId, productSkuId,
productName, productName,

View File

@ -49,7 +49,8 @@
<text>退款原因</text> <text>退款原因</text>
</view> </view>
<view class="u-m-t-24 u-flex u-flex-wrap gap-28"> <view class="u-m-t-24 u-flex u-flex-wrap gap-28">
<view class="tag" @click="changeTuiKuanSel(index)" v-for="(item,index) in tuikuan.list" :key="index"> <view class="tag" @click="changeTuiKuanSel(index)" :class="{active:index==tuikuan.sel}"
v-for="(item,index) in tuikuan.list" :key="index">
{{item}} {{item}}
</view> </view>
</view> </view>
@ -60,7 +61,8 @@
<view style="height: 200rpx;"></view> <view style="height: 200rpx;"></view>
<view class="fixed-b"> <view class="fixed-b">
<up-button text="确认退款" shape="circle" type="primary" size="large" :color="color.ColorMain"></up-button> <up-button text="确认退款" @click="tuikuanConfirm" shape="circle" type="primary" size="large"
:color="color.ColorMain"></up-button>
</view> </view>
</view> </view>
@ -68,7 +70,12 @@
<script setup> <script setup>
import color from '@/commons/color.js'; import color from '@/commons/color.js';
import infoBox from '@/commons/utils/infoBox.js';
import * as orderApi from '@/http/yskApi/order.js' import * as orderApi from '@/http/yskApi/order.js'
import {hasPermission} from '@/commons/utils/hasPermission.js'
import {
$returnOrder
} from '@/http/yskApi/Instead.js'
import { import {
onLoad, onLoad,
onShow, onShow,
@ -84,7 +91,7 @@
let note = ref('') let note = ref('')
const tuikuan = reactive({ const tuikuan = reactive({
list: ['点错', '数量点错', '客人要求', '协商退费'], list: ['点错', '数量点错', '客人要求', '协商退费'],
sel: 0 sel: -1
}) })
function changeTuiKuanSel(i) { function changeTuiKuanSel(i) {
@ -98,40 +105,79 @@
} }
}) })
watch(()=>allTui.value,(newval)=>{ watch(() => allTui.value, (newval) => {
orderDetail.goodsList.map(v=>{ orderDetail.goodsList.map(v => {
v.number=newval?v.num:0 v.number = newval ? v.num : 0
}) })
}) })
const totalNumber = computed(() => {
return orderDetail.goodsList.reduce((prve, cur) => {
return prve + cur.num * 1
}, 0)
})
const tuikuanNumber = computed(() => {
return orderDetail.goodsList.reduce((prve, cur) => {
return prve + cur.number * 1
}, 0)
})
const totalPrice = computed(() => { const totalPrice = computed(() => {
return orderDetail.goodsList.reduce((prve, cur) => { return orderDetail.goodsList.reduce((prve, cur) => {
return prve+cur.priceAmount*1 return prve + cur.priceAmount * 1
}, 0) }, 0)
}) })
const tuikuanPrice = computed(() => { const tuikuanPrice = computed(() => {
return orderDetail.goodsList.reduce((prve, cur) => { return orderDetail.goodsList.reduce((prve, cur) => {
return prve+cur.number*cur.price return prve + cur.number * cur.price
}, 0) }, 0)
}) })
function to2(n){ function to2(n) {
return Number(n).toFixed(2) return Number(n).toFixed(2);
} }
function changeItem(item, step) { function changeItem(item, step) {
console.log(item); console.log(item);
let newval = item.number * 1 + step * 1 let newval = item.number * 1 + step * 1;
if (newval <= 0) { if (newval <= 0) {
newval = 0 newval = 0;
} }
if (newval >= item.num) { if (newval >= item.num) {
newval = item.num newval = item.num;
} }
item.number = newval item.number = newval;
allTui.value = totalNumber.value == tuikuanNumber.value ? true : false;
} }
async function tuikuanConfirm() {
const canTuikuan=await hasPermission('允许退款')
if(!canTuikuan){
return infoBox.showToast('您没有退款权限')
}
if (tuikuanNumber.value <= 0) {
return infoBox.showToast('退款商品数量不能为0')
}
const selTag=tuikuan.list[tuikuan.sel]
await $returnOrder({
"orderId": option.orderId,
"note":`${selTag?selTag:''}${note.value?(','+note.value):''}` ,
"orderDetails":orderDetail.goodsList.filter(v=>v.number*1).map(v=>{
return {
id:v.id,
num:v.number*1
}
})
})
infoBox.showToast('退款请求提交成功')
setTimeout(()=>{
uni.navigateBack({delta:1})
},500)
}
const option=reactive({})
onLoad((opt) => { onLoad((opt) => {
Object.assign(option,opt)
if (Array.isArray(opt)) { if (Array.isArray(opt)) {
orderDetail.goodsList = opt orderDetail.goodsList = opt
} else { } else {

View File

@ -8,6 +8,7 @@ H5, 不影响。
### 全局文件结构 ### 全局文件结构
* commons->utils>hasPermission.js 全局权限验证文件
* commons->style->global.scss 全局公共样式文件 * commons->style->global.scss 全局公共样式文件
* commons->style->uniStyle.css 覆写uniapp 组件样式文件 * commons->style->uniStyle.css 覆写uniapp 组件样式文件
* commons->style->variable.css scss 变量 * commons->style->variable.css scss 变量