shangfutong-ui/jeepay-ui-uapp-cashier/pages/payway/index.vue

900 lines
22 KiB
Vue
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<template>
<view class="content">
<!-- <view class="content-top-bg" :style="{'backgroundColor': vdata.primaryColor}"></view> -->
<view class="payment">
<view class="payment-mchName" @tap="advancedFunc">
<view style="display: contents;">
<image src="/static/img/store.svg" mode="scaleToFill" class="payment-mchName-img" />
<view style="display: grid;margin-left: 16rpx;">
<text class="payment-mchName1">{{ vdata.payOrderInfo.mchName }}</text>
<view class="payment-mchName2">
<text class="payment-mchName2-text1">门店</text>
<text class="payment-mchName2-text2">{{vdata.payOrderInfo.storeName}}</text>
</view>
</view>
</view>
</view>
<view class="payment-divider"></view>
<view class="payment-amountTips">
<view class="desc1 ">付款金额</view>
<view class="desc2 " v-if="!vdata.buyerRemark" @tap="showRemarkModel"><span v-if="vdata.isForceReamrk" style='color: #FF0000;'>*</span>添加备注</view>
<text class="desc2 buyer-remark" v-else @tap="showRemarkModel">
{{ vdata.buyerRemark }}
<text :style="{ 'padding-left': '6rpx'}">修改</text>
</text>
</view>
<view class="payment-amount" >
<text class="payment-amount-rmb">¥</text>
<text class="payment-amount-value">{{ doubleToThousands(vdata.amount) }}</text>
</view>
</view>
<view class="payment-amountTips-price" >
<!-- -->
<view class="desc3">
<view v-if="vdata.redPacketIsOpen">
<text class="desc3-text1" >红包</text><text class="desc3-text2">可用余额:¥{{(appConfig.redbalance / 100).toFixed(2)}} </text>
</view>
</view>
<!-- <view class="desc4" ><text class="desc4-text1" >实付金额</text><text class="desc4-text2">¥{{doubleToThousands(vdata.originAmount) }}</text></view> -->
<!-- <view class="payment-text-amount txt">实付金额:<text></text></view> -->
</view>
<!-- <view class="pay-div-type">
<radio-group @change="radioChange" style="width: 100%;">
<view class="radio-group-box" style="display: flex;" v-if="appConfig.pageType == 'wechatLite'" >
<view class="radio-group-name " >
<img src="https://syb-jq-public.oss-cn-hangzhou.aliyuncs.com/oem/6e4f3ca5-a334-4af4-a57c-63fca61c95d7.svg" alt="">
<text class="radio-group-name1">微信</text>
</view>
<view class="radio-group-radio " >
<radio color="#1678FF" value="1" :checked="1 == vdata.current" />
</view>
</view>
<view class="radio-group-box" style="display: flex;" v-if="appConfig.pageType == 'alipayLite'">
<view class="radio-group-name " >
<img src="https://syb-jq-public.oss-cn-hangzhou.aliyuncs.com/oem/0e4f0b6a-e96e-45bf-a5bb-127c64c3396a.svg" alt="">
<text class="radio-group-name1">支付宝</text>
</view>
<view class="radio-group-radio " >
<radio color="#1678FF" value="2" :checked="2 == vdata.current" />
</view>
</view>
<view class="radio-group-box" style="display: flex;" v-if="appConfig.redPacketIsOpen" >
<view class="radio-group-name " >
<img src="https://syb-jq-public.oss-cn-hangzhou.aliyuncs.com/notice/d3be6339-5abe-415b-981c-3568ebd66f57.png" alt="">
<text class="radio-group-name1">红包</text>
<text class="radio-group-name-price" >(可用{{appConfig.redbalance}}元)</text>
</view>
<view class="radio-group-radio " >
<radio color="#1678FF" value="3" :checked="3 == vdata.current" />
</view>
</view>
</radio-group>
</view> -->
<!-- v-if="!vdata.payOrderInfo['fixedFlag']" -->
<view class="payment-keyboard" >
<!-- <text class="buyer-remark" v-if="!vdata.buyerRemark" @tap="showRemarkModel">添加备注</text> -->
<!-- <text class="buyer-remark" v-else @tap="showRemarkModel">
{{ vdata.buyerRemark }}
<text :style="{ 'padding-left': '6rpx'}">修改</text>
</text> -->
<view class="payment-text" v-if="vdata.isAdsOpen">
<view class="payment-text-guanggao txt" @click="getadsName()" >
<!-- <scroll-view class="scroll-view" scroll-x="true" :scroll-left="vdata.scrollLeft" autoplay @scrolltolower="scrollToLower"> -->
<view class="scroll-content" >
{{appConfig.marketingConfig.adsName}}
</view>
<!-- <text ></text> -->
<!-- </scroll-view> -->
</view>
<!-- <view class="payment-text-amount txt">实付金额:<text>¥{{doubleToThousands(vdata.originAmount) }}</text></view> -->
</view>
<syb-keyboard
ref="sybKeyboardRef"
:primaryColor="vdata.primaryColor"
@change="onChange"
@pay="getSybPayType">
</syb-keyboard>
</view>
<!-- <view v-if="vdata.payOrderInfo['fixedFlag']" class="payment-no-keyboard" @tap="pay">付 款</view> -->
<view v-if="vdata.remarkVisible" class="remark-model">
<view class="remark-content">
<text class="remark-content-title" >添加备注</text>
<input v-model="vdata.modelRemark" :focus="vdata.remarkVisible" maxlength="40" placeholder="最多输入20个字" class="remark-content-body" />
<view class="remark-content-btn">
<text class="btn-cancel" @tap.stop="closeRemarkModel">取消</text>
<text class="btn-confirm" :style="{'backgroundColor': '#1678FF', 'borderColor': '#ffffff'}" @tap.stop="confirmRemark">确认</text>
</view>
</view>
</view>
</view>
<!-- <SelectedPay ref="sybCodePay" :list="vdata.payTypeList" @choiceValue="updataBank" /> -->
<!-- 选择支付 接口 -->
<!-- <JeepayPopupListSelect style="background-color: #fff;" ref="selectIfcodeRef" title='支付方式' :isCheckbox="false" :reqTableDataFunc="reqTableDataByIfcodeFunc"
:fields="{ key: 'value', left: 'name', right: 'value', img: 'img' }" @confirm="confirmIfCode">
</JeepayPopupListSelect> -->
</template>
<script setup lang="ts">
import { onMounted, reactive, ref } from 'vue'
import { onLoad } from '@dcloudio/uni-app'
import { $getPayOrderInfo, $getPayPackage,$getMarketingConfig,$getCalcDiscount } from '@/http/apiManager.js'
import { doubleToThousands } from '@/util/amount.js'
import { toErrPageFunc } from '@/util/toErrorPageUtil.js'
import appConfig from '@/config/appConfig.js'
import theme from '@/config/theme.js'
// import SelectedPay from './components/SelectedPay.vue'
import paywayCallFunc from '@/pages/payway/payway.js'
const sybCodePay = ref()
const sybKeyboardRef = ref()
const selectIfcodeRef = ref()
const vdata = reactive({
scrollLeft: 0, // 滚动位置
scrollSpeed: 2, // 滚动速度单位px/ms
scrollInterval: null, // 定时器ID
payTypeList:[] as any,
typeItems: [{
img:"/static/img/wechat.png",
value: 1,
name: '微信支付',
checked: false,
},{
img:"/static/img/wechat.png",
value: 2,
name: '微信H5',
checked: false,
},{
img:"/static/payIcon/zfb.png",
value: 3,
name: '支付宝支付',
checked: false,
},{
img:"/static/payIcon/zfb.png",
value: 4,
name: '支付宝H5',
checked: false,
},{
img:"/static/img/payred.png",
value: 5,
name: '红包',
checked: false,
price: '',
},
],
addIfCodeList:{} as any,
isAdsOpen:false,
redPacketIsOpen:false,
current: 0,
primaryColor: '',
originAmount: '0',
amount: '0',
buyerRemark: '', // 买家备注
modelRemark: '', // 弹层显示备注
remarkVisible: false,
doubleToThousands: doubleToThousands(),
payOrderInfo: {},
calcDiscount:{},
storeId:'',
clearStorageFlag: 0, //显示清空缓存的提示
isForceReamrk:false,
}) as any
onLoad(() => {
vdata.amount = '0'
vdata.primaryColor = theme.changeColors()
// #ifdef H5
console.log(111111111111111111111111111111111111111)
//解决H5的刷新问题
if(!appConfig.tokenValue){ // 不存在 则需要跳转到首页再次放置 获取userID等信息。
window.location.href = '/cashier/pages/hub/default?' + appConfig.tokenKey + "=" + window.sessionStorage.getItem(appConfig.tokenKey)
return false;
}
// #endif
// 获取订单信息
// getOrderInfo()
})
onMounted(() => {
getOrderInfo()
})
function getPayType(){
const typeItems = vdata.typeItems
vdata.payTypeList = [];
console.log(appConfig.redPacketIsOpen,'appConfigredPacketIsOpen')
if(!appConfig.redPacketIsOpen){
delete typeItems[4]
}
if(appConfig.currentPageType == 'wechatLite'){
delete typeItems[1]
delete typeItems[2]
delete typeItems[3]
}
if(appConfig.currentPageType == 'wechatH5'){
delete typeItems[0]
delete typeItems[2]
delete typeItems[3]
}
if(appConfig.currentPageType == 'alipayLite'){
delete typeItems[0]
delete typeItems[1]
delete typeItems[3]
}
// return uni.showToast({
// title: appConfig.currentPageType,
// icon: 'none'
// })
if(appConfig.currentPageType == 'alipayH5'){
delete typeItems[0]
delete typeItems[1]
delete typeItems[2]
}
console.log(typeItems,'codePay')
typeItems.forEach(function(item,index){
if(index == 4){
item.price = appConfig.redbalance
}
if(appConfig.currentPageType == 'wechatLite' || appConfig.currentPageType == 'wechatH5'){
if(item.value == 3 || item.value == 4){
}else{
vdata.payTypeList.push(item)
}
}else if(appConfig.currentPageType == 'alipayLite' || appConfig.currentPageType == 'alipayH5'){
if(item.value == 0 || item.value == 1){
}else{
vdata.payTypeList.push(item)
}
}
})
if(typeItems.length){
typeItems[0].checked = true
}
}
function updataBank (index,type=0) {
console.log(type,'typetype')
if(type == 1){
pay()
return false;
}
if(vdata.payTypeList[index].value == 5){
if(appConfig.redPacketIsOpen){
getCalcDiscount(vdata.amount)
}else{
vdata.originAmount = vdata.amount
}
}
}
function startAutoScroll() {
if (vdata.scrollInterval) {
clearInterval(vdata.scrollInterval);
}
const contentWidth = uni.upx2px(375) * 3; // 假设内容宽度是屏幕宽度的三倍,这里需要根据实际情况调整
vdata.scrollInterval = setInterval(() => {
if (vdata.scrollLeft < contentWidth) {
vdata.scrollLeft += vdata.scrollSpeed;
} else {
vdata.scrollLeft = 0;
}
}, 100); // 每100ms滚动一次可以根据需要调整
}
function stopAutoScroll() {
clearInterval(vdata.scrollInterval);
vdata.scrollInterval = null;
}
function scrollToLower(){
vdata.scrollLeft = 0;
}
function getSybPayType(){
if(vdata.amount <= 0) {
return uni.showToast({
title: '金额必须大于0',
icon: 'none'
})
return false;
}
if(vdata.payTypeList.length <= 1){
pay()
return false;
}else{
sybCodePay.value.open();
}
}
// 选择支付通道
function confirmIfCode (selected) {
selectIfcodeRef.value.close()
}
function radioChange(evt) {
console.log(evt.target.value,'evt')
vdata.current = evt.target.value;
}
// 输入金额
function onChange(e: any) {
if(vdata.payOrderInfo['fixedFlag']){
return false;
}
vdata.amount = e
if(appConfig.redPacketIsOpen){
getCalcDiscount(e)
}else{
vdata.originAmount = e
}
}
function getadsName(){
if(!appConfig.marketingConfig.isAdsOpen){
return false;
}
uni.navigateTo({
url: '/pages/H5/H5?url='+ appConfig.marketingConfig.adsUrl
})
}
//获取红包信息
function getMarketingConfig(storeId){
$getMarketingConfig('marketingConfig',storeId).then(({bizData}) => {
vdata.redPacketIsOpen = bizData.marketingConfig.isOpen
console.log(bizData.marketingConfig.isAdsOpen,'bizData.marketingConfig.isAdsOpen')
vdata.isAdsOpen = bizData.marketingConfig.isAdsOpen
appConfig.redPacketIsOpen = bizData.marketingConfig.isOpen
appConfig.redbalance = bizData.marketingConfig.balance
appConfig.marketingConfig = bizData.marketingConfig
})
}
//计算红包实付金额
function getCalcDiscount(originAmount){
$getCalcDiscount(originAmount,vdata.storeId).then(({bizData}) => {
vdata.calcDiscount = bizData;
vdata.originAmount = (bizData.findAmt/100).toFixed(2)
vdata.discountAmt = bizData.discountAmt
})
}
// 获取订单信息
function getOrderInfo() {
$getPayOrderInfo().then(({bizData}) => {
console.log(bizData,'bizDatabizDatabizDatabizData')
appConfig.video = bizData.video
vdata.payOrderInfo = bizData
vdata.isForceReamrk = bizData.isForceReamrk
vdata.storeId = '';
if(bizData.storeId) {
vdata.storeId = bizData.storeId
}
getMarketingConfig(vdata.storeId)
if(bizData.amount) {
vdata.amount = (bizData.amount/100).toString()
getCalcDiscount(vdata.amount)
}
// 金额传入键盘组件
sybKeyboardRef.value.setValue(vdata.amount)
// 如果订单已支付,则转到提示页面
if(bizData.state && bizData.state === 2) {
return toErrPageFunc("订单已支付");
}
setTimeout(()=>{
getPayType()
},2000)
// 自动调起支付
if(bizData.autoPay) {
// pay()
}
}).catch(err => {
console.log(err);
})
}
//视频号数据
function sphGet(){
console.log(appConfig.video,'videovideovideovideovideo')
if(appConfig.currentPageType == 'alipayLite' || appConfig.currentPageType == 'alipayH5' || appConfig.video == undefined || appConfig.video == null){
}else{
uni.openChannelsActivity({
finderUserName: appConfig.video.uniqueId,//视频号ID
feedId: appConfig.video.exportId,//视频ID
complete (res) {
console.log(res)
}
})
}
}
function toAddPage () {
vdata.addIfCodeList = [
{ifCode:"dgpay",ifName:"汇付斗拱支付"},
{ifCode:"yspay",ifName:"银盛支付"},
{ifCode:"kqpay",ifName:"快钱支付"},
{ifCode:"lklspay",ifName:"拉卡拉支付"},
{ifCode:"dgpay2",ifName:"汇付斗拱支付"}
]
vdata.addIfCodeList = vdata.typeItems
selectIfcodeRef.value.open()
}
function reqTableDataByIfcodeFunc () {
// 模拟请求数据
return Promise.resolve({ bizData: { records: vdata.addIfCodeList, hasNext: false } })
}
// 发起支付
function pay() {
if(vdata.isForceReamrk && !vdata.modelRemark){
vdata.remarkVisible = true
return false;
}
vdata.payOrderInfo.amount = vdata.amount
if(vdata.amount <= 0) {
return uni.showToast({
title: '金额必须大于0',
icon: 'none'
})
return false;
}
// console.log(111111111)
// uni.navigateTo({
// url: '/pages/paySuccess/redSuccess?payOrderId=20240124O1750143430237061121'
// })
// return false;
if(vdata.redPacketIsOpen){
if(!vdata.calcDiscount){
return false;
}
if(!vdata.calcDiscount.findAmt){
return false;
}
}
uni.showLoading({
title: '请稍等...',
mask: true
})
// setTimeout(() => {
// uni.navigateTo({
// url: '/pages/paySuccess/redSuccess?payOrderId=O1749678699690803202'
// })
// }, 1000)
// return false;
$getPayPackage(vdata.amount, vdata.buyerRemark,null,null,vdata.calcDiscount).then( ({bizData}) => {
uni.hideLoading()
console.log(bizData,'bizDatabizData')
//订单创建异常
if(bizData.code != '0') {
let msg = bizData.msg;
if(bizData.msg =='系统Success'){
msg = '订单异常'
}
return uni.showToast({title: msg,icon:'none'})
// return toErrPageFunc(bizData.msg);
}
// 订单响应结果
let orderRes = bizData.data;
if(orderRes.orderState != 1 ) { //订单不是支付中,说明订单异常
if(orderRes.msg){
return uni.showToast({title: orderRes.msg,icon:'none'})
}else if(orderRes.errMsg){
return uni.showToast({title: orderRes.errMsg,icon:'none'})
}else{
return uni.showToast({title: '订单异常',icon:'none'})
}
// return toErrPageFunc(orderRes.errMsg);
}
// if(bizData.code == 0){
// uni.navigateTo({
// url:"/pages/paySuccess/redSuccess"
// })
// return false;
// }
if(orderRes.payUrl){
location.href = orderRes.payUrl;
return false;
}
// 以下为调起 jsapi的函数 分为: H5 和 各端小程序
let thisPaywayCallFunc = paywayCallFunc()[appConfig.currentPageType];
thisPaywayCallFunc(orderRes, vdata.payOrderInfo);
}).catch( () => {
uni.hideLoading()
})
}
// 显示备注弹窗
function showRemarkModel() {
vdata.modelRemark = vdata.buyerRemark
vdata.remarkVisible = true
}
// 备注弹窗确认
function confirmRemark() {
vdata.buyerRemark = vdata.modelRemark
vdata.remarkVisible = false
}
// 关闭备注弹窗
function closeRemarkModel() {
vdata.modelRemark = ''
vdata.remarkVisible = false
}
// 高级功能模块的显示
function advancedFunc(){
vdata.clearStorageFlag = vdata.clearStorageFlag + 1
if(vdata.clearStorageFlag >= 10){
vdata.clearStorageFlag = 0
// 目前仅清空缓存
uni.showModal({
title: '确认清除缓存?',
success: function(r) {
if (r.confirm) {
uni.clearStorageSync()
return uni.showToast({title: '已清空'})
}
}
});
}
}
</script>
<style lang="scss">
.remark-model {
position: fixed;
height: 100vh;
width: 100vw;
z-index: 20;
background-color: rgba(0,0,0,0.6);
display: flex;
flex-direction: row;
justify-content: center;
align-items: center;
.remark-content {
height: 290rpx;
width: 600rpx;
background-color: #FFFFFF;
border-radius: 20rpx;
display: flex;
flex-direction: column;
justify-content: space-between;
padding: 50rpx 0 20rpx 0;
margin-bottom: 70%;
.remark-content-title {
font-weight: bold;
font-size: 33rpx;
letter-spacing: 0.05em;
margin-left: 50rpx;
}
.remark-content-body {
margin-left: 50rpx;
}
.remark-content-btn {
display: flex;
flex-direction: row;
justify-content: space-around;
margin-left: 20rpx;
text {
width: 230rpx;
height: 90rpx;
border-radius: 10rpx;
display: flex;
flex-direction: row;
justify-content: center;
align-items: center;
}
.btn-cancel{
background: #fff;
border: 1rpx solid #c5c7cc;
font-weight: 500;
font-size: 30rpx;
letter-spacing: 0.07em;
color: #808080;
}
.btn-confirm{
border: 3rpx solid #0041c4;
font-weight: 500;
font-size: 30rpx;
letter-spacing: 0.07em;
color: #fff;
}
}
}
}
.content {
position: relative;
display: flex;
flex-direction: column;
align-items: center;
justify-content: flex-start;
width: 100%;
height: 100%;
.content-top-bg {
position: absolute;
top: 0;
left: 0;
right: 0;
width: 100%;
height: 212rpx;
border-radius: 0 0 30rpx 30rpx;
z-index: 0;
}
}
.payment {
// position: relative;
// width: 650rpx;
width: 96%;
// height: 321rpx;
margin-top: 20rpx;
border-radius: 30rpx;
background: #fff;
z-index: 1;
display: flex;
flex-direction: column;
.payment-mchName {
width: 100%;
// height: 105rpx;
padding: 30rpx 0;
font-size: 30rpx;
letter-spacing: 0.04em;
padding-left: 30rpx;
color: #000;
display: flex;
align-items: center;
}
.payment-divider {
height: 1rpx;
width: 100%;
background-color: $uni-bg-color-grey;
}
.payment-amountTips {
display: flex;
width: 100%;
font-size: 25rpx;
letter-spacing: 0.04em;
text-align: left;
padding: 30rpx 0 0 40rpx;
color: rgba(0, 0, 0, 0.6);
.desc{
width: 50%;
}
.desc1{
width: 30%;
}
.desc2{
width: 70%;
text-align: right;
margin-right: 10%;
color: #387CE7;
text-decoration: underline;
}
}
.payment-amount {
padding: 15rpx 0 0 40rpx;
.payment-amount-value {
font-size: 80rpx;
letter-spacing: 0.03em;
padding-left: 15rpx;
}
}
}
.payment-keyboard {
width: 100%;
position: fixed;
left: 0;
bottom: 0;
z-index: 5;
bottom: constant(safe-area-inset-bottom);
bottom: env(safe-area-inset-bottom);
.buyer-remark {
position: absolute;
top : -80rpx;
width: 100%;
display: flex;
flex-direction: row;
justify-content: center;
}
}
.payment-no-keyboard {
width: 80%;
height: 88rpx;
position: fixed;
left: 10%;
right: 10%;
bottom: 240rpx;
display: flex;
justify-content: center;
align-items: center;
font-size: 36rpx;
color: $uni-text-color-inverse;
border-radius: 8rpx;
}
.payment-text{
margin-bottom: 16rpx;
width: 92%;
background: #FAFAFA;
display: flex;
padding:15px;
color: #8F97A9;
margin-left: 1%;
.txt{
width: 50%;
}
.payment-text-guanggao{
text-align: left;
width: 100%;
overflow: hidden;
white-space: nowrap;
}
.payment-text-amount{
text-align: right;
// margin-right: 10%;
text{
font-weight: 600;
color: #000;
}
}
}
.pay-div-type{
width: 96%;
border-radius: 5%;
margin-left: 1%;
margin-top: 10px;
background: #ffffff;
.radio-group-box{
padding: 20rpx;
border-bottom: 2rpx solid #F4F4F4;
.radio-group-div{
width: 50%;
}
.radio-group-name{
width: 70%;
text-align: left;
display: flex;
image{
width: 50rpx;
height: 50rpx;
border-radius: 50%;
}
text{
padding: 8rpx 0 10rpx 10rpx ;
}
.radio-group-name-price{
color: #c3c3c3;
}
}
.radio-group-radio{
width: 30%;
text-align: right;
}
}
}
.payment-amountTips-price{
display: flex;
width: 100%;
font-size: 25rpx;
letter-spacing: 0.04em;
text-align: left;
padding: 30rpx 0 0 40rpx;
color: rgba(0, 0, 0, 0.6);
padding: 20rpx 0;
.desc3{
font-size: 21rpx;
width: 50%;
text-align: left;
margin-left: 3%;
color: #3D3D3D;
.desc3-text1{
border:2rpx solid #FE5735 ;
border-radius: 10rpx;
color: #FE5735;
padding: 2rpx;
}
.desc3-text2{
padding-left: 8rpx;
}
}
.desc4{
font-size: 30rpx;
width: 50%;
text-align: right;
margin-left: 3%;
margin-right: 20rpx;
color: #3D3D3D;
.desc4-text1{
color: #8F97A9;
font-size: 24rpx;
// border:2rpx solid #FE5735 ;
// border-radius: 10rpx;
// color: #FE5735;
padding: 2rpx;
}
.desc4-text2{
font-weight: 600;
padding-left: 8rpx;
}
}
}
.payment-mchName-img{
width: 120rpx;
height: 120rpx;
margin-right: 10rpx;
}
.payment-mchName1{
font-size: 32rpx;
font-weight: 500;
}
.payment-mchName2{
font-size: 26rpx;
margin-top: 15rpx;
font-weight: 400;
}
.payment-mchName2-text1{
color: #3598FE;
border: 1px solid #3598FE;
border-radius: 10rpx;
padding: 4rpx 8rpx;
}
.payment-mchName2-text2{
font-size: 28rpx;
color: #3D3D3D;
margin-left: 10rpx;
}
.scroll-view {
width: 100%;
}
.scroll-content {
display: inline-block;
// width: 1000rpx; /* 设置一个足够大的宽度以确保文本可以滚动 */
animation: slide 5s linear infinite;
}
@keyframes slide {
0% {
transform: translateX(0);
}
100% {
transform: translateX(-100%);
}
}
</style>