<template> <div class="new-contoner"> <div class="left-box"> <div class="box-top"> <div class="o-top" v-if="userInfo"> <div style="width: 50%"> <div class="d-s"> <img src="./imgs/new_user.png" style="width: 28px;height: 28px;margin-right: 10px"> <div > <div style="font-weight: bold">{{chooseVipUser.name||'匿名'}}</div> <div class="d-s"> <span>{{chooseVipUser.mobile}}</span> <img src="./imgs/fz.png" @click="copyToClipboard(chooseVipUser.mobile)" style="width: 17px;height: 17px;margin: 0px 10px"> <img src="./imgs/vipicon.png" style="width: 23px;height: 19px;"> </div> </div> </div> <div class="d-s" > <div style="font-size: 12px;margin-right: 5px">储值卡:¥{{chooseVipUser.cardBalance}} </div> <div style="font-size: 12px">囤油卡:¥1000.000</div> </div> </div> <div class="d-s" style="width: 50%"> <div class="an_bor" @click="addMemberRecharge()">会员充值</div> <div class="an_bor" @click="restVipUser">重置会员</div> <div class="an_bor" @click="addFreeTicket()" >赠送优惠券</div> </div> </div> <div class="o-top" v-if="!userInfo"> <div class="left_input"> <el-autocomplete v-model="userMobile" style="width: 95%;margin: 15px " :fetch-suggestions="getUser" placeholder="请输入会员手机号" > <template slot-scope="{ item }"> <div class="name" @click="chooseUser(item)">{{ item.name+" "+item.mobile }}</div> </template> </el-autocomplete> </div> <div class="d-s"> <div class="an_bor" @click="addVip()">新增会员</div> </div> <!-- 渲染会员列表 --> <div class="taber-box" v-for="(item,index) in vipUserList" :key="index"> <div class="goods_name"> <!-- <img src="../../../assets/images/goods.png" style="width: 30px;height: 30px">--> {{ item.name }} </div> </div> </div> <div class="t-top"> <div class="three_box">油品:¥{{ oilGunClearing.amount || 0.00 }}</div> <div style="color: #F4F5F9">|</div> <div class="three_box">商品:¥{{ getGoodsNum }}</div> <div style="color: #F4F5F9">|</div> <div class="three_box">合计:¥{{ orderAmount }}</div> </div> <div class="d-top"> <div class="d-b"> <el-checkbox v-model="checkAll">活动优惠 <i class="el-icon-arrow-down"></i></el-checkbox> <div class="or_num">-¥0.00</div> </div> <!-- 下拉列表插入--> <div v-if="checkAll == true"> <div v-if="activityList.length>0"> <el-radio-group style="width: 100%" v-model="chooseAct"> <div class="x-d-b" v-for="(item,index) in activityList"> <el-radio :label="item.id">{{null==item.ruleName?item.actName:item.ruleName}}<div class="or_num">-¥{{item.disAmount}}</div></el-radio> </div> </el-radio-group> </div> <div v-if="activityList.length==0"> 暂无可用优惠活动 </div> </div> <div class="d-b"> <el-checkbox v-model="checkAll">优惠券 <i class="el-icon-arrow-down"></i></el-checkbox> <div class="or_num">-¥0.00</div> </div> <!-- 下拉列表插入--> <div v-if="checkAll == true"> <div class="x-d-b"> <el-checkbox v-model="checkAll1">优惠券1</el-checkbox> <div class="or_num">-¥0.00</div> </div> <div class="x-d-b"> <el-checkbox v-model="checkAll2">优惠券2</el-checkbox> <div class="or_num">-¥0.00</div> </div> <div class="x-d-b"> <el-checkbox v-model="checkAll3">优惠券3</el-checkbox> <div class="or_num">-¥0.00</div> </div> </div> </div> <div class="three-top"> <div class="addbor"> <div class="">扫码支付</div> <div class="or_num">0.00</div> </div> <div class="addbor"> <div class="">找零</div> <div class="or_num">0.00</div> </div> <div class="addbor"> <div class="">加油员</div> <div class="or_num">0.00</div> </div> </div> <div class="er-box"></div> <div class="wrap-box"> <div class="f-box" v-for="(item,index) in payList" :class="{'f-acvite' : item.dictValue == payWay }" @click="setindex(item.dictValue)" :key="item.dictValue" >{{ item.dictLabel }} </div> </div> </div> <div class="box-bottom"> <div> <div class="price_">¥0.00</div> <div class="price_prefer">优惠合计:¥0.00元</div> </div> <div class="anniu">立即结算</div> </div> </div> <div class="cont-box"> <div class="box-top"> <div class="cont-tab"> <div class="tab-box" v-for="(value,key,index) in tabList" :key="index" @click="setTabindex(key,index)"> <div class="tab-name" :class="{ 'active_name' : tabIndex == index }">{{ key }}</div> <div class="gang" :class="{ 'active_gang' : tabIndex == index }"></div> </div> </div> <div class="tab-kuang" style="flex-wrap: wrap"> <div :class=item.classStyle v-for="(item,index) in dataList" @click="setRefuelingAmount(item)"> <div>{{ item.oilType }} {{ item.oilName }}</div> <div class="card-title">{{ item.gunName }}</div> <div class="c-b-d"> <img :src=item.img style="width: 16px;height: 16px"> <div>{{ item.oilName }} {{ item.oilType + '罐' }}</div> </div> </div> </div> <div class="c-bottom"> {{ getGoodsItem }} </div> <div class="bottom-b-d"> <!-- <div>订单笔数 <span style="color: #FF9655">0件</span></div>--> <div>油品金额 <span style="color: #FF9655">¥{{ oilGunClearing.amount || 0.00 }}</span></div> </div> </div> <div class="box-bottom"> <div class="anniu-c" @click="oilGunReset()"> 重置 </div> </div> </div> <div class="right-box"> <div class="box-top"> <div class="r-top">非油商品</div> <el-autocomplete style="width: 95%;margin: 15px " popper-class="my-autocomplete" v-model="state" :fetch-suggestions="querySearchAsync" placeholder="请输入内容" @select="handleSelect" > <template slot-scope="{ item }"> <div class="name">{{ item.name }}</div> </template> </el-autocomplete> <div class="taber-top"> <div class="goods_name">商品</div> <div class="stock_name">库存</div> <div class="u-price_name">单价</div> <div class="num_name">数量</div> <div class="orerate_name">操作</div> </div> <!-- 渲染商品列表 --> <div class="taber-box" v-for="(item,index) in goodsList" :key="index"> <div class="goods_name"> <!-- <img src="../../../assets/images/goods.png" style="width: 30px;height: 30px">--> {{ item.name }} </div> <div class="stock_name">{{ item.stock }}</div> <div class="u-price_name">{{ item.retailPrice }}</div> <div class="num_name">{{ item.num }}</div> <div class="orerate_name"> <span style="color: red;cursor: pointer" @click="deleteGoods(item.id)">删除</span> </div> </div> <div class="bottom-b-d"> <div>商品总数 <span style="color: #FF9655">{{ getGoodsListNum }}件</span></div> <div>商品总金额 <span style="color: #FF9655">¥{{ getGoodsNum }}</span></div> </div> </div> <div class="box-bottom"> <div class="anniu-c" @click="goodsReset()"> 重置 </div> <div class="d-s"> <div class="anniu-lv" @click="invokePickUpTheOrder">取单</div> <div class="anniu-lan" @click="invokeHangingAnOrder">挂单</div> </div> </div> </div> <!-- 弹窗--> <el-dialog title="送券" :visible.sync="freeTicket" width="800px" > <div class="ds-tc"> <div class="left_tc"> <div class="t-tc"> <div style="font-size: 18px;font-weight: bold">所有卡券</div> <div style="font-size: 16px;color: #ff9655">打印所有二维码</div> </div> <div class="wrap-tc"> <div class="tc_wa" :class="{'tc-active' : freeIndex == index }" @click="setFreeIndex(index)" v-for="(item,index) in freeTicketList">{{ item.name }} </div> </div> </div> <div class="right_tc"> <div style="font-weight: 600;font-size: 16px;color: #333333;text-align: center;margin-bottom: 15px"> 优惠价格固定1元 </div> <div style="font-weight: 600;font-size: 16px;color: #333333;margin-bottom: 10px">油品立减券</div> <div style="margin-bottom: 10px">可用时间:周一至周日 全天</div> <div style="display: flex"> <div style="width: 70px">可用日期:</div> <div style="width: 150px">2024-09-01 12:00:00至2024-09-01 12:00:00</div> </div> <div style="font-weight: 600;font-size: 16px;color: #333333;margin-bottom: 5px">使用规则</div> <div>优惠说明:价值10元代金券一张消费满100可用</div> <div style="margin-top: 20px;text-align: end"> <el-button type="primary" >确定赠送</el-button> </div> </div> </div> </el-dialog> <el-dialog title="新增会员" :visible.sync="newMember" width="439px" center > <div class="tc-box"> <div>请顾客扫码领取会员卡</div> <img id="collection" class="qrcode" :src="baseUrl + collectionImg"/><br/> <div class="red-size">微信扫一扫</div> </div> <span slot="footer" class="dialog-footer"> <el-button type="primary" @click="handleDownloadqrCode('collection')">下载二维码</el-button> </span> </el-dialog> <el-dialog title="扫码支付" :visible.sync="ScanCodePayment" width="439px" center > <div class="tc-box"> <div class="title_">收款: <span style="color: #F44522">¥0.00</span></div> <img src="./imgs/smzf.png" style="width: 171px;height: 122px;"> <div>请顾客出示付款码,或者刷脸支付</div> </div> <span slot="footer" class="dialog-footer"> <el-button type="primary" @click="ScanCodePayment = false">关闭</el-button> </span> </el-dialog> <el-dialog title="现金支付" :visible.sync="cashPayment" width="439px" center > <div class="tc-box"> <div class="title_">应收款: <span style="color: #F44522">¥98.00</span></div> <el-form :model="ruleForm" :rules="rules" ref="ruleForm" label-width="100px" class="demo-ruleForm"> <el-form-item label="收款金额" prop="name"> <el-input v-model="ruleForm.name"> <template slot="append">元</template> </el-input> </el-form-item> <div class="t-size"> 应找零:<span style="color: #F44522">¥20.00</span> </div> </el-form> </div> <span slot="footer" class="dialog-footer"> <el-button type="primary" @click="cashPayment = false">确定收款</el-button> </span> </el-dialog> <el-dialog title="挂单" :visible.sync="hangingAnOrder" width="542px" center > <div class="tc-box"> <el-form :model="ruleForms" :rules="rules" ref="ruleForm" label-width="100px" class="demo-ruleForm"> <el-form-item label="挂单名称" prop="name"> <el-input v-model="ruleForms.name"> </el-input> </el-form-item> <div class="h-size"> 挂单只可将非油商品进行挂单,挂单成功后可在取单页面进行取单操作、取单 时,可根据挂单名称取单 </div> </el-form> </div> <span slot="footer" class="dialog-footer"> <el-button @click="hangingAnOrder = false">取 消</el-button> <el-button type="primary" @click="pendingOrders()">确定挂单</el-button> </span> </el-dialog> <el-dialog title="支付结果" :visible.sync="paymentResults" width="439px" center > <div class="tc-box"> <div class="hui-box"> <div class="hui-box-bt"> <div>支付方式</div> <div>现金</div> </div> <div class="hui-box-bt"> <div>实付金额</div> <div>¥0.00</div> </div> <div class="hui-box-bt"> <div>订单金额</div> <div>¥10.00</div> </div> </div> </div> <span slot="footer" class="dialog-footer"> <el-button type="primary" @click="paymentResults = false">关闭(3s)</el-button> </span> </el-dialog> <el-dialog title="取单" :visible.sync="pickUpTheOrder" width="910px" center > <!-- 商品挂单 子组件 --> <pickUp :pendingOrdersList="pendingOrdersList" @fatherPendingOrdersList="fatherPendingOrdersList" @fatherPendingOrdersName="fatherPendingOrdersName" ></pickUp> <span slot="footer" class="dialog-footer"> <el-button @click="pickUpTheOrder = false">取消</el-button> <!-- pendingOrdersList pickUpTheOrder = false pickUpTheOrder = false --> <el-button type="primary" @click="deletePendingOrdersList">作废</el-button> <el-button type="primary" @click="getPendingOrdersList">取单</el-button> </span> </el-dialog> <el-dialog title="挂账" :visible.sync="accountPending" width="542px" center > <accountPending></accountPending> <span slot="footer" class="dialog-footer"> <el-button @click="accountPending = false">取 消</el-button> <el-button type="primary" @click="accountPending = false">确 定</el-button> </span> </el-dialog> <el-dialog title="会员充值" :visible.sync="memberRecharge" width="910px" center > <memberRecharge :userId="chooseVipUser.id" ref="rechargeRef"></memberRecharge> <span slot="footer" class="dialog-footer"> <el-button @click="memberRecharge = false">取 消</el-button> <el-button type="primary" @click="rechargeConfirm()">确认充值</el-button> </span> </el-dialog> <el-dialog title="加油金额" :visible.sync="refuelingAmount" width="542px" center > <div class="tc-box"> <refuelingAmount :goodsItem="oilGun" ref="refuelingAmount" @fatherMethod="fatherMethod"></refuelingAmount> </div> <span slot="footer" class="dialog-footer"> <el-button @click="refuelingAmount = false">取 消</el-button> <el-button type="primary" @click="sonButton()">确 定</el-button> </span> </el-dialog> <!-- 确认充值--> <el-dialog :close-on-click-modal="false" title="确认充值" :visible.sync="openConfirm" width="500px" append-to-body> <div v-if="isPay" v-loading="loading"> <div style="text-align: center;font-size: 15px;font-weight: bold">付款金额</div> <div style="text-align: center;font-size: 30px;font-weight: bold;color: red;margin: 10px 0"> ¥{{ payForm.realyPayBills }} </div> <!-- <div style="text-align: center;margin-bottom: 10px">赠送金额</div> --> <div v-if="payForm.paymentType !== 'CASH' "> <div> <el-input v-model="payForm.authCode" v-focus ref="getFocus" autofocus @keydown.enter.native="collection1" placeholder="扫描或输入付款码、支持微信、支付宝、云闪付"> <i slot="suffix"> <svg t="1697791915471" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="1479" width="32" height="32"> <path d="M149.333333 170.858667A21.546667 21.546667 0 0 1 170.858667 149.333333H384V106.666667H170.858667A64.213333 64.213333 0 0 0 106.666667 170.858667V384h42.666666V170.858667zM170.858667 874.666667A21.546667 21.546667 0 0 1 149.333333 853.141333V640H106.666667v213.141333A64.213333 64.213333 0 0 0 170.858667 917.333333H384v-42.666666H170.858667zM853.12 149.333333A21.546667 21.546667 0 0 1 874.666667 170.858667V384h42.666666V170.858667A64.213333 64.213333 0 0 0 853.141333 106.666667H640v42.666666h213.141333zM874.666667 853.141333A21.546667 21.546667 0 0 1 853.141333 874.666667H640v42.666666h213.141333A64.213333 64.213333 0 0 0 917.333333 853.141333V640h-42.666666v213.141333zM106.666667 490.666667h810.666666v42.666666H106.666667v-42.666666z" fill="#3D3D3D" p-id="1480"></path> </svg> </i> </el-input> </div> <div class="demo-image"> <div class="block" style="text-align: center"> <el-image style="width: 200px; height: 200px" fit="cover" src="https://oil.wudb.cn/static/img/scan-demo.fcb8b1ab.png"></el-image> </div> </div> </div> <div v-else> <div> <el-input v-model="payForm.authCode" v-focus ref="getFocus" autofocus maxlength="10" @input="changeSeekZero1" @keydown.enter.native="collection1" oninput="value=value.replace(/^\D*(\d*(?:\.\d{0,2})?).*$/g, '$1')" placeholder="请输入收款金额"> </el-input> </div> <div style="text-align: right;margin: 10px 0"> <span>应找零</span> <span style="color: red;font-size: 18px"> ¥{{ payForm.seekZero }}</span> </div> </div> <el-divider></el-divider> <div style="display: flex;justify-content: space-around"> <el-button @click="cancelCollection">取消收款</el-button> <el-button type="primary" @click="collection1">确定收款</el-button> </div> </div> <div v-else> <div v-if="isPaySuccess"> <el-result icon="success" title="收款成功"> <template slot="extra"> <el-button type="primary" @click="handClose1">关 闭</el-button> </template> </el-result> </div> <div v-else-if="isAwait"> <el-result icon="warning" title="支付等待超时,请前往订单列表查看是否支付成功!"> <template slot="extra"> <el-button type="primary" @click="handClose1">关 闭</el-button> </template> </el-result> </div> <div v-else> <el-result icon="error" title="支付失败,请重新支付"> <template slot="extra"> <el-button type="primary" @click="handClose1">关 闭</el-button> </template> </el-result> </div> </div> </el-dialog> </div> </template> <script> import QRCode from 'qrcode' import html2canvas from "html2canvas"; import pickUp from './newHomeComponents/pickUpTheOrder.vue' import accountPending from './newHomeComponents/accountPending.vue' import memberRecharge from './newHomeComponents/memberRecharge.vue' import refuelingAmount from './newHomeComponents/refuelingAmount.vue' import { cashRegisterList, cashRegisterGoodsList,getActivityList,getCouponList } from '@/api/newHome/newHome.js' import {QRCodeByStoreId} from "@/api/staff/qrcode"; import {userListByPhone} from "@/api/cashier/user"; import { VueClipboard } from 'vue-clipboard2'; import {getDicts} from "@/api/dict/data"; import { getCheckTheStatusOfYourPaymentApi, getCheckTheStatusOfYourPaymentByFuelApi, getPrepaidCardTopUpApi, getPrepaidFuelTopUpApi } from "@/api/cashier/cardSet"; import {getReturnCode} from "@/api/print"; export default { data() { return { payForm:{ realyPayBills:0.00, paymentType:null, authCode:null, seekZero:0.00 }, //可参加的活动 activityList:[], //选中的活动 actId_ruleId chooseAct:"", //支付方式--默认支付宝 payWay: "ALIPAY", //订单总金额 orderAmount:0.0, //加油升数 oilLiter:0, openConfirm:false, isPay:false, loading:false, // 门店二维码 collectionImg: '', baseUrl: process.env.VUE_APP_BASE_API, // value: '', userMobile:null, //商品子组件选中时 容器 sonGoodsList: [], //油枪 父传子 oilGun: '', //油枪结算 容器 oilGunClearing: '', //商品列表 goodsList: [], restaurants: [], state: '', //挂单数据容器 pendingOrdersList: [], timeout: null, boxShow: true, boxShow1: true, boxShow2: true, checkList: [], checkAll: true, checkAll1: false, checkAll2: false, checkAll3: false, isIndeterminate: true, freeTicket:false, freeIndex:0, freeTicketList:[ { name: '油品券', num: '0' }, { name: '储值卡券', num: '0' }, { name: '会员卡券', num: '0' }, { name: '油品券', num: '0' }, { name: '储值卡券', num: '0' }, { name: '会员卡券', num: '0' }, ], payList: [ ], //油枪数据 初始化容器 tabList: { '01': [], '02': [], '03': [], '04': [] }, //油枪列表数据 dataList: {}, userInfo: false,//判断登录状态 tabIndex: 0, newMember: false, ScanCodePayment: false, cashPayment: false, ruleForm: { name: '' }, ruleForms: { name: '' }, rules: { name: [ { required: true, message: '请输入挂单名称', trigger: 'blur' } ] }, refuelingAmount: false, hangingAnOrder: false, paymentResults: false, pickUpTheOrder: false, accountPending: false, memberRecharge: false, //会员搜索列表 vipUserList:[], chooseVipUser:{}, cardValueForm:{}, flag:1, jishuqi:0, continuePolling: true, // 控制轮询的变量 } }, watch: { //监听子弹窗成功 提交了 然后再隐藏子元素标签 oilGunClearing: { immediate: true, deep: true, handler(newValue, oldValue) { console.log('油枪发生变化', newValue); if(newValue && newValue.hasOwnProperty("oilNameId")){ this.orderAmount = (Number(newValue.amount)+Number(this.getGoodsNum)).toFixed(2) }else{ this.orderAmount = this.getGoodsNum } this.refuelingAmount = false //查询可用优惠活动 this.getActivity() } }, //监听商品总金额发生变化 getGoodsNum(newVal, oldVal) { console.log('商品总金额发生变化', newVal); // 商品总金额发生变化,重查优惠券 if(this.oilGunClearing!='' && this.oilGunClearing.hasOwnProperty("oilNameId")){ this.orderAmount = (Number(newVal)+Number(this.oilGunClearing.amount)).toFixed(2) }else { this.orderAmount = newVal } } }, components: { pickUp, accountPending, memberRecharge, refuelingAmount }, created() { //初始化 油枪 商品 this.getOilList() this.getGoodsList() this.getQRCodeInfoByStoreId(0); this.getPayList() }, computed: { getGoodsItem() { if (this.oilGunClearing.amount && this.oilGunClearing.amount !== undefined) { // 保留两位小数 this.oilLiter = (this.oilGunClearing.amount / this.oilGunClearing.oilPrice).toFixed(2) // 8号枪(21.03L/191.7936元) return `${this.oilGunClearing.gunName}(${this.oilLiter}L/${this.oilGunClearing.amount}元)` } else { return '' } }, //总金额 getGoodsNum() { let total = 0 this.goodsList.forEach(item => { total += item.retailPrice * item.num }) return total.toFixed(2) }, //总数量 getGoodsListNum() { let total = 0 this.goodsList.forEach(item => { total += item.num }) return total } }, methods: { async collection1() { let actualPayment = 0 let makeChange = 0 let userForm = this.chooseVipUser if (this.flag === 1) { if (!this.payForm.authCode && this.payForm.paymentType !== "CASH") { this.$message.error('请先扫码'); return }else { if (this.payForm.authCode<this.payForm.amount || this.seekZero<0){ this.$modal.msgError("请输入正确的金额"); return; } if (!this.payForm.authCode){ this.$modal.msgError("请输入正确的金额"); return; } actualPayment = this.payForm.authCode makeChange = this.seekZero } // 会员id 会员名字会员手机号码 this.cardValueForm.mtUserId = userForm.id this.cardValueForm.name = userForm.name this.cardValueForm.mobile = userForm.mobile // 支付码 this.cardValueForm.authCode = this.payForm.authCode this.cardValueForm.realyPayBills = this.realyPayBills this.cardValueForm.actualPayment = actualPayment this.cardValueForm.makeChange = makeChange let id; await getPrepaidCardTopUpApi(this.cardValueForm).then(response => { if (response.data != null) { this.loading = true; id = response.data.id } }); let this_ = this // let timer = setInterval(async () => { await getCheckTheStatusOfYourPaymentApi(id).then(async response => { if (response.data != null) { const payStatus = response.data.payStatus if (payStatus === "unpaid") { this_.isQuery = true; } else if (payStatus === "paid") { // 当支付成功时 this_.isPaySuccess = true; this_.isQuery = false; this_.rechargeBalCard = true // await this_.printLocally1() await this_.cardValueReport() await this_.getMemberAfter(); clearInterval(timer); } else if (payStatus === "payFail") { this_.isPaySuccess = false; this_.isQuery = false; clearInterval(timer); } } await this_.getMemberAfter(); }) }, 1000); let timer2 = setInterval(function () { if (!this_.isQuery || !this_.openConfirm) { this_.loading = false; this_.isPay = false; clearInterval(timer); clearTimeout(timer3); } }, 500) var timer3 = setTimeout(function () { clearInterval(timer2); clearInterval(timer); this_.loading = false; this_.isPay = false; this_.isPaySuccess = false; this_.isAwait = true; }, 15000) } else if (this.flag === 2) { if (!this.payForm.authCode && this.cardFuelDieselForm.paymentType !== "CASH") { this.$message.error('请先扫码'); return }else { if (this.payForm.authCode<this.cardValueForm.amount || this.seekZero<0){ this.$modal.msgError("请输入正确的金额"); return; } if (!this.payForm.authCode){ this.$modal.msgError("请输入正确的金额"); return; } actualPayment = this.payForm.authCode makeChange = this.seekZero } this.cardFuelDieselForm.mtUserId = userForm.id this.cardFuelDieselForm.name = userForm.name this.cardFuelDieselForm.mobile = userForm.mobile this.cardFuelDieselForm.authCode = this.payForm.authCode this.cardFuelDieselForm.actualPayment = actualPayment this.cardFuelDieselForm.makeChange = makeChange let id; await getPrepaidFuelTopUpApi(this.cardFuelDieselForm).then(response => { if (response.data != null) { this.loading = true; id = response.data.id } }); let timer = setInterval(async () => { getCheckTheStatusOfYourPaymentByFuelApi(id).then(async response => { if (response.data != null) { if (response.data.payStatus == "unpaid") { this_.isQuery = true; } if (response.data.payStatus == "paid") { this_.isPaySuccess = true; this_.isQuery = false; this_.rechargeOilCard = true // await this.printLocally2() await this.fuelDieselReport() await this.getMemberAfter(); clearInterval(timer); } if (response.data.payStatus == "payFail") { this_.isPaySuccess = false; this_.isQuery = false; clearInterval(timer); } } }) }, 500); let timer2 = setInterval(function () { if (this_.isQuery == false || !this_.openConfirm) { this_.loading = false; this_.isPay = false; clearInterval(timer); clearInterval(timer2); } }, 500) setTimeout(function () { clearInterval(timer2); clearInterval(timer); this_.loading = false; this_.isPay = false; this_.isPaySuccess = false; this_.isAwait = true; }, 15000) let this_ = this } this.$forceUpdate(); }, cancelCollection(){ this.openConfirm = false }, // 获取支付方式 getPayList(){ getDicts("payment_type").then( response => { this.payList = response.data; }) }, // 确认充值 async rechargeConfirm() { let selectCard = this.$refs.rechargeRef.selectCard if (!selectCard.paymentType) { this.$message.error('请选择支付方式'); return } if (!selectCard.paymentType) { this.$message.error('请选择输入充值本金'); return } if (!selectCard.paymentType) { this.$message.error('请选择输入充值本金'); return } this.payForm.realyPayBills = selectCard.rechargeBalance this.payForm.paymentType = selectCard.paymentType if (selectCard.cardType == 0){ this.flag = 1 }else if(selectCard.cardType == 1){ this.flag = 2 } // // 发送扫码机请求(易联云网络下发) // await this.getSendPrintIndex(this.realyPayBills); this.memberRecharge = false this.openConfirm = true; this.isPay = true //this.getCode(this.realyPayBills, this.flag) }, // 网络下发之后获取条码 getCode(amount,flag) { console.log("payType",this.payForm.payType) // 现金不参与 if (this.payForm.payType == "CASH" && flag == 1) { return } // if (this.cardValueForm.paymentType == "CASH" && flag == 1) // this.jishuqi++; if (this.jishuqi == 30) { this.jishuqi = 0 return } this.continuePolling = true; getReturnCode ({payAmount:amount}).then(res=>{ if (res.data === "300" && this.continuePolling) { setTimeout(() => { this.getCode(amount); // 重新发起请求 }, 1000); // 停顿一秒 }else { this.payForm.authCode = res.data } }) }, /** * @description 油枪金额和商品金额发生变化,请求后端查询可用优惠活动 * 传入后台的参数,会员的用户id、加油油号、加油订单金额(不包括商品金额)、加油订单总金额(包括商品金额)、加油总升数 * @author vinjor-m * @date 2024年9月19日 */ getActivity(){ //组装请求参数 if(this.oilGunClearing!='' && this.oilGunClearing.hasOwnProperty("oilNameId") && this.chooseVipUser.hasOwnProperty("id")){ //油枪已结算,且已选择会员 let dataObj = { userId: this.chooseVipUser.id, oilId: this.oilGunClearing.oilNameId, oilPrice:this.oilGunClearing.oilPrice, oilAmount: this.oilGunClearing.amount, orderAmount: this.orderAmount, payWay: this.payWay, oilLiter: this.oilLiter } getActivityList(dataObj).then(res => { console.log("返回的可参加活动",res) this.activityList = res.data }) }else { //可用活动清空 this.activityList =[] } }, /** * @description 油枪金额和商品金额发生变化,请求后端查询可用优惠券 * 传入后台的参数,会员的用户id、加油油号、加油订单金额(不包括商品金额)、加油订单总金额(包括商品金额)、加油总升数 * @author vinjor-m * @date 2024年9月19日 */ getCoupon(){ //组装请求参数 if(this.oilGunClearing!='' && this.oilGunClearing.hasOwnProperty("oilNameId") && this.chooseVipUser.hasOwnProperty("id")){ // 保留两位小数 let oilLiter = (this.oilGunClearing.amount / this.oilGunClearing.oilPrice).toFixed(2) //油枪已结算,且已选择会员 let dataObj = { userId: this.chooseVipUser.id, oilId: this.oilGunClearing.oilNameId, oilPrice:this.oilGunClearing.oilPrice, oilAmount: this.oilGunClearing.amount, orderAmount: this.orderAmount, oilLiter: oilLiter } getCouponList(dataObj).then(res => { console.log("返回结果",res) }) } }, copyToClipboard(textToCopy) { VueClipboard(textToCopy).then(() => { this.$message.success("复制成功") // 复制成功的操作 }, () => { console.log('复制失败'); // 复制失败的操作 }); }, restVipUser(){ this.userInfo = false this.chooseVipUser = {} }, chooseUser(data){ if (data){ //选择会员 this.userInfo = true this.chooseVipUser = data console.log(this.chooseVipUser,598) } }, // 根据手机号查询会员信息 getUser(queryString, cb){ userListByPhone({mobile:queryString}).then( response => { if (response.data){ cb(response.data) console.log(response.data,608) }else { this.$modal.msgError("会员信息不存在") } }) }, // 获取二维码信息 getQRCodeInfoByStoreId(type) { QRCodeByStoreId({type: type}).then(response => { this.collectionImg = response.data; }) }, // 根据字符串获取二维码图片url地址 getQRcode() { let opts = { errorCorrectionLevel: "L",//容错级别 type: "image/png",//生成的二维码类型 quality: 0.3,//二维码质量 margin: 0,//二维码留白边距 width: 180,//宽 height: 180,//高 text: "http://www.xxx.com",//二维码内容 color: { dark: "#666666",//前景色 light: "#fff"//背景色 } }; if (this.qrcode.length > 0) { //this.QRlink 生成的二维码地址url QRCode.toDataURL(this.qrcode[0].collection, opts, (err, url) => { if (err) throw err //将生成的二维码路径复制给data的QRImgUrl this.collectionImg = url }) QRCode.toDataURL(this.qrcode[0].payment, opts, (err, url) => { if (err) throw err //将生成的二维码路径复制给data的QRImgUrl this.paymentImg = url }) } }, // 根据dom生成图片并下载到本地 handleDownloadqrCode(id) { html2canvas(document.getElementById(id)).then((canvas) => { let imgUrl = canvas.toDataURL("image/png"); //可将 canvas 转为 base64 格式 let a = document.createElement('a') a.href = imgUrl; if (id == 'collection') { a.download = "门店二维码"; //文件名 } else { a.download = "收款二维码"; //文件名 } document.body.appendChild(a); a.click(); // 触发点击 document.body.removeChild(a); // 然后移除 }); }, //油枪初始化 getOilList() { cashRegisterList().then(res => { this.tabList = res.data //加上全部选项 this.tabList = { '全部': 'all', ...this.tabList } for (const key in this.tabList) { // 循环为 不同油号 赋值不同图片样式 if (key == '0#') { this.tabList[key].forEach(item => { item.img = './imgs/0oil.png' item.classStyle = 'card0' }) } if (key == '98#') { this.tabList[key].forEach(item => { item.img = './imgs/98oil.png' item.classStyle = 'card98' }) } if (key == '95#') { this.tabList[key].forEach(item => { item.img = './imgs/95oil.png' item.classStyle = 'card95' }) } if (key == '92#') { this.tabList[key].forEach(item => { item.img = './imgs/92oil.png' item.classStyle = 'card92' }) } } // 调用一下油枪数据列表 初始化 this.setTabindex('全部', 0) }) }, //商品初始化 async getGoodsList() { const res = await cashRegisterGoodsList() this.restaurants = res.data }, invokePickUpTheOrder() { //获取存储数据 this.pendingOrdersList = JSON.parse(window.sessionStorage.getItem('pendingOrders')) || [] this.pickUpTheOrder = true }, //确定挂单 pendingOrders() { this.$refs['ruleForm'].validate((valid) => { if (valid) { // 1.先取出之前的转 json 然后追加 将 JSON 字符串解析回对象 this.pendingOrdersList = JSON.parse(window.sessionStorage.getItem('pendingOrders')) || [] // 2.商品列表没有数据不允许添加 if (!this.goodsList.length) { this.$message.error('商品列表为空,请添加商品') return } // 3.如果名称重复则不允许添加 let bo1 = true this.pendingOrdersList.forEach(item => { if (item.name == this.ruleForms.name) { this.$message.error('名称重复,请重新输入') bo1 = false return } }) // 4.追加数据 if (bo1) { this.pendingOrdersList.push( { name: this.ruleForms.name, list: this.goodsList } ) // 将当前 商品订单表 放入 sessionStorage window.sessionStorage.setItem('pendingOrders', JSON.stringify(this.pendingOrdersList)) // 清空当前商品 this.goodsList = [] //重置表单 关闭弹窗 this.ruleForms = { name: '' } this.hangingAnOrder = false this.$message({ message: '挂单成功', type: 'success' }); } } else { console.log('error submit!!') return false } }) }, //挂单 invokeHangingAnOrder() { this.hangingAnOrder = true //必须 输入 挂单名称 将数据临时存储在 sessionStorage 刷新自动取消 }, addVip() { this.newMember = true }, setFreeIndex(index){ this.freeIndex = index }, addFreeTicket(){ this.freeTicket = true }, addMemberRecharge() { this.memberRecharge = true this.$nextTick(res=>{ this.$refs.rechargeRef.getCardValueList(); }) }, setTabindex(key, index) { //列表选中样式 this.tabIndex = index if (key == '全部') { this.dataList = [] for (const tabKey in this.tabList) { this.dataList = this.dataList.concat(this.tabList[tabKey]) } //因为 页面展示多加了一个 全部 要删掉第一个元素 this.dataList.shift() } else { for (const tabKey in this.tabList) { if (key == tabKey) { this.dataList = this.tabList[tabKey] } } } }, /** * 设置选中的支付方式 * @param value */ setindex(value) { this.payWay = value }, setRefuelingAmount(item) { this.refuelingAmount = true //赋值 传给子组件的油枪对象 this.oilGun = item }, //必须是异步方法 querySearchAsync(queryString, cb) { const restaurants = this.restaurants let results if (queryString) { results = restaurants.filter(this.createFilter(queryString)) } else { results = restaurants } cb(results) }, createFilter(queryString) { return (restaurant) => { return (restaurant.name.toLowerCase().indexOf(queryString.toLowerCase()) === 0) } }, //取单 下拉框是子组件 子组件通过数据监听 将数据发送给父组件 getPendingOrdersList() { //并且删除 父传子数据容器 以及 重新存储sessionStorage this.pendingOrdersList = JSON.parse(window.sessionStorage.getItem('pendingOrders')) || [] if (this.pendingOrdersList.length) { let found = false this.pendingOrdersList = this.pendingOrdersList.filter(item => { if (item.name === this.value) { if (!found) { this.goodsList = item.list found = true } return false // 不保留匹配的项 } return true // 保留不匹配的项 }) window.sessionStorage.setItem('pendingOrders', JSON.stringify(this.pendingOrdersList)) this.pickUpTheOrder = false this.$message({ message: '取单成功', type: 'success' }); } else { this.$message.error('当前无存单 请存单后再取单') } }, //作废 下拉框是子组件 子组件通过数据监听 将数据发送给父组件 deletePendingOrdersList() { //并且删除 父传子数据容器 以及 重新存储sessionStorage this.pendingOrdersList = JSON.parse(window.sessionStorage.getItem('pendingOrders')) || [] if (this.pendingOrdersList.length) { this.pendingOrdersList = this.pendingOrdersList.filter(item => { return item.name !== this.value }) window.sessionStorage.setItem('pendingOrders', JSON.stringify(this.pendingOrdersList)) this.$message({ message: '作废成功', type: 'success' }); } else { this.$message.error('当前无存单 请存单后再作废') } }, // 接受子组件列表数据变化 fatherPendingOrdersList(list) { this.sonGoodsList = list }, // 接受子组件下拉选中名字变化 fatherPendingOrdersName(value) { this.value = value }, //删除商品 deleteGoods(id) { //根据id删除数组元素 this.goodsList = this.goodsList.filter(item => item.id != id) }, // 子组件提交调用父组件方法 fatherMethod(list) { //将当前选中油枪 放入 油枪订单容器 (需要被数据监听) this.oilGunClearing = { amount: list, ...this.oilGun } }, //获取子组件数据 sonButton() { //调用子组件方法 this.$refs.refuelingAmount.submitForm('ruleForm') }, handleSelect(row) { let bo1 = true // 如果 item 存在 goodsList 则 属性+1 不存在直接添加到数组 // 使用 map 生成新数组 防止vue监听不到数组内数据变化 this.goodsList = this.goodsList.map( item => { if (item.id == row.id) { bo1 = false return { ...item, num: item.num + 1 } } else { return item } } ) if (bo1) { //如果没有先添加数量属性 默认1 row.num = 1 this.goodsList.push(row) } }, // 油枪重置 oilGunReset() { this.oilGunClearing = {} }, // 收银重置 goodsReset() { this.goodsList = [] } } } </script> <style scoped lang="scss"> input { width: 100%; border: none; outline: none; background-color: transparent; padding: 0; margin: 0; font-family: inherit; font-size: inherit; color: inherit; } .new-contoner { width: 100%; box-sizing: border-box; height: 100vh; padding: 20px 0px; padding-right: 20px; padding-bottom: 0px; display: flex; align-content: center; justify-content: space-between; } .left-box { width: 33%; box-shadow: 0px 3px 6px 1px rgba(255, 255, 255, 0.4), inset 0px 3px 6px 1px rgba(255, 255, 255, 0.5); border-radius: 10px; overflow: hidden; } .cont-box { width: 33%; box-shadow: 0px 3px 6px 1px rgba(255, 255, 255, 0.4), inset 0px 3px 6px 1px rgba(255, 255, 255, 0.5); border-radius: 10px; margin: 0px 20px; overflow: hidden; } .right-box { width: 33%; box-shadow: 0px 3px 6px 1px rgba(255, 255, 255, 0.4), inset 0px 3px 6px 1px rgba(255, 255, 255, 0.5); border-radius: 10px; overflow: hidden; } .box-top { height: 84vh; background: #fff; margin-bottom: 5px; position: relative; } .box-bottom { height: 12vh; background: #fff; z-index: 9; box-sizing: border-box; padding: 15px; display: flex; align-items: center; justify-content: space-between } .o-top { width: 100%; height: 80px; background: #FF9655; box-sizing: border-box; padding: 15px; display: flex; align-items: center; font-size: 14px; color: #fff; justify-content: space-between; } .d-s { display: flex; align-items: center; } .an_bor { box-sizing: border-box; padding: 5px; border: 1px solid #fff; border-radius: 50px; display: flex; align-items: center; font-size: 14px; color: #FFFFFF; justify-content: center; margin: 0px 5px; cursor: pointer; } .t-top { width: 100%; display: flex; align-items: center; justify-content: space-between; box-sizing: border-box; padding: 20px 0px; border-bottom: #F4F5F9 1px solid; } .three_box { width: 33%; display: flex; align-items: center; justify-content: center; font-size: 16px; color: #555555; } .d-b { width: 100%; display: flex; align-items: center; justify-content: space-between; margin: 15px 0px; } .x-d-b { width: 90%; display: flex; align-items: center; justify-content: space-between; margin: 15px 0px; margin-left: 10%; } .d-top { width: 100%; box-sizing: border-box; padding: 0px 40px; font-size: 16px; color: #555555; border-bottom: #f6f8f9 4px solid; } .checkbox { width: 15px; height: 15px; border: 1px solid #ddd; display: flex; align-items: center; justify-content: center; border-radius: 2px; } .d_text { color: #555555; margin-left: 10px; font-size: 16px; } .or_num { color: #FF9655; } .active { background: #FF9655 !important; color: #FFFFFF !important; border: 1px solid #FF9655; } .three-top { width: 100%; box-sizing: border-box; border-bottom: #f6f8f9 4px solid; } .addbor { border-bottom: 1px solid #f6f8f9; padding: 15px 40px; box-sizing: border-box; display: flex; align-items: center; justify-content: space-between; } .er-box { width: 100%; } .wrap-box { height: 190px; position: absolute; bottom: 0px; width: 100%; flex-wrap: wrap; display: flex; box-sizing: border-box; padding: 20px; } .f-box { width: 31%; height: 44px; border-radius: 4px; display: flex; align-items: center; justify-content: center; font-weight: 400; font-size: 16px; color: #555555; margin-right: 2%; margin-bottom: 2%; border-radius: 10px; border: 1px solid #409EFF; cursor: pointer; } .f-acvite { background: #409eff !important; color: #fff !important; box-shadow: 0px 3px 6px 1px rgba(255, 255, 255, 0.4), inset 0px 3px 6px 1px rgba(255, 255, 255, 0.5); } .anniu { width: 160px; height: 60px; background: linear-gradient(312deg, #FF945B 0%, #FEB37C 100%); border-radius: 6px 6px 6px 6px; display: flex; align-items: center; justify-content: center; color: #fff; } .price_ { font-size: 24px; color: #333333; font-weight: bold; } .price_prefer { font-size: 16px; color: #FF4347; } .cont-tab { width: 100%; display: flex; align-items: center; border-bottom: 1px solid #EEEEEE; box-sizing: border-box; font-size: 14px; color: #999999; padding: 0px 20px; padding-top: 25px; } .r-top { width: 100%; display: flex; align-items: center; border-bottom: 1px solid #EEEEEE; padding: 0px 20px; padding-top: 15px; padding-bottom: 10px; font-size: 16px; color: #555555; } .input-box { width: 90%; height: 40px; background: #FAFAFA; border-radius: 6px 6px 6px 6px; border: 1px solid #DDDDDD; display: flex; align-items: center; box-sizing: border-box; padding: 0px 15px; margin: 15px auto; } .gang { width: 24px; height: 3px; //background: linear-gradient( 90deg, #FF8646 0%, #FFA360 100%); border-radius: 3px 3px 3px 3px; } .active_gang { background: linear-gradient(90deg, #FF8646 0%, #FFA360 100%) !important; } .tab-box { margin-right: 30px; cursor: pointer; } .active_name { font-size: 14px; color: #555555; font-weight: bold; } .tab-kuang { width: 100%; box-sizing: border-box; padding: 20px; margin: 0 auto; display: flex; align-content: flex-start; flex-wrap: wrap; overflow: auto; height: 68vh; } .card92 { width: 32%; height: 90px; box-sizing: border-box; padding: 5px; background: rgba(255, 150, 85, 0.1); box-shadow: 0px 3px 6px 1px rgba(255, 255, 255, 0.4), inset 0px 3px 6px 1px rgba(255, 255, 255, 0.5); border-radius: 6px 6px 6px 6px; border: 1px solid #FF9655; color: #FF9655; font-size: 12px; color: #FF9655; overflow: hidden; margin-right: 1%; margin-bottom: 1%; cursor: pointer; } .card0 { width: 32%; height: 90px; box-sizing: border-box; padding: 5px; background: rgba(255, 181, 25, 0.1); box-shadow: 0px 3px 6px 1px rgba(255, 255, 255, 0.4), inset 0px 3px 6px 1px rgba(255, 255, 255, 0.5); border-radius: 6px 6px 6px 6px; border: 1px solid #FFB519; cursor: pointer; font-size: 12px; color: #FFB519; overflow: hidden; margin-right: 1%; margin-bottom: 1%; } .card98 { width: 32%; height: 90px; box-sizing: border-box; padding: 5px; background: rgba(64, 158, 255, 0.1); box-shadow: 0px 3px 6px 1px rgba(255, 255, 255, 0.4), inset 0px 3px 6px 1px rgba(255, 255, 255, 0.5); border-radius: 6px 6px 6px 6px; border: 1px solid #409EFF; font-size: 12px; color: #409EFF; overflow: hidden; margin-right: 1%; margin-bottom: 1%; cursor: pointer; } .card95 { width: 32%; height: 90px; box-sizing: border-box; padding: 5px; background: rgba(13, 194, 145, 0.1); box-shadow: 0px 3px 6px 1px rgba(255, 255, 255, 0.4), inset 0px 3px 6px 1px rgba(255, 255, 255, 0.5); border-radius: 6px 6px 6px 6px; border: 1px solid #0DC291; font-size: 12px; color: #0DC291; overflow: hidden; margin-right: 1%; margin-bottom: 1%; cursor: pointer; } .card-title { font-size: 24px; color: #555555; margin: 6px auto; text-align: center; } .c-b-d { display: flex; align-items: center; justify-content: space-between; } .c-bottom { font-size: 14px; color: #333333; border-bottom: 2px solid #F4F5F9; box-sizing: border-box; padding: 10px 20px; } .bottom-b-d { position: absolute; bottom: 0px; width: 100%; display: flex; align-content: center; justify-content: space-between; box-sizing: border-box; padding: 10px 20px; font-size: 16px; color: #777777; } .anniu-c { width: 80px; height: 36px; background: #FFFFFF; border-radius: 6px 6px 6px 6px; border: 1px solid #DDDDDD; display: flex; align-items: center; justify-content: center; color: #777777; } .anniu-lv { width: 80px; height: 36px; background: linear-gradient(312deg, #9CDCA0 0%, #5BC557 100%); border-radius: 6px 6px 6px 6px; cursor: pointer; display: flex; align-items: center; justify-content: center; color: #fff; } .anniu-lan { cursor: pointer; width: 80px; height: 36px; background: linear-gradient(312deg, #70CAFD 0%, #0BADFE 100%, #02AAFE 100%); border-radius: 6px 6px 6px 6px; margin: 0px 15px; display: flex; align-items: center; justify-content: center; color: #fff; } .taber-top { width: 100%; box-sizing: border-box; padding: 5px 20px; background: #f4f5f9; display: flex; align-items: center; } .taber-box { width: 100%; box-sizing: border-box; padding: 10px 20px; border-bottom: 1px solid #f4f5f9; display: flex; align-items: center; } .goods_name { width: 35%; } .stock_name { width: 15%; text-align: center; } .u-price_name { width: 15%; text-align: center; } .num_name { width: 15%; text-align: center; } .orerate_name { width: 20%; text-align: center; } .tc-box { text-align: center; } .ds-tc{ width: 100%; display: flex; } .left_tc{ width: 500px; } .right_tc{ width: 300px; height: 100%; box-sizing: border-box; padding: 0px 15px; } .t-tc{ width: 100%; display: flex; align-items: center; justify-content: space-between; } .red-size { font-size: 18px; color: #F44522; } .title_ { font-size: 28px; color: #333333; margin-bottom: 10px; } .r-size { font-size: 16px; } .t-size { width: 100%; text-align: right; font-size: 12px; color: #333333; } .h-size { font-size: 12px; color: #999999; margin-left: 100px; text-align: left; } .hui-box { width: 282px; background: #FAFAFA; margin: 15px auto; box-sizing: border-box; padding: 15px; } .hui-box-bt { width: 100%; display: flex; align-items: center; justify-content: space-between; margin: 15px auto; } .left_input { width: 70%; box-sizing: border-box; display: flex; align-items: center; justify-content: space-between; box-sizing: border-box; padding: 10px 5px; border-radius: 8px; color: white; ::v-deep.el-input__inner { background: transparent !important; border: white 1px solid; .el-input__placeholder{ color: red; } } ::v-deep input:-moz-placeholder, ::v-deep textarea:-moz-placeholder { color: #fff; } ::v-deep input:-ms-input-placeholder, ::v-deep textarea:-ms-input-placeholder { color: #fff; } ::v-deep input::-webkit-input-placeholder, ::v-deep textarea::-webkit-input-placeholder { color: #fff ; } } .wrap-tc{ width: 100%; display: flex; flex-wrap: wrap; margin-top: 15px; } .tc_wa{ width: 32%; margin-bottom: 4%; margin-right: 1%; box-sizing: border-box; padding: 10px; background: url("./imgs/dx.png") no-repeat; height: 65px; background-size: 100% 100%; cursor: pointer; } .tc-active{ background: url("./imgs/zxz.png") no-repeat !important; background-size: 100% 100% !important; color: #fff !important; } .qrcode { width: 350px; margin-top: 0px; } .el-radio-group label{ width: 100%; } .el-radio-group .or_num{ float: right; } </style>