店铺详情收款码下载处理,耗材报损增加

This commit is contained in:
GaoHao 2024-09-28 15:16:31 +08:00
parent fad44dd3c5
commit 78580644f5
11 changed files with 252 additions and 180 deletions

View File

@ -2,24 +2,24 @@
<up-popup customStyle="overflow: hidden;" :show="show" round="20" mode="bottom" @close="close" @open="open"> <up-popup customStyle="overflow: hidden;" :show="show" round="20" mode="bottom" @close="close" @open="open">
<view class="reportDamage"> <view class="reportDamage">
<view class="reportDamage_head"> <view class="reportDamage_head">
<view class="reportDamage_title">{{item.title}}</view> <view class="reportDamage_title">{{title}}</view>
<up-icon name="close-circle-fill" color="#333" size="25" @tap="show=false"></up-icon> <up-icon name="close-circle-fill" color="#333" size="25" @tap="close"></up-icon>
</view> </view>
<view class="reportDamage_content"> <view class="reportDamage_content">
<view class="reportDamage_cell"> <view class="reportDamage_cell">
<view class="cell_lable"> <view class="cell_lable">
<up-image class="thumbnail" radius="10" :show-loading="true" :src="item.thumbnail"></up-image> <up-image v-if="type=='product'" class="thumbnail" radius="10" :show-loading="true" :src="item.coverImg"></up-image>
<view>{{item.name}}</view> <view>{{item.conName}}</view>
</view> </view>
<view class="cell_value"> <view class="cell_value">
<up-icon name="minus-circle" color="#999" size="25" @tap="minus"></up-icon> <up-icon name="minus-circle" color="#999" size="25" @tap="minus"></up-icon>
<view class="text">{{vdata.num}}</view> <view class="text">{{vdata.stockNumber}}</view>
<up-icon name="plus-circle-fill" color="#318AFE" size="25" @tap="plus"></up-icon> <up-icon name="plus-circle-fill" color="#318AFE" size="25" @tap="plus"></up-icon>
</view> </view>
</view> </view>
<view class="reportDamage_cell"> <view class="reportDamage_cell">
<view class="cell_lable">商品单位</view> <view class="cell_lable">商品单位</view>
<view class="cell_value"><view></view> <up-icon name="arrow-right" color="#999999" size="15"></up-icon></view> <view class="cell_value"><view>{{item.conUnit}}</view> <up-icon name="arrow-right" color="#999999" size="15"></up-icon></view>
</view> </view>
<view class="reportDamage_cell"> <view class="reportDamage_cell">
<view class="cell_lable">报损图片</view> <view class="cell_lable">报损图片</view>
@ -49,14 +49,25 @@
computed, computed,
ref, ref,
reactive, reactive,
onMounted,
watch watch
} from 'vue'; } from 'vue';
import { $uploadFile } from '@/http/yskApi/file.js' import { $uploadFile } from '@/http/yskApi/file.js'
import { consumableBreakage , productBreakage ,tbConCheck} from '@/http/yskApi/breakage.js'
const props = defineProps({ const props = defineProps({
show:{ show:{
type: Boolean, type: Boolean,
default: false default: false
}, },
type:{
type: String,
default: ""
},
title:{
type: String,
default: ""
},
item:{ item:{
type: Object, type: Object,
}, },
@ -64,16 +75,23 @@
}) })
const emits = defineEmits(['close','open',"affirm"]) const emits = defineEmits(['close','open',"affirm"])
const vdata = reactive({ const vdata = reactive({
num: 1, stockNumber: 1,
imgUrlList: [], imgUrlList: [],
}) })
let show = ref(props.show)
let type = ref(props.type)
let itemData = ref(props.item)
watch(()=>props.show,(newval)=>{ watch(()=>props.show,(newval)=>{
show.value=newval show.value=newval
}) })
let show = ref(props.show) onMounted(() => {
})
function close() { function close() {
show.value = false show.value = false;
vdata.imgUrlList = [];
vdata.stockNumber = 1;
emits('close') emits('close')
} }
@ -81,7 +99,7 @@
* 打开报损弹窗 * 打开报损弹窗
*/ */
function open() { function open() {
show.value = true show.value = true;
emits('open') emits('open')
} }
@ -89,17 +107,17 @@
* 报损数量减少 * 报损数量减少
*/ */
function minus() { function minus() {
if ( vdata.num <= 1) { if ( vdata.stockNumber <= 1) {
return; return;
} }
vdata.num--; vdata.stockNumber--;
} }
/** /**
* 报损数量增加 * 报损数量增加
*/ */
function plus() { function plus() {
vdata.num++; vdata.stockNumber++;
} }
@ -155,7 +173,28 @@
* 确认 * 确认
*/ */
function affirm () { function affirm () {
emits('affirm') // emits('affirm')
if (vdata.imgUrlList.length <= 0) {
uni.showToast({
title:'请上传报损图片',
icon:'none'
})
return;
}
let params = {
coverImg: vdata.imgUrlList,
}
//
if ( type.value == 'consumable') {
params.consId = itemData.value.conIn;
params.amount = vdata.stockNumber;
}
consumableBreakage(params).then((res) => {
show.value = false;
vdata.imgUrlList = [];
vdata.stockNumber = 1;
})
} }
defineExpose({ defineExpose({

33
http/yskApi/breakage.js Normal file
View File

@ -0,0 +1,33 @@
import http from './http.js'
const request=http.request
/**
* 商品报损
* @returns
*/
export function productBreakage(data) {
return request({
url: `/api/tbProductStockDetail/frmLoss`,
method: 'post',
data:{
shopId: uni.getStorageSync('shopId'),
...data
}
})
}
/**
* 耗材报损
* @returns
*/
export function consumableBreakage(data) {
return request({
url: `/api/tbConsInfoFlow/frmLoss`,
method: 'post',
data:{
shopId: uni.getStorageSync('shopId'),
...data
}
})
}

View File

@ -71,7 +71,7 @@
</view> </view>
<my-action-sheet @itemClick="sheetClick" ref="refMoreSheet" :list="actionSheet.list"></my-action-sheet> <my-action-sheet @itemClick="sheetClick" ref="refMoreSheet" :list="actionSheet.list"></my-action-sheet>
<my-reportDamage ref="reportDamage" :item="report.data" @affirm="affirm"></my-reportDamage> <my-reportDamage ref="reportDamage" :title="'耗材报损'" :type="'consumable'" :show="report.show" :item="report.data" @affirm="affirm"></my-reportDamage>
</template> </template>
<script setup> <script setup>
@ -109,11 +109,11 @@
let reportDamage = ref(null) let reportDamage = ref(null)
const report = reactive({ const report = reactive({
data: { data: {
thumbnail: 'https://cashier-oss.oss-cn-beijing.aliyuncs.com/upload/20240918/a17a62b7b55a4b65a2a2542050672b34.png', conIn: 960,
name: "美式咖啡", conName: "味精",
title: "商品报损", conUnit: "克",
unit: "杯",
}, },
show: false,
}) })
/** /**
* 报损确认 * 报损确认

View File

@ -12,6 +12,7 @@
<uni-icons type="right" size="16" color="#000"></uni-icons> <uni-icons type="right" size="16" color="#000"></uni-icons>
</view> </view>
</view> </view>
<text class="u-font-28 color-666" @click="reportDamage">报损</text>
<text class="u-font-28 color-666" @click="changeClick">修改</text> <text class="u-font-28 color-666" @click="changeClick">修改</text>
</view> </view>
@ -89,7 +90,7 @@
import { import {
ColorMain ColorMain
} from '@/commons/color.js' } from '@/commons/color.js'
const emits = defineEmits(['radioClick', 'changeClick', 'xiajia','del']) const emits = defineEmits(['radioClick', 'reportDamage','changeClick', 'xiajia','del'])
const props = defineProps({ const props = defineProps({
index: { index: {
type: Number type: Number
@ -143,6 +144,9 @@
emits('changeClick', props.index) emits('changeClick', props.index)
} }
function reportDamage () {
emits('reportDamage', props.index)
}
function xiajia() { function xiajia() {
emits('xiajia', props.index) emits('xiajia', props.index)
} }

View File

@ -44,7 +44,7 @@
<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 @changeClick="goodsChangeClick" @reportDamage="reportDamageClick" @radioClick="goodsRadioClick" :index="index" :data="item"
@del="goodsDel" @del="goodsDel"
:showChecked="showChecked" :showDetail="pageData.showGoodsDetail"></my-goods> :showChecked="showChecked" :showDetail="pageData.showGoodsDetail"></my-goods>
</view> </view>
@ -118,6 +118,9 @@
</view> </view>
</template> </template>
</my-model> </my-model>
<!-- 商品报损 -->
<my-reportDamage ref="reportDamage" :title="'商品报损'" :type="'product'" :show="reportShow" :item="pageData.reportData" @affirm="affirm"></my-reportDamage>
</view> </view>
</template> </template>
@ -145,6 +148,7 @@
import myModel from "@/components/my-components/my-model.vue" import myModel from "@/components/my-components/my-model.vue"
import myButton from "@/components/my-components/my-button.vue" import myButton from "@/components/my-components/my-button.vue"
import mySwitch from "@/components/my-components/my-switch.vue" import mySwitch from "@/components/my-components/my-switch.vue"
import myReportDamage from '@/components/my-components/my-reportDamage';
import { import {
$tbProduct, $tbProduct,
$upProSort, $upProSort,
@ -173,7 +177,9 @@
category:'', category:'',
categoryShow:false, categoryShow:false,
categoryName:'', categoryName:'',
hasAjax:false hasAjax:false,
reportShow: false, //
reportData: {}, //
}) })
function onCategoryShowChange(show){ function onCategoryShowChange(show){
console.log(show); console.log(show);
@ -208,7 +214,12 @@
const control = ref(null) const control = ref(null)
const model = ref(null) const model = ref(null)
const goodsStockModel = ref(null) const goodsStockModel = ref(null)
let reportDamage = ref(null) //
//
function reportDamageClick(index) {
pageData.reportData = pageData.goodsList[index]
reportDamage.value.open();
}
function returnGoodsStockData() { function returnGoodsStockData() {
return reactive({ return reactive({
sort: 0, sort: 0,
@ -256,6 +267,7 @@
Object.assign(goodsStockData,goods) Object.assign(goodsStockData,goods)
goodsStockModel.value.open() goodsStockModel.value.open()
} }
// //
function goodsDel(index){ function goodsDel(index){
const goods = pageData.goodsList[index] const goods = pageData.goodsList[index]

View File

@ -49,6 +49,26 @@
</view><up-icon name="arrow-right" color="#999999" size="15"></up-icon> </view><up-icon name="arrow-right" color="#999999" size="15"></up-icon>
</view> </view>
</view> </view>
<view class="page-cell m">
<view class="label">付费模式</view>
<view class="right">
<up-radio-group
v-model="vdata.shopInfo.registerType"
placement="row"
>
<up-radio
:customStyle="{marginRight: '10px'}"
v-for="(item, index) in vdata.registerTypeList"
:key="index"
:label="item.name"
:name="item.value"
@change="radioChange"
>
</up-radio>
</up-radio-group>
</view>
</view>
<view class="page-cell" @tap="go.to('PAGES_SHOP_QRCODE',{paymentQrcode: vdata.shopInfo.paymentQrcode})"> <view class="page-cell" @tap="go.to('PAGES_SHOP_QRCODE',{paymentQrcode: vdata.shopInfo.paymentQrcode})">
<view class="label">店铺收款码</view> <view class="label">店铺收款码</view>
<view class="right"><up-icon name="arrow-right" color="#999999" size="15"></up-icon></view> <view class="right"><up-icon name="arrow-right" color="#999999" size="15"></up-icon></view>
@ -65,13 +85,13 @@
</view> </view>
<view class="extend_content"> <view class="extend_content">
<view class="preview"> <view class="preview">
<up-image class="index_bg" v-if="'index_bg' == vdata.extendInfo.autokey" :src="vdata.extendInfo.value"></up-image> <view class="index_bg"><up-image v-if="'index_bg' == vdata.extendInfo.autokey" :src="vdata.extendInfo.value"></up-image></view>
<up-image class="my_bg" v-if="'my_bg' == vdata.extendInfo.autokey" :src="vdata.extendInfo.value"></up-image> <view class="my_bg"><up-image v-if="'my_bg' == vdata.extendInfo.autokey" :src="vdata.extendInfo.value"></up-image></view>
<up-image class="bg" v-if="'member_bg' == vdata.extendInfo.autokey" :src="'https://czg-qr-order.oss-cn-beijing.aliyuncs.com/cashier_admin_app_shopSet/'+vdata.extendInfo.autokey+'1.png'" ></up-image> <view class="bg"><up-image v-if="'member_bg' == vdata.extendInfo.autokey" :src="'https://czg-qr-order.oss-cn-beijing.aliyuncs.com/cashier_admin_app_shopSet/'+vdata.extendInfo.autokey+'1.png'" ></up-image></view>
<up-image class="member_bg" v-if="'member_bg' == vdata.extendInfo.autokey" :src="vdata.extendInfo.value"></up-image> <view class="member_bg"><up-image v-if="'member_bg' == vdata.extendInfo.autokey" :src="vdata.extendInfo.value"></up-image></view>
<up-image class="shopinfo_bg" v-if="'shopinfo_bg' == vdata.extendInfo.autokey" :src="vdata.extendInfo.value"></up-image> <view class="shopinfo_bg"><up-image v-if="'shopinfo_bg' == vdata.extendInfo.autokey" :src="vdata.extendInfo.value"></up-image></view>
<view class="shopinfo_bg_f" v-if="'shopinfo_bg' == vdata.extendInfo.autokey"></view> <view class="shopinfo_bg_f" v-if="'shopinfo_bg' == vdata.extendInfo.autokey"></view>
<up-image class="bg" :src="'https://czg-qr-order.oss-cn-beijing.aliyuncs.com/cashier_admin_app_shopSet/'+vdata.extendInfo.autokey+'.png'" ></up-image> <view class="bg"><up-image :src="'https://czg-qr-order.oss-cn-beijing.aliyuncs.com/cashier_admin_app_shopSet/'+vdata.extendInfo.autokey+'.png'" ></up-image></view>
</view> </view>
<view class="extend_img"> <view class="extend_img">
<view class="extend_title">{{vdata.extendInfo.title}}背景图片</view> <view class="extend_title">{{vdata.extendInfo.title}}背景图片</view>
@ -83,7 +103,7 @@
</view> </view>
</view> </view>
</view> </view>
<view class="cutShop" @tap="go.to('PAGES_SHOP_LIST')">切换门店</view> <!-- <view class="cutShop" @tap="go.to('PAGES_SHOP_LIST')">切换门店</view> -->
</view> </view>
@ -103,6 +123,10 @@ const phone = ref(null)
const vdata = reactive({ const vdata = reactive({
shopInfo: {}, shopInfo: {},
extendList: [], extendList: [],
registerTypeList: [
{name: "先付费", value: "munchies"},
{name: "后付费", value: "restaurant"}
],
extendIndex: 0, extendIndex: 0,
extendInfo: {}, extendInfo: {},
dineIn: false, dineIn: false,
@ -115,7 +139,6 @@ const vdata = reactive({
maxLength: '999', maxLength: '999',
}) })
onMounted(() => { onMounted(() => {
shopExtend(); shopExtend();
}) })
@ -128,14 +151,14 @@ onShow(() => {
}); });
}) })
/**
* 输入内容修改
*/
let refreshData = (e) => { let refreshData = (e) => {
let params = { let params = {
id : vdata.shopInfo.id, id : vdata.shopInfo.id,
} }
for(let item in params){
params[e.name] = e.value;
}
vdata.type = e.name;
vdata.inputValue = e.value; vdata.inputValue = e.value;
updateShopInfo(params,'input') updateShopInfo(params,'input')
} }
@ -171,6 +194,18 @@ let shopExtend = () => {
}) })
} }
/**
* 付费模式修改
*/
let radioChange = (n) => {
console.log('radioChange', n);
let params = {
id : vdata.shopInfo.id,
registerType : n,
}
updateShopInfo(params)
};
/** /**
* 修改 * 修改
*/ */
@ -194,7 +229,7 @@ let updateShopInfo = (params,type) => {
} }
/** /**
* 修改 * 修改店铺图片
*/ */
let updateShopExtend = () => { let updateShopExtend = () => {
editShopExtend(vdata.extendInfo).then((res) => { editShopExtend(vdata.extendInfo).then((res) => {

View File

@ -3,10 +3,12 @@
<view class="content"> <view class="content">
<view class="title">门店收款码</view> <view class="title">门店收款码</view>
<view ref="qrcode" class="qrcode"> <view ref="qrcode" class="qrcode">
<up-qrcode :size="vdata.size" @result="result" :val="vdata.paymentQrcode"></up-qrcode> <!-- <up-qrcode cid="123" :size="vdata.size" @result="result" :val="vdata.paymentQrcode"></up-qrcode> -->
<!-- <canvas canvas-id="qrcodeCanvas" style="width: 200px; height: 200px;"></canvas> -->
<image :src="vdata.paymentQrcodeUrl" style="width: 100%;height: 100%;" mode="scaleToFill" />
</view> </view>
<view class="bom"> <view class="bom">
<view @click="download">下载收款码</view> <view @click="saveImage">下载收款码</view>
<view>下载收款码样式</view> <view>下载收款码样式</view>
</view> </view>
</view> </view>
@ -18,18 +20,19 @@
<script setup> <script setup>
import { reactive, ref, onMounted } from 'vue'; import { reactive, ref, onMounted } from 'vue';
import { onLoad, onShow } from '@dcloudio/uni-app'; import { onLoad, onShow } from '@dcloudio/uni-app';
import ak from '@/commons/utils/ak.js'; import infoBox from '@/commons/utils/infoBox.js'
import { getShopList } from '@/http/yskApi/shop.js' import qrCode from '@/commons/utils/qrCode.js'
import { saveHeadImgFile } from '@/commons/utils/saveImg.js'
const vdata = reactive({ const vdata = reactive({
size: 0, size: 20,
qrcodeUrl: null, qrcodeUrl: null,
paymentQrcode: null, paymentQrcode: null,
paymentQrcodeUrl: "",
}); });
onLoad((options) => { onLoad((options) => {
vdata.paymentQrcode = options.paymentQrcode; vdata.paymentQrcodeUrl = qrCode.drawImg(options.paymentQrcode)
}) })
@ -39,105 +42,99 @@ onShow(() => {
}) })
onMounted(() => { onMounted(() => {
//
let query = uni.createSelectorQuery().in(this);
query.select('.qrcode').boundingClientRect(data => {
if (data) {
vdata.size = data.width
}
}).exec();
}) })
/** const saveImage = () => {
* 二维码图片 // #ifdef APP-PLUS
*/ saveQrcodeImg()
let result = (e) => { uni.downloadFile({
vdata.qrcodeUrl = e; url: vdata.paymentQrcodeUrl,
console.log(vdata.qrcodeUrl)
let blob = dataURLtoBlob()
console.log(blob)
}
let dataURLtoBlob = (dataurl) => {
var arr = vdata.qrcodeUrl.split(',')
var mime = arr[0].match(/:(.*?);/)[1]
var bstr = atob(arr[1])
var n = bstr.length
var u8arr = new Uint8Array(n)
while (n--) {
u8arr[n] = bstr.charCodeAt(n)
}
return new Blob([u8arr], { type: mime })
}
let saveImageToPhotosAlbum = (imgSrc) => {
let base64 = imgSrc.replace(/^data:image\/\w+;base64,/, ""); //
let filePath = '123' + '/qrcode.png';
uni.getFileSystemManager().writeFile({
filePath: filePath, //
data: base64, //
encoding: 'base64', //
success: (res) => { success: (res) => {
uni.saveImageToPhotosAlbum({ console.log(res)
filePath: filePath, if (res.statusCode == 200) {
success: () => { uni.saveImageToPhotosAlbum({
uni.showToast({ filePath: res.tempFilePath,
title: '保存成功', success: (r) => {
icon: "none", infoBox.showSuccessToast('保存成功')
duration: 5000 uni.vibrateShort()
}) },
}, fail: (er) => {
fail: (err) => { console.log(er)
console.log(err); infoBox.showErrorToast('保存失败')
uni.showToast({ }
title: '保存失败', })
icon: "none", }
duration: 5000
})
}
})
}, },
fail: (err) => { fail: (err) => {
console.log(err) console.log(err)
infoBox.showErrorToast('保存失败')
} }
}) })
// #endif
//#ifdef MP-WEIXIN
downloadQR()
//#endif
} }
//#ifdef MP-WEIXIN
let getUrlBase64 = (url) => { function downloadQR() {
return new Promise(resolve => { wx.getSetting({
let canvas = document.createElement('canvas') //
let ctx = canvas.getContext('2d') success(res) {
let img = new Image() if (res.authSetting['scope.writePhotosAlbum']) {
img.crossOrigin = 'Anonymous' // saveWxQrcodeImg(vdata.paymentQrcodeUrl)
img.src = vdata.qrcodeUrl } else {
img.onload = function() { wx.authorize({
canvas.height = 300 scope: 'scope.writePhotosAlbum',
canvas.width = 300 success() {
ctx.drawImage(img, 0, 0, 300, 300) saveWxQrcodeImg(vdata.paymentQrcodeUrl)
let dataURL = canvas.toDataURL('image/png') },
canvas = null })
resolve(dataURL) }
} },
})
}
let download = () => {
// base64
let link = document.createElement('a')
let url = vdata.qrcodeUrl//
// urlblob
fetch(url).then(res => res.blob()).then(blob => { //blob
link.href = URL.createObjectURL(blob)
console.log(link.href)
link.download ='QrCode'
document.body.appendChild(link)
link.click()
}) })
} }
//#endif
const saveQrcodeImg = () => {
saveHeadImgFile(vdata.paymentQrcodeUrl, 80)
.then((success) => {
infoBox.showSuccessToast('保存成功')
})
.catch((err) => {
console.log(err)
infoBox.showErrorToast('保存失败')
})
}
const saveWxQrcodeImg = (data) => {
const fileManager = wx.getFileSystemManager()
console.log( )
const filePath = wx.env.USER_DATA_PATH + '/qrCode'+new Date().getTime()+'.png'
//
fileManager.writeFile({
filePath: filePath,
data: data.slice(22),
encoding: 'base64',
success: (res) => {
wx.saveImageToPhotosAlbum({
filePath: filePath,
success: function (res) {
//
infoBox.showSuccessToast('保存成功')
},
fail: function (err) {
console.log(err)
//
infoBox.showErrorToast('保存失败')
},
})
},
fail: (err) => {
infoBox.showErrorToast('保存失败')
},
})
}

View File

@ -1,15 +0,0 @@
'use strict';
const uniPush = uniCloud.getPushManager({
appId: "__UNI__71D61A3"
})
exports.main = async (event, context) => {
//event为客户端上传的参数
const body = JSON.parse(event.body)
console.log('入参', {
cids: body.cids
});
const data = await uniPush.getDeviceStatusByCid(body.cids)
//返回数据给客户端
return data
};

View File

@ -1,7 +0,0 @@
{
"name": "queryCids",
"dependencies": {},
"extensions": {
"uni-cloud-push": {}
}
}

View File

@ -1,19 +0,0 @@
'use strict';
const uniPush = uniCloud.getPushManager({
appId: "__UNI__71D61A3"
})
exports.main = async (event, context) => {
//event为客户端上传的参数
console.log('event : ', event)
let obj = JSON.parse(event.body)
return await uniPush.sendMessage({
"push_clientid": obj.cids, // 设备id支持多个以数组的形式指定多个设备如["cid-1","cid-2"]数组长度不大于1000
"title": obj.title, // 标题
"content": obj.content, // 内容
"payload": obj.data, // 数据
// "force_notification": true, // 服务端推送 需要加这一句
// "badge": +1, // 服务端推送 需要加这一句
"request_id": obj.request_id //请求唯一标识号10-32位之间如果request_id重复会导致消息丢失
})
};

View File

@ -1,7 +0,0 @@
{
"name": "unipush",
"dependencies": {},
"extensions": {
"uni-cloud-push": {}
}
}