支付宝完成水印添加,支付界面

This commit is contained in:
tangxinyue 2026-01-16 13:46:10 +08:00
parent bcb487daab
commit 56f24cd7ab
91 changed files with 5785 additions and 1290 deletions

51
App.vue
View File

@ -1,5 +1,10 @@
<script>
export default {
globalData: {
NativeEvent: true,
recentNativeEvent: "", //
recentNativeData: 0 //
},
onLaunch: function (options) {
const startTime = Date.now()
console.log('App Launch', options)
@ -27,11 +32,57 @@ export default {
onShow: function () {
console.log('App Show')
if (this.globalData.NativeEvent) {
this.globalData.NativeEvent = false
//宿
uni.onNativeEventReceive((event, data) => {
if (event) {
if (event == "token") {
let header = uni.getStorageSync('header')
header["x-token"] = data
uni.setStorageSync('header', header)
//宿
try {
//宿
this.$getUserInfo()
} catch (error) {
//TODO handle the exception
}
// } else if (event == "jump") {
// if (data == 'pages/index/index' || data == 'pages/contacts/index' || data ==
// 'pages/discover/index' || data == 'pages/me/index') {
// uni.switchTab({
// url: '/' + data
// });
// } else {
// uni.navigateTo({
// url: '/' + data
// });
// }
} else if (event == 'wx_pay_result' || event == 'ios_pay_result') {
this.globalData.recentNativeEvent = event
this.globalData.recentNativeData = data
}
console.log('全局监听接收到宿主App消息-' + event + '' + data);
}
})
}
},
onHide: function () {
console.log('App Hide')
},
onExit: function () {
//
// #ifdef APP
// plus.sqlite.closeDatabase({ name: 'zyds' })
uni.sendNativeEvent('unimp_stop', "stop", ret => {
// console.log('宿App' + ret);
});
// #endif
console.log('App onExit')
},
methods: {
/**

View File

@ -0,0 +1,166 @@
<!--
usage:
num:显示的数字
color字体颜色
width每个数字的宽度
height:字体高度
fontSize字体大小
<countup :num="123.453" color="#ff9e50" width='13' height='23' fontSize='23'></countup>
-->
<template>
<view class="number-box">
<block v-for="(myIndex, index) in indexArr" :key="index">
<swiper class="swiper" vertical="true" :current="myIndex" circular="true" v-bind:style="{color:color,width:myIndex == 10 ? '7px' : width+'px',height:height+'px',lineHeight:fontSize+'px',fontSize:fontSize+'px'}">
<swiper-item>
<view class="swiper-item">0</view>
</swiper-item>
<swiper-item>
<view class="swiper-item">1</view>
</swiper-item>
<swiper-item>
<view class="swiper-item">2</view>
</swiper-item>
<swiper-item>
<view class="swiper-item">3</view>
</swiper-item>
<swiper-item>
<view class="swiper-item">4</view>
</swiper-item>
<swiper-item>
<view class="swiper-item">5</view>
</swiper-item>
<swiper-item>
<view class="swiper-item">6</view>
</swiper-item>
<swiper-item>
<view class="swiper-item">7</view>
</swiper-item>
<swiper-item>
<view class="swiper-item">8</view>
</swiper-item>
<swiper-item>
<view class="swiper-item">9</view>
</swiper-item>
<swiper-item>
<view class="swiper-item">.</view>
</swiper-item>
</swiper>
</block>
</view>
</template>
<script>
export default {
props: {
num: [String, Number],
color: {
type: String,
default: '#000000'
},
width: {
type: String,
default: '15'
},
height: {
type: String,
default: '15'
},
fontSize: {
type: String,
default: '15'
}
},
data() {
return {
indexArr: []
};
},
created() {
let {
num
} = this;
let arr = new Array(num.toString().length);
arr.fill(0);
this.indexArr = arr;
},
watch: {
num: function(val, oldVal) {
//
let arr = Array.prototype.slice.apply(this.indexArr);
let newLen = val.toString().length;
let oldLen = oldVal.toString().length;
if (newLen > oldLen) {
for (let i = 0; i < newLen - oldLen; i++) {
arr.push(0);
}
this.indexArr = arr;
}
if (newLen < oldLen) {
for (let i = 0; i < oldLen - newLen; i++) {
arr.pop();
}
this.indexArr = arr;
}
this.numChange(val);
}
},
mounted() {
//app
this._time = setTimeout(() => {
this.numChange(this.num);
clearTimeout(this._time);
}, 50);
},
methods: {
/**
* 数字改变
* @value 数字
*/
numChange(num) {
let {
indexArr
} = this;
let copyIndexArr = Array.prototype.slice.apply(indexArr);
let _num = num.toString();
for (let i = 0; i < _num.length; i++) {
if (_num[i] === '.') {
copyIndexArr[i] = 10;
} else {
copyIndexArr[i] = Number(_num[i]);
}
}
this.indexArr = copyIndexArr;
// this.log(this.indexArr);
}
}
};
</script>
<style lang="scss">
.number-box {
display: flex;
flex-wrap: wrap;
justify-content: center;
}
.swiper {
position: relative;
// line-height: 30upx;
// width: 30upx;
// height: 30upx;
// font-size: 30upx;
// background: red;
}
.swiper:after {
content: '';
position: absolute;
left: 0;
top: 0;
width: 100%;
height: 100%;
}
</style>

View File

@ -0,0 +1,81 @@
<template>
<view class="watermark">
<view class="watermarkBox">
<!-- <image v-if="dark=='light'" class="watermarkImg" src="/static/image/watermark.png" mode=""></image>
<image v-else class="watermarkImg" src="/static/image/watermarkDark.png" mode=""></image>
<image v-if="dark=='light'" class="colse" src="/static/image/watermarkColseLight.png" mode=""></image>
<image v-else class="colse" src="/static/image/watermarkColseDark.png" mode=""></image> -->
<image class="watermarkImg" src="/static/image/watermark.png" mode=""></image>
<image class="colse" src="/static/image/watermarkColse.png" mode="" @click="$goRechargePage('watermark_close')"></image>
</view>
</view>
</template>
<script>
export default {
props: {
dark: {
type: String,
default: 'light'
}
},
name: "watermark",
data() {
return {
statusBarHeight: 0
};
},
mounted() {
this.getStatusBarHeight()
},
methods: {
getStatusBarHeight() {
//
const systemInfo = uni.getSystemInfoSync()
this.statusBarHeight = systemInfo.statusBarHeight
console.log('状态栏高度:', this.statusBarHeight + 'px')
}
},
}
</script>
<style lang="scss">
.watermark {
pointer-events: none;
width: 100vw;
position: fixed;
height: 100vh;
top: 0;
left: 0;
right: 0;
bottom: 0;
display: flex;
align-items: center;
justify-content: center;
z-index: 99 !important;
background-image: url('/static/image/watermarkBG.png');
background-size: 125px 125px;
.watermarkBox {
width: 200px;
height: 255px;
position: relative;
z-index: 99 !important;
.colse {
position: absolute;
right: -18px;
top: -18px;
width: 18px;
height: 20px;
pointer-events: auto;
}
}
.watermarkImg {
width: 200px;
height: 55px;
pointer-events: none;
}
}
</style>

36
main.js
View File

@ -1,32 +1,38 @@
import App from './App'
import globalMethods from '@/utils/globalMethods.js';
// #ifndef VUE3
import Vue from 'vue'
import './uni.promisify.adaptor'
Vue.config.productionTip = false
App.mpType = 'app'
const app = new Vue({
...App
...App
})
app.$mount()
// #endif
// #ifdef VUE3
import { createSSRApp } from 'vue'
import { store, useStore } from './store'
import {
createSSRApp
} from 'vue'
import {
store,
useStore
} from './store'
export function createApp() {
const app = createSSRApp(App)
const app = createSSRApp(App)
// 将store挂载到全局
app.config.globalProperties.$store = store
// 将store挂载到全局
app.config.globalProperties.$store = store
// 从缓存读取系统信息已在App.vue中获取
const systemInfo = uni.getStorageSync('systemInfo') || {}
app.config.globalProperties.$platform = systemInfo.platform
app.config.globalProperties.$systemInfo = systemInfo
return {
app
}
// 从缓存读取系统信息已在App.vue中获取
const systemInfo = uni.getStorageSync('systemInfo') || {}
app.config.globalProperties.$system = systemInfo.platform == 'ios' ? 'iOS' : 'Android'
app.config.globalProperties.$systemInfo = systemInfo
uni.setStorageSync('version', '1.1.0')
app.use(globalMethods);
return {
app
}
}
// #endif

View File

@ -1,34 +1,36 @@
{
"name": "alipay-emulator",
"appid": "__UNI__D535736",
"description": "",
"versionName": "1.0.0",
"versionCode": "100",
"transformPx": false,
"name" : "alipay-emulator",
"appid" : "__UNI__D535736",
"description" : "",
"versionName" : "1.0.0",
"versionCode" : "100",
"transformPx" : false,
/* 5+App */
"app-plus": {
"usingComponents": true,
"nvueStyleCompiler": "uni-app",
"compilerVersion": 3,
"splashscreen": {
"alwaysShowBeforeRender": true,
"waiting": true,
"autoclose": true,
"delay": 0
"app-plus" : {
"usingComponents" : true,
"nvueStyleCompiler" : "uni-app",
"compilerVersion" : 3,
"splashscreen" : {
"alwaysShowBeforeRender" : true,
"waiting" : true,
"autoclose" : true,
"delay" : 0
},
"optimization": {
"subPackages": true
"optimization" : {
"subPackages" : true
},
"runmode": "liberate", //
"runmode" : "liberate", //
/* */
"modules": {
"Camera": {}
"modules" : {
"Camera" : {},
"Payment" : {}
},
/* */
"distribute": {
"distribute" : {
/* android */
"android": {
"permissions": [
"android" : {
"permissions" : [
"<uses-permission android:name=\"android.permission.CHANGE_NETWORK_STATE\"/>",
"<uses-permission android:name=\"android.permission.MOUNT_UNMOUNT_FILESYSTEMS\"/>",
"<uses-permission android:name=\"android.permission.VIBRATE\"/>",
@ -47,35 +49,46 @@
]
},
/* ios */
"ios": {
"dSYMs": false
"ios" : {
"dSYMs" : false
},
/* SDK */
"sdkConfigs": {}
"sdkConfigs" : {
"payment" : {
"weixin" : {
"__platform__" : [ "ios", "android" ],
"appid" : "123456",
"UniversalLinks" : "123456"
},
"alipay" : {
"__platform__" : [ "ios", "android" ]
}
}
}
},
"nvueLaunchMode": ""
"nvueLaunchMode" : ""
},
/* */
"quickapp": {},
"quickapp" : {},
/* */
"mp-weixin": {
"appid": "",
"setting": {
"urlCheck": false
"mp-weixin" : {
"appid" : "",
"setting" : {
"urlCheck" : false
},
"usingComponents": true
"usingComponents" : true
},
"mp-alipay": {
"usingComponents": true
"mp-alipay" : {
"usingComponents" : true
},
"mp-baidu": {
"usingComponents": true
"mp-baidu" : {
"usingComponents" : true
},
"mp-toutiao": {
"usingComponents": true
"mp-toutiao" : {
"usingComponents" : true
},
"uniStatistics": {
"enable": false
"uniStatistics" : {
"enable" : false
},
"vueVersion": "3"
}
"vueVersion" : "3"
}

21
package-lock.json generated
View File

@ -12,7 +12,9 @@
"@dcloudio/uni-app": "^2.0.2-4080720251210002",
"@dcloudio/uni-cli-shared": "^2.0.2-4080720251210002",
"@dcloudio/uni-ui": "^1.5.11",
"crypto-js": "^4.2.0"
"crypto-js": "^4.2.0",
"lottie-web": "^5.13.0",
"uuid": "^13.0.0"
},
"devDependencies": {
"less": "^4.5.1",
@ -345,6 +347,11 @@
}
}
},
"node_modules/lottie-web": {
"version": "5.13.0",
"resolved": "https://registry.npmjs.org/lottie-web/-/lottie-web-5.13.0.tgz",
"integrity": "sha512-+gfBXl6sxXMPe8tKQm7qzLnUy5DUPJPKIyRHwtpCpyUEYjHYRJC/5gjUvdkuO2c3JllrPtHXH5UJJK8LRYl5yQ=="
},
"node_modules/make-dir": {
"version": "2.1.0",
"resolved": "https://registry.npmjs.org/make-dir/-/make-dir-2.1.0.tgz",
@ -590,6 +597,18 @@
"resolved": "https://registry.npmjs.org/urijs/-/urijs-1.19.11.tgz",
"integrity": "sha512-HXgFDgDommxn5/bIv0cnQZsPhHDA90NPHD6+c/v21U5+Sx5hoP8+dP9IZXBU1gIfvdRfhG8cel9QNPeionfcCQ=="
},
"node_modules/uuid": {
"version": "13.0.0",
"resolved": "https://registry.npmjs.org/uuid/-/uuid-13.0.0.tgz",
"integrity": "sha512-XQegIaBTVUjSHliKqcnFqYypAd4S+WCYt5NIeRs6w/UAry7z8Y9j5ZwRRL4kzq9U3sD6v+85er9FvkEaBpji2w==",
"funding": [
"https://github.com/sponsors/broofa",
"https://github.com/sponsors/ctavan"
],
"bin": {
"uuid": "dist-node/bin/uuid"
}
},
"node_modules/vue": {
"version": "2.6.14",
"resolved": "https://registry.npmjs.org/vue/-/vue-2.6.14.tgz",

View File

@ -17,6 +17,8 @@
"@dcloudio/uni-app": "^2.0.2-4080720251210002",
"@dcloudio/uni-cli-shared": "^2.0.2-4080720251210002",
"@dcloudio/uni-ui": "^1.5.11",
"crypto-js": "^4.2.0"
"crypto-js": "^4.2.0",
"lottie-web": "^5.13.0",
"uuid": "^13.0.0"
}
}

View File

@ -9,11 +9,9 @@
}
}
],
"subPackages": [
{
"subPackages": [{
"root": "pages/balance",
"pages": [
{
"pages": [{
"path": "index",
"style": {
"navigationBarTitleText": "余额页面",
@ -32,8 +30,7 @@
},
{
"root": "pages/bill",
"pages": [
{
"pages": [{
"path": "bill-list/bill-list",
"style": {
"navigationBarTitleText": "账单列表页面",
@ -58,8 +55,7 @@
},
{
"root": "pages/common",
"pages": [
{
"pages": [{
"path": "hot-icon/hot-icon",
"style": {
"navigationBarTitleText": "热门图标",
@ -79,6 +75,13 @@
"navigationBarTitleText": "支付宝年度账单",
"navigationStyle": "custom"
}
},
{
"path": "recharge/index",
"style": {
"navigationBarTitleText": "充值页",
"navigationStyle": "custom"
}
}
]
}

View File

@ -1,4 +1,11 @@
<template>
<!-- 水印 -->
<view v-if="$isVip()">
<watermark :dark="data.dark" />
<liu-drag-button :canDocking="false" @clickBtn="$goRechargePage('watermark')">
<c-lottie ref="cLottieRef" :src='$watermark()' width="94px" height='74px' :loop="true"></c-lottie>
</liu-drag-button>
</view>
<view class="container" :style="{ height: data.windowHeight + 'px' }">
<view class="bg-container"></view>
<NavBar class="nav-bar" isRightIcon title="" :bgColor="data.navBar.bgColor" :buttonGroup="buttonGroup"
@ -48,10 +55,21 @@
</view>
</view>
<view class="menu-box">
<view class="item menu-icon-box" v-for="item in menuList">
<image class="menu-icon" :src="`/static/image/balance/menu-icon/${item.label}.png`" mode="">
</image>
<text class="icon-name">{{ item.name }}</text>
<scroll-view class="menu-scroll-view" scroll-x="true" @scroll="onMenuScroll"
:show-scrollbar="false">
<view class="menu-content">
<view class="item menu-icon-box" v-for="item in menuList">
<image class="menu-icon" :src="`/static/image/balance/menu-icon/${item.label}.png`"
mode="">
</image>
<text class="icon-name">{{ item.name }}</text>
</view>
</view>
</scroll-view>
<view class="scroll-bar-container" v-if="menuList.length > 5">
<view class="scroll-bar-track">
<view class="scroll-bar-thumb" :style="{ left: scrollBarLeft + '%' }"></view>
</view>
</view>
</view>
<view class="balance-change-detail-list">
@ -161,16 +179,18 @@ const data = reactive({
bgColor: "#00000000"
},
statusBarHeight: 0,
balance: 0,
balance: 1000000,
windowHeight: 0,
changeDetailList: [],
menuList: []
menuList: [],
scrollBarLeft: 0
})
let {
balance,
changeDetailList,
menuList
menuList,
scrollBarLeft
} = toRefs(data)
onLoad(async () => {
@ -388,6 +408,29 @@ const handleDelete = () => {
}
closeContextMenu()
}
//
const onMenuScroll = (e) => {
const {
scrollLeft,
scrollWidth
} = e.detail
if (!data.menuViewWidth) {
// : viewWidth scrollWidth * (5 / listLength)
if (data.menuList.length > 0) {
data.menuViewWidth = scrollWidth * (5 / data.menuList.length)
}
}
if (data.menuViewWidth) {
const maxScroll = scrollWidth - data.menuViewWidth
let percent = scrollLeft / maxScroll
if (percent < 0) percent = 0
if (percent > 1) percent = 1
data.scrollBarLeft = percent * 50
}
}
</script>
<style lang="less" scoped>
@ -559,24 +602,27 @@ const handleDelete = () => {
.menu-box {
display: flex;
flex-direction: row;
align-items: center;
justify-content: space-between;
margin-top: 8px;
border-radius: 12px;
/* overflow: hidden; */
/* overflow-x: scroll; */
/* Remove original flex properties causing conflict with scroll-view */
flex-direction: column;
align-items: stretch;
background-color: #FFFFFF;
padding: 20px 0;
margin-left: 12px;
margin-right: 12px;
overflow: hidden;
overflow-x: scroll;
margin: 16rpx 24rpx;
padding: 40rpx 0 22rpx;
border-radius: 24rpx;
.menu-icon-box {
width: 20%;
display: inline-flex;
flex-direction: column;
align-items: center;
flex-shrink: 0;
/* 修复 item 在 scroll-view 中的显示 */
}
&::-webkit-scrollbar {
/* hide scrollbar */
::v-deep ::-webkit-scrollbar {
display: none;
width: 0;
height: 0;
@ -600,6 +646,48 @@ const handleDelete = () => {
margin-top: 8px;
}
.menu-scroll-view {
white-space: nowrap;
width: 100%;
}
.menu-content {
display: flex;
flex-direction: row;
align-items: center;
}
.scroll-bar-container {
width: 100%;
display: flex;
justify-content: center;
margin-top: 10px;
}
.scroll-bar-track {
width: 50rpx;
height: 6rpx;
background-color: #F0F0F0;
border-radius: 2px;
position: relative;
overflow: hidden;
border-radius: 500px !important;
}
.scroll-bar-thumb {
width: 50%;
height: 100%;
background-color: #D8D8D8;
border-radius: 2px;
position: absolute;
top: 0;
left: 0;
transition: left 0.1s;
border-radius: 500px !important;
}
.balance-change-detail-list {
border-radius: 12px;
margin-top: 8px;

View File

@ -1,4 +1,11 @@
<template>
<!-- 水印 -->
<view v-if="$isVip()">
<watermark :dark="data.dark" />
<liu-drag-button :canDocking="false" @clickBtn="$goRechargePage('watermark')">
<c-lottie ref="cLottieRef" :src='$watermark()' width="94px" height='74px' :loop="true"></c-lottie>
</liu-drag-button>
</view>
<view style="overflow: hidden;overflow-y: scroll; height: 100vh;">
<navBar :title="data.navBar.title" :bgColor="data.navBar.bgColor" :buttonGroup="data.navBar.buttonGroup"
@button-click="util.clickTitlePopupButton"></navBar>

View File

@ -1,4 +1,11 @@
<template>
<!-- 水印 -->
<view v-if="$isVip()">
<watermark :dark="data.dark" />
<liu-drag-button :canDocking="false" @clickBtn="$goRechargePage('watermark')">
<c-lottie ref="cLottieRef" :src='$watermark()' width="94px" height='74px' :loop="true"></c-lottie>
</liu-drag-button>
</view>
<view style="overflow: hidden;height: 100vh;;">
<navBar isRightIcon :bgColor="data.navBar.bgColor" :buttonGroup="data.navBar.buttonGroup"
@button-click="clickTitlePopupButton">

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

Binary file not shown.

Before

Width:  |  Height:  |  Size: 34 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 269 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 28 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 127 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 100 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 157 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 63 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 124 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 844 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 856 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 13 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 235 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 890 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 207 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 697 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 790 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 31 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.3 KiB

BIN
static/image/watermark.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 20 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.9 KiB

3
static/json/page.json Normal file
View File

@ -0,0 +1,3 @@
{
}

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

238
static_files_list.txt Normal file
View File

@ -0,0 +1,238 @@
D:\AAA-Code\新建文件夹\alipay-emulator\static\logo.png
D:\AAA-Code\新建文件夹\alipay-emulator\static\font\AlipayNumber.ttf
D:\AAA-Code\新建文件夹\alipay-emulator\static\font\WeChatSansStd-Light.otf
D:\AAA-Code\新建文件夹\alipay-emulator\static\font\WeChatSansStd-Medium.otf
D:\AAA-Code\新建文件夹\alipay-emulator\static\font\WeChatSansStd-Regular.otf
D:\AAA-Code\新建文件夹\alipay-emulator\static\image\watermark.png
D:\AAA-Code\新建文件夹\alipay-emulator\static\image\watermarkBG.png
D:\AAA-Code\新建文件夹\alipay-emulator\static\image\watermarkColse.png
D:\AAA-Code\新建文件夹\alipay-emulator\static\image\alipay-bill\alipay-annual-bill.png
D:\AAA-Code\新建文件夹\alipay-emulator\static\image\alipay-bill\back.png
D:\AAA-Code\新建文件夹\alipay-emulator\static\image\alipay-bill\find-more.png
D:\AAA-Code\新建文件夹\alipay-emulator\static\image\alipay-bill\footer.png
D:\AAA-Code\新建文件夹\alipay-emulator\static\image\alipay-bill\hide.png
D:\AAA-Code\新建文件夹\alipay-emulator\static\image\alipay-bill\main-bg.png
D:\AAA-Code\新建文件夹\alipay-emulator\static\image\alipay-bill\music-icon.png
D:\AAA-Code\新建文件夹\alipay-emulator\static\image\alipay-bill\share-icon.png
D:\AAA-Code\新建文件夹\alipay-emulator\static\image\balance\eye.png
D:\AAA-Code\新建文件夹\alipay-emulator\static\image\balance\right-blue.png
D:\AAA-Code\新建文件夹\alipay-emulator\static\image\balance\safe-icon-blue.png
D:\AAA-Code\新建文件夹\alipay-emulator\static\image\balance\menu-icon\beiyongyue.png
D:\AAA-Code\新建文件夹\alipay-emulator\static\image\balance\menu-icon\dadada.png
D:\AAA-Code\新建文件夹\alipay-emulator\static\image\balance\menu-icon\dingshichongzhi.png
D:\AAA-Code\新建文件夹\alipay-emulator\static\image\balance\menu-icon\hongbao.png
D:\AAA-Code\新建文件夹\alipay-emulator\static\image\balance\menu-icon\linghuaqian.png
D:\AAA-Code\新建文件夹\alipay-emulator\static\image\balance\menu-icon\mianfeiedu.png
D:\AAA-Code\新建文件夹\alipay-emulator\static\image\balance\menu-icon\qinqingka.png
D:\AAA-Code\新建文件夹\alipay-emulator\static\image\balance\menu-icon\xiaohebao.png
D:\AAA-Code\新建文件夹\alipay-emulator\static\image\balance\menu-icon\xinyongkahuankuan.png
D:\AAA-Code\新建文件夹\alipay-emulator\static\image\balance\menu-icon\yinhangka.png
D:\AAA-Code\新建文件夹\alipay-emulator\static\image\balance\menu-icon\zhuanyongjin.png
D:\AAA-Code\新建文件夹\alipay-emulator\static\image\balance\menu-icon\zhuanyongzijin.png
D:\AAA-Code\新建文件夹\alipay-emulator\static\image\balance\menu-icon\zhuanzhang.png
D:\AAA-Code\新建文件夹\alipay-emulator\static\image\bill\add-bill\add-avatar.png
D:\AAA-Code\新建文件夹\alipay-emulator\static\image\bill\add-bill\edit.png
D:\AAA-Code\新建文件夹\alipay-emulator\static\image\bill\add-bill\payment-reward.png
D:\AAA-Code\新建文件夹\alipay-emulator\static\image\bill\add-bill\service-detail-image.png
D:\AAA-Code\新建文件夹\alipay-emulator\static\image\bill\bill-detail\alipay-merchant-img.png
D:\AAA-Code\新建文件夹\alipay-emulator\static\image\bill\bill-detail\bill-remark-img.png
D:\AAA-Code\新建文件夹\alipay-emulator\static\image\bill\bill-list\bg-right.png
D:\AAA-Code\新建文件夹\alipay-emulator\static\image\bill\bill-list\current-month-bill-bg.png
D:\AAA-Code\新建文件夹\alipay-emulator\static\image\bill\bill-list\down-black.png
D:\AAA-Code\新建文件夹\alipay-emulator\static\image\bill\bill-list\search-black.png
D:\AAA-Code\新建文件夹\alipay-emulator\static\image\bill\blue-icon\AAshoukuan.png
D:\AAA-Code\新建文件夹\alipay-emulator\static\image\bill\blue-icon\chakanjiaofeijindu.png
D:\AAA-Code\新建文件夹\alipay-emulator\static\image\bill\blue-icon\chakanwanglaijilu.png
D:\AAA-Code\新建文件夹\alipay-emulator\static\image\bill\blue-icon\duidingdanyouyiwen.png
D:\AAA-Code\新建文件夹\alipay-emulator\static\image\bill\blue-icon\lianxifukuanfang.png
D:\AAA-Code\新建文件夹\alipay-emulator\static\image\bill\blue-icon\lianxishangjia.png
D:\AAA-Code\新建文件夹\alipay-emulator\static\image\bill\blue-icon\lianxishoukuanfang.png
D:\AAA-Code\新建文件夹\alipay-emulator\static\image\bill\blue-icon\shenqingdianzihuidan.png
D:\AAA-Code\新建文件夹\alipay-emulator\static\image\bill\blue-icon\wanglailiushuizhengming.png
D:\AAA-Code\新建文件夹\alipay-emulator\static\image\bill\blue-icon\zhuanzhangpingzheng.png
D:\AAA-Code\新建文件夹\alipay-emulator\static\image\bill\white-icon\AAshoukuan.png
D:\AAA-Code\新建文件夹\alipay-emulator\static\image\bill\white-icon\chakanjiaofeijindu.png
D:\AAA-Code\新建文件夹\alipay-emulator\static\image\bill\white-icon\chakanwanglaijilu.png
D:\AAA-Code\新建文件夹\alipay-emulator\static\image\bill\white-icon\duidingdanyouyiwen.png
D:\AAA-Code\新建文件夹\alipay-emulator\static\image\bill\white-icon\lianxifukuanfang.png
D:\AAA-Code\新建文件夹\alipay-emulator\static\image\bill\white-icon\lianxishangjia.png
D:\AAA-Code\新建文件夹\alipay-emulator\static\image\bill\white-icon\lianxishoukuanfang.png
D:\AAA-Code\新建文件夹\alipay-emulator\static\image\bill\white-icon\shenqingdianzihuidan.png
D:\AAA-Code\新建文件夹\alipay-emulator\static\image\bill\white-icon\wanglailiushuizhengming.png
D:\AAA-Code\新建文件夹\alipay-emulator\static\image\bill\white-icon\zhuanzhangpingzheng.png
D:\AAA-Code\新建文件夹\alipay-emulator\static\image\common\close.png
D:\AAA-Code\新建文件夹\alipay-emulator\static\image\common\down-grey.png
D:\AAA-Code\新建文件夹\alipay-emulator\static\image\common\random-dice.png
D:\AAA-Code\新建文件夹\alipay-emulator\static\image\common\right-black.png
D:\AAA-Code\新建文件夹\alipay-emulator\static\image\common\right-blue.png
D:\AAA-Code\新建文件夹\alipay-emulator\static\image\common\right-grey.png
D:\AAA-Code\新建文件夹\alipay-emulator\static\image\common\hot-icon\1688.png
D:\AAA-Code\新建文件夹\alipay-emulator\static\image\common\hot-icon\711.png
D:\AAA-Code\新建文件夹\alipay-emulator\static\image\common\hot-icon\add.png
D:\AAA-Code\新建文件夹\alipay-emulator\static\image\common\hot-icon\aiqiyi.png
D:\AAA-Code\新建文件夹\alipay-emulator\static\image\common\hot-icon\baiguoyuan.png
D:\AAA-Code\新建文件夹\alipay-emulator\static\image\common\hot-icon\bilibili.png
D:\AAA-Code\新建文件夹\alipay-emulator\static\image\common\hot-icon\bishengke.png
D:\AAA-Code\新建文件夹\alipay-emulator\static\image\common\hot-icon\chabaidao.png
D:\AAA-Code\新建文件夹\alipay-emulator\static\image\common\hot-icon\chuxvyinhang.png
D:\AAA-Code\新建文件夹\alipay-emulator\static\image\common\hot-icon\dazhongdianping.png
D:\AAA-Code\新建文件夹\alipay-emulator\static\image\common\hot-icon\default.png
D:\AAA-Code\新建文件夹\alipay-emulator\static\image\common\hot-icon\dianfei.png
D:\AAA-Code\新建文件夹\alipay-emulator\static\image\common\hot-icon\dianjingwangba.png
D:\AAA-Code\新建文件夹\alipay-emulator\static\image\common\hot-icon\didichuxing.png
D:\AAA-Code\新建文件夹\alipay-emulator\static\image\common\hot-icon\dingdongmaicai.png
D:\AAA-Code\新建文件夹\alipay-emulator\static\image\common\hot-icon\douyin.png
D:\AAA-Code\新建文件夹\alipay-emulator\static\image\common\hot-icon\douyinshangcheng.png
D:\AAA-Code\新建文件夹\alipay-emulator\static\image\common\hot-icon\eleme.png
D:\AAA-Code\新建文件夹\alipay-emulator\static\image\common\hot-icon\gaodeditu.png
D:\AAA-Code\新建文件夹\alipay-emulator\static\image\common\hot-icon\gongshangyinhang.png
D:\AAA-Code\新建文件夹\alipay-emulator\static\image\common\hot-icon\guming.png
D:\AAA-Code\新建文件夹\alipay-emulator\static\image\common\hot-icon\haidilao.png
D:\AAA-Code\新建文件夹\alipay-emulator\static\image\common\hot-icon\haluo.png
D:\AAA-Code\新建文件夹\alipay-emulator\static\image\common\hot-icon\hanbaowang.png
D:\AAA-Code\新建文件夹\alipay-emulator\static\image\common\hot-icon\hemaxiansheng.png
D:\AAA-Code\新建文件夹\alipay-emulator\static\image\common\hot-icon\hepinjinyin.png
D:\AAA-Code\新建文件夹\alipay-emulator\static\image\common\hot-icon\huabei.png
D:\AAA-Code\新建文件夹\alipay-emulator\static\image\common\hot-icon\hualaishi.png
D:\AAA-Code\新建文件夹\alipay-emulator\static\image\common\hot-icon\huaxiaozhu.png
D:\AAA-Code\新建文件夹\alipay-emulator\static\image\common\hot-icon\huyazhibo.png
D:\AAA-Code\新建文件夹\alipay-emulator\static\image\common\hot-icon\jianbingdao.png
D:\AAA-Code\新建文件夹\alipay-emulator\static\image\common\hot-icon\jiansheyinhang.png
D:\AAA-Code\新建文件夹\alipay-emulator\static\image\common\hot-icon\jiaotongyinhang.png
D:\AAA-Code\新建文件夹\alipay-emulator\static\image\common\hot-icon\jinchanchan.png
D:\AAA-Code\新建文件夹\alipay-emulator\static\image\common\hot-icon\jingdong.png
D:\AAA-Code\新建文件夹\alipay-emulator\static\image\common\hot-icon\kendeji.png
D:\AAA-Code\新建文件夹\alipay-emulator\static\image\common\hot-icon\luosen.png
D:\AAA-Code\新建文件夹\alipay-emulator\static\image\common\hot-icon\maidanglao.png
D:\AAA-Code\新建文件夹\alipay-emulator\static\image\common\hot-icon\maidelong.png
D:\AAA-Code\新建文件夹\alipay-emulator\static\image\common\hot-icon\mangguoTV.png
D:\AAA-Code\新建文件夹\alipay-emulator\static\image\common\hot-icon\maoyandianying.png
D:\AAA-Code\新建文件夹\alipay-emulator\static\image\common\hot-icon\meituan.png
D:\AAA-Code\新建文件夹\alipay-emulator\static\image\common\hot-icon\meituanwaimai.png
D:\AAA-Code\新建文件夹\alipay-emulator\static\image\common\hot-icon\micunbanfan.png
D:\AAA-Code\新建文件夹\alipay-emulator\static\image\common\hot-icon\mixuebingcheng.png
D:\AAA-Code\新建文件夹\alipay-emulator\static\image\common\hot-icon\naixuedecha.png
D:\AAA-Code\新建文件夹\alipay-emulator\static\image\common\hot-icon\nongyeyinhang.png
D:\AAA-Code\新建文件夹\alipay-emulator\static\image\common\hot-icon\pinduoduo.png
D:\AAA-Code\新建文件夹\alipay-emulator\static\image\common\hot-icon\pufayinhang.png
D:\AAA-Code\新建文件夹\alipay-emulator\static\image\common\hot-icon\ranqifei.png
D:\AAA-Code\新建文件夹\alipay-emulator\static\image\common\hot-icon\ruixingkafei.png
D:\AAA-Code\新建文件夹\alipay-emulator\static\image\common\hot-icon\sanjiaozhou.png
D:\AAA-Code\新建文件夹\alipay-emulator\static\image\common\hot-icon\shangpin.png
D:\AAA-Code\新建文件夹\alipay-emulator\static\image\common\hot-icon\shanmuchaoshi.png
D:\AAA-Code\新建文件夹\alipay-emulator\static\image\common\hot-icon\shaxianxiaochi.png
D:\AAA-Code\新建文件夹\alipay-emulator\static\image\common\hot-icon\shuifei.png
D:\AAA-Code\新建文件夹\alipay-emulator\static\image\common\hot-icon\taobao.png
D:\AAA-Code\新建文件夹\alipay-emulator\static\image\common\hot-icon\taopiaopiao.png
D:\AAA-Code\新建文件夹\alipay-emulator\static\image\common\hot-icon\tasiting.png
D:\AAA-Code\新建文件夹\alipay-emulator\static\image\common\hot-icon\tengxunshipin.png
D:\AAA-Code\新建文件夹\alipay-emulator\static\image\common\hot-icon\tianmao.png
D:\AAA-Code\新建文件夹\alipay-emulator\static\image\common\hot-icon\tuikuan.png
D:\AAA-Code\新建文件夹\alipay-emulator\static\image\common\hot-icon\wangzherongyao.png
D:\AAA-Code\新建文件夹\alipay-emulator\static\image\common\hot-icon\weipinhui.png
D:\AAA-Code\新建文件夹\alipay-emulator\static\image\common\hot-icon\wuweiqiyue.png
D:\AAA-Code\新建文件夹\alipay-emulator\static\image\common\hot-icon\xianyu.png
D:\AAA-Code\新建文件夹\alipay-emulator\static\image\common\hot-icon\xingbake.png
D:\AAA-Code\新建文件夹\alipay-emulator\static\image\common\hot-icon\yanyunshiliusheng.png
D:\AAA-Code\新建文件夹\alipay-emulator\static\image\common\hot-icon\yidiandian.png
D:\AAA-Code\新建文件夹\alipay-emulator\static\image\common\hot-icon\yonghuichaoshi.png
D:\AAA-Code\新建文件夹\alipay-emulator\static\image\common\hot-icon\youku.png
D:\AAA-Code\新建文件夹\alipay-emulator\static\image\common\hot-icon\yuanshen.png
D:\AAA-Code\新建文件夹\alipay-emulator\static\image\common\hot-icon\yuebao.png
D:\AAA-Code\新建文件夹\alipay-emulator\static\image\common\hot-icon\yunshangguizhou.png
D:\AAA-Code\新建文件夹\alipay-emulator\static\image\common\hot-icon\zhaoshangyinhang.png
D:\AAA-Code\新建文件夹\alipay-emulator\static\image\common\hot-icon\zhengxinjipai.png
D:\AAA-Code\新建文件夹\alipay-emulator\static\image\common\hot-icon\zhongguoyinhang.png
D:\AAA-Code\新建文件夹\alipay-emulator\static\image\common\hot-icon\zhouheiya.png
D:\AAA-Code\新建文件夹\alipay-emulator\static\image\common\hot-icon\zhuanzhuan.png
D:\AAA-Code\新建文件夹\alipay-emulator\static\image\index\alipay-year-bill.png
D:\AAA-Code\新建文件夹\alipay-emulator\static\image\index\hot-icon.png
D:\AAA-Code\新建文件夹\alipay-emulator\static\image\index\index-bg.png
D:\AAA-Code\新建文件夹\alipay-emulator\static\image\index\lifetime-vip-bg.png
D:\AAA-Code\新建文件夹\alipay-emulator\static\image\index\monixiaobao.png
D:\AAA-Code\新建文件夹\alipay-emulator\static\image\index\no-vip-bg.png
D:\AAA-Code\新建文件夹\alipay-emulator\static\image\index\open-vip-btn.png
D:\AAA-Code\新建文件夹\alipay-emulator\static\image\index\shipingjiaocheng.png
D:\AAA-Code\新建文件夹\alipay-emulator\static\image\index\vip-bg.png
D:\AAA-Code\新建文件夹\alipay-emulator\static\image\index\vip-btn.png
D:\AAA-Code\新建文件夹\alipay-emulator\static\image\index\vip-logo.png
D:\AAA-Code\新建文件夹\alipay-emulator\static\image\index\menu-icon\huabei.png
D:\AAA-Code\新建文件夹\alipay-emulator\static\image\index\menu-icon\licaiheika.png
D:\AAA-Code\新建文件夹\alipay-emulator\static\image\index\menu-icon\yuemoni.png
D:\AAA-Code\新建文件夹\alipay-emulator\static\image\index\menu-icon\zhangdanshencheng.png
D:\AAA-Code\新建文件夹\alipay-emulator\static\image\index\menu-name\huabei.png
D:\AAA-Code\新建文件夹\alipay-emulator\static\image\index\menu-name\licaiheika.png
D:\AAA-Code\新建文件夹\alipay-emulator\static\image\index\menu-name\yuemoni.png
D:\AAA-Code\新建文件夹\alipay-emulator\static\image\index\menu-name\zhangdanshencheng.png
D:\AAA-Code\新建文件夹\alipay-emulator\static\image\nav-bar\back-black.png
D:\AAA-Code\新建文件夹\alipay-emulator\static\image\nav-bar\back-white.png
D:\AAA-Code\新建文件夹\alipay-emulator\static\image\nav-bar\more-black.png
D:\AAA-Code\新建文件夹\alipay-emulator\static\image\nav-bar\more-white.png
D:\AAA-Code\新建文件夹\alipay-emulator\static\image\recharge\activePackagItemBg.png
D:\AAA-Code\新建文件夹\alipay-emulator\static\image\recharge\alipay.png
D:\AAA-Code\新建文件夹\alipay-emulator\static\image\recharge\banner1.png
D:\AAA-Code\新建文件夹\alipay-emulator\static\image\recharge\bottom-button.png
D:\AAA-Code\新建文件夹\alipay-emulator\static\image\recharge\checked1.png
D:\AAA-Code\新建文件夹\alipay-emulator\static\image\recharge\checked2.png
D:\AAA-Code\新建文件夹\alipay-emulator\static\image\recharge\checked3.png
D:\AAA-Code\新建文件夹\alipay-emulator\static\image\recharge\couponHeaderBg.png
D:\AAA-Code\新建文件夹\alipay-emulator\static\image\recharge\couponItemBg.png
D:\AAA-Code\新建文件夹\alipay-emulator\static\image\recharge\couponItemTips.png
D:\AAA-Code\新建文件夹\alipay-emulator\static\image\recharge\couponMin.png
D:\AAA-Code\新建文件夹\alipay-emulator\static\image\recharge\dialogImg.png
D:\AAA-Code\新建文件夹\alipay-emulator\static\image\recharge\dialogTitleLeft.png
D:\AAA-Code\新建文件夹\alipay-emulator\static\image\recharge\dialogTitleRight.png
D:\AAA-Code\新建文件夹\alipay-emulator\static\image\recharge\guoqi.png
D:\AAA-Code\新建文件夹\alipay-emulator\static\image\recharge\headerBg.png
D:\AAA-Code\新建文件夹\alipay-emulator\static\image\recharge\huiyuanqun.png
D:\AAA-Code\新建文件夹\alipay-emulator\static\image\recharge\icon1.png
D:\AAA-Code\新建文件夹\alipay-emulator\static\image\recharge\icon10.png
D:\AAA-Code\新建文件夹\alipay-emulator\static\image\recharge\icon11.png
D:\AAA-Code\新建文件夹\alipay-emulator\static\image\recharge\icon12.png
D:\AAA-Code\新建文件夹\alipay-emulator\static\image\recharge\icon2.png
D:\AAA-Code\新建文件夹\alipay-emulator\static\image\recharge\icon3.png
D:\AAA-Code\新建文件夹\alipay-emulator\static\image\recharge\icon4.png
D:\AAA-Code\新建文件夹\alipay-emulator\static\image\recharge\icon5.png
D:\AAA-Code\新建文件夹\alipay-emulator\static\image\recharge\icon6.png
D:\AAA-Code\新建文件夹\alipay-emulator\static\image\recharge\icon7.png
D:\AAA-Code\新建文件夹\alipay-emulator\static\image\recharge\icon8.png
D:\AAA-Code\新建文件夹\alipay-emulator\static\image\recharge\icon9.png
D:\AAA-Code\新建文件夹\alipay-emulator\static\image\recharge\moniweixin.png
D:\AAA-Code\新建文件夹\alipay-emulator\static\image\recharge\moniweixinDialog.png
D:\AAA-Code\新建文件夹\alipay-emulator\static\image\recharge\myCouponContainerBg.png
D:\AAA-Code\新建文件夹\alipay-emulator\static\image\recharge\myCouponContainerClose.png
D:\AAA-Code\新建文件夹\alipay-emulator\static\image\recharge\notice.png
D:\AAA-Code\新建文件夹\alipay-emulator\static\image\recharge\packagItemBg.png
D:\AAA-Code\新建文件夹\alipay-emulator\static\image\recharge\question1.png
D:\AAA-Code\新建文件夹\alipay-emulator\static\image\recharge\question2.png
D:\AAA-Code\新建文件夹\alipay-emulator\static\image\recharge\selected.png
D:\AAA-Code\新建文件夹\alipay-emulator\static\image\recharge\shadowBg.png
D:\AAA-Code\新建文件夹\alipay-emulator\static\image\recharge\starRating.png
D:\AAA-Code\新建文件夹\alipay-emulator\static\image\recharge\titleLeft.png
D:\AAA-Code\新建文件夹\alipay-emulator\static\image\recharge\titleRight.png
D:\AAA-Code\新建文件夹\alipay-emulator\static\image\recharge\unselected.png
D:\AAA-Code\新建文件夹\alipay-emulator\static\image\recharge\wenjuan.png
D:\AAA-Code\新建文件夹\alipay-emulator\static\image\recharge\wuguanggao.png
D:\AAA-Code\新建文件夹\alipay-emulator\static\image\recharge\wuguanggaoDialog.png
D:\AAA-Code\新建文件夹\alipay-emulator\static\image\recharge\wushuiyin.png
D:\AAA-Code\新建文件夹\alipay-emulator\static\image\recharge\wushuiyinDialog.png
D:\AAA-Code\新建文件夹\alipay-emulator\static\image\recharge\wxpay.png
D:\AAA-Code\新建文件夹\alipay-emulator\static\image\recharge\zhuanshukefu.png
D:\AAA-Code\新建文件夹\alipay-emulator\static\image\recharge\zhuanshukefuDialog.png
D:\AAA-Code\新建文件夹\alipay-emulator\static\js\globalMethods.js
D:\AAA-Code\新建文件夹\alipay-emulator\static\json\add-bill.json
D:\AAA-Code\新建文件夹\alipay-emulator\static\json\hot-icon.json
D:\AAA-Code\新建文件夹\alipay-emulator\static\json\initial.json
D:\AAA-Code\新建文件夹\alipay-emulator\static\json\page.json
D:\AAA-Code\新建文件夹\alipay-emulator\static\lottie\christmas.json
D:\AAA-Code\新建文件夹\alipay-emulator\static\lottie\coupon.json
D:\AAA-Code\新建文件夹\alipay-emulator\static\lottie\couponButton.json
D:\AAA-Code\新建文件夹\alipay-emulator\static\lottie\couponTop.json
D:\AAA-Code\新建文件夹\alipay-emulator\static\lottie\hongbao.json
D:\AAA-Code\新建文件夹\alipay-emulator\static\lottie\index_christmas1.json
D:\AAA-Code\新建文件夹\alipay-emulator\static\lottie\index_christmas2.json
D:\AAA-Code\新建文件夹\alipay-emulator\static\lottie\template.json
D:\AAA-Code\新建文件夹\alipay-emulator\static\lottie\template2.json
D:\AAA-Code\新建文件夹\alipay-emulator\static\lottie\watermark.json
D:\AAA-Code\新建文件夹\alipay-emulator\static\lottie\watermarkEyes.png
D:\AAA-Code\新建文件夹\alipay-emulator\static\lottie\watermarkNavbar.json

View File

@ -0,0 +1,20 @@
## 1.0.92023-09-08
修复在微信小程序端当多个Lottie组件存在时无法单独控制某一组件的问题
## 1.0.82023-07-14
新增加载成功事件dataReady 加载失败事件 dataFailed
## 1.0.72023-07-14
新增加载成功事件dataReady 加载失败事件 dataFailed
## 1.0.62023-04-18
优化实现细节
## 1.0.52023-04-18
修复已知问题
## 1.0.42023-04-18
修复条件编译导致的编译异常
## 1.0.32023-04-04
修复vue2编译到H5平台加载异常的问题
## 1.0.22023-03-29
兼容vue2
## 1.0.12023-03-08
修复props响应性丢失问题
## 1.0.02023-03-02
init

View File

@ -0,0 +1,269 @@
<template>
<!-- #ifdef H5||APP-PLUS -->
<view class="c-lottie" :style="{width,height}" :lottieData="lottieData" :change:lottieData="lottie.render" :fun='fun'
:change:fun='lottie.callPlayer'>
<div :id='myCanvasId'></div>
</view>
<!-- #endif -->
<!-- #ifdef MP -->
<view class="c-lottie" :style="{width,height}">
<canvas class="canvas" :id="myCanvasId" type="2d"></canvas>
</view>
<!-- #endif -->
</template>
<script>
/**
* c-lottie Lottie组件
* @property {String} canvasId 画布id
* @property {String} width 图像宽度 默认750rpx 单位rpx/px
* @property {String} height 图像高度 默认750rpx 单位rpx/px
* @property {String} src Lottie文件地址 小程序只支持网络地址
* @property {String} data Lottie文件data
* @property {Boolean} autoPlay 是否自动播放 默认true
* @property {Boolean} loop 是否循环播放 默认值为 true
* @property {String} renderer 渲染模式 默认值为canvas 可选值 svg|canvas 小程序不支持
* @property {Boolean} isOnChange 是否开启播放进度监听 默认false false时不触发EnterFrame
* @event {Function()} Complete 监听动画播放完成
* @event {Function()} LoopComplete 监听当前循环播放完成
* @event {Function()} EnterFrame 监听动画播放进度
* @event {Function()} SegmentStart 监听开始播放一个动画片段
* @event {Function()} dataReady 当动画的所有部分都已加载时触发
* @event {Function()} dataFailed 当部分动画无法加载时触发
* 组件内方法统一使用 call(funName, args) 调用player实例方法 详见文档
* */
import uuid from './js/uuid.js'
// #ifdef MP&VUE3
import lottie from 'lottie-miniprogram'
// #endif
// #ifdef MP&VUE2
import lottie from '../../node_modules/lottie-miniprogram'
// #endif
export default {
props: {
canvasId: {
type: String
},
width: {
type: String,
default: '750rpx'
},
height: {
type: String,
default: '750rpx'
},
src: {
type: String,
},
data: {
type: String,
},
autoPlay: { //
type: Boolean,
default: true
},
loop: { // true
type: Boolean,
default: true
},
renderer: { // canvas svg
type: String,
default: 'canvas',
},
isOnChange: {
type: Boolean,
default: false
}
},
emits: ['Complete', 'LoopComplete', 'EnterFrame', 'SegmentStart','dataReady','dataFailed'],
data() {
return {
fun: {}
}
},
computed: {
myCanvasId() {
if (!this.canvasId) {
return 'c' + uuid(18)
} else {
return this.canvasId
}
},
lottieData() {
return {
myCanvasId: this.myCanvasId,
width: this.width,
height: this.height,
src: this.src,
data: this.data,
autoPlay: this.autoPlay,
loop: this.loop,
renderer: this.renderer,
isOnChange: this.isOnChange
}
}
},
watch: {
lottieData() {
// #ifdef MP
this.render()
// #endif
}
},
methods: {
call(name, args) {
this.fun = {name,args}
// #ifdef MP
this.callPlayer(this.fun)
// #endif
},
// #ifdef MP
getContext() {
return new Promise((resolve) => {
const {
pixelRatio
} = uni.getSystemInfoSync()
uni.createSelectorQuery()
.in(this)
.select(`#${this.myCanvasId}`)
.fields({
node: true,
size: true
})
.exec(res => {
const {
width,
height
} = res[0]
const canvas = res[0].node
resolve({
canvas,
width,
height,
pixelRatio
})
})
})
},
async render() {
if (this.player) {
// console.log(player);
// call('stop')
this.call('destroy', this.player)
}
let {
canvas,
width,
height,
pixelRatio
} = await this.getContext()
this.myCanvas = canvas
this.context = canvas.getContext('2d')
//齿
this.context.scale(pixelRatio, pixelRatio)
canvas.width = width * pixelRatio
canvas.height = height * pixelRatio
lottie.setup(this.myCanvas)
this.player = lottie.loadAnimation({
loop: this.loop,
autoplay: this.autoPlay,
// json
animationData: this.data,
//json
path: this.src,
rendererSettings: {
context:this.context,
},
})
this.player.addEventListener('data_ready',(val)=>{ //
this.$emit('dataReady', val)
})
this.player.addEventListener('data_failed',(val)=>{ //
this.$emit('dataFailed', val)
})
this.player.onComplete = (val) => { //
// console.log('',val);
this.$emit('Complete', val)
}
this.player.onLoopComplete = (val) => { //
// console.log('',val);
this.$emit('LoopComplete', val)
}
if (this.isOnChange) {
this.player.onEnterFrame = (val) => { //
// console.log('',val);
this.$emit('EnterFrame', val)
}
}
this.player.onSegmentStart = (val) => { //
// console.log('',val);
this.$emit('SegmentStart', val)
}
},
callPlayer(val) {
if (!val.name) return;
let {name,args} = val
// console.log(name, args);
if (Array.isArray(args)) {
this.player[name](...args)
} else {
this.player[name](args)
}
},
// #endif
// #ifndef MP
receiveRenderData(val) {
// console.log(val);
this.$emit(val.name, val.val)
}
// #endif
},
mounted() {
// #ifdef MP
this.render()
// #endif
},
beforeDestroy() {
//
this.call('destroy')
}
}
</script>
<!-- #ifndef MP -->
<!-- #ifdef VUE3 -->
<script lang="renderjs" src='./js/render.js' module='lottie'></script>
<!-- #endif -->
<!-- #ifdef VUE2 -->
<script lang="renderjs" module='lottie'>
import lottieRender from "./js/render.js"
export default {
mixins:[lottieRender],
}
</script>
<!-- #endif -->
<!-- #endif -->
<style lang="scss" scoped>
.c-lottie {
// width: v-bind(width);
// height: v-bind(height);
/* #ifndef MP */
div {
width: 100%;
height: 100%;
}
/* #endif */
.canvas {
width: 100%;
height: 100%;
}
}
</style>

View File

@ -0,0 +1,67 @@
export default function getfile(e,isIosDown=false) {
// #ifdef APP-PLUS
let isIOS = plus.os.name==='iOS'
let url = plus.io.convertLocalFileSystemURL(e)
return new Promise((resolve, reject) => {
if (/(http|https):\/\/([\w.]+\/?)\S*/.test(url)) {
if(!isIosDown||!isIOS){
resolve(e)
return
}
if(isIOS){
let dtask = plus.downloader.createDownload(url, {}, function(d, status) {
// 下载完成
if (status == 200) {
let newurl = plus.io.convertLocalFileSystemURL(d.filename);
// console.log("Download success: " + newurl);
plus.io.resolveLocalFileSystemURL(newurl, entry => {
let reader = null;
entry.file(file => {
reader = new plus.io.FileReader();
reader.onloadend = (read) => {
resolve(read.target.result)
};
reader.readAsDataURL(file);
}, function(error) {
console.log(error.message);
});
}, err => {
resolve(e)
})
} else {
console.log("Download failed: " + status);
reject(status)
}
})
dtask.start();
}
} else {
plus.io.resolveLocalFileSystemURL(url, entry => {
let reader = null;
entry.file(file => {
reader = new plus.io.FileReader();
reader.onloadend = (read) => {
resolve(read.target.result)
};
reader.readAsDataURL(file);
}, function(error) {
console.log(error.message);
});
}, err => {
resolve(e)
})
}
})
// #endif
// #ifdef H5
return new Promise((resolve, reject) => {
resolve(e)
})
// #endif
}

View File

@ -0,0 +1,79 @@
// #ifdef VUE3
import lottie from 'lottie-web'
// #endif
// #ifdef VUE2
import lottie from '../../../node_modules/lottie-web'
// #endif
import getfile from './getfile.js'
export default {
data() {
return {
player: null,
pdata:{}
}
},
methods: {
async render(val,oldValue,vm) {
this.$nextTick(async()=>{
let data,player;
// console.log(val);
if(val){
data =val
this.pdata=data
}else{
data=this.pdata
}
// console.log(data);
if(this.player){
this.player.destroy()
}
player = lottie.loadAnimation({
container:document.getElementById(data.myCanvasId), // the dom element
renderer: data.renderer,
loop: data.loop,
autoplay: data.autoPlay,
// 动画json的本地数据
animationData: data.data,
// 动画json的网络路径
path: data.src?await getfile(data.src):''
})
player.addEventListener('data_ready',(val)=>{ //当动画的所有部分都已加载时
vm.callMethod('receiveRenderData',{name:'dataReady',val})
})
player.addEventListener('data_failed',(val)=>{ //当部分动画无法加载时
vm.callMethod('receiveRenderData',{name:'dataFailed',val})
})
player.onComplete=(val)=>{ //动画播放完成触发
//console.log('动画播放完成触发',val);
vm.callMethod('receiveRenderData',{name:'Complete',val})
}
player.onLoopComplete=(val)=>{ //当前循环播放完成触发
//console.log('当前循环播放完成触发',val);
vm.callMethod('receiveRenderData',{name:'LoopComplete',val})
}
if(data.isOnChange){
player.onEnterFrame=(val)=>{ //播放动画的时候触发
//console.log('播放动画的时候触发',val);
vm.callMethod('receiveRenderData',{name:'EnterFrame',val})
}
}
player.onSegmentStart=(val)=>{ //开始播放一个动画片段的时候触发
//console.log('开始播放一个动画片段的时候触发',val);
vm.callMethod('receiveRenderData',{name:'SegmentStart',val})
}
this.player=player
})
},
async callPlayer(val){
if(!val.name)return;
let {name, args} = val
// console.log(name, args);
if(Array.isArray(args)){
this.player[name](...args)
}else{
this.player[name](args)
}
}
},
}

View File

@ -0,0 +1,23 @@
export default (len = 32, radix = null) => {
let chars = '0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz'.split('');
let uuid = [];
radix = radix || chars.length;
if (len) {
// 如果指定uuid长度,只是取随机的字符,0|x为位运算,能去掉x的小数位,返回整数位
for (let i = 0; i < len; i++) uuid[i] = chars[0 | Math.random() * radix];
} else {
let r;
// rfc4122标准要求返回的uuid中,某些位为固定的字符
uuid[8] = uuid[13] = uuid[18] = uuid[23] = '-';
uuid[14] = '4';
for (let i = 0; i < 36; i++) {
if (!uuid[i]) {
r = 0 | Math.random() * 16;
uuid[i] = chars[(i == 19) ? (r & 0x3) | 0x8 : r];
}
}
}
return uuid.join('');
}

View File

@ -0,0 +1,87 @@
{
"id": "c-lottie",
"displayName": "c-lottie",
"version": "1.0.9",
"description": "c-design c-lottie动画 支持app h5 微信小程序",
"keywords": [
"lottie",
"动画",
"微信lottie"
],
"repository": "https://gitee.com/wangziwl/c-designc",
"engines": {
"HBuilderX": "^3.7.0"
},
"dcloudext": {
"type": "component-vue",
"sale": {
"regular": {
"price": "0.00"
},
"sourcecode": {
"price": "0.00"
}
},
"contact": {
"qq": ""
},
"declaration": {
"ads": "无",
"data": "无",
"permissions": "无"
},
"npmurl": ""
},
"uni_modules": {
"dependencies": [],
"encrypt": [],
"platforms": {
"cloud": {
"tcb": "y",
"aliyun": "y"
},
"client": {
"Vue": {
"vue2": "y",
"vue3": "y"
},
"App": {
"app-vue": "y",
"app-nvue": "n"
},
"H5-mobile": {
"Safari": "y",
"Android Browser": "y",
"微信浏览器(Android)": "y",
"QQ浏览器(Android)": "y"
},
"H5-pc": {
"Chrome": "y",
"IE": "u",
"Edge": "y",
"Firefox": "y",
"Safari": "y"
},
"小程序": {
"微信": "y",
"阿里": "u",
"百度": "u",
"字节跳动": "u",
"QQ": "u",
"钉钉": "u",
"快手": "u",
"飞书": "u",
"京东": "u"
},
"快应用": {
"华为": "u",
"联盟": "u"
}
}
}
},
"dependencies": {
"lottie-miniprogram": "^1.0.12",
"lottie-web": "^5.10.2"
}
}

View File

@ -0,0 +1,220 @@
# c-lottie
###
- c-lottie lottie动画
### c-design交流群号330647926
### 示例预览
[https://cloud.vuedata.wang/cdesign/#/pages/lottie/lottie](https://cloud.vuedata.wang/cdesign/#/pages/lottie/lottie)
####
![微信小程序预览](https://mp-eeab6da6-80cd-4e80-844a-66b2a7203834.cdn.bspapp.com/cloudstorage/dca3227b-0028-47f6-b576-cb89def67177.png?x-oss-process=image/resize,m_fixed,w_240)
### 一、使用示例
#### vue2/vue3
```html
<template>
<view>
<c-lottie
ref="cLottieRef"
:src='src'
@LoopComplete="onLoopComplete"
width="750rpx" height='750rpx' :loop="true"></c-lottie>
<view class="content">
<view>切换图像</view>
<view class="btnBox">
<button @click="src='https://mp-eeab6da6-80cd-4e80-844a-66b2a7203834.cdn.bspapp.com/cloudstorage/7b538fb7-d2d5-4524-bf21-6c20e3b5ce6f.json'" size="mini">热销</button>
<button @click="src='https://mp-eeab6da6-80cd-4e80-844a-66b2a7203834.cdn.bspapp.com/cloudstorage/c42b5f05-06b9-43e7-8436-c1029eee610a.json'" size="mini">字母</button>
</view>
<view>播放暂停</view>
<view class="btnBox">
<button @click="this.$refs.cLottieRef.call('play')" size="mini">播放</button>
<button @click="this.$refs.cLottieRef.call('setDirection',-1)" size="mini">反向播放</button>
<button @click="this.$refs.cLottieRef.call('pause')" size="mini">暂停播放</button>
<button @click="this.$refs.cLottieRef.call('stop')" size="mini">停止播放</button>
</view>
<view>播放速度</view>
<view class="btnBox">
<button @click="this.$refs.cLottieRef.call('setSpeed',1)" size="mini">播放速度1x</button>
<button @click="this.$refs.cLottieRef.call('setSpeed',2)" size="mini">播放速度2x</button>
</view>
<view>播放其它设置</view>
<view class="btnBox">
<button @click="this.$refs.cLottieRef.call('goToAndStop',[2000,false])" size="mini">跳转到2s并暂停</button>
<button @click="this.$refs.cLottieRef.call('goToAndPlay',[2000,false])" size="mini">跳转到2s并播放</button>
</view>
<view class="btnBox">
<button @click="this.$refs.cLottieRef.call('goToAndStop',[2,true])" size="mini">跳转到第2帧并暂停</button>
<button @click="this.$refs.cLottieRef.call('goToAndPlay',[2,true])" size="mini">跳转到第2帧并播放</button>
</view>
<view class="btnBox">
<button @click="this.$refs.cLottieRef.call('playSegments',[[10,20],false])" size="mini">播放完之前的片段播放10-20帧</button>
</view>
<view class="btnBox">
<button @click="this.$refs.cLottieRef.call('playSegments',[[[0,5],[10,18]],true])" size="mini">直接播放0-5帧和10-18帧</button>
</view>
</view>
</view>
</template>
<script>
export default {
data() {
return {
src: 'https://mp-eeab6da6-80cd-4e80-844a-66b2a7203834.cdn.bspapp.com/cloudstorage/7b538fb7-d2d5-4524-bf21-6c20e3b5ce6f.json'
}
},
methods: {
onLoopComplete(val) {
// console.log('当前循环播放完成',val);
}
},
}
</script>
<style lang="scss">
.page{
width: 100vw;
overflow-x: hidden;
}
.content{
padding: 20rpx;
font-size: 28rpx;
}
.btnBox{
width: 100%;
display: flex;align-items: center;
margin-top: 20rpx;
margin-bottom: 30rpx;
}
</style>
```
#### vue3
```html
<template>
<view>
<c-lottie
ref="cLottieRef"
:src='src'
@LoopComplete="onLoopComplete"
width="750rpx" height='750rpx' :loop="true"></c-lottie>
<view class="content">
<view>切换图像</view>
<view class="btnBox">
<button @click="src='https://mp-eeab6da6-80cd-4e80-844a-66b2a7203834.cdn.bspapp.com/cloudstorage/7b538fb7-d2d5-4524-bf21-6c20e3b5ce6f.json'" size="mini">热销</button>
<button @click="src='https://mp-eeab6da6-80cd-4e80-844a-66b2a7203834.cdn.bspapp.com/cloudstorage/c42b5f05-06b9-43e7-8436-c1029eee610a.json'" size="mini">字母</button>
</view>
<view>播放暂停</view>
<view class="btnBox">
<button @click="cLottieRef.call('play')" size="mini">播放</button>
<button @click="cLottieRef.call('setDirection',-1)" size="mini">反向播放</button>
<button @click="cLottieRef.call('pause')" size="mini">暂停播放</button>
<button @click="cLottieRef.call('stop')" size="mini">停止播放</button>
</view>
<view>播放速度</view>
<view class="btnBox">
<button @click="cLottieRef.call('setSpeed',1)" size="mini">播放速度1x</button>
<button @click="cLottieRef.call('setSpeed',2)" size="mini">播放速度2x</button>
</view>
<view>播放其它设置</view>
<view class="btnBox">
<button @click="cLottieRef.call('goToAndStop',[2000,false])" size="mini">跳转到2s并暂停</button>
<button @click="cLottieRef.call('goToAndPlay',[2000,false])" size="mini">跳转到2s并播放</button>
</view>
<view class="btnBox">
<button @click="cLottieRef.call('goToAndStop',[2,true])" size="mini">跳转到第2帧并暂停</button>
<button @click="cLottieRef.call('goToAndPlay',[2,true])" size="mini">跳转到第2帧并播放</button>
</view>
<view class="btnBox">
<button @click="cLottieRef.call('playSegments',[[10,20],false])" size="mini">播放完之前的片段播放10-20帧</button>
</view>
<view class="btnBox">
<button @click="cLottieRef.call('playSegments',[[[0,5],[10,18]],true])" size="mini">直接播放0-5帧和10-18帧</button>
</view>
</view>
</view>
</template>
<script setup>
import { ref } from "vue";
const cLottieRef = ref()
let src=ref('https://mp-eeab6da6-80cd-4e80-844a-66b2a7203834.cdn.bspapp.com/cloudstorage/7b538fb7-d2d5-4524-bf21-6c20e3b5ce6f.json')
const onLoopComplete=(val)=>{
// console.log('当前循环播放完成',val);
}
</script>
<style lang="scss">
.page{
width: 100vw;
overflow-x: hidden;
}
.content{
padding: 20rpx;
font-size: 28rpx;
}
.btnBox{
width: 100%;
display: flex;align-items: center;
margin-top: 20rpx;
margin-bottom: 30rpx;
}
</style>
```
### 二、Props
| 字段 | 类型 | 必填 | 默认值 | 描述 |
| ----------- | -------- | ---- | ----------------------| -------------------------------
| canvasId | String | 否| 'c'+uuid(18) | canvasId 画布id 可不填此项 |
| width | String | 否| 750rpx | 图像宽度 单位rpx/px |
| height | String | 否| 750rpx | 图像高度 单位rpx/px |
| src | String | 是| | Lottie文件地址 小程序只支持网络地址 |
| data | String | 否| | Lottie文件data |
| autoPlay | Boolean | 否| true | 是否自动播放 |
| loop | Boolean | 否| true | 是否循环播放 |
| renderer | String | 否| canvas | 可选值 svg,canvas 小程序不支持 |
| isOnChange| Boolean | 否| false |false时不触发 EnterFrame监听 |
### 三、Event
| 字段 | 描述 |
| --------- | ------------------------ |
| Complete | 监听动画播放完成 |
| LoopComplete | 监听当前循环播放完成 |
| EnterFrame | 监听动画播放进度 |
| SegmentStart | 监听开始播放一个动画片段 |
| dataReady | 加载完成事件 |
| dataFailed | 加载失败事件 |
### 四、Methods
#### 组件内方法统一使用 call(funName, args) 调用
```js
this.$refs.cLottieRef.call('play')
//or
const cLottieRef = ref()
cLottieRef.value.call('play')
```
#### funName args入参为array类型 单个参数可传入string类型
* play(); - 播放
* stop(); - 停止播放
* pause(); - 暂停播放
* setSpeed(speed); -播放速度 speed: 1 为正常速度.
* goToAndStop(value, isFrame); -暂停到某一时间点或帧 value:数值 isFrame:定义第一个参数是基于时间的值还是基于帧的值默认为false)
* goToAndPlay(value, isFrame); -从某一时间点或帧开始播放 value:数值 isFrame:定义第一个参数是基于时间的值还是基于帧的值默认为false)
* setDirection(direction); - direction: 1 为正向, -1 为反向.
* playSegments(segments,forceFlag) - 播放选定的片段 segments:array.可以包含2个数值它们将用作动画的第一帧和最后一帧。或者可以包含一个数组序列每个数组带有2个数值。 forceFlag:boolean.如果设置为false它将等待当前段完成。如果为真则它将立即更新值。
* setSubframe(useSubFrames); - useSubFrames: 如果为false它将遵循原始的AE fps。如果为true它将更新每个请求动画帧的中间值。默认值为true。
* destroy(); - 销毁实例
* ...
### 方法与lottie-web 方法保持一致 [详情可参考](http://airbnb.io/lottie/#/web?id=usage)
### 微信小程序端会提示’发现 Lottie 动态创建 canvas 组件,但小程序不支持动态创建组件,接下来可能会出现异常‘ 组件内部已进行处理忽略即可
### 暂不支持nvue nvue请使用性能更好的原生插件
### 注意由于Hbuilderx上传插件无法上传node_odules依赖 导入插件后进入插件目录/uni_modules/c-lottie 使用npm i 进行依赖安装

View File

@ -0,0 +1,12 @@
## 1.0.52023-07-13
优化
## 1.0.42023-06-08
增加预览二维码
## 1.0.32023-05-31
增加license
## 1.0.22023-04-28
优化
## 1.0.12023-04-26
增加示例
## 1.0.02023-04-26
初始化发布

View File

@ -0,0 +1,148 @@
<template>
<view>
<movable-area class="movable-area" :scale-area="false">
<movable-view class="movable-view" :class="!isRemove?'animation-info':''" style="pointer-events: auto;" :style="{width:width,height:height}"
@click="clickBtn" @touchstart="touchstart" @touchend="touchend" @change="onChange" direction="all"
inertia="true" :x="x" :y="y" :disabled="disabled" :out-of-bounds="true" :damping="200" :friction="100">
<slot></slot>
</movable-view>
</movable-area>
</view>
</template>
<script>
export default {
props: {
//
disabled: {
type: Boolean,
default: false
},
//
canDocking: {
type: Boolean,
default: true
},
//px
bottomPx: {
type: Number,
default: 60
},
//px
rightPx: {
type: Number,
default: 0
},
width: {
type: String,
default: '100px'
},
height: {
type: String,
default: '100px'
},
},
data() {
return {
left: 0,
top: 0,
isRemove: true,
windowWidth: 0,
windowHeight: 0,
btnWidth: 0,
btnHeight: 0,
x: 10000,
y: 10000,
old: {
x: 0,
y: 0
}
};
},
mounted() {
this.getSysInfo()
},
methods: {
getSysInfo() {
let sysInfo = uni.getSystemInfoSync()
this.windowWidth = sysInfo.windowWidth
this.windowHeight = sysInfo.windowHeight
let view = uni.createSelectorQuery().in(this).select(".movable-view")
view.boundingClientRect(rect => {
this.btnWidth = rect.width
this.btnHeight = rect.height
this.x = this.old.x
this.y = this.old.y
this.$nextTick(res => {
this.x = this.windowWidth - this.btnWidth - this.rightPx
this.y = this.windowHeight - this.btnHeight - this.bottomPx
})
}).exec()
},
//
onChange(e) {
this.old.x = e.detail.x
this.old.y = e.detail.y
},
//
touchstart(e) {
this.isRemove = true
},
//
touchend(e) {
if (this.canDocking && this.old.x) {
this.x = this.old.x
this.y = this.old.y
let bWidth = (this.windowWidth - this.btnWidth) / 2
if (this.x < 0 || (this.x > 0 && this.x <= bWidth)) {
this.$nextTick(res => {
this.x = 0
})
} else {
this.$nextTick(res => {
this.x = this.windowWidth - this.btnWidth
})
}
this.isRemove = false
}
},
//
clickBtn() {
this.$emit('clickBtn')
}
}
};
</script>
<style scoped>
.movable-view {
/* background: linear-gradient(360deg, #287BF8 0%, #6EA8FF 100%); */
/* box-shadow: 0px 4rpx 12rpx 0px #ADC3F8; */
/* border-radius: 50rpx; */
color: #FFFFFF;
font-size: 26rpx;
/* touch-action: none; */
display: flex;
align-items: center;
justify-content: center;
pointer-events: none;
}
.animation-info {
transition: left .25s ease;
}
.movable-area {
width: 100%;
height: 100%;
position: fixed;
top: 0;
left: 0;
right: 0;
bottom: 0;
z-index: 999999 !important;
pointer-events: none;
}
</style>

View File

@ -0,0 +1,6 @@
### 1、本插件可免费下载使用
### 2、未经许可严禁复制本插件派生同类插件上传插件市场
### 3、未经许可严禁在插件市场恶意复制抄袭本插件进行违规获利;
### 4、对本软件的任何使用都必须遵守这些条款违反这些条款的个人或组织将面临法律追究。

View File

@ -0,0 +1,85 @@
{
"id": "liu-drag-button",
"displayName": "可拖动悬浮按钮",
"version": "1.0.5",
"description": "可拖动的悬浮按钮兼容小程序、H5支持自动停靠支持自定义样式使用相当简单源码简单易修改。",
"keywords": [
"悬浮按钮",
"拖拽按钮",
"拖动",
"按钮",
"拖拽"
],
"repository": "",
"engines": {
"HBuilderX": "^3.1.0"
},
"dcloudext": {
"type": "component-vue",
"sale": {
"regular": {
"price": "0.00"
},
"sourcecode": {
"price": "0.00"
}
},
"contact": {
"qq": ""
},
"declaration": {
"ads": "无",
"data": "无",
"permissions": "无"
},
"npmurl": ""
},
"uni_modules": {
"dependencies": [],
"encrypt": [],
"platforms": {
"cloud": {
"tcb": "y",
"aliyun": "y"
},
"client": {
"Vue": {
"vue2": "y",
"vue3": "u"
},
"App": {
"app-vue": "u",
"app-nvue": "u"
},
"H5-mobile": {
"Safari": "y",
"Android Browser": "y",
"微信浏览器(Android)": "y",
"QQ浏览器(Android)": "y"
},
"H5-pc": {
"Chrome": "u",
"IE": "u",
"Edge": "u",
"Firefox": "u",
"Safari": "u"
},
"小程序": {
"微信": "y",
"阿里": "u",
"百度": "u",
"字节跳动": "u",
"QQ": "u",
"钉钉": "u",
"快手": "u",
"飞书": "u",
"京东": "u"
},
"快应用": {
"华为": "u",
"联盟": "u"
}
}
}
}
}

View File

@ -0,0 +1,36 @@
# liu-drag-button适用于uni-app项目的可拖动悬浮按钮组件
### 本组件目前兼容微信小程序、H5
### 本组件是可拖动的悬浮按钮兼容小程序、H5支持自动停靠支持自定义样式源码简单易修改
# --- 扫码预览、关注我们 ---
## 扫码关注公众号,查看更多插件信息,预览插件效果!
![](https://uni.ckapi.pro/uniapp/publicize.png)
### 使用方式
``` html
<liu-drag-button @clickBtn="clickBtn">按钮</liu-drag-button>
```
``` javascript
export default {
data() {
return {
};
},
methods: {
//点击按钮
clickBtn(){
console.log('按钮被点击了')
},
}
}
```
### 属性说明
| 名称 | 类型 | 默认值 | 描述 |
| ----------------------------|--------------- | ------------------ | ---------------|
| disabled | Boolean | false | 是否禁用拖动
| canDocking | Boolean | true | 是否自动停靠
| bottomPx | Number | 30 | 按钮默认位置离底部距离px
| rightPx | Number | 0 | 按钮默认位置离右边距离px

View File

@ -148,6 +148,16 @@ export const numberUtil = {
*/
random(min, max) {
return Math.floor(Math.random() * (max - min + 1)) + min;
},
/**
* 保留小数位
* @param {number} num - 数字
* @param {number} decimals - 小数位数默认为2
* @returns {string} 保留小数位后的数字字符串
*/
toFiexd(num, decimals = 2) {
return Number(num).toFixed(decimals);
}
};
@ -519,6 +529,9 @@ export const randomUtil = {
}
};
// 默认导出所有工具方法
export default {
...dateUtil,

239
utils/globalMethods.js Normal file
View File

@ -0,0 +1,239 @@
import CryptoJS from "crypto-js";
import * as uuid from "uuid";
import {
postJson
} from "@/utils/requests.js"
import pageData from "@/static/json/page.json"
export default {
install(app, options) {
// 水印
app.config.globalProperties.$watermark = () => {
// if(app.config.globalProperties.$isChristmasPeriod()){
// return "/static/lottie/christmas.json"
// }else{
return "/static/lottie/watermark.json"
// }
}
app.config.globalProperties.$apiUserEvent = async (type, adminData, uniData) => {
let AppUser = uni.getStorageSync('AppUser')
if (type != 'uni') {
await postJson('a', 'api/user/event', {
type: adminData.type,
key: adminData.type + ".uni." + adminData.key,
value: adminData.value,
extra: JSON.stringify({
uni_version: app.config.globalProperties.$version,
...adminData.extra
}),
})
}
if (type != 'admin') {
// 公共
let ggData = {
app_id: AppUser.app_id,
user_name: AppUser.name, //宿主用户id
uni_version: app.config.globalProperties.$version, //uni版本号
app_version: plus.runtime.version, //宿主版本号
}
uni.report(uniData.type, {
...ggData,
...uniData.data
})
}
}
// 跳转页面方法
app.config.globalProperties.$goRechargePage = (type) => { //保留小数
// let pages = getCurrentPages();
// let currentPage = pages[pages.length - 1];
// let currentUrl = currentPage.route;
// currentUrl = pageData[currentUrl]
// // 点击水印
// app.config.globalProperties.$apiUserEvent('all', {
// type: "click",
// key: type,
// value: type != "watermark" ? "关闭水印" : "点击右下角水印图标",
// extra: {
// page: currentUrl
// }
// }, {
// type: 'click_' + type,
// data: {
// page: currentUrl
// }
// })
// // 进入页面
// app.config.globalProperties.$apiUserEvent('all', {
// type: "event",
// key: "payment_onload",
// value: "进入充值页面",
// extra: {
// from: currentUrl
// }
// }, {
// type: 'payment_onload',
// data: {
// from: currentUrl
// }
// })
uni.navigateTo({
url: '/pages/common/recharge/index'
});
}
app.config.globalProperties.$isVip = () => {
let user = uni.getStorageSync('userInfo')
if (user.vip >= 2) {
return false
} else {
return true
}
}
//解密
const deCode = (str) => {
const key = CryptoJS.enc.Utf8.parse(uni.getStorageSync('decrypt'));
const iv = key.clone();
iv.sigBytes = 16;
iv.clamp();
let res = CryptoJS.AES.decrypt(str, key, {
iv,
mode: CryptoJS.mode.CBC,
padding: CryptoJS.pad.Pkcs7,
}).toString(CryptoJS.enc.Utf8);
res = JSON.parse(res);
return res;
};
// 加密签名
const sign = (config) => {
let key = uni.getStorageSync('encrypt')
const method = config.method;
if (!config.data) {
config.data = {};
}
config.data.timestamp = Math.floor(new Date().getTime() / 1000);
config.data.nonce = uuid.v4();
if (
method === "GET" ||
method === "DELETE" ||
method === "get" ||
method === "delete"
) {
const keys = Object.keys(config.data);
keys.sort();
for (const i in keys) {
keys[i] = keys[i] + "=" + encodeURIComponent(config.data[keys[i]]);
}
const temp = keys.join("&") + "&" + CryptoJS.MD5(key).toString();
config.data.signature = CryptoJS.MD5(temp).toString();
} else if (
method === "POST" ||
method === "PUT" ||
method === "post" ||
method === "put"
) {
if (!config.data) {
config.data = {};
}
const keys = Object.keys(config.data);
keys.sort();
for (const i in keys) {
keys[i] = keys[i] + "=" + encodeURIComponent(config.data[keys[i]]);
}
let temp = keys.join("&");
temp += "&" + JSON.stringify(config.data);
temp += "&" + CryptoJS.MD5(key).toString();
config.data.signature = CryptoJS.MD5(temp).toString();
}
// console.log("config:", config)
return config
};
// 请求
app.config.globalProperties.$requestPromise = async (data, isCode = true) => {
//头部header
let header = uni.getStorageSync('header')
//请求地址
let host = uni.getStorageSync('host') + data.url
// 签名
if (isCode) {
data = sign(data)
} else {
host = "http://10.3.0.24:9209/" + data.url
header['x-token'] = "bdf87a98-eef0-47df-9faf-41d547b0457e"
}
// 排序
const sortedKeys = Object.keys(data.data).sort();
let str = ''
for (const key of sortedKeys) {
str += '&' + key + '=' + encodeURIComponent(data.data[key]);
}
str = str.replace('&', '?')
// 拼接URL
host = host + str
const response = await new Promise((resolve, reject) => {
uni.request({
url: host,
method: data.method,
data: data.data,
header,
success: res => {
try {
if (isCode) {
res.data = deCode(res.data.data)
} else {
res.data = res.data.data
}
} catch (err) {
}
resolve(res.data);
},
fail: e => {
reject(e);
}
});
});
return response;
};
app.config.globalProperties.$getUserInfo = async () => {
try {
let user = await app.config.globalProperties.$requestPromise({
url: 'api/user',
method: "GET",
data: {}
})
console.log("模拟请求:", JSON.stringify(user))
if (user.code == 0) {
uni.setStorageSync('AppUser', user.data)
// uni.showModal({
// title: '提示',
// content: JSON.stringify(user.data),
// success: function (res) {
// if (res.confirm) {
// console.log('用户点击确定');
// } else if (res.cancel) {
// console.log('用户点击取消');
// }
// }
// });
}
} catch (error) {
//TODO handle the exception
}
}
}
};