no message

This commit is contained in:
PC-202306242200\Administrator
2026-03-28 23:00:29 +08:00
commit 4d06351f6a
2830 changed files with 166480 additions and 0 deletions

20
.hbuilderx/launch.json Normal file
View File

@@ -0,0 +1,20 @@
{ // launch.json 配置了启动调试时相关设置configurations下节点名称可为 app-plus/h5/mp-weixin/mp-baidu/mp-alipay/mp-qq/mp-toutiao/mp-360/
// launchtype项可配置值为local或remote, local代表前端连本地云函数remote代表前端连云端云函数
"version": "0.0",
"configurations": [{
"app-plus" :
{
"launchtype" : "local"
},
"default" :
{
"launchtype" : "local"
},
"mp-weixin" :
{
"launchtype" : "local"
},
"type" : "uniCloud"
}
]
}

5
.idea/.gitignore generated vendored Normal file
View File

@@ -0,0 +1,5 @@
# 默认忽略的文件
/shelf/
/workspace.xml
# 基于编辑器的 HTTP 客户端请求
/httpRequests/

8
.idea/modules.xml generated Normal file
View File

@@ -0,0 +1,8 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="ProjectModuleManager">
<modules>
<module fileurl="file://$PROJECT_DIR$/.idea/云充电.iml" filepath="$PROJECT_DIR$/.idea/云充电.iml" />
</modules>
</component>
</project>

12
.idea/云充电.iml generated Normal file
View File

@@ -0,0 +1,12 @@
<?xml version="1.0" encoding="UTF-8"?>
<module type="WEB_MODULE" version="4">
<component name="NewModuleRootManager">
<content url="file://$MODULE_DIR$">
<excludeFolder url="file://$MODULE_DIR$/.tmp" />
<excludeFolder url="file://$MODULE_DIR$/temp" />
<excludeFolder url="file://$MODULE_DIR$/tmp" />
</content>
<orderEntry type="inheritedJdk" />
<orderEntry type="sourceFolder" forTests="false" />
</component>
</module>

26
App.vue Normal file
View File

@@ -0,0 +1,26 @@
<script>
import { login } from '@/common/js/user.js';
import { init } from '@/utils/sok.js';
export default {
onLaunch: function () {
// login()
if(uni.getStorageSync('token')){
init()
}
uni.hideTabBar()
console.log('App Launch');
},
onShow: function () {
console.log('App Show');
},
onHide: function () {
console.log('App Hide');
}
};
</script>
<style lang="scss">
/*每个页面公共css */
@import '@/uni_modules/uview-plus/index.scss';
@import '@/common/index.scss';
</style>

87
api/api.js Normal file
View File

@@ -0,0 +1,87 @@
import {
http
} from '@/request/index.js'
// 登录
export const loginApi = (params, config = {}) => http('/api/v0/login/loginByWx', params)
export const loginCodeApi = (params, config = {}) => http('/api/v0/login/loginByWxCode', params)
export const loginByZfbCode = (params, config = {}) => http('/api/v0/login/loginByZfbCode', params)
// 首页
// 获取附近站点
export const aroundAreaApi = (params, config = {}) => http('/api/v0/stations/aroundArea', params, 'GET')
export const infoAroundApi = (params, config = {}) => http('/api/v0/stations/info', params, 'GET')
export const listByStationId = (params, config = {}) => http('/api/v0/device/gun/listByStationId', params, 'GET')
// 开始充电
export const startCharging = (params, config = {}) => http('/api/v0/orders/startCharging', params)
//获取电枪详情
export const gunInfo = (params, config = {}) => http('/api/v0/device/gun/info', params, 'GET')
//用户信息
export const userInfo = (params, config = {}) => http('/api/v0/user/info', params, 'GET')
//订单
export const ordersList = (params, config = {}) => http('/api/v0/orders/list', params, 'GET')
// 开始充电-钱包
export const startChargingByWallet = (params, config = {}) => http('/api/v0/orders/startChargingByWallet', params)
// 开始充电-电卡
export const startChargingByCard = (params, config = {}) => http('/api/v0/orders/startChargingByCard', params)
// 开始充电-预付款-上海汇付
export const startChargingByAdaPay = (params, config = {}) => http('/api/v0/orders/startChargingByAdaPay', params)
// 结束停止充电
export const stopCharging = (params, config = {}) => http('/api/v0/orders/stopCharging', params)
// 轮播图
export const bannerList = (params, config = {}) => http('/api/v0/banner/list', params, 'GET')
// 修改用户昵称
export const updateNickName = (params, config = {}) => http('/api/v0/user/updateNickName', params)
// 修改用户头像
export const updateAvatar = (params, config = {}) => http('/api/v0/user/updateAvatar', params)
// 获取OSS
export const getOssUploadParams = (params, config = {}) => http('/api/v0/user/getOssUploadParams', params, 'GET')
// 实时充电详情
export const realtimeInfo = (params, config = {}) => http('/api/v0/orders/realtimeInfo', params, 'GET')
// 钱包记录
export const walletRecord = (params, config = {}) => http('/api/v0/wallet/record', params, 'GET')
export const userCardList = (params, config = {}) => http('/api/v0/card/userCardList', params, 'GET')
export const userCardRecord = (params, config = {}) => http('/api/v0/card/userCardRecord', params, 'GET')
// 充值
export const jqbPay = (params, config = {}) => http('/api/v0/wallet/charge/jqbPay', params)
// 汇付
export const adaPay = (params, config = {}) => http('/api/v0/wallet/charge/adaPay', params)
// 地图获取附近站点
export const aroundAreaMap = (params, config = {}) => http('/api/v0/stations/aroundAreaMap', params, 'GET')
// 协议详情获取
export const selectProtocolInfo = (params, config = {}) => http('/api/v0/protocol/info', params, 'GET')
//发票列表
export const invoiceList = (params, config = {}) => http('/api/v0/invoice/list', params, 'GET')
// 可开发票列表
export const orderList = (params, config = {}) => http('/api/v0/invoice/orderList', params, 'GET')
// 申请开具发票列表
export const preApply = (params, config = {}) => http('/api/v0/invoice/preApply', params)
// 申请开具发票请求
export const apply = (params, config = {}) => http('/api/v0/invoice/apply', params)
// 查询可用电卡
export const userCardUsableList = (params, config = {}) => http('/api/v0/card/userCardUsableList', params, 'GET')
// 退款
export const refund = (params, config = {}) => http('/api/v0/wallet/refund', params)
// 订单详情
export const ordersInfo = (params, config = {}) => http('/api/v0/orders/info', params,'GET')

21
common/index.scss Normal file
View File

@@ -0,0 +1,21 @@
view {
box-sizing: border-box;
}
page {
background: #f7f7f7;
}
.p30 {
padding: 0 30rpx;
}
.mt10 {
margin-bottom: 10rpx;
}
.flex-acsb {
display: flex;
align-items: center;
justify-content: space-between;
}
.flex1 {
flex: 1;
}

120
common/js/user.js Normal file
View File

@@ -0,0 +1,120 @@
import {
loginApi,
loginCodeApi,
loginByZfbCode
} from "@/api/api.js"
import {
init
} from '@/utils/sok.js';
export const login = async (params, type = 1) => {
if (type == 1) {
var {
code: loginCode
} = await uni.login({
provider: 'weixin'
});
try {
let {
token,
userInfo
} = await loginCodeApi({
loginCode
})
uni.setStorageSync('token', token);
uni.setStorageSync('user', userInfo);
} catch (err) {
if (err.code == 10) {
uni.setStorageSync('token', false);
}
}
} else if (type == 2) {
var {
code: phoneCode
} = params.detail;
var {
code: loginCode
} = await uni.login({
provider: 'alipay'
});
try {
// #ifdef MP-WEIXIN
let {
token,
user
} = await loginApi({
phoneCode,
loginCode
});
// #endif
// #ifdef MP-ALIPAY
let {
token,
user
} = await loginByZfbCode({
phoneCode,
loginCode
});
// #endif
uni.setStorageSync('token', token);
uni.setStorageSync('user', user);
// uni.reLaunch({
// url: '/pages/home/home'
// });
// uni.navigateBack()
uni.navigateBack()
init()
} catch (err) {
console.log(err);
}
}
}
const download = (e, type) => {
const base64 = uni.arrayBufferToBase64(e.data);
const fs = wx.getFileSystemManager()
var imgPath = ''
if (type == 'video') {
imgPath = wx.env.USER_DATA_PATH + '/base64Video' + '.mp4' //自定义下载图片的名称
} else {
imgPath = wx.env.USER_DATA_PATH + '/base64img' + '.png' //自定义下载图片的名称
}
fs.writeFile({
filePath: imgPath, //设置下载图片的地址
data: base64, //slice(22)的目的是去掉data:image/png;base64,如果本身就不带的话就直接this.data.codeImg就好了
encoding: 'base64',
success: function(res) {
//读取文件
wx.getImageInfo({
src: imgPath,
success: function(ret) {
console.log("请求到了");
var path = ret.path;
wx.saveImageToPhotosAlbum({
filePath: imgPath, //设置下载图片的地址
success(result) {
console.log("保存成功"); //保存成功
}
})
}
})
// console.log(res);
// console.log("请求到了");
// wx.saveImageToPhotosAlbum({
// filePath: imgPath, //设置下载图片的地址
// success: function() {
// console.log("保存成功"); //保存成功
// }
// })
}
})
}

BIN
components/.DS_Store vendored Normal file

Binary file not shown.

BIN
components/orange-user/.DS_Store vendored Normal file

Binary file not shown.

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1,81 @@
<template>
<view :class="Fixed ? 'Fixed' : ''">
<view :style="{ height: statusBarHeight }"></view>
<view style="height: 44px"></view>
<view class="search">
<!-- <view class="search_left" :class="Fixed ? 'opacityLeft' : ''">
<image class="search_left_img" src="/static/icon/xai.png" mode="widthFix"></image>
<view>郑州市</view>
</view> -->
<view class="search_right p30">
<up-input placeholder="查找地点、电站" confirmType="search" suffixIcon="/static/icon/search.png" border="none" v-model="value" @change="change" @confirm="confirm"></up-input>
</view>
</view>
</view>
</template>
<script setup>
import { ref } from 'vue';
let value = ref('');
const statusBarHeight = uni.getSystemInfoSync().statusBarHeight + 'px';
const emits = defineEmits(['change', 'search']);
const data = defineProps({
Fixed: {
type: Boolean,
default: false
}
});
let change = (e) => {
emits('change', e);
};
let confirm = (e) => {
emits('search', e);
};
</script>
<style lang="scss">
.Fixed {
position: fixed;
left: 0;
width: 100%;
padding: 0 30rpx;
z-index: 99;
}
.search {
@include flex($space: space-between);
&_left {
@include flex;
font-weight: bold;
font-size: 40rpx;
color: #232323;
height: 86rpx;
&_img {
width: 36rpx;
height: 36rpx;
margin-right: 15rpx;
}
}
.opacityLeft {
background: rgba(255, 255, 255, 0.27);
border-radius: 10rpx 10rpx 10rpx 10rpx;
padding: 0 10rpx;
}
&_right {
flex: 1;
@include flex;
// max-width: 500rpx;
height: 86rpx;
background: #ffffff;
box-shadow: inset 0rpx 0rpx 22rpx 2rpx #f9fbff;
border-radius: 20rpx 20rpx 20rpx 20rpx;
}
}
</style>

BIN
components/static/.DS_Store vendored Normal file

Binary file not shown.

File diff suppressed because it is too large Load Diff

File diff suppressed because one or more lines are too long

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.4 KiB

View File

@@ -0,0 +1,30 @@
<template>
<view style="position: relative">
<view :style="{ height: statusBarHeight }"></view>
<view style="height: 44px"></view>
<view class="statusBar_blur"></view>
</view>
</template>
<script setup>
const statusBarHeight = uni.getSystemInfoSync().statusBarHeight + 'px';
</script>
<style lang="scss">
.statusBar_blur {
width: 100%;
height: 185rpx;
position: absolute;
top: 0;
left: 0;
background: #dbe6ff;
opacity: 0.8;
filter: blur(50px);
/* #ifdef MP-ALIPAY */
z-index: 0;
/* #endif */
/* #ifdef MP-WEIXIN */
z-index: -1;
/* #endif */
}
</style>

View File

@@ -0,0 +1,101 @@
<template>
<view class="tabbar_pages p30">
<view class="tabbar_pages_view" v-for="(item, index) in list" :key="index" @click="toLink(item.pagePath)">
<view v-if="item.type == 1">
<view style="height: 70rpx">
<image mode="widthFix" style="width: 132rpx; height: 64rpx" :src="item.icon"></image>
</view>
<view :style="{ color: path == item.pagePath ? '#4879e6' : '' }">{{ item.text }}</view>
</view>
<view v-else>
<view style="height: 70rpx">
<image mode="widthFix" :src="path == item.pagePath ? item.icon : item.icon_select"></image>
</view>
<view :style="{ color: path == item.pagePath ? '#4879e6' : '' }">{{ item.text }}</view>
</view>
</view>
</view>
</template>
<script setup>
import { ref } from 'vue';
const data = defineProps({
path: {
type: String,
default: ''
}
});
let list = ref([
{
pagePath: '/pages/home/home',
text: '首页',
icon_select: '/static/tabbar/select_home.png',
icon: '/static/tabbar/home.png',
type: 0
},
{
pagePath: '/pages/index/index',
text: '地图',
icon_select: '/static/tabbar/select_sq.png',
icon: '/static/tabbar/sq.png',
type: 0
},
{
pagePath: '/pages/sweep/sweep',
text: '扫码充电',
icon_select: '/static/tabbar/find.png',
icon: '/static/tabbar/find.png',
type: 1
},
{
pagePath: '/pages/order/order',
text: '订单',
icon_select: '/static/tabbar/select_order.png',
icon: '/static/tabbar/order.png',
type: 0
},
{
pagePath: '/pages/mine/mine',
text: '我的',
icon_select: '/static/tabbar/select_my.png',
icon: '/static/tabbar/my.png',
type: 0
}
]);
const toLink = (e) => {
uni.vibrateShort();
if (data.path == e) return true;
uni.switchTab({
url: e
});
};
</script>
<style lang="scss">
.tabbar_pages {
position: fixed;
bottom: 0;
left: 0;
width: 750rpx;
height: 140rpx;
@include flex($space: space-between);
background-color: #fff;
box-shadow: 0rpx -6rpx 12rpx 2rpx rgba(88, 140, 255, 0.1);
border-radius: 15rpx 15rpx 0rpx 0rpx;
z-index: 99;
&_view {
view {
font-size: 24rpx;
color: #999999;
@include flex($direction: column, $space: space-between);
image {
width: 65rpx;
height: 65rpx;
}
}
}
}
</style>

7
config.js Normal file
View File

@@ -0,0 +1,7 @@
export default {
// baseUrl: 'http://192.168.1.63:1017',
// baseUrl: 'https://app.zhongshuai2023.com',
// sok: 'app.zhongshuai2023.com'
// sok: '192.168.1.63:1017',
baseUrl: 'https://appapi.prod.zhongshuai2023.com',
}

74
hooks/useNav.js Normal file
View File

@@ -0,0 +1,74 @@
import {
ref,
watch
} from 'vue';
export function useNav() {
const nav = (e) => {
if (e.call) {
uni.makePhoneCall({
phoneNumber: '4008005326' //仅为示例
});
return
}
if (!uni.getStorageSync('token')) {
uni.showModal({
title: '提示',
content: '为提供更好的服务,请前往登录',
success: (res) => {
if (res.confirm) {
uni.navigateTo({
url: '/pages/login/login'
})
} else if (res.cancel) {
console.log('用户点击取消');
}
}
})
return
}
uni[e.type == 'nav' || !e.type ? 'navigateTo' : e.type == 'switchTab' ? 'switchTab' : 'navigateTo']({
url: e.path
})
}
const navTo = (path, token, call) => {
if (!uni.getStorageSync('token')) {
uni.showModal({
title: '提示',
content: '为提供更好的服务,请前往登录',
success: (res) => {
if (res.confirm) {
uni.navigateTo({
url: '/pages/login/login'
})
} else if (res.cancel) {
console.log('用户点击取消');
}
}
})
return
}
uni.navigateTo({
url: path
})
}
return {
nav,
navTo
}
}
export default useNav

20
index.html Normal file
View File

@@ -0,0 +1,20 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<script>
var coverSupport = 'CSS' in window && typeof CSS.supports === 'function' && (CSS.supports('top: env(a)') ||
CSS.supports('top: constant(a)'))
document.write(
'<meta name="viewport" content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0' +
(coverSupport ? ', viewport-fit=cover' : '') + '" />')
</script>
<title></title>
<!--preload-links-->
<!--app-context-->
</head>
<body>
<div id="app"><!--app-html--></div>
<script type="module" src="/main.js"></script>
</body>
</html>

34
main.js Normal file
View File

@@ -0,0 +1,34 @@
import App from './App'
import store from './store/index.js'
import uviewPlus from '@/uni_modules/uview-plus'
// 引入uview-plus对小程序分享的mixin封装
import mpShare from '@/uni_modules/uview-plus/libs/mixin/mpShare'
// #ifndef VUE3
import Vue from 'vue'
import './uni.promisify.adaptor'
Vue.config.productionTip = false
App.mpType = 'app'
const app = new Vue({
...App
})
app.$mount()
// #endif
// #ifdef VUE3
import {
createSSRApp
} from 'vue'
export function createApp() {
const app = createSSRApp(App)
app.mixin(mpShare)
app.use(uviewPlus)
app.use(store)
return {
app,
}
}
// #endif

90
manifest.json Normal file
View File

@@ -0,0 +1,90 @@
{
"name" : "云充电",
"appid" : "__UNI__334883D",
"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
},
/* */
"modules" : {},
/* */
"distribute" : {
/* android */
"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\"/>",
"<uses-permission android:name=\"android.permission.READ_LOGS\"/>",
"<uses-permission android:name=\"android.permission.ACCESS_WIFI_STATE\"/>",
"<uses-feature android:name=\"android.hardware.camera.autofocus\"/>",
"<uses-permission android:name=\"android.permission.ACCESS_NETWORK_STATE\"/>",
"<uses-permission android:name=\"android.permission.CAMERA\"/>",
"<uses-permission android:name=\"android.permission.GET_ACCOUNTS\"/>",
"<uses-permission android:name=\"android.permission.READ_PHONE_STATE\"/>",
"<uses-permission android:name=\"android.permission.CHANGE_WIFI_STATE\"/>",
"<uses-permission android:name=\"android.permission.WAKE_LOCK\"/>",
"<uses-permission android:name=\"android.permission.FLASHLIGHT\"/>",
"<uses-feature android:name=\"android.hardware.camera\"/>",
"<uses-permission android:name=\"android.permission.WRITE_SETTINGS\"/>"
]
},
/* ios */
"ios" : {},
/* SDK */
"sdkConfigs" : {}
}
},
/* */
"quickapp" : {},
/* */
"mp-weixin" : {
"appid" : "wxbf62981cd056044f",
"setting" : {
"urlCheck" : false
},
"usingComponents" : true,
"permission" : {
"scope.userLocation" : {
"desc" : "你的位置信息将用于小程序位置接口的效果展示"
}
},
"requiredPrivateInfos" : [ "getLocation" ]
},
"mp-alipay" : {
"usingComponents" : true,
"appid" : "2021004150609395"
},
"mp-baidu" : {
"usingComponents" : true
},
"mp-toutiao" : {
"usingComponents" : true
},
"uniStatistics" : {
"enable" : false
},
"vueVersion" : "3",
"h5" : {
"sdkConfigs" : {
"maps" : {
"amap" : {
"key" : "fe4a4b418bf5fdb5f52209072fc6354e",
"securityJsCode" : "f3036e5e1fba79865f29c32195d3b192",
"serviceHost" : ""
}
}
}
}
}

17
package.json Normal file
View File

@@ -0,0 +1,17 @@
{
"id": "itsse-20230104",
"name": "顶部导航栏滚动渐变",
"displayName": "顶部导航栏滚动渐变",
"version": "1.0",
"description": "顶部导航栏滚动渐变适用于微信小程序其他小程序APP没有测试过",
"keywords": [
"滚动渐变",
"导航栏滚动渐变"
],
"dcloudext": {
"category": [
"前端组件",
"通用组件"
]
}
}

View File

@@ -0,0 +1,172 @@
<template>
<view class="invoice">
<view class="invoice_tip">
<view style="display: flex; align-items: center">
<up-icon name="error-circle-fill" color="#3c9cff"></up-icon>
发票须知
</view>
<view>1.开票金额为用户实际支付金额(不含返利返佣)</view>
<view>2.未寄出的纸质发票会在开票确认后的20个工作日内寄出</view>
<view>3.单笔订单只支持开具一种发票类型</view>
<view>4.云快充仅为平台方实际开票主体以申请开票时展示的开票运营商公司为准</view>
<view>5.发票由各家电站运营商提供一起申请可能会生成多张发票</view>
<view>6.若超过20个工作日仍未收到发票您可以通过(区号)+12366向开票公司所在区域的主管税务机关进行反馈处理</view>
</view>
<view style="height: 20rpx"></view>
<view>
<z-paging ref="paging" v-model="dataList" use-page-scroll @query="queryList">
<up-checkbox-group v-model="checkboxValue1" placement="column" @change="checkboxChange">
<view class="invoice_list" style="margin-bottom: 20rpx" v-for="(item, index) in dataList" :key="index">
<view style="display: flex; align-items: center; font-weight: bold; font-size: 30rpx; margin-bottom: 30rpx">
<up-checkbox shape="circle" :customStyle="{ margin: '0' }" :name="item.id"></up-checkbox>
充电单号{{ item.orderNo }}
</view>
<view style="display: flex; align-items: center; justify-content: space-between; background-color: #f6f6f6; border-radius: 15rpx; padding: 20rpx">
<view style="font-size: 28rpx">
<view style="margin-bottom: 15rpx">即途展厅</view>
<view style="margin-bottom: 15rpx">{{item.electricityAmount}}电费</view>
<view>{{ item.serviceAmount }}服务费</view>
</view>
<view style="text-align: right">
<view style="margin-bottom: 25rpx; font-size: 36rpx; font-weight: bold; color: #4879e6">
{{ item.actuallyAmount }}
<text style="font-size: 30rpx"></text>
</view>
<view style="font-size: 28rpx">个人支付</view>
</view>
</view>
</view>
</up-checkbox-group>
</z-paging>
</view>
<view
style="
position: fixed;
bottom: 0;
left: 0;
width: 750rpx;
padding: 20rpx 50rpx;
background-color: #fff;
display: flex;
align-items: center;
justify-content: space-between;
"
>
<view style="display: flex; align-items: center">
<up-checkbox label="本页全选" v-model:checked="allCel" shape="circle" usedAlone @change="allCheck" :customStyle="{ margin: '0 10rpx 0 0' }"></up-checkbox>
</view>
<view style="width: 230rpx">
<up-button
@click="navTo(`/pageMake/invoice/applyForDay?list=${encodeURIComponent(JSON.stringify(checkboxValue1))}`)"
:customStyle="{ height: '80rpx', width: '230rpx' }"
color="#4879e6"
text="下一步"
shape="circle"
:disabled="checkboxValue1.length == 0"
></up-button>
</view>
</view>
</view>
</template>
<script setup>
import { ref } from 'vue';
import { onLoad, onShow, onPullDownRefresh, onPageScroll, onReachBottom } from '@dcloudio/uni-app';
import { useNav } from '@/hooks/useNav.js';
const { nav, navTo } = useNav();
import { orderList } from '@/api/api.js';
let checkboxValue1 = ref([]);
const dataList = ref([]);
const paging = ref(null);
let allCel = ref(false);
const allCheck = (e) => {
if (e) {
checkboxValue1.value = dataList.value.map((item, index) => {
return item.id;
});
} else {
checkboxValue1.value = [];
}
allCel.value = e;
console.log(e);
};
const queryList = async (pageNo, pageSize) => {
const params = {
current: pageNo,
pageSize: pageSize
};
orderList(params)
.then((res) => {
paging.value.complete(res);
uni.hideLoading();
})
.catch((res) => {
paging.value.complete(false);
uni.hideLoading();
});
};
const checkboxChange = (e) => {
if (e.length == dataList.value.length) {
allCel.value = true;
} else {
allCel.value = false;
}
console.log(e);
};
let isPagingRefNotFound = () => {
return !paging.value;
};
onPullDownRefresh(() => {
if (isPagingRefNotFound()) return;
paging.value.reload().catch(() => {});
});
onPageScroll((e) => {
if (isPagingRefNotFound()) return;
paging.value.updatePageScrollTop(e.scrollTop);
e.scrollTop < 10 && paging.value.doChatRecordLoadMore();
});
onReachBottom(() => {
if (isPagingRefNotFound()) return;
paging.value.pageReachBottom();
});
</script>
<style scoped lang="scss">
.invoice {
&_tip {
padding: 20rpx;
font-size: 24rpx;
color: #3c9cff;
background-color: rgba(60, 156, 255, 0.2);
view {
line-height: 40rpx;
}
}
&_list {
padding: 15rpx 30rpx;
background-color: #fff;
&_view {
display: flex;
align-items: center;
justify-content: space-between;
font-size: 28rpx;
margin-bottom: 25rpx;
&_left {
color: #646368;
}
&_right {
color: #262626;
}
}
}
}
</style>

View File

@@ -0,0 +1,115 @@
<template>
<view class="invoice">
<view class="invoice_tip">
<view style="display: flex; align-items: center">
<up-icon name="error-circle-fill" color="#3c9cff"></up-icon>
发票须知
</view>
<view>1.开票金额为用户实际支付金额(不含返利返佣)</view>
<view>2.未寄出的纸质发票会在开票确认后的20个工作日内寄出</view>
<view>3.单笔订单只支持开具一种发票类型</view>
<view>4.云快充仅为平台方实际开票主体以申请开票时展示的开票运营商公司为准</view>
<view>5.发票由各家电站运营商提供一起申请可能会生成多张发票</view>
<view>6.若超过20个工作日仍未收到发票您可以通过(区号)+12366向开票公司所在区域的主管税务机关进行反馈处理</view>
</view>
<view style="height: 20rpx"></view>
<view>
<view class="invoice_list" style="margin-bottom: 20rpx" v-for="(item, index) in dataList" :key="index">
<view style="display: flex; align-items: center; font-weight: bold; font-size: 30rpx; margin-bottom: 30rpx">
<!-- <up-checkbox shape="circle" :customStyle="{ margin: '0' }" :name="item.transactionNo"></up-checkbox> -->
开票运营商{{ item.merchantName }}
</view>
<view style="display: flex; align-items: center; justify-content: space-between; background-color: #f6f6f6; border-radius: 15rpx; padding: 20rpx">
<view style="font-size: 28rpx">
<view style="margin-bottom: 15rpx">{{ item.electricityAmount }}电费</view>
<view>{{ item.serviceAmount }}服务费</view>
</view>
<view style="text-align: right">
<view style="margin-bottom: 25rpx; font-size: 36rpx; font-weight: bold; color: #4879e6">
{{ item.invoiceAmount }}
<text style="font-size: 30rpx"></text>
</view>
<view style="font-size: 28rpx">个人支付</view>
</view>
</view>
</view>
</view>
<view
style="
position: fixed;
bottom: 0;
left: 0;
width: 750rpx;
padding: 20rpx 50rpx;
background-color: #fff;
display: flex;
align-items: center;
justify-content: space-between;
"
>
<view></view>
<!-- <view style="display: flex; align-items: center">
<up-checkbox label="本页全选" v-model:checked="allCel" shape="circle" usedAlone @change="allCheck" :customStyle="{ margin: '0 10rpx 0 0' }"></up-checkbox>
</view> -->
<view style="width: 230rpx">
<up-button
@click="navTo(`/pageMake/invoice/makeInvoice?list=${encodeURIComponent(JSON.stringify(checkboxValue1))}`)"
:customStyle="{ height: '80rpx', width: '230rpx' }"
color="#4879e6"
text="下一步"
shape="circle"
></up-button>
</view>
</view>
</view>
</template>
<script setup>
import { ref } from 'vue';
import { onLoad } from '@dcloudio/uni-app';
import { useNav } from '@/hooks/useNav.js';
const { nav, navTo } = useNav();
import { preApply } from '@/api/api.js';
const dataList = ref([]);
let checkboxValue1 = ref([]);
onLoad(async (options) => {
checkboxValue1.value = JSON.parse(decodeURIComponent(options.list));
console.log(checkboxValue1.value);
let _res = await preApply({ ordersIds: JSON.parse(decodeURIComponent(options.list)) });
dataList.value = _res;
});
</script>
<style scoped lang="scss">
.invoice {
&_tip {
padding: 20rpx;
font-size: 24rpx;
color: #3c9cff;
background-color: rgba(60, 156, 255, 0.2);
view {
line-height: 40rpx;
}
}
&_list {
padding: 15rpx 30rpx;
background-color: #fff;
&_view {
display: flex;
align-items: center;
justify-content: space-between;
font-size: 28rpx;
margin-bottom: 25rpx;
&_left {
color: #646368;
}
&_right {
color: #262626;
}
}
}
}
</style>

View File

@@ -0,0 +1,127 @@
<template>
<view class="invoice">
<view class="invoice_tip">
<view style="display: flex; align-items: center">
<up-icon name="error-circle-fill" color="#3c9cff"></up-icon>
温馨提示
</view>
<view>1.云充电仅为平台方实际开票主体以下方展示的开票公司为准</view>
<view>2.若超过20个工作日仍未收到发票您可以通过(区号)+12366向开票公司所在区域的主管税务机关进行反馈处理</view>
</view>
<view style="height: 20rpx"></view>
<z-paging ref="paging" v-model="dataList" use-page-scroll @query="queryList">
<view class="invoice_list" v-for="(item, index) in dataList" :key="index">
<view class="invoice_list_view">
<view class="invoice_list_view_left" style="display: flex; align-items: center">
<up-icon name="clock-fill"></up-icon>
{{item.createTime}}
</view>
<up-icon name="arrow-right"></up-icon>
</view>
<view class="invoice_list_view">
<view class="invoice_list_view_left">发票抬头</view>
<view class="invoice_list_view_right">{{item.invoiceTitle}}</view>
</view>
<view class="invoice_list_view">
<view class="invoice_list_view_left">开票运营商</view>
<view class="invoice_list_view_right">{{item.merchantInvoice || '-'}}</view>
</view>
<view style="border: 1px dashed #eee"></view>
<view style="height: 20rpx"></view>
<view style="display: flex; align-items: center; justify-content: space-between">
<view>
<up-tag v-if="item.status == 0" text="待开票" type="warning" plain plainFill></up-tag>
<up-tag v-if="item.status == 1" text="已开票" type="success" plain plainFill></up-tag>
<up-tag v-if="item.status == -1" text="取消" type="error" plain plainFill></up-tag>
</view>
<view style="font-size: 36rpx; font-weight: bold">
{{item.invoiceAmount}}
<text style="font-size: 30rpx"></text>
</view>
</view>
</view>
</z-paging>
<view style="height: 150rpx;"></view>
<view style="position: fixed; bottom: 0; left: 0; width: 750rpx; padding: 20rpx 50rpx; background-color: #fff">
<up-button @click="navTo('/pageMake/invoice/applyFor')" :customStyle="{ height: '80rpx' }" color="#4879e6" text="申请开票" shape="circle"></up-button>
</view>
</view>
</template>
<script setup>
import { onLoad, onShow, onPullDownRefresh, onPageScroll, onReachBottom } from '@dcloudio/uni-app';
import { useNav } from '@/hooks/useNav.js';
import { ref } from 'vue';
const { nav, navTo } = useNav();
import { invoiceList } from '@/api/api.js';
const dataList = ref([]);
const paging = ref(null);
const queryList = async (pageNo, pageSize) => {
const params = {
current: pageNo,
pageSize: pageSize
};
invoiceList(params)
.then((res) => {
paging.value.complete(res);
uni.hideLoading();
})
.catch((res) => {
paging.value.complete(false);
uni.hideLoading();
});
};
let isPagingRefNotFound = () => {
return !paging.value;
};
onPullDownRefresh(() => {
if (isPagingRefNotFound()) return;
paging.value.reload().catch(() => {});
});
onPageScroll((e) => {
if (isPagingRefNotFound()) return;
paging.value.updatePageScrollTop(e.scrollTop);
e.scrollTop < 10 && paging.value.doChatRecordLoadMore();
});
onReachBottom(() => {
if (isPagingRefNotFound()) return;
paging.value.pageReachBottom();
});
</script>
<style scoped lang="scss">
.invoice {
&_tip {
padding: 20rpx;
font-size: 24rpx;
color: #3c9cff;
background-color: rgba(60, 156, 255, 0.2);
view {
line-height: 40rpx;
}
}
&_list {
padding: 15rpx 30rpx;
background-color: #fff;
&_view {
display: flex;
align-items: center;
justify-content: space-between;
font-size: 28rpx;
margin-bottom: 25rpx;
&_left {
color: #646368;
}
&_right {
color: #262626;
}
}
}
}
</style>

View File

@@ -0,0 +1,296 @@
<template>
<view class="invoice">
<view class="invoice_tip">
<view style="display: flex; align-items: center">
<up-icon name="error-circle-fill" color="#3c9cff"></up-icon>
发票须知
</view>
<view>1.开票金额为用户实际支付金额(不含返利返佣)</view>
<view>2.未寄出的纸质发票会在开票确认后的20个工作日内寄出</view>
<view>3.单笔订单只支持开具一种发票类型</view>
<view>4.云快充仅为平台方实际开票主体以申请开票时展示的开票运营商公司为准</view>
<view>5.发票由各家电站运营商提供一起申请可能会生成多张发票</view>
<view>6.若超过20个工作日仍未收到发票您可以通过(区号)+12366向开票公司所在区域的主管税务机关进行反馈处理</view>
</view>
<view style="height: 30rpx"></view>
<view style="padding: 30rpx; font-size: 28rpx; background-color: #fff">
<view class="flex-acsb" style="height: 80rpx">
<view>
发票主体
<text style="color: #f56c6c">*</text>
</view>
<view class="flex-acsb" @click="show2 = true">
<text :style="{ color: !dataFrom.subjectType ? '#808080' : '' }">
{{ !dataFrom.subjectType ? '请选择' : columns2[0].find((val) => val.id == dataFrom.subjectType).label }}
</text>
<up-icon name="arrow-down"></up-icon>
</view>
</view>
<view class="flex-acsb" style="height: 80rpx">
<view>
发票类型
<text style="color: #f56c6c">*</text>
</view>
<view class="flex-acsb" @click="show1True">
<text :style="{ color: !dataFrom.invoiceType ? '#808080' : '' }">
{{ !dataFrom.invoiceType ? '请选择' : columns1[0].find((val) => val.id == dataFrom.invoiceType).label }}
</text>
<up-icon name="arrow-down"></up-icon>
</view>
</view>
<view class="flex-acsb" style="height: 80rpx">
<view>
发票抬头
<text style="color: #f56c6c">*</text>
</view>
<view>
<input v-model="dataFrom.invoiceTitle" placeholder="请输入发票抬头" style="text-align: right" type="text" />
</view>
</view>
<view class="flex-acsb" style="height: 80rpx" v-if="dataFrom.subjectType == 1">
<view>
发票税号
<text style="color: #f56c6c">*</text>
</view>
<view>
<input v-model="dataFrom.taxNumber" placeholder="请输入发票税号" style="text-align: right" type="text" />
</view>
</view>
<view class="flex-acsb" style="height: 80rpx" v-if="dataFrom.invoiceType == 2">
<view>
公司地址
<text style="color: #f56c6c">*</text>
</view>
<view>
<input v-model="dataFrom.registrationAddress" placeholder="请输入公司地址" style="text-align: right" type="text" />
</view>
</view>
<view class="flex-acsb" style="height: 80rpx" v-if="dataFrom.invoiceType == 2">
<view>
公司电话
<text style="color: #f56c6c">*</text>
</view>
<view>
<input v-model="dataFrom.registrationPhone" placeholder="请输入公司电话" style="text-align: right" type="text" />
</view>
</view>
<view class="flex-acsb" style="height: 80rpx" v-if="dataFrom.invoiceType == 2">
<view>
开户行名称
<text style="color: #f56c6c">*</text>
</view>
<view>
<input v-model="dataFrom.bankName" placeholder="请输入开户行名称" style="text-align: right" type="text" />
</view>
</view>
<view class="flex-acsb" style="height: 80rpx" v-if="dataFrom.invoiceType == 2">
<view>
开户行账号
<text style="color: #f56c6c">*</text>
</view>
<view>
<input v-model="dataFrom.bankAccount" placeholder="请输入开户行账号" style="text-align: right" type="text" />
</view>
</view>
</view>
<view style="height: 30rpx"></view>
<view style="padding: 30rpx; font-size: 28rpx; background-color: #fff">
<view class="flex-acsb" style="height: 80rpx">
<view>
收票人姓名
<text style="color: #f56c6c">*</text>
</view>
<view>
<input v-model="dataFrom.name" placeholder="请输入收票人姓名" style="text-align: right" type="text" />
</view>
</view>
<view class="flex-acsb" style="height: 80rpx">
<view>
收票人手机
<text style="color: #f56c6c">*</text>
</view>
<view>
<input v-model="dataFrom.phone" type="number" placeholder="请输入收票人手机" style="text-align: right" />
</view>
</view>
<view class="flex-acsb" style="height: 80rpx">
<view>
收票人地址
<text style="color: #f56c6c">*</text>
</view>
<view>
<input v-model="dataFrom.address" placeholder="请输入收票人地址" style="text-align: right" type="text" />
</view>
</view>
<view class="flex-acsb" style="height: 80rpx">
<view>
收票人邮箱
<text style="color: #f56c6c">*</text>
</view>
<view>
<input v-model="dataFrom.email" placeholder="请输入收票人邮箱" style="text-align: right" type="text" />
</view>
</view>
</view>
<view style="height: 30rpx"></view>
<view class="p30">
<view style="font-weight: bold; font-size: 30rpx">发票备注改内容会打印在发票上</view>
<up-textarea v-model="dataFrom.invoiceRemark" placeholder="请输入内容"></up-textarea>
</view>
<view style="height: 150rpx"></view>
<view
style="
position: fixed;
bottom: 0;
left: 0;
width: 750rpx;
padding: 20rpx 50rpx;
background-color: #fff;
display: flex;
align-items: center;
justify-content: space-between;
"
>
<view style="display: flex; align-items: center; font-size: 28rpx">
<text>合计</text>
<text style="font-size: 36rpx; font-weight: bold; margin: 0 15rpx">14.05</text>
<text></text>
</view>
<view style="width: 230rpx">
<up-button @click="applyCon" :customStyle="{ height: '80rpx', width: '230rpx' }" color="#4879e6" text="确认开票" shape="circle"></up-button>
</view>
</view>
<up-picker @confirm="aaa1" keyName="label" :show="show1" @cancel="show1 = false" :columns="columns1"></up-picker>
<up-picker @confirm="aaa2" keyName="label" :show="show2" @cancel="show2 = false" :columns="columns2"></up-picker>
</view>
</template>
<script setup>
import { ref, reactive } from 'vue';
import { apply } from '@/api/api.js';
import { onLoad } from '@dcloudio/uni-app';
let checkboxValue1 = ref([]);
let dataFrom = ref({
invoiceType: null,
subjectType: null,
ordersIds: []
});
let show1 = ref(false);
let show2 = ref(false);
onLoad(async (options) => {
console.log(options);
console.log(JSON.parse(decodeURIComponent(options.list)));
dataFrom.value.ordersIds = JSON.parse(decodeURIComponent(options.list));
});
const applyCon = async () => {
if (!dataFrom.value.subjectType) return uni.showToast({ title: '请选择发票主体', icon: 'none' });
if (!dataFrom.value.invoiceType) return uni.showToast({ title: '请选择发票类型', icon: 'none' });
if (!dataFrom.value.invoiceType == 1 && !dataFrom.value.taxNumber) return uni.showToast({ title: '请输入发票税号', icon: 'none' });
if (!dataFrom.value.subjectType == 1 && !dataFrom.value.registrationPhone) return uni.showToast({ title: '请输入发票税号', icon: 'none' });
if (!dataFrom.value.subjectType == 1 && !dataFrom.value.invoiceType == 2 && !dataFrom.value.taxNumber) return uni.showToast({ title: '请输入发票税号', icon: 'none' });
if (!dataFrom.value.subjectType == 1 && !dataFrom.value.invoiceType == 2 && !dataFrom.value.registrationAddress)
return uni.showToast({ title: '请输入公司地址', icon: 'none' });
if (!dataFrom.value.subjectType == 1 && !dataFrom.value.invoiceType == 2 && !dataFrom.value.registrationPhone) return uni.showToast({ title: '请输入公司电话', icon: 'none' });
if (!dataFrom.value.subjectType == 1 && !dataFrom.value.invoiceType == 2 && !dataFrom.value.bankName) return uni.showToast({ title: '请输入开户行名称', icon: 'none' });
if (!dataFrom.value.subjectType == 1 && !dataFrom.value.invoiceType == 2 && !dataFrom.value.bankAccount) return uni.showToast({ title: '请输入开户行账户', icon: 'none' });
if (!dataFrom.value.name) return uni.showToast({ title: '请输入收票人姓名', icon: 'none' });
if (!dataFrom.value.address) return uni.showToast({ title: '请输入收票人地址', icon: 'none' });
if (!dataFrom.value.phone) return uni.showToast({ title: '请输入收票人电话', icon: 'none' });
if (!dataFrom.value.email) return uni.showToast({ title: '请输入收票人邮箱', icon: 'none' });
let _res = await apply(dataFrom.value);
uni.navigateBack({
delta: 3
});
};
const aaa1 = (ee) => {
dataFrom.value.invoiceType = ee.value[0].id;
show1.value = false;
console.log(dataFrom.value.invoiceType);
};
const aaa2 = (ee) => {
dataFrom.value.subjectType = ee.value[0].id;
show2.value = false;
if (ee.value[0].id == 2) {
dataFrom.value.invoiceType = 1;
}
};
const show1True = () => {
if (dataFrom.value.subjectType == 2) {
return;
}
show1.value = true;
};
const columns1 = reactive([
[
{
label: '增值税普通发票',
id: 1
},
{
label: '增值税专用发票',
id: 2
}
]
]);
const columns2 = reactive([
[
{
label: '企业',
id: 1
},
{
label: '个人',
id: 2
}
]
]);
const checkboxChange = (e) => {
console.log(e);
};
</script>
<style>
page {
background-color: #f5f5f5;
}
</style>
<style scoped lang="scss">
.invoice {
&_tip {
padding: 20rpx;
font-size: 24rpx;
color: #3c9cff;
background-color: rgba(60, 156, 255, 0.2);
view {
line-height: 40rpx;
}
}
&_list {
padding: 15rpx 30rpx;
background-color: #fff;
&_view {
display: flex;
align-items: center;
justify-content: space-between;
font-size: 28rpx;
margin-bottom: 25rpx;
&_left {
color: #646368;
}
&_right {
color: #262626;
}
}
}
}
</style>

View File

@@ -0,0 +1,83 @@
<template>
<view class="p30">
<view style="font-size: 36rpx; font-weight: bold; margin-top: 40rpx">
退款信息
<text style="font-size: 26rpx; color: chocolate; font-weight: 500">活动金额不在退款范围内</text>
</view>
<view style="display: flex; align-items: center; height: 100rpx; justify-content: space-between">
<view></view>
<input v-model="dataFrom.amount" :placeholder="`可申请退款${balance}元`" style="width: 500rpx; font-size: 32rpx" type="number" />
<view @click="dataFrom.amount = balance" style="font-size: 28rpx; color: #4879e6">全部</view>
</view>
<view style="font-size: 28rpx; margin-bottom: 20rpx">申请退款理由</view>
<view style="margin-bottom: 30rpx">
<up-textarea v-model="dataFrom.refundReason" placeholder="请输入退款理由"></up-textarea>
</view>
<view style="font-weight: bold; font-size: 30rpx; margin-bottom: 20rpx">退款须知</view>
<view style="font-size: 26rpx; color: #60646b; line-height: 50rpx">1.退款金额不包含充值时使用的第三方优惠抵扣金额退款时充值享受到的优惠金额也将全部扣除</view>
<view style="font-size: 26rpx; color: #60646b; line-height: 50rpx">2.您的退款金额到账时间由各充值渠道微信/支付宝决定请耐心等待约1~3工作日到账</view>
<view style="font-size: 26rpx; color: #60646b; line-height: 50rpx">3.退款按照充值记录进行逐笔退款一次申请可能产生多笔退款到账记录请注意查收</view>
<view style="font-size: 26rpx; color: #60646b; line-height: 50rpx">4.正在充电或存在异常订单时无法进行退款操作</view>
<view style="font-size: 26rpx; color: #60646b; line-height: 50rpx">5.根据各充值渠道规则只可退一年内的充值金额</view>
<view style="position: fixed; bottom: 0; left: 0; width: 750rpx; padding: 20rpx 30rpx; border-top: 1rpx solid #eee" class="flex-acsb">
<view style="width: 230rpx">
<!-- openType="contact" -->
<up-button @click="toKft" :customStyle="{ height: '80rpx' }" text="联系客服" shape="circle"></up-button>
</view>
<view style="width: 400rpx">
<up-button @click="refundTo" :customStyle="{ height: '80rpx' }" color="#4879e6" text="提交" shape="circle"></up-button>
</view>
</view>
</view>
</template>
<script>
import { refund } from '@/api/api.js';
export default {
data() {
return {
balance: 0,
dataFrom: {
amount: '',
refundReason: ''
}
};
},
onLoad(options) {
if (options.balance) {
this.balance = options.balance;
}
},
methods: {
toKft() {
uni.makePhoneCall({
phoneNumber: '4008005326' //仅为示例
});
},
refundTo() {
if (!this.dataFrom.amount) {
return uni.showToast({
title: '请输入退款金额',
icon: 'none'
});
}
refund(this.dataFrom).then((res) => {
uni.showModal({
title: '提示',
content: '提交成功',
showCancel: false,
success: function (res) {
uni.navigateBack();
}
});
});
}
}
};
</script>
<style>
page {
background-color: #fff;
}
</style>

View File

@@ -0,0 +1,285 @@
<template>
<view class="recharge">
<view class="recharge_orderId">
<view>
订单号{{ store.state.dataObj.orderNo }}
<image src="/static/icon/ic-copy1.png" @click="copy(store.state.dataObj.orderNo)" mode="widthFix"></image>
</view>
</view>
<view class="recharge_trn">
<view class="recharge_trn_yuan">
<image class="recharge_trn_yuan_img" src="https://zhongshuai-prod.oss-cn-beijing.aliyuncs.com/appImage/order/bg_charging_turn.png" mode="widthFix"></image>
</view>
<image class="recharge_trn_hei" src="https://zhongshuai-prod.oss-cn-beijing.aliyuncs.com/appImage/order/order-charging-black-circle.png" mode="widthFix"></image>
<view class="recharge_trn_text">
<view>{{ store.state.dataObj.currentAmount || 0 }}</view>
<view>已用时长</view>
<view>{{ store.state.dataObj.cumulativeTime || 0 }}min</view>
</view>
<view class="recharge_trn_car">
<image class="recharge_trn_car_img" src="https://zhongshuai-prod.oss-cn-beijing.aliyuncs.com/appImage/order/order-real-time-car-bg.png" mode="widthFix"></image>
<image class="recharge_trn_car_img1" src="https://zhongshuai-prod.oss-cn-beijing.aliyuncs.com/appImage/order/order-real-time-car-bg1.png" mode="widthFix"></image>
</view>
</view>
<view class="recharge_list p30">
<view class="recharge_list_view">
<image src="https://zhongshuai-prod.oss-cn-beijing.aliyuncs.com/appImage/order/order-real-time-charged-power.png" mode="widthFix"></image>
<view class="recharge_list_view_num">{{ store.state.dataObj.chargingDegree || 0 }}</view>
<view class="recharge_list_view_name">已充电量()</view>
</view>
<view class="recharge_list_view">
<image src="https://zhongshuai-prod.oss-cn-beijing.aliyuncs.com/appImage/order/order-real-time-charged-time.png" mode="widthFix"></image>
<view class="recharge_list_view_num">{{ store.state.dataObj.cumulativeTime || 0 }}min</view>
<view class="recharge_list_view_name">已充时长</view>
</view>
<view class="recharge_list_view">
<image src="https://zhongshuai-prod.oss-cn-beijing.aliyuncs.com/appImage/order/order-real-time-charged-amount.png" mode="widthFix"></image>
<view class="recharge_list_view_num">{{ store.state.dataObj.currentAmount || 0 }}</view>
<view class="recharge_list_view_name">已充金额()</view>
</view>
</view>
<view class="recharge_block p30">
<view class="recharge_block_view">
<view>{{ store.state.dataObj.outputVoltage || 0 }}</view>
<view>实时电压(V)</view>
</view>
<view class="recharge_block_view">
<view>{{ store.state.dataObj.outputCurrent || 0 }}</view>
<view>实时电流(A)</view>
</view>
<view class="recharge_block_view">
<view>{{ store.state.dataObj.power || 0 }}</view>
<view>实时功率(KW)</view>
</view>
</view>
<view class="recharge_note p30">
<view>终端名称{{ store.state.dataObj.gunNo }}</view>
<view>终端编码{{ store.state.dataObj.deviceNo || '' }}</view>
</view>
<view class="recharge_btn1" @click="end(1)">结束充电</view>
</view>
</template>
<script setup>
import { ref, reactive } from 'vue';
import { onLoad, onShow } from '@dcloudio/uni-app';
import { stopCharging, realtimeInfo, ordersInfo } from '@/api/api.js';
import { copy } from '@/utils/fun.js';
import store from '@/store/index.js';
let transactionNo = ref('');
let type = ref('');
onLoad(async (options) => {
transactionNo.value = options.transactionNo;
if (options.type) {
let _res = await realtimeInfo({
transactionNo: options.transactionNo
});
store.commit('setDataObj', _res);
}
});
const end = (e) => {
uni.showModal({
title: '提示',
content: e == 1 ? '是否确认结束充电?' : '结束充电失败,请重试!',
success: function (res) {
if (res.confirm) {
stopCharging({ transactionNo: transactionNo.value }).then((res) => {
uni.showLoading({
title: '停止充电中...'
});
store.commit('setSokStatus', 0);
timeMap(transactionNo.value);
});
} else if (res.cancel) {
console.log('用户点击取消');
}
}
});
};
const timeMap = (_res) => {
var time = setTimeout(async () => {
if (store.state.sokStatus != 1) {
let _data = await ordersInfo({
transactionNo: _res
});
store.commit('setDataObj', _data);
if (_data.status == 3 || _data.status == 4) {
uni.hideLoading();
end(2);
}
if (_data.status == 5 || _data.status == 6) {
uni.hideLoading();
uni.navigateBack();
store.commit('setSokStatus', 0);
}
}
}, 30000);
};
</script>
<style>
page {
background-color: #000;
}
</style>
<style scoped lang="scss">
.recharge {
&_orderId {
width: 1000rpx;
margin-left: -125rpx;
margin-top: -20rpx;
height: 230rpx;
background: url(https://zhongshuai-prod.oss-cn-beijing.aliyuncs.com/appImage/order/order-realtime-pile-number-bg.png) no-repeat 100% 100% / contain;
color: #828282;
text-align: center;
padding-top: 30rpx;
font-size: 26rpx;
view {
@include flex($space: center);
image {
width: 30rpx;
height: 30rpx;
margin-left: 15rpx;
}
}
}
&_trn {
margin-top: -130rpx;
@include flex($direction: column, $space: center);
&_yuan {
width: 500rpx;
height: 500rpx;
position: relative;
&_img {
width: 100%;
height: 100%;
animation: rotate 5s linear infinite;
}
}
&_text {
z-index: 9;
@include flex($direction: column, $space: center);
margin-top: -470rpx;
view:nth-child(1) {
color: #fff;
font-weight: bold;
font-size: 60rpx;
}
view:nth-child(2) {
color: #11927c;
font-size: 28rpx;
margin: 25rpx 0 15rpx;
}
view:nth-child(3) {
color: #24efe8;
font-weight: bold;
font-size: 36rpx;
margin-bottom: 30rpx;
}
}
&_hei {
margin-top: -360rpx;
width: 500rpx;
height: 500rpx;
z-index: 9;
}
&_car {
z-index: 10;
width: 450rpx;
position: relative;
&_img {
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
}
&_img1 {
width: 100%;
height: 100%;
}
}
}
&_list {
@include flex($space: space-between);
padding: 0 50rpx;
&_view {
display: flex;
align-items: center;
flex-direction: column;
justify-content: center;
@include flex($direction: column, $space: center);
image {
width: 75rpx;
height: 75rpx;
}
&_num {
color: #fff;
font-weight: bold;
font-size: 36rpx;
margin: 10rpx 0;
}
&_name {
color: #8b8b8b;
font-weight: bold;
font-size: 28rpx;
}
}
}
&_block {
margin-top: 50rpx;
@include flex($space: space-between);
&_view {
width: 200rpx;
padding: 10rpx;
border-radius: 25rpx;
background: linear-gradient(0deg, #0b1521, #193c65);
font-size: 28rpx;
@include flex($direction: column, $space: center);
view:nth-child(1) {
color: #fff;
}
view:nth-child(2) {
color: #8b98a0;
}
}
}
&_note {
margin-top: 30rpx;
@include flex($space: space-between);
color: #828282;
font-size: 24rpx;
}
&_btn1 {
width: 650rpx;
height: 100rpx;
margin: 0 auto;
font-size: 32rpx;
font-weight: bold;
@include flex($space: center);
background-color: #1879fe;
border-radius: 50rpx;
color: #fff;
margin-top: 150rpx;
}
}
@keyframes rotate {
0% {
transform: rotate(0deg);
}
100% {
transform: rotate(360deg);
}
}
</style>

225
pages.json Normal file
View File

@@ -0,0 +1,225 @@
{
"easycom": {
"autoscan": true,
// 注意一定要放在custom里否则无效https://ask.dcloud.net.cn/question/131175
"custom": {
"^u--(.*)": "@/uni_modules/uview-plus/components/u-$1/u-$1.vue",
"^up-(.*)": "@/uni_modules/uview-plus/components/u-$1/u-$1.vue",
"^u-([^-].*)": "@/uni_modules/uview-plus/components/u-$1/u-$1.vue"
}
},
"pages": [ //pages数组中第一项表示应用启动页参考https://uniapp.dcloud.io/collocation/pages
{
"path": "pages/home/home",
"style": {
"navigationBarTitleText": "",
"enablePullDownRefresh": false,
"navigationStyle": "custom",
"mp-alipay": {
"transparentTitle": "always",
"titlePenetrate": "YES"
}
}
},
{
"path": "pages/index/index",
"style": {
"navigationBarTitleText": "",
"navigationStyle": "custom",
"mp-alipay": {
"transparentTitle": "always",
"titlePenetrate": "YES"
}
}
},
{
"path": "pages/mine/mine",
"style": {
"navigationBarTitleText": "",
"enablePullDownRefresh": false,
"navigationStyle": "custom",
"mp-alipay": {
"transparentTitle": "always",
"titlePenetrate": "YES"
}
}
},
{
"path": "pages/order/order",
"style": {
"navigationBarTitleText": "",
"enablePullDownRefresh": false,
"navigationStyle": "custom",
"mp-alipay": {
"transparentTitle": "always",
"titlePenetrate": "YES"
}
}
},
{
"path": "pages/sweep/sweep",
"style": {
"navigationBarTitleText": "扫码充电",
"navigationStyle": "custom",
"mp-alipay": {
"transparentTitle": "always",
"titlePenetrate": "YES"
}
}
},
{
"path": "pages/order/detail",
"style": {
"navigationBarTitleText": ""
}
},
{
"path": "pages/home/detail",
"style": {
"navigationBarTitleText": "电站详情",
"navigationStyle": "custom",
"mp-alipay": {
"transparentTitle": "always",
"titlePenetrate": "YES"
}
}
},
{
"path": "pages/login/login",
"style": {
"navigationBarTitleText": "",
"navigationStyle": "custom",
"mp-alipay": {
"transparentTitle": "always",
"titlePenetrate": "YES"
}
}
},
{
"path": "pages/home/star",
"style": {
"navigationBarTitleText": "开始充电"
}
},
{
"path": "pages/mine/earnings",
"style": {
"navigationBarTitleText": "收益"
}
},
{
"path": "pages/mine/sett",
"style": {
"navigationBarTitleText": ""
}
},
{
"path": "pages/mine/incomeList",
"style": {
"navigationBarTitleText": "余额明细"
}
},
{
"path": "pages/mine/card",
"style": {
"navigationBarTitleText": "我的电卡"
}
},
{
"path": "pages/mine/cardList",
"style": {
"navigationBarTitleText": "电卡记录"
}
},
{
"path": "pages/money/recharge",
"style": {
"navigationBarTitleText": "充值"
}
},
{
"path": "pages/agreement/agreement",
"style": {
"navigationBarTitleText": ""
}
}
],
"subPackages": [{
"root": "pageOrder",
"pages": [{
"path": "recharge/recharge",
"style": {
"navigationBarTitleText": "充电中",
"navigationBarBackgroundColor": "#000",
"navigationBarTextStyle": "white",
"mp-alipay": {
"transparentTitle": "always",
"titlePenetrate": "YES"
}
}
}]
}, {
"root": "pageMake",
"pages": [{
"path": "invoice/invoice",
"style": {
"navigationBarTitleText": "开票记录"
}
},
{
"path": "invoice/applyFor",
"style": {
"navigationBarTitleText": "申请开票"
}
},
{
"path": "invoice/makeInvoice",
"style": {
"navigationBarTitleText": "申请开票"
}
},
{
"path": "invoice/applyForDay",
"style": {
"navigationBarTitleText": "申请开票"
}
},
{
"path": "refund/refund",
"style": {
"navigationBarTitleText": "退款申请"
}
}
]
}],
"globalStyle": {
"navigationBarTextStyle": "black",
"navigationBarTitleText": "",
"navigationBarBackgroundColor": "#F8F8F8",
"backgroundColor": "#F8F8F8"
},
"uniIdRouter": {},
"tabBar": {
"color": "#999999",
"selectedColor": "#999999",
"borderStyle": "black",
"backgroundColor": "#ffffff",
"list": [{
"pagePath": "pages/home/home",
"text": "首页"
}, {
"pagePath": "pages/index/index",
"text": "地图"
}, {
"pagePath": "pages/sweep/sweep",
"text": "扫码充电"
}, {
"pagePath": "pages/order/order",
"text": "订单"
}, {
"pagePath": "pages/mine/mine",
"text": "我的"
}]
}
}

View File

@@ -0,0 +1,21 @@
<template>
<view class="p30">
<mp-html :content="info.protocolContent" />
<view style="height: 100rpx;"></view>
</view>
</template>
<script setup>
import { ref } from 'vue';
import { onLoad } from '@dcloudio/uni-app';
import { selectProtocolInfo } from '@/api/api.js';
let info = ref({});
onLoad(async (options) => {
let _res = await selectProtocolInfo({ id: options.id });
info.value = _res;
});
</script>
<style></style>

445
pages/home/detail.vue Normal file
View File

@@ -0,0 +1,445 @@
<template>
<view class="orderdetail">
<!-- <statusBar /> -->
<view class="orderdetail_header p30" :style="{ backgroundColor: headerBg ? '#FFF' : '' }">
<view :style="{ height: statusBarHeight }"></view>
<view style="height: 44px; display: flex; align-items: center" @click="">
<up-icon name="arrow-left" bold color="#000" @click="back"></up-icon>
<view @click="back" style="margin-left: 25rpx; transition: all 0.5s" :style="{ opacity: headerBg ? 1 : 0 }">电站详情</view>
</view>
</view>
<up-swiper :list="info.pictures" height="530rpx"></up-swiper>
<view class="p30" style="margin-top: -80rpx">
<orderList
:info="{
...info,
priceAmount: fullCost.totalAmount
}"
type="info"
></orderList>
<view style="height: 30rpx"></view>
<view class="orderdetail_info" style="margin-bottom: 30rpx">
<view class="orderdetail_info_title">
<view>费用信息</view>
<view style="display: flex; align-items: center" @click="showJf = true">
价格详情
<view style="margin-left: 30rpx">
<up-icon color="#333" size="28rpx" name="arrow-right"></up-icon>
</view>
</view>
</view>
<view style="max-width: 420rpx">
<up-tag size="mini" :text="`当前计费时间段:${fullCost.startTime}-${fullCost.endTime}`" plain plainFill></up-tag>
</view>
<view class="orderdetail_info_fy">
<view class="orderdetail_info_fy_left">电站价格</view>
<view class="orderdetail_info_fy_right">
{{ fullCost.totalAmount }}
<text style="font-weight: 500; font-size: 24rpx; color: #333; margin-left: 15rpx">/</text>
</view>
</view>
</view>
<view class="orderdetail_info" style="margin-bottom: 30rpx">
<view>
<view class="orderdetail_info_title">终端明细</view>
</view>
<view class="orderdetail_info_zd" style="position: relative" @click="showZd">
<view class="orderdetail_info_zd_zdbg"></view>
<image
src="/static/icon/eleclist-terminal.png"
style="transform: rotateY(180deg); position: absolute; left: 0; bottom: 0; width: 100rpx; height: 100rpx"
mode="widthFix"
></image>
<view>交流</view>
<view style="display: flex; align-items: center">
{{ info.gunCount - info.gunUseCount }}
<text style="font-size: 28rpx; opacity: 0.9; margin-left: 10rpx">空闲</text>
<text style="font-size: 24rpx; opacity: 0.8">/{{ info.gunCount }}</text>
<view style="margin-left: 30rpx">
<up-icon color="#fff" size="28rpx" name="arrow-right"></up-icon>
</view>
</view>
</view>
</view>
<view class="orderdetail_info">
<view class="orderdetail_info_title">基本信息</view>
<view class="orderdetail_info_view">
<view class="orderdetail_info_view_left">服务提供方</view>
<view class="orderdetail_info_view_right" @click="lookImg([info.licenseImage])">
{{ info.merchantName }}
<image src="/static/icon/9you.png" mode="widthFix"></image>
</view>
</view>
<!-- <view class="orderdetail_info_view">
<view class="orderdetail_info_view_left" style="color: #232323">{{ info.merchantName }}</view>
</view> -->
<view class="orderdetail_info_view">
<view class="orderdetail_info_view_left">营业时间</view>
<view class="orderdetail_info_view_right" @click="lookImg([info.licenseImage])">
{{ info.busineHours }}
</view>
</view>
<!-- <view class="orderdetail_info_view">
<view class="orderdetail_info_view_left" style="margin-right: 30rpx">
{{ info.busineHours }}
</view>
</view> -->
<view class="orderdetail_info_xian"></view>
<view class="orderdetail_info_view">
<view class="orderdetail_info_view_left">发票服务</view>
<view class="orderdetail_info_view_right">{{ info.invoice }}</view>
</view>
<view class="orderdetail_info_view">
<view class="orderdetail_info_view_left">备注信息</view>
<view class="orderdetail_info_view_right">{{ info.remarks || '' }}</view>
</view>
<view class="orderdetail_info_view">
<view class="orderdetail_info_view_left">服务提供方</view>
<view class="orderdetail_info_view_right" @click="call(info.stationTel)" style="color: #4879e6; font-weight: bold">{{ info.stationTel }}</view>
</view>
</view>
</view>
<view class="orderdetail_btn p30">
<view class="orderdetail_btn_left">
{{ fullCost.totalAmount }}
<text>/</text>
</view>
<view class="orderdetail_btn_right" @click="toRecharge">扫码充电</view>
</view>
<view style="height: 150rpx"></view>
<up-popup :show="show" @close="show = false" closeable round="10">
<view class="orderdetail_info" style="padding-top: 50rpx">
<view class="orderdetail_info_zd" style="position: relative" @click="show = true">
<view class="orderdetail_info_zd_zdbg"></view>
<image
src="/static/icon/eleclist-terminal.png"
style="transform: rotateY(180deg); position: absolute; left: 0; bottom: 0; width: 100rpx; height: 100rpx"
mode="widthFix"
></image>
<view>交流</view>
<view style="display: flex; align-items: center">
{{ info.gunCount - info.gunUseCount }}
<text style="font-size: 28rpx; opacity: 0.9; margin-left: 10rpx">空闲</text>
<text style="font-size: 24rpx; opacity: 0.8">/{{ info.gunCount }}</text>
</view>
</view>
</view>
<view class="gun">
<z-paging ref="paging" :fixed="false" :loading-more-enabled="false" v-model="dataList" @query="queryList" height="600rpx;" :auto="false" show-refresher-when-reload>
<view class="gun_list" v-for="(item, index) in dataList" :key="index">
<view class="gun_list_left">
<view class="gun_list_left_view1">
<up-tag v-if="item.realtimeStatus == 1" size="mini" type="error" text="故障" plain plainFill></up-tag>
<up-tag v-else-if="item.realtimeStatus == 2" size="mini" type="success" text="空闲" plain plainFill></up-tag>
<up-tag v-else-if="item.realtimeStatus == 3" size="mini" type="warning" text="充电中" plain plainFill></up-tag>
<up-tag v-else size="mini" type="error" text="离线" plain plainFill></up-tag>
<view style="margin-left: 15rpx"><up-tag v-if="item.insertStatus == 1" size="mini" text="已插枪" plain plainFill></up-tag></view>
<view style="margin-left: 15rpx">{{ item.gunName }}</view>
</view>
<view class="gun_list_left_view">{{ item.deviceNo }}</view>
<view class="gun_list_left_view">
<view>最高功率{{ item.maxPower }}KW</view>
<view style="margin-left: 30rpx">电压{{ item.maxVoltage }}V</view>
</view>
</view>
<view>
<up-button @click="startCd(item)" v-if="item.realtimeStatus == 2" shape="circle" type="success" :plain="true" text="启动充电"></up-button>
<up-button
v-if="item.realtimeStatus == 1 || item.realtimeStatus == 0"
shape="circle"
type="error"
:plain="true"
text="报故障"
openType="contact"
></up-button>
</view>
</view>
</z-paging>
</view>
</up-popup>
<up-popup :show="showJf" @close="showJf = false" closeable round="10">
<view style="font-size: 36rpx; font-weight: bold; padding: 30rpx">价格详情</view>
<view style="padding: 30rpx; padding-top: 0">
<scroll-view scroll-y="true" style="height: 800rpx">
<view v-for="(item, index) in info.priceList" :key="index" style="margin-bottom: 30rpx; position: relative; position: relative">
<view
style="
height: 80rpx;
background: linear-gradient(to right, rgba(72, 121, 230, 1), rgba(72, 121, 230, 0.4));
border-radius: 15rpx;
color: #fff;
font-size: 28rpx;
padding-top: 10rpx;
padding-left: 30rpx;
"
>
<text v-if="item.isCurrent == 1" style="margin-right: 30rpx">当前计费时间段</text>
{{ item.startTime }}-{{ item.endTime }}
</view>
<view style="border: 1rpx solid #4879e6; border-radius: 15rpx; padding: 30rpx; margin-top: -30rpx; background-color: #fff; font-size: 28rpx">
<view style="display: flex; justify-content: space-between; margin-bottom: 15rpx">
<view>电费</view>
<view>{{ item.electricityRate }}/</view>
</view>
<view style="display: flex; justify-content: space-between; margin-bottom: 15rpx">
<view>服务费</view>
<view>{{ item.serviceFeeRate }}/</view>
</view>
<view style="border-top: 1rpx solid #eee; margin-bottom: 15rpx"></view>
<view style="display: flex; justify-content: space-between">
<view>总计</view>
<view>{{ item.totalAmount }}/</view>
</view>
</view>
</view>
</scroll-view>
</view>
</up-popup>
</view>
</template>
<script setup>
import { ref, reactive, computed } from 'vue';
import { infoAroundApi, listByStationId, startCharging } from '@/api/api.js';
import { onLoad, onPageScroll } from '@dcloudio/uni-app';
import { lookImg, call, urlQuery } from '@/utils/fun.js';
import { useNav } from '@/hooks/useNav.js';
const { nav, navTo } = useNav();
const headerBg = ref(false);
const statusBarHeight = uni.getSystemInfoSync().statusBarHeight + 'px';
let info = reactive({});
let show = ref(false);
const dataList = ref([]);
const paging = ref(null);
let showJf = ref(false);
const fullCost = computed(() => {
let data = info?.priceList?.find((val) => val.isCurrent == 1);
return data || {};
});
onLoad((options) => {
getInfo(options.id, options.distance);
});
onPageScroll((e) => {
if (e.scrollTop > uni.getSystemInfoSync().statusBarHeight + 44) {
headerBg.value = true;
} else {
headerBg.value = false;
}
});
const getInfo = async (e, distance) => {
let _res = await infoAroundApi({ id: e });
_res.distance = distance;
Object.assign(info, _res);
};
// 使用 ref 创建响应式引用
const list3 = ref(['https://cdn.uviewui.com/uview/swiper/swiper3.png', 'https://cdn.uviewui.com/uview/swiper/swiper2.png', 'https://cdn.uviewui.com/uview/swiper/swiper1.png']);
let toRecharge = () => {
uni.scanCode({
success: function (res) {
let query = urlQuery(res.result);
if (!query.num) {
uni.showToast({
title: '请扫描正确的设备码',
icon: 'none'
});
} else {
navTo(`/pages/home/star?id=${query.num}`);
}
// navTo(`/pages/home/star?id=${res.result}`);
}
});
};
const back = () => {
uni.navigateBack();
};
const queryList = async () => {
listByStationId({ stationId: info.id })
.then((res) => {
paging.value.complete(res);
})
.catch((res) => {
paging.value.complete(false);
});
};
const showZd = () => {
show.value = true;
paging.value.reload();
};
const startCd = async (e) => {
uni.navigateTo({
url: './star?id=' + e.deviceGunNo
});
// let _res = startCharging({
// deviceNo: e.deviceNo,
// gunNo: e.gunNo
// });
};
</script>
<style scoped lang="scss">
.orderdetail {
padding-bottom: 150rpx;
&_header {
width: 750rpx;
position: fixed;
left: 0;
top: 0;
z-index: 99;
transition: all 0.5s;
}
&_info {
background: #ffffff;
border-radius: 16rpx 16rpx 16rpx 16rpx;
padding: 25rpx;
box-shadow: 0rpx -6rpx 8rpx 2rpx rgba(66, 115, 229, 0.05);
&_title {
font-size: 32rpx;
color: #232323;
margin-bottom: 30rpx;
@include flex($space: space-between);
}
&_fy {
background: linear-gradient(to right, rgba(72, 121, 230, 0.4), rgba(72, 121, 230, 0));
border-radius: 15rpx;
padding: 40rpx 20rpx 40rpx 40rpx;
color: #fff;
margin-top: 30rpx;
@include flex;
&_left {
font-size: 32rpx;
font-weight: 800;
font-style: italic;
color: #4879e6;
}
&_right {
font-size: 36rpx;
font-weight: 800;
color: #4879e6;
margin-left: 30rpx;
@include flex;
}
}
&_zd {
border-radius: 15rpx;
padding: 40rpx 20rpx 40rpx 130rpx;
background-color: #4879e6;
color: #fff;
@include flex($space: space-between);
&_zdbg {
position: absolute;
left: 0;
top: 0;
width: 40%;
height: 100%;
background: linear-gradient(to right, rgba(255, 255, 255, 0) 0%, rgba(255, 255, 255, 0.3) 100%);
}
}
&_view {
@include flex($space: space-between);
margin-bottom: 30rpx;
&_left {
font-weight: 400;
font-size: 28rpx;
color: #232323;
}
&_right {
@include flex;
font-weight: bold;
font-size: 28rpx;
color: #232323;
image {
width: 28rpx;
height: 28rpx;
margin-left: 10rpx;
}
}
}
&_xian {
width: 100%;
border: 2rpx solid #707070;
margin-bottom: 30rpx;
opacity: 0.06;
}
}
&_btn {
width: 100%;
position: fixed;
left: 0;
bottom: 40rpx;
@include flex($space: space-between);
view {
@include flex($space: center);
width: 330rpx;
height: 92rpx;
border-radius: 46rpx 46rpx 46rpx 46rpx;
}
&_left {
background-color: #e5eaf4;
color: #4879e6;
font-size: 34rpx;
font-weight: bold;
text {
font-size: 26rpx;
}
}
&_right {
background: #4879e6;
color: #fff;
font-weight: bold;
font-size: 32rpx;
}
}
.gun {
height: 600rpx;
&_list {
@include flex($space: space-between);
padding: 30rpx;
&_left {
flex: 1;
&_view {
font-size: 24rpx;
color: #b0b2b6;
margin-bottom: 10rpx;
@include flex;
}
&_view1 {
@include flex;
font-size: 28rpx;
color: #333;
margin-bottom: 10rpx;
}
}
}
}
::v-deep .u-popup__content__close--top-right {
top: 10rpx;
}
}
</style>

292
pages/home/home.vue Normal file
View File

@@ -0,0 +1,292 @@
<template>
<view>
<view class="search_header p30">
<!-- position: sticky; top: 0; left: 0; z-index: 999; -->
<view style="width: 100%">
<view class="search_header_blur"></view>
<search @search="searchChange" />
</view>
<view style="margin: 30rpx 0 0">
<up-swiper :list="list1" height="150rpx" keyName="imageUrl" indicator></up-swiper>
</view>
<view class="search_header_grid" style="position: sticky; top: 0; left: 0; background-color: #ffffff; padding: 15rpx">
<view class="search_header_grid_view" @click="toOrder">
<image src="/static/icon/dd.png"></image>
<view>我的订单</view>
</view>
<view class="search_header_grid_view" @click="showMode">
<image src="/static/icon/kj.png"></image>
<view>卡卷中心</view>
</view>
<view class="search_header_grid_view" @click="navTo('/pageMake/invoice/invoice')">
<image src="/static/icon/kp.png"></image>
<view>我要开票</view>
</view>
<!-- open-type="contact" -->
<button style="all: unset" @click="toKft">
<view class="search_header_grid_view">
<image src="/static/icon/kf.png"></image>
<view>在线客服</view>
</view>
</button>
</view>
</view>
<z-paging ref="paging" v-model="dataList" use-page-scroll @query="queryList">
<view style="height: 35rpx"></view>
<!-- <view style="padding: 0 30rpx">
<view class="order_list" style="position: sticky; top: 0; left: 0">
<view class="order_list_header p30">
<view class="order_list_header_view" @click="tabChange(1)">
<view>距我最近</view>
<view v-if="query.orderByType == 1" class="order_list_header_view_dian"></view>
</view>
<view class="order_list_header_view" @click="tabChange(2)">
<view>空闲最多</view>
<view v-if="query.orderByType == 2" class="order_list_header_view_dian"></view>
</view>
</view>
</view>
</view> -->
<view class="order_list">
<view :class="[query.orderByType == 1 ? 'order_list_active' : '']" class="order_list_view" @click="tabChange(1)">距我最近</view>
<view :class="[query.orderByType == 2 ? 'order_list_active' : '']" class="order_list_view" @click="tabChange(2)">空闲最多</view>
</view>
<!-- <view style="display: flex; flex-direction: column; align-items: center; justify-content: center; padding: 0 30rpx">
<view style="background-color: #ffffff; width: 690rpx">
</view>
</view> -->
<view style="margin-bottom: 30rpx; padding: 0 30rpx" v-for="(item, index) in dataList" :key="index">
<orderList toNav :info="item"></orderList>
</view>
</z-paging>
<view style="height: 180rpx"></view>
<!-- <tabbar path="/pages/home/home"></tabbar> -->
<cc-myTabbar :tabBarShow="0"></cc-myTabbar>
</view>
</template>
<script setup>
import { ref, reactive } from 'vue';
import { onLoad, onShow, onPullDownRefresh, onPageScroll, onReachBottom } from '@dcloudio/uni-app';
import { aroundAreaApi, bannerList } from '@/api/api.js';
import { useNav } from '@/hooks/useNav.js';
const { nav, navTo } = useNav();
const dataList = ref([]);
const paging = ref(null);
const query = reactive({
lon: '',
lat: '',
orderByType: 1, //1-最近;2-空闲较多
keyWord: ''
});
const list1 = ref([]);
onLoad(async () => {
let _res = await bannerList();
list1.value = _res;
});
onShow(() => {
uni.hideTabBar();
});
let toKft = (e) => {
uni.makePhoneCall({
phoneNumber: '4008005326' //仅为示例
});
};
const queryList = async () => {
uni.showLoading({
title: '加载中...'
});
try {
if (!query.lon && !query.lat) {
const { longitude: lon, latitude: lat } = await uni.getLocation();
query.lon = lon;
query.lat = lat;
}
} catch (err) {
console.log(err);
}
console.log(query);
aroundAreaApi(query)
.then((res) => {
console.log(res, 'list');
paging.value.complete(res);
uni.hideLoading();
})
.catch((res) => {
paging.value.complete(false);
uni.hideLoading();
});
};
let tabChange = (e) => {
query.orderByType = e;
paging.value.reload();
};
let isPagingRefNotFound = () => {
return !paging.value;
};
onPullDownRefresh(() => {
if (isPagingRefNotFound()) return;
paging.value.reload().catch(() => {});
});
onPageScroll((e) => {
if (isPagingRefNotFound()) return;
paging.value.updatePageScrollTop(e.scrollTop);
e.scrollTop < 10 && paging.value.doChatRecordLoadMore();
});
onReachBottom(() => {
if (isPagingRefNotFound()) return;
paging.value.pageReachBottom();
});
const toOrder = () => {
uni.switchTab({
url: '/pages/order/order'
});
};
let searchChange = (e) => {
query.keyWord = e;
paging.value.reload();
};
let showMode = () => {
uni.showModal({
title: '提示',
content: '暂未开放',
showCancel: false,
confirmText: '确认',
success: () => {}
});
};
</script>
<style>
page {
/* background: linear-gradient(180deg, #ffffff 0%, #f7f7f7 100%); */
background-color: #f7f7f7;
}
</style>
<style lang="scss" scoped>
.search_header {
position: relative;
&_blur {
width: 100%;
height: 185rpx;
position: absolute;
top: 0;
left: 0;
background: #dbe6ff;
opacity: 0.8;
filter: blur(50px);
/* #ifdef MP-ALIPAY */
z-index: 0;
/* #endif */
/* #ifdef MP-WEIXIN */
z-index: -1;
/* #endif */
}
&_grid {
// margin: 35rpx 0;
margin-top: 25rpx;
border-radius: 15rpx;
@include flex($space: space-between);
&_view {
display: flex;
flex-direction: column;
align-items: center;
width: 126rpx;
font-size: 26rpx;
// background: #ffffff;
// border-radius: 24rpx 24rpx 24rpx 24rpx;
image {
width: 99rpx;
height: 99rpx;
margin-bottom: 10rpx;
}
}
}
}
.order_list {
display: flex;
align-items: center;
padding: 15rpx;
margin-bottom: 30rpx;
font-size: 30rpx;
background-color: #fff;
width: 690rpx;
margin: 0 30rpx 30rpx;
border-radius: 15rpx;
// width: 690rpx;
// background: linear-gradient(180deg, #ffffff 0%, #f6f6f6 100%);
// box-shadow: 0rpx -6rpx 12rpx 2rpx rgba(88, 140, 255, 0.1);
// border-radius: 44rpx 44rpx 0rpx 0rpx;
&_view {
padding: 15rpx 30rpx;
background-color: #fff;
border-radius: 15rpx;
margin-right: 30rpx;
}
&_active {
background-color: #4879e6;
color: #fff;
}
// &_header {
// width: 100%;
// height: 100rpx;
// @include flex;
// font-weight: bold;
// font-size: 36rpx;
// color: #232323;
// background-color: #ffffff;
// position: sticky;
// top: 360rpx;
// left: 0;
// &_view {
// position: relative;
// margin-right: 50rpx;
// view {
// position: relative;
// z-index: 99;
// }
// &_dian {
// position: absolute !important;
// bottom: 0rpx;
// right: 20rpx;
// width: 66rpx;
// height: 20rpx;
// background-color: #4879e6;
// border-radius: 10rpx;
// z-index: 1 !important;
// }
// }
// }
}
button::after {
all: unset;
}
</style>

561
pages/home/star.vue Normal file
View File

@@ -0,0 +1,561 @@
<template>
<view class="p30">
<!-- <view class="star_pile" style="margin-bottom: 30rpx"></view> -->
<view class="orderdetail_info" style="margin-bottom: 30rpx">
<view class="orderdetail_info_title">
<view>{{ info.stationName }}</view>
</view>
<view style="font-size: 26rpx; margin-bottom: 15rpx; display: flex; align-items: center">
<view style="opacity: 0.7">枪号{{ info.gunName }}</view>
<image style="width: 40rpx; height: 40rpx; margin-left: 15rpx" src="/static/icon/copy.png" @click="copy(info.gunName)" mode="widthFix"></image>
</view>
<view style="font-size: 26rpx; margin-bottom: 15rpx; opacity: 0.7">停车收费说明{{ info.occupyCostInfo }}</view>
<view style="font-size: 26rpx; opacity: 0.7">占用收费说明{{ info.parkCostInfo }}</view>
</view>
<view class="orderdetail_info" style="margin-bottom: 30rpx">
<view class="orderdetail_info_title">
<view>费用信息</view>
</view>
<view style="max-width: 420rpx">
<up-tag size="mini" :text="`当前计费时间段:${currentPrice.startTime}-${currentPrice.endTime}`" plain plainFill></up-tag>
</view>
<view class="orderdetail_info_fy">
<view class="orderdetail_info_fy_left">电站价格</view>
<view class="orderdetail_info_fy_right">
{{ currentPrice.totalAmount }}
<text style="font-weight: 500; font-size: 24rpx; color: #333; margin-left: 15rpx">/</text>
</view>
</view>
</view>
<view class="orderdetail_info" style="margin-bottom: 30rpx">
<view class="orderdetail_info_title">
<view style="display: flex; align-items: center">
<view>支付方式</view>
<!-- -->
<view style="margin-left: 15rpx">
<up-tag v-if="store.state.insertStatus == 1" size="mini" text="已插枪" plain plainFill></up-tag>
</view>
</view>
<view style="display: flex; align-items: center">
<up-button type="primary" size="small" :plain="true" text="余额充值" @click="navTo('/pages/money/recharge')"></up-button>
</view>
</view>
<view style="font-size: 30rpx; margin-bottom: 30rpx">
<!-- @click="payTo" -->
<!-- <view>支付方式</view> -->
<!-- <view>{{ payType == 1 ? '余额付款' : payType == 2 ? '电卡支付' : payType == 3 ? '预付款' : '请选择' }}</view> -->
<view>
<view
class="flex-acsb"
style="padding: 15rpx 30rpx; border-radius: 10rpx"
v-for="(item, index) in payList"
:key="index"
:style="{
border: item.id == payType ? '1rpx solid #4879e6' : ''
}"
@click="payType = item.id"
>
<view style="display: flex; align-items: center">
<image :src="`/static/icon/lie${item.id}.png`" style="width: 50rpx; height: 50rpx; margin-right: 25rpx"></image>
{{ item.name }}
</view>
<view v-if="item.id == 1" style="font-size: 28rpx; opacity: 0.7">可用余额{{ infoUser.balance || 0 }}</view>
</view>
</view>
</view>
</view>
<view class="orderdetail_info" style="margin-bottom: 30rpx">
<view class="orderdetail_info_yf">
<view class="orderdetail_info_yf_left">
<view class="orderdetail_info_yf_left_tit">
<view style="margin-right: 30rpx">预付费</view>
<up-tag size="mini" :text="`余额原路退款`" plain plainFill></up-tag>
</view>
<!-- <view>{{ dataForm.money }} </view> -->
<view class="orderdetail_info_yf_left_mon">
<!-- 预付金额 -->
<view
@click="
dataForm.money = 30;
inputBorder = false;
"
:style="{ border: `1rpx solid ${dataForm.money == 30 && !inputBorder ? '#4879e6' : '#c5c5c5'}` }"
>
30
</view>
<view
@click="
dataForm.money = 50;
inputBorder = false;
"
:style="{ border: `1rpx solid ${dataForm.money == 50 && !inputBorder ? '#4879e6' : '#c5c5c5'}` }"
>
50
</view>
<view
@click="
dataForm.money = 100;
inputBorder = false;
"
:style="{ border: `1rpx solid ${dataForm.money == 100 && !inputBorder ? '#4879e6' : '#c5c5c5'}` }"
>
100
</view>
<view @click="inputClik" :style="{ border: `1rpx solid ${inputBorder ? '#4879e6' : '#c5c5c5'}` }">
<input adjust-position v-if="inputBorder" focus type="number" v-model="dataForm.money" placeholder="自定义" />
<text v-else>自定义</text>
</view>
</view>
</view>
<!-- <view class="orderdetail_info_yf_right" @click="openDialog">预付金额</view> -->
</view>
</view>
<view class="orderdetail_info" style="margin-bottom: 30rpx" v-if="payType == 2">
<view>
<view class="flex-acsb" style="font-size: 30rpx; margin-bottom: 20rpx">
<view>当前可用电卡</view>
</view>
<view @click="userCardId = item.id" style="margin-bottom: 30rpx; position: relative" class="mt30 wallet_list" v-for="(item, index) in userCard" :key="index">
<view v-if="userCardId == item.id" style="position: absolute; top: 0; left: 0; background-color: #e45656; border-radius: 0 0 20rpx 0">
<up-icon name="checkbox-mark" color="#fff"></up-icon>
</view>
<view style="color: #fff">
<view style="font-weight: bold; font-size: 30rpx; margin-bottom: 18rpx">
{{ item.name }}
</view>
<view style="font-size: 28rpx; color: #eee">卡号{{ item.cardNo }}</view>
</view>
<view style="display: flex; flex-direction: column; align-items: center; color: #fff; font-weight: bold; font-size: 26rpx">
<view style="font-size: 36rpx; margin-bottom: 10rpx">{{ item.balance }}</view>
<view style="font-weight: 500">余额</view>
</view>
</view>
</view>
</view>
<view style="height: 500rpx"></view>
<view class="orderdetail_btn p30" style="background-color: #fff">
<view class="orderdetail_btn_left">
{{ currentPrice.totalAmount }}
<text>/ 免费停车</text>
</view>
<view>
<up-button v-if="!payType" :customStyle="{ height: '80rpx', width: '230rpx' }" disabled color="#4879e6" text="请选择支付方式" shape="circle"></up-button>
<up-button v-if="payType == 1" :customStyle="{ height: '80rpx', width: '280rpx' }" @click="toRecharge" color="#4879e6" shape="circle" text="启动充电"></up-button>
<up-button
v-if="payType == 3"
:customStyle="{ height: '80rpx', width: '280rpx' }"
@click="toRechargeYuFu"
color="#4879e6"
shape="circle"
:text="`预付${dataForm.money}元,启动充电`"
></up-button>
<!-- :text="`预付${dataForm.money}元,启动充电`" -->
<up-button
v-if="payType == 2"
:customStyle="{ height: '80rpx', width: '280rpx' }"
:disabled="!userCardId"
color="#4879e6"
:text="userCardId ? '启动充电' : '请选择电卡'"
shape="circle"
@click="toRechargeCard"
></up-button>
</view>
<!-- <view v-if="!payType" class="orderdetail_btn_right" style="opacity: 0.5;">请选择支付方式</view> -->
<!-- <view v-if="payType == 1" class="orderdetail_btn_right" @click="toRecharge">预付{{ dataForm.money }}启动充电</view> -->
<!-- <view v-if="payType == 2" class="orderdetail_btn_right" @click="toRecharge">电卡支付启动充电</view> -->
</view>
<uni-popup ref="inputDialog" type="dialog">
<uni-popup-dialog
ref="inputClose"
mode="input"
title="请输入预付金额"
:value="dataForm.money"
placeholder="请输入内容"
@confirm="dialogInputConfirm"
></uni-popup-dialog>
</uni-popup>
</view>
</template>
<script setup>
import { ref, reactive, computed } from 'vue';
import { gunInfo, infoAroundApi, startChargingByWallet, userCardUsableList, startChargingByCard, ordersInfo, startChargingByAdaPay, userInfo } from '@/api/api.js';
import { onLoad, onShow } from '@dcloudio/uni-app';
import store from '@/store/index.js';
import { copy } from '@/utils/fun.js';
import { useNav } from '@/hooks/useNav.js';
const { navTo } = useNav();
const inputDialog = ref(null);
let info = reactive({});
let infoUser = reactive({});
let inputBorder = ref(false);
let currentPrice = ref({});
let id = ref('');
let userCard = ref([]);
let userCardId = ref(null);
let payType = ref(1);
let dataForm = reactive({
money: 30
});
let payList = reactive([
{
id: 1,
name: '余额支付'
}
]);
onLoad((options) => {
if (options.q) {
let search = decodeURIComponent(options.q);
search = search.split('?')[1];
const pairs = search ? search.split('&') : [];
const query = {};
for (let i = 0; i < pairs.length; ++i) {
const [key, value] = pairs[i].split('=');
query[key] = query[key] || decodeURIComponent(value);
}
if (query.num) {
id.value = query.num;
infoDate(query.num);
}
}
if (options.id) {
id.value = options.id;
infoDate(options.id);
}
});
onShow(async () => {
if (uni.getStorageSync('token') && id.value) {
infoDate(id.value);
let _res = await userInfo();
infoUser.value = _res;
}
});
let getUserCard = async (e) => {
let _res = await userCardUsableList({ stationId: e });
userCard.value = _res;
if (_res.length == 0) {
payType.value = 1;
} else {
payType.value = 2;
userCardId.value = _res[0].id;
if (!payList.find((val) => val.name == '电卡支付')) {
payList.push({
id: 2,
name: '电卡支付'
});
}
}
};
let inputClik = () => {
inputBorder.value = true;
dataForm.money = dataForm.money == 30 || dataForm.money == 50 || dataForm.money == 100 ? '' : dataForm.money;
};
let infoDate = async (e) => {
let _res = await gunInfo({ deviceNo: e });
info = _res;
getUserCard(_res.stationId);
currentPrice.value = _res.currentPrice;
console.log(_res.deviceNo, '_res.deviceNo');
console.log(_res.gunNo, '_res.gunNo');
store.commit('setInsertStatus', _res.insertStatus);
uni.sendSocketMessage({
data: JSON.stringify({
command: 'sub',
deviceNo: _res.deviceNo,
gunNo: _res.gunNo
}),
success: (res) => {
console.log('发送成功');
},
fail: (err) => {
console.log(err);
console.log('发送失败');
}
});
};
let dialogInputConfirm = (e) => {
dataForm.money = e;
};
let openDialog = () => {
console.log(12345);
inputDialog.value.open();
};
let toRechargeCard = async () => {
uni.showLoading({
title: '启动充电中...',
mask: true
});
let _res = await startChargingByCard({
deviceNo: info.deviceNo,
gunNo: info.gunNo,
amount: dataForm.money,
userCardId: userCardId.value
});
};
let toRechargeYuFu = async () => {
uni.showLoading({
title: '启动充电中...',
mask: true
});
let _res = await startChargingByAdaPay({
deviceNo: info.deviceNo,
gunNo: info.gunNo,
amount: dataForm.money
});
let data = _res.payInfo;
uni.requestPayment({
provider: 'wxpay',
timeStamp: data.timeStamp,
nonceStr: data.nonceStr,
package: data.package,
signType: data.signType,
paySign: data.paySign,
success: function (r) {
store.commit('setTransactionNo', _res.transactionNo);
store.commit('setSokStatus', 0);
timeMap(_res);
},
fail: function (err) {
uni.showToast({
title: '已取消支付',
icon: 'none'
});
console.log('fail:' + JSON.stringify(err));
}
});
// store.commit('setTransactionNo', _res.transactionNo);
// store.commit('setSokStatus', 0);
// timeMap(_res);
// uni.navigateTo({
// url: `/pageOrder/recharge/recharge?transactionNo=${_res.transactionNo}&type=order`
// });
};
let toRecharge = async () => {
uni.showLoading({
title: '启动充电中...',
mask: true
});
let _res = await startChargingByWallet({
deviceNo: info.deviceNo,
gunNo: info.gunNo,
amount: dataForm.money
});
store.commit('setTransactionNo', _res.transactionNo);
store.commit('setSokStatus', 0);
timeMap(_res);
// uni.navigateTo({
// url: `/pageOrder/recharge/recharge?transactionNo=${_res.transactionNo}&type=order`
// });
// uni.navigateTo({
// url: `/pageOrder/recharge/recharge?transactionNo=${_res.transactionNo}`
// });
// console.log(_res);
};
const timeMap = (_res) => {
var time = setInterval(async () => {
if (store.state.sokStatus != 1) {
let _data = await ordersInfo({
transactionNo: _res.transactionNo
});
store.commit('setDataObj', _data);
if (_data.status == 3) {
uni.hideLoading();
uni.navigateTo({
url: `/pageOrder/recharge/recharge?transactionNo=${_res.transactionNo}&type=order`
});
clearTimeout(time);
store.commit('setSokStatus', 0);
}
if (_data.status == -1) {
uni.hideLoading();
uni.showModal({
title: '提示',
content: '启动失败,请重试',
showCancel: false,
confirmText: '确认',
success: () => {}
});
clearTimeout(time);
store.commit('setSokStatus', 0);
}
if (_data.status == -2) {
uni.hideLoading();
uni.showModal({
title: '提示',
content: '启动超时,请重试',
showCancel: false,
confirmText: '确认',
success: () => {}
});
clearTimeout(time);
store.commit('setSokStatus', 0);
}
}
}, 5000);
};
const payTo = () => {
let itemList = ['余额付款'];
if (userCard.value.length != 0) {
itemList.push('电卡支付');
}
// itemList.push('预付款');
uni.showActionSheet({
itemList: itemList,
success: function (res) {
// if (itemList[1] == '预付款' && res.tapIndex == 1) {
// payType.value = 3;
// } else {
// payType.value = res.tapIndex + 1;
// }
payType.value = res.tapIndex + 1;
},
fail: function (res) {
console.log(res.errMsg);
}
});
};
</script>
<style lang="scss">
.star_pile {
width: 100%;
box-shadow: 0rpx -6rpx 8rpx 2rpx rgba(66, 115, 229, 0.05);
border-radius: 16rpx 16rpx 16rpx 16rpx;
padding: 20rpx;
background-color: #fff;
}
.orderdetail_info {
background: #ffffff;
border-radius: 16rpx 16rpx 16rpx 16rpx;
padding: 25rpx;
box-shadow: 0rpx -6rpx 8rpx 2rpx rgba(66, 115, 229, 0.05);
&_title {
font-size: 32rpx;
color: #232323;
margin-bottom: 30rpx;
@include flex($space: space-between);
}
&_fy {
background: linear-gradient(to right, rgba(72, 121, 230, 0.4), rgba(72, 121, 230, 0));
border-radius: 15rpx;
padding: 40rpx 20rpx 40rpx 40rpx;
color: #fff;
margin-top: 30rpx;
@include flex;
&_left {
font-size: 32rpx;
font-weight: 800;
font-style: italic;
color: #4879e6;
}
&_right {
font-size: 36rpx;
font-weight: 800;
color: #4879e6;
margin-left: 30rpx;
@include flex;
}
}
&_yf {
@include flex($space: space-between);
&_left {
flex: 1;
// view {
// @include flex;
// }
&_tit {
font-size: 28rpx;
color: rgba(51, 51, 51, 0.8);
margin-bottom: 20rpx;
@include flex;
}
&_mon {
font-size: 30rpx;
@include flex($space: space-between);
view {
// width: 22%;
padding: 15rpx 35rpx;
border: 1rpx solid #c5c5c5;
margin-right: 15rpx;
border-radius: 10rpx;
}
input {
width: 100rpx;
}
}
}
&_right {
padding: 15rpx 30rpx;
color: #1779ff;
border: 1rpx solid #1779ff;
border-radius: 50rpx;
}
}
}
.orderdetail_btn {
width: 100%;
position: fixed;
left: 0;
bottom: 0rpx;
padding: 30rpx;
@include flex($space: space-between);
&_left {
// background-color: #e5eaf4;
color: #333;
font-size: 38rpx;
font-weight: bold;
text {
font-size: 26rpx;
font-weight: 500;
}
}
&_right {
background: #1779ff;
color: #fff;
font-weight: bold;
font-size: 32rpx;
padding: 0 40rpx;
}
}
.wallet_list {
border-radius: 15rpx;
background-color: #4879e6;
padding: 20rpx 50rpx 20rpx 30rpx;
display: flex;
align-items: flex-end;
justify-content: space-between;
}
</style>

266
pages/index/index.vue Normal file
View File

@@ -0,0 +1,266 @@
<template>
<view class="content">
<!-- <search :Fixed="true" /> -->
<map
id="map"
:longitude="longitude"
@markertap="markerClick"
@callouttap="markerClick"
@regionchange="regionchange"
height="90"
width="90"
:markers="markList"
:latitude="latitude"
class="map_content"
>
<cover-view slot="callout">
<template v-for="(item, index) in markList">
<cover-view class="callout" :marker-id="item.id">
<cover-view class="callout_item">
<cover-image class="callout_item_img" src="/static/icon/mc.png"></cover-image>
<cover-view class="callout_item_view"> {{ item.gunUseCount || 0 }}/{{ item.gunCount || 0 }}</cover-view>
</cover-view>
</cover-view>
</template>
</cover-view>
</map>
<uni-transition ref="mapLocationRef" :show="true">
<view class="map-location" @click="mapLocation">
<image src="/static/icon/location-marker-icon.png" mode="widthFix"></image>
</view>
</uni-transition>
<uni-transition modeClass="fade" :show="mapBox">
<view class="map_box">
<orderList toNav :Image="true" :info="infoDz" :list="infoDz.pictures" />
</view>
</uni-transition>
<cc-myTabbar :tabBarShow="1"></cc-myTabbar>
<!-- <tabbar path="/pages/index/index"></tabbar> -->
</view>
</template>
<script setup>
import { ref } from 'vue';
import { onLoad } from '@dcloudio/uni-app';
import { aroundAreaMap, infoAroundApi } from '@/api/api.js';
let longitude = ref(113.675688);
let latitude = ref(34.75527700365562);
let mapContext = ref(null);
let mapBox = ref(false);
let mapLocationRef = ref();
let infoDz = ref([]);
let markList = ref([]);
onLoad(async () => {
// #ifndef MP-WEIXIN
uni.hideTabBar();
// #endif
mapContext.value = uni.createMapContext('map');
const { longitude: lon, latitude: lat } = await uni.getLocation({
type: 'gcj02' // 根据实际需要选择坐标系
});
latitude.value = lat;
longitude.value = lon;
getInfo();
setTimeout(() => {
mapLocation();
}, 300);
});
let getInfo = async () => {
let _res = await aroundAreaMap({
orderByType: 1,
lat: latitude.value,
lon: longitude.value
});
let list = _res.map((item, index) => {
return {
id: item.id,
longitude: item.location.lng,
latitude: item.location.lat,
iconPath: '/static/icon/marker-pointer.png',
width: 20,
height: 23,
content: '2',
gunUseCount: item.gunUseCount,
gunCount: item.gunCount,
distance: item.distance,
customCallout: {
display: 'ALWAYS', // 显示方式
anchorX: 0, // 锚点X轴
anchorY: -10 // 锚点Y轴
}
};
});
list.unshift({
longitude: longitude.value,
latitude: latitude.value,
iconPath: '/static/icon/my-location-default.png',
width: 45,
height: 45,
id: -1
});
markList.value = list;
};
const mapLocation = () => {
const log = longitude.value;
const lat = latitude.value;
mapContext.value.moveToLocation({
longitude: log,
latitude: lat
});
};
// 地图缩放移动触发
const regionchange = (e) => {
// 地图移动手松开结束触发type:end
if (e.type == 'end') {
console.log(e);
console.log(e.detail.scale);
mapBox.value = false;
mapLocationRefStep(false);
}
};
// marker点击事件
const markerClick = async (e) => {
console.log(e, 'eeeeeee');
if (e.markerId == -1) {
return;
}
uni.showLoading();
let _res = await infoAroundApi({
id: e.markerId
});
let markerInfo = markList.value.find((val) => val.id == e.markerId);
let data = _res?.priceList?.find((val) => val.isCurrent == 1);
infoDz.value = {
..._res,
distance: markerInfo.distance,
priceAmount: data.totalAmount
};
console.log(infoDz, 'infoDzinfoDz');
// infoDz.value.priceAmount = data.totalAmount;
// infoDz.value.distance = data.distance;
uni.hideLoading();
mapBox.value = true;
mapLocationRefStep(true);
};
const mapLocationRefStep = (type) => {
if (type) {
mapLocationRef.value.step(
{
translateY: '-200rpx'
},
{
timingFunction: 'ease-in',
duration: 100
}
);
} else {
mapLocationRef.value.step(
{
translateY: '0rpx'
},
{
timingFunction: 'ease',
duration: 500
}
);
}
mapLocationRef.value.run();
};
</script>
<style lang="scss">
.map_content {
width: 750rpx;
height: 100vh;
/* #ifdef MP-ALIPAY */
height: calc(100vh - 100upx);
/* #endif */
}
.map-location {
width: 90rpx;
height: 90rpx;
background-color: #fff;
position: fixed;
left: 30rpx;
bottom: 570rpx;
border-radius: 20rpx;
display: flex;
align-items: center;
justify-content: center;
box-shadow: 0 5px 11px rgba(0, 0, 0, 0.2);
image {
width: 45rpx;
height: 45rpx;
}
}
.callout {
box-sizing: border-box;
background: rgba(15, 75, 203, 0.26);
border-radius: 15rpx 15rpx 15rpx 0;
padding: 10rpx 15rpx;
@include flex($direction: column);
&_item {
@include flex;
font-weight: bold;
font-size: 28rpx;
color: #ffffff;
box-sizing: border-box;
&_img {
width: 40rpx;
height: 40rpx;
margin-right: 15rpx;
}
}
&_item:nth-child(1) {
margin-bottom: 15rpx;
}
}
.recharge {
width: 690rpx;
background-color: #fff;
min-height: 300rpx;
position: fixed;
left: 30rpx;
bottom: 250rpx;
border-radius: 20rpx;
padding: 20rpx;
box-shadow: 0 5px 11px rgba(0, 0, 0, 0.2);
&_title {
font-size: 36rpx;
margin-bottom: 20rpx;
}
&_con {
font-size: 26rpx;
}
}
.map_box {
width: 690rpx;
position: fixed;
left: 30rpx;
bottom: 230rpx;
z-index: 999;
}
</style>

166
pages/login/login.vue Normal file
View File

@@ -0,0 +1,166 @@
<template>
<view class="content">
<view class="head">
<image src="/static/image/login26_bg.png" mode="widthFix"></image>
</view>
<view class="title">
<text class="name">Hello!</text>
<text class="sub-name">欢迎登录云快充</text>
</view>
<view class="form-box">
<button class="login-btn" :disabled="!aloneChecked" open-type="getPhoneNumber" @getphonenumber="getPhoneNumber">一键注册登录</button>
<view class="tip-link" style="display: flex; align-items: center">
<up-checkbox shape="circle" name="agree" usedAlone @change="change"></up-checkbox>
我已阅读并同意
<text @click="toNav('/pages/agreement/agreement?id=9')">用户协议</text>
<text @click="toNav('/pages/agreement/agreement?id=10')">隐私政策</text>
</view>
</view>
</view>
</template>
<script setup>
import { ref } from 'vue';
import { login } from '@/common/js/user.js';
let aloneChecked = ref(false);
let getPhoneNumber = async (e) => {
if (!aloneChecked.value) {
return uni.showToast({
title: '请先阅读并同意用户协议和隐私政策',
icon: 'none'
});
}
try {
login(e, 2);
// let token = uni.getStorageSync('token');
// if (!token) {
// login(e, 2);
// } else {
// login();
// uni.navigateBack();
// }
} catch (err) {
uni.showToast({
title: err,
icon: 'none'
});
}
};
const toNav = (e) => {
uni.navigateTo({
url: e
});
};
const change = (e) => {
aloneChecked.value = e;
};
</script>
<style lang="scss">
page {
background-color: #e9edf6;
}
.head {
position: fixed;
top: 0;
left: 0;
right: 0;
width: 100%;
height: 30vh;
z-index: -1;
image {
width: 100%;
height: 100%;
}
}
.title {
padding-left: 80rpx;
padding-top: 100rpx;
display: flex;
justify-content: center;
align-items: flex-start;
flex-direction: column;
height: 30vh;
.name {
font-size: 70rpx;
line-height: 100rpx;
font-weight: bold;
}
.sub-name {
line-height: 80rpx;
font-size: 45rpx;
letter-spacing: 8rpx;
font-weight: bold;
}
}
.form-box {
padding: 0rpx 80rpx;
.row-input {
display: flex;
justify-content: flex-start;
align-items: center;
height: 100rpx;
background-color: #ffffff;
border-radius: 12rpx;
margin: 50rpx 0rpx;
image {
margin: 0 25rpx;
flex-shrink: 0;
width: 31rpx;
height: 35rpx;
}
input {
font-size: 30rpx;
flex: 1;
}
}
.menu-link {
display: flex;
justify-content: space-between;
align-items: center;
font-size: 26rpx;
}
.login-btn {
margin-top: 250rpx;
display: flex;
justify-content: center;
align-items: center;
height: 90rpx;
border-radius: 12rpx;
background-color: #819682;
color: #f4f4f4;
font-size: 30rpx;
letter-spacing: 5rpx;
box-shadow: 0rpx 5rpx 20rpx #94ac95;
}
.tip-link {
display: flex;
justify-content: center;
letter-spacing: 3rpx;
line-height: 150rpx;
font-size: 26rpx;
text {
color: #57a2ee;
}
}
}
</style>

96
pages/mine/card.vue Normal file
View File

@@ -0,0 +1,96 @@
<template>
<view class="earnings p30">
<z-paging ref="paging" v-model="dataList" use-page-scroll @query="queryList">
<view style="margin-bottom: 30rpx" @click="toCrud(item)" class="mt30 wallet_list" v-for="(item, index) in dataList" :key="index">
<view style="color: #fff">
<view style="font-weight: bold; font-size: 32rpx; margin-bottom: 18rpx">
{{ item.name }}
</view>
<view style="margin-bottom: 12rpx; font-size: 28rpx; color: #eee">
卡号{{ item.cardNo }}
</view>
<view style="margin-bottom: 12rpx; font-size: 28rpx; color: #eee">
电站{{ item.stationName }}
</view>
<view style="font-size: 28rpx; color: #eee">
商户{{ item.merchantName }}
</view>
</view>
<view style="display: flex; flex-direction: column; align-items: center; color: #fff; font-weight: bold; font-size: 26rpx">
<view style="font-size: 55rpx; margin-bottom: 30rpx">{{ item.balance }}</view>
<view style="font-weight: 500">余额</view>
</view>
</view>
</z-paging>
</view>
</template>
<script setup>
import { reactive, ref, computed } from 'vue';
import { onPullDownRefresh, onPageScroll, onReachBottom } from '@dcloudio/uni-app';
import { timeFormat } from '@/uni_modules/uview-plus';
import { userCardList } from '@/api/api.js';
import { onLoad, onShow } from '@dcloudio/uni-app';
import { useNav } from '@/hooks/useNav.js';
const changeSele = (e) => {
paging.value.reload();
};
const { nav, navTo } = useNav();
let getInfo = ref({});
const paging = ref(null);
let dataList = ref([]);
let isPagingRefNotFound = () => {
return !paging.value;
};
onPullDownRefresh(() => {
if (isPagingRefNotFound()) return;
paging.value.reload().catch(() => {});
});
onPageScroll((e) => {
if (isPagingRefNotFound()) return;
paging.value.updatePageScrollTop(e.scrollTop);
e.scrollTop < 10 && paging.value.doChatRecordLoadMore();
});
onReachBottom(() => {
if (isPagingRefNotFound()) return;
paging.value.pageReachBottom();
});
const queryList = (pageNo, pageSize) => {
const params = {
current: pageNo,
pageSize: pageSize
};
userCardList(params)
.then((res) => {
paging.value.complete(res);
})
.catch((res) => {
paging.value.complete(false);
});
};
let toCrud = ()=>{
uni.navigateTo({
url:'./cardList?id=' + e.id
})
}
</script>
<style scoped lang="scss">
.wallet_list {
border-radius: 15rpx;
background-color: #4879e6;
padding: 35rpx 50rpx 35rpx 30rpx;
display: flex;
align-items: flex-end;
justify-content: space-between;
}
</style>

151
pages/mine/cardList.vue Normal file
View File

@@ -0,0 +1,151 @@
<template>
<view class="earnings p30">
<z-paging ref="paging" v-model="dataList" use-page-scroll @query="queryList">
<view style="margin-bottom: 30rpx" class="mt30 wallet_list" v-for="(item, index) in dataList" :key="index">
<view class="wallet_list_left">
<view>{{ item.recordName || '-' }}</view>
<view>{{ item.createTime }}</view>
</view>
<view class="wallet_list_right" style="display: flex; flex-direction: column; align-items: flex-end">
<!-- <view style="margin-bottom: 10rpx; width: 75rpx">
<view></view>
<up-tag v-if="item.pointType == 2" size="mini" text="余额" type="warning" plain plainFill></up-tag>
<up-tag v-if="item.pointType == 1" size="mini" text="收益" plain plainFill></up-tag>
</view> -->
<view>{{ item.amount }}</view>
</view>
</view>
</z-paging>
</view>
</template>
<script setup>
import { reactive, ref, computed } from 'vue';
import { onPullDownRefresh, onPageScroll, onReachBottom } from '@dcloudio/uni-app';
import { timeFormat } from '@/uni_modules/uview-plus';
import { userCardRecord } from '@/api/api.js';
import { onLoad, onShow } from '@dcloudio/uni-app';
import { useNav } from '@/hooks/useNav.js';
let id = ref('');
const changeSele = (e) => {
paging.value.reload();
};
const { nav, navTo } = useNav();
let getInfo = ref({});
const paging = ref(null);
let dataList = ref([]);
let isPagingRefNotFound = () => {
return !paging.value;
};
onLoad((options) => {
id.value = options.id;
});
onPullDownRefresh(() => {
if (isPagingRefNotFound()) return;
paging.value.reload().catch(() => {});
});
onPageScroll((e) => {
if (isPagingRefNotFound()) return;
paging.value.updatePageScrollTop(e.scrollTop);
e.scrollTop < 10 && paging.value.doChatRecordLoadMore();
});
onReachBottom(() => {
if (isPagingRefNotFound()) return;
paging.value.pageReachBottom();
});
const queryList = (pageNo, pageSize) => {
const params = {
current: pageNo,
pageSize: pageSize,
id: id.value
};
userCardRecord(params)
.then((res) => {
paging.value.complete(res);
})
.catch((res) => {
paging.value.complete(false);
});
};
</script>
<style scoped lang="scss">
.wallet_pall {
width: 690rpx;
height: 272rpx;
border-radius: 16rpx 16rpx 16rpx 16rpx;
padding: 40rpx;
background: #ffffff;
&_header {
font-weight: bold;
font-size: 26rpx;
color: #002ea4;
}
&_ye {
display: flex;
align-items: center;
justify-content: space-between;
height: 70%;
view:nth-child(1) {
font-weight: bold;
font-size: 68rpx;
color: #002ea4;
}
view:nth-child(2) {
width: 128rpx;
height: 58rpx;
background: rgba(0, 46, 164, 0.07);
border-radius: 32rpx 32rpx 32rpx 32rpx;
display: flex;
align-items: center;
justify-content: center;
font-size: 26rpx;
color: #002ea4;
}
}
}
.wallet_list {
width: 690rpx;
// height: 120rpx;
background: #ffffff;
border-radius: 8rpx 8rpx 8rpx 8rpx;
padding: 15rpx 30rpx;
@include flex($space: space-between);
&_left {
view:nth-child(1) {
font-weight: bold;
font-size: 28rpx;
color: #232323;
margin-bottom: 10rpx;
}
view:nth-child(2) {
font-size: 24rpx;
color: #232323;
}
view:nth-child(3) {
font-size: 24rpx;
color: #232323;
}
view:nth-child(4) {
font-size: 24rpx;
color: #232323;
}
}
&_right {
font-weight: bold;
font-size: 28rpx;
color: #ff2727;
}
}
</style>

18
pages/mine/earnings.vue Normal file
View File

@@ -0,0 +1,18 @@
<template>
<view class="earnings">
<up-cell-group>
<up-cell icon="integral-fill" title="会员等级" value="新版本"></up-cell>
</up-cell-group>
</view>
</template>
<script>
export default {
data() {
return {};
},
methods: {}
};
</script>
<style></style>

146
pages/mine/incomeList.vue Normal file
View File

@@ -0,0 +1,146 @@
<template>
<view class="earnings p30">
<z-paging ref="paging" v-model="dataList" use-page-scroll @query="queryList">
<view style="margin-bottom: 30rpx;" class="mt30 wallet_list" v-for="(item, index) in dataList" :key="index">
<view class="wallet_list_left">
<view>{{ item.recordName || '-' }}</view>
<view>{{ item.createTime }}</view>
</view>
<view class="wallet_list_right" style="display: flex; flex-direction: column; align-items: flex-end">
<!-- <view style="margin-bottom: 10rpx; width: 75rpx">
<view></view>
<up-tag v-if="item.pointType == 2" size="mini" text="余额" type="warning" plain plainFill></up-tag>
<up-tag v-if="item.pointType == 1" size="mini" text="收益" plain plainFill></up-tag>
</view> -->
<view>{{ item.amount }}</view>
</view>
</view>
</z-paging>
</view>
</template>
<script setup>
import { reactive, ref, computed } from 'vue';
import { onPullDownRefresh, onPageScroll, onReachBottom } from '@dcloudio/uni-app';
import { timeFormat } from '@/uni_modules/uview-plus';
import { walletRecord } from '@/api/api.js';
import { onLoad, onShow } from '@dcloudio/uni-app';
import { useNav } from '@/hooks/useNav.js';
const changeSele = (e) => {
paging.value.reload();
};
const { nav, navTo } = useNav();
let getInfo = ref({});
const paging = ref(null);
let dataList = ref([]);
let isPagingRefNotFound = () => {
return !paging.value;
};
onPullDownRefresh(() => {
if (isPagingRefNotFound()) return;
paging.value.reload().catch(() => {});
});
onPageScroll((e) => {
if (isPagingRefNotFound()) return;
paging.value.updatePageScrollTop(e.scrollTop);
e.scrollTop < 10 && paging.value.doChatRecordLoadMore();
});
onReachBottom(() => {
if (isPagingRefNotFound()) return;
paging.value.pageReachBottom();
});
const queryList = (pageNo, pageSize) => {
const params = {
current: pageNo,
pageSize: pageSize,
};
walletRecord(params)
.then((res) => {
paging.value.complete(res);
})
.catch((res) => {
paging.value.complete(false);
});
};
</script>
<style scoped lang="scss">
.wallet_pall {
width: 690rpx;
height: 272rpx;
border-radius: 16rpx 16rpx 16rpx 16rpx;
padding: 40rpx;
background: #ffffff;
&_header {
font-weight: bold;
font-size: 26rpx;
color: #002ea4;
}
&_ye {
display: flex;
align-items: center;
justify-content: space-between;
height: 70%;
view:nth-child(1) {
font-weight: bold;
font-size: 68rpx;
color: #002ea4;
}
view:nth-child(2) {
width: 128rpx;
height: 58rpx;
background: rgba(0, 46, 164, 0.07);
border-radius: 32rpx 32rpx 32rpx 32rpx;
display: flex;
align-items: center;
justify-content: center;
font-size: 26rpx;
color: #002ea4;
}
}
}
.wallet_list {
width: 690rpx;
// height: 120rpx;
background: #ffffff;
border-radius: 8rpx 8rpx 8rpx 8rpx;
padding: 15rpx 30rpx;
@include flex($space: space-between);
&_left {
view:nth-child(1) {
font-weight: bold;
font-size: 28rpx;
color: #232323;
margin-bottom: 10rpx;
}
view:nth-child(2) {
font-size: 24rpx;
color: #232323;
}
view:nth-child(3) {
font-size: 24rpx;
color: #232323;
}
view:nth-child(4) {
font-size: 24rpx;
color: #232323;
}
}
&_right {
font-weight: bold;
font-size: 28rpx;
color: #ff2727;
}
}
</style>

257
pages/mine/mine.vue Normal file
View File

@@ -0,0 +1,257 @@
<template>
<view class="mine">
<statusBar />
<view class="p30">
<view class="mine_header">
<view class="mine_header_img">
<up-avatar size="150rpx" :src="info.avatar"></up-avatar>
</view>
<!-- <image :src="info.avatar" class="mine_header_img" mode="aspectFill"></image> -->
<view class="mine_header_user">
<view>{{ info.nickName }}</view>
<view>{{ info.phone || '' }}</view>
</view>
<image class="mine_header_sett" @click="toEarnings" src="/static/icon/sett.png"></image>
</view>
<view class="mine_money">
<view class="flex-acsb flex1 mine_money_top" style="width: 100%">
<view class="mine_money_left" @click="navTo('/pages/mine/incomeList')">
<view>{{ info.balance || 0 }}</view>
<view>钱包余额</view>
</view>
<view class="mine_money_left" @click="navTo('/pages/mine/incomeList')">
<view>0</view>
<view>赠送余额</view>
</view>
</view>
<view class="flex1 mine_money_bottom" style="display: flex; align-items: center">
<!-- class="mine_money_right" -->
<!-- class="mine_money_right" -->
<view @click="navTo(`/pageMake/refund/refund?balance=${info.refundableAmount}`)">退款</view>
<view @click="navTo('/pages/money/recharge')">充值</view>
</view>
</view>
<view class="mine_grid">
<view class="mine_grid_tit">常用功能</view>
<view class="mine_grid_views">
<view class="mine_grid_views_block" v-for="(item, index) in gridList" :key="index" @click="nav(item)">
<image :src="item.img" mode="widthFix"></image>
<view>{{ item.name }}</view>
</view>
</view>
</view>
<!-- <view class="mine_fun">
<view class="mine_fun_view" @click="navTo('/pages/mine/card')">
<image class="mine_fun_view_left" src="/static/icon/ka.png"></image>
<view class="mine_fun_view_name">充电卡</view>
<image class="mine_fun_view_right" src="/static/icon/9you.png" mode="widthFix"></image>
</view>
</view> -->
</view>
<view style="width: 100%; height: 100vh; background: #f7f7f7; position: absolute; top: 0; left: 0; z-index: -1"></view>
<cc-myTabbar :tabBarShow="4"></cc-myTabbar>
<!-- <tabbar path="/pages/mine/mine"></tabbar> -->
</view>
</template>
<script setup>
import { onShow } from '@dcloudio/uni-app';
import { userInfo } from '@/api/api.js';
import { ref } from 'vue';
import { useNav } from '@/hooks/useNav.js';
const { nav, navTo } = useNav();
let info = ref({});
let gridList = ref([
{
name: '我的电卡',
img: '/static/icon/dk_mine.png',
path: '/pages/mine/card',
type: 'nav'
},
{
name: '充电订单',
img: '/static/icon/cd_mine.png',
path: '/pages/order/order',
type: 'switchTab'
},
{
name: '余额明细',
img: '/static/icon/ye_mine.png',
path: '/pages/mine/incomeList',
type: 'nav'
},
{
name: '客服中心',
img: '/static/icon/kf_mine.png',
call: true
}
]);
onShow(async () => {
uni.hideTabBar();
let _res = await userInfo();
info.value = _res;
});
const toEarnings = () => {
uni.navigateTo({
url: './sett'
});
};
</script>
<style lang="scss" scoped>
.mine {
&_header {
@include flex($space: space-between);
&_img {
width: 150rpx;
height: 150rpx;
// border-radius: 50%;
margin-right: 15rpx;
}
&_user {
flex: 1;
view:nth-child(1) {
font-weight: bold;
font-size: 32rpx;
color: #232323;
margin-bottom: 15rpx;
}
view:nth-child(2) {
font-weight: bold;
font-size: 44rpx;
color: #232323;
}
}
&_sett {
width: 42rpx;
height: 42rpx;
}
}
&_money {
margin-top: 35rpx;
@include flex($direction: column);
width: 100%;
// height: 152rpx;
background: linear-gradient(178deg, #9ab6ff 0%, #4879e6 100%);
border-radius: 16rpx 16rpx 16rpx 16rpx;
padding: 20rpx 0rpx 0;
&_top {
padding: 0 150rpx;
}
&_bottom {
width: 100%;
@include flex($space: center);
border-top: 1rpx solid rgba(255, 255, 255, 0.3);
margin-top: 20rpx;
padding: 15rpx 0;
view {
width: 50%;
display: flex;
align-items: center;
justify-content: center;
font-size: 30rpx;
color: #fff;
}
}
&_left {
@include flex($direction: column, $space: center);
view:nth-child(1) {
font-weight: bold;
font-size: 48rpx;
color: #ffffff;
margin-bottom: 5rpx;
}
view:nth-child(2) {
font-weight: bold;
font-size: 20rpx;
color: #ffffff;
}
}
&_right {
@include flex($space: center);
width: 124rpx;
height: 54rpx;
background: rgba(255, 255, 255, 0.24);
border-radius: 140rpx 140rpx 140rpx 140rpx;
font-weight: bold;
font-size: 24rpx;
color: #ffffff;
}
}
&_grid {
width: 100%;
padding: 20rpx 30rpx;
background-color: #fff;
border-radius: 15rpx;
margin-top: 30rpx;
&_tit {
font-size: 30rpx;
color: #333;
opacity: 0.8;
}
&_views {
margin-top: 20rpx;
display: flex;
flex-wrap: wrap;
align-items: center;
justify-content: space-between;
width: 100%;
&_block {
height: 95rpx;
display: flex;
flex-direction: column;
align-items: center;
justify-content: space-between;
font-size: 30rpx;
color: #333;
image {
width: 45rpx;
height: 45rpx;
}
}
}
}
&_fun {
margin-top: 35rpx;
width: 100%;
// background: linear-gradient(180deg, #ffffff 0%, #f7f7f7 100%);
background-color: #fff;
border-radius: 16rpx 16rpx 16rpx 16rpx;
padding: 35rpx;
&_view {
@include flex($space: space-between);
margin-bottom: 35rpx;
&_left {
width: 58rpx;
height: 58rpx;
margin-right: 20rpx;
// background: #eeeeee;
}
&_name {
flex: 1;
font-weight: bold;
font-size: 24rpx;
color: #232323;
}
&_right {
width: 24rpx;
height: 24rpx;
}
}
}
}
</style>

95
pages/mine/sett.vue Normal file
View File

@@ -0,0 +1,95 @@
<template>
<view class="p30">
<view style="background-color: #fff; border-radius: 15rpx">
<up-cell-group :border="false">
<button style="all: unset" open-type="chooseAvatar" @chooseavatar="chooseAvatar">
<up-cell title="头像" :isLink="true" size="min">
<template #value>
<up-avatar :src="info.avatar"></up-avatar>
</template>
</up-cell>
</button>
<up-cell title="昵称" :isLink="true" size="min" @click="upNickName">
<template #value>
<text class="u-slot-value">{{ info.nickName }}</text>
</template>
</up-cell>
<up-cell title="手机号" size="min" :border="false">
<template #value>
<text class="u-slot-value">{{ info.phone || '-' }}</text>
</template>
</up-cell>
</up-cell-group>
</view>
<view style="height: 100rpx"></view>
<up-button type="error" text="退出登录" @click="outLogin"></up-button>
</view>
</template>
<script setup>
import { onShow } from '@dcloudio/uni-app';
import { userInfo, updateNickName, updateAvatar } from '@/api/api.js';
import { ref } from 'vue';
import { uploadFiles } from '@/utils/fun.js';
let info = ref({});
onShow(async () => {
getInfo();
});
const getInfo = async () => {
let _res = await userInfo();
info.value = _res;
};
const chooseAvatar = async (e) => {
let img = await uploadFiles(e.detail.avatarUrl);
updateAvatar({ avatar: img }).then((res) => {
getInfo();
});
console.log(img);
};
const upNickName = () => {
uni.showModal({
title: '修改昵称',
content: info.value.nickName,
editable: true,
success: function (res) {
if (res.confirm) {
updateNickName({ nickName: res.content }).then((res) => {
getInfo();
});
console.log(res);
console.log('用户点击确定');
} else if (res.cancel) {
console.log('用户点击取消');
}
}
});
};
const outLogin = () => {
uni.showModal({
title: '提示',
content: '是否确认退出登录?',
success: (res) => {
if (res.confirm) {
uni.clearStorageSync();
uni.reLaunch({
url: '/pages/home/home'
});
} else if (res.cancel) {
console.log('用户点击取消');
}
}
});
};
</script>
<style>
button::after {
all: unset;
}
</style>

341
pages/money/recharge.vue Normal file
View File

@@ -0,0 +1,341 @@
<template>
<view class="buy">
<view class="title">
<!-- <image src="../../static/image/travel/matching/buy.png"></image> -->
<text class="text">当前余额</text>
<text class="num">{{info.balance}}</text>
</view>
<view class="number">
<view class="list">
<view :class="num == index ? 'item real' : 'item'" v-for="(item, index) in list" :key="index" @click="pick(item, index)">
<view class="card">
<view class="top">
<text>{{ item.number }}</text>
</view>
<!-- <text class="money">{{ item.money }}</text> -->
</view>
</view>
<view :class="num == 'input' ? 'item real' : 'item'" @click="pick('input', 'input')">
<view class="card">
<view class="top" style="padding: 0 15rpx; text-align: center">
<input @change="inputChange" placeholder="其他面额" style="font-weight: bold; color: #666666" v-model="moneyNum" type="number" />
</view>
<!-- <text class="money">{{ item.money }}</text> -->
</view>
</view>
</view>
<view class="tip">
<text class="titl">温馨提示</text>
<view>
<text>1本次充值金额尽可用于充电消费</text>
</view>
<view>
<text>2若充值时若使用了第三方优惠抵扣时,该笔金额不支持直接退款</text>
</view>
</view>
</view>
<view style="position: fixed; bottom: 0; left: 0; width: 750rpx">
<view style="display: flex; align-items: center; justify-content: center; font-size: 26rpx; background-color: rgba(72, 121, 230, 0.3); padding: 15rpx 0">
<up-checkbox shape="circle" name="agree" usedAlone @change="change"></up-checkbox>
我已阅读并同意
<text style="color: #4879e6">云充电用户充值协议</text>
</view>
<view style="display: flex; align-items: center; justify-content: space-between; padding: 20rpx 30rpx">
<view style="font-size: 40rpx; font-weight: bold">
{{ money }}
<text style="font-size: 26rpx; font-weight: 500"></text>
</view>
<view style="width: 220rpx">
<up-button @click="toUp" color="#4879e6" text="充值" shape="circle" :disabled="!aloneChecked"></up-button>
</view>
</view>
</view>
</view>
</template>
<script setup>
import { ref, reactive } from 'vue';
import { jqbPay,userInfo,adaPay } from '@/api/api.js';
import { onShow, onLoad } from '@dcloudio/uni-app';
let info = ref({});
let money = ref(30);
let moneyNum = ref('');
let num = ref(0);
let aloneChecked = ref(false);
let list = ref([
{
number: '¥30',
money: '30'
},
{
number: '¥50',
money: '50'
},
{
number: '¥80',
money: '80'
},
{
number: '¥100',
money: '100'
},
{
number: '¥200',
money: '200'
},
{
number: '¥300',
money: '300'
},
{
number: '¥400',
money: '400'
},
{
number: '¥500',
money: '500'
}
]);
const pick = (item, index) => {
if (item != 'input') {
money.value = item.money;
moneyNum.value = '';
}
num.value = index;
};
const change = (e) => {
aloneChecked.value = e;
console.log(e);
};
const toUp = () => {
adaPay({
amount: money.value
}).then((res) => {
let data = res;
uni.requestPayment({
provider: 'wxpay',
timeStamp: data.timeStamp,
nonceStr: data.nonceStr,
package: data.package,
signType: data.signType,
paySign: data.paySign,
success: function (r) {
uni.showModal({
title: '提示',
content: '充值成功',
showCancel: false,
success: function (res) {
if (res.confirm) {
uni.navigateBack();
} else if (res.cancel) {
console.log('用户点击取消');
}
}
});
},
fail: function (err) {
console.log('fail:' + JSON.stringify(err));
}
});
});
// jqbPay({
// amount: money.value
// }).then((res) => {
// let data = JSON.parse(res.payData);
// uni.requestPayment({
// provider: 'wxpay',
// timeStamp: data.timeStamp,
// nonceStr: data.nonceStr,
// package: data.package,
// signType: data.signType,
// paySign: data.paySign,
// success: function (r) {
// uni.showModal({
// title: '提示',
// content: '充值成功',
// showCancel: false,
// success: function (res) {
// if (res.confirm) {
// uni.navigateBack();
// } else if (res.cancel) {
// console.log('用户点击取消');
// }
// }
// });
// },
// fail: function (err) {
// console.log('fail:' + JSON.stringify(err));
// }
// });
// });
};
onShow(async () => {
let _res = await userInfo();
info.value = _res;
});
const inputChange = (e) => {
money.value = e.detail.value;
};
</script>
<style lang="scss" scoped>
.buy {
width: 100%;
height: 100%;
.title {
display: flex;
align-items: center;
padding: 20rpx 0 20rpx 50rpx;
background-color: #ffffff;
> image {
width: 32rpx;
height: 32rpx;
margin-right: 6rpx;
}
> text {
font-size: 28rpx;
font-family: PingFangSC-Regular, PingFang SC;
font-weight: 400;
color: #666666;
line-height: 40rpx;
}
.num {
color: #ff4141;
}
}
.number {
width: 100%;
background-color: #ffffff;
margin-top: 18rpx;
display: flex;
flex-direction: column;
align-items: center;
.list {
display: flex;
flex-wrap: wrap;
justify-content: space-between;
padding: 38rpx 40rpx 0rpx 40rpx;
.item {
width: 194rpx;
height: 194rpx;
background: #ffffff;
box-shadow: 0rpx 0rpx 6rpx 0rpx rgba(0, 0, 0, 0.1);
border-radius: 20rpx;
margin-bottom: 44rpx;
display: flex;
.card {
width: 194rpx;
height: 194rpx;
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
.top {
display: flex;
align-items: center;
> text {
font-size: 32rpx;
font-family: PingFangSC-Semibold, PingFang SC;
font-weight: 600;
color: #666666;
line-height: 44rpx;
margin-right: 12rpx;
}
> image {
width: 30rpx;
height: 30rpx;
}
}
.money {
font-size: 24rpx;
font-family: PingFangSC-Regular, PingFang SC;
font-weight: 400;
color: #999999;
line-height: 34rpx;
margin-top: 12rpx;
}
}
.recommend {
width: 112rpx;
height: 36rpx;
background: #f3f2ea;
border-radius: 8rpx 0rpx 8rpx 0rpx;
position: absolute;
text-align: center;
margin-top: -18rpx;
> text {
font-size: 20rpx;
font-family: PingFangSC-Medium, PingFang SC;
font-weight: 500;
color: #666666;
line-height: 36rpx;
}
}
}
.real {
border: 2rpx solid #f88700;
background-color: rgba(248, 135, 0, 0.1);
}
&:after {
content: '';
width: 194rpx;
}
}
.sure {
width: 582rpx;
height: 80rpx;
background: #ff6a5f;
border-radius: 40rpx;
text-align: center;
> text {
font-size: 28rpx;
font-family: PingFangSC-Medium, PingFang SC;
font-weight: 600;
color: #ffffff;
line-height: 80rpx;
}
}
}
.tip {
background: #ffffff;
padding: 40rpx;
padding-top: 0;
.titl {
font-size: 28rpx;
font-family: PingFangSC-Medium, PingFang SC;
font-weight: 600;
color: #666666;
line-height: 40rpx;
margin-bottom: 6rpx;
}
> view {
> text {
font-size: 22rpx;
font-family: PingFangSC-Regular, PingFang SC;
color: #999999;
line-height: 32rpx;
}
&:nth-child(2) {
> text:nth-child(2) {
color: #333333;
}
}
&:nth-child(5) {
> text:nth-child(2) {
color: #ff6a5f;
font-weight: 600;
border-bottom: 2rpx solid #ff6a5f;
}
}
}
}
}
</style>

22
pages/order/detail.vue Normal file
View File

@@ -0,0 +1,22 @@
<template>
<view>
<statusBar />
</view>
</template>
<script>
export default {
data() {
return {
}
},
methods: {
}
}
</script>
<style>
</style>

205
pages/order/order.vue Normal file
View File

@@ -0,0 +1,205 @@
<template>
<view class="order">
<z-paging ref="paging" v-model="dataList" use-page-scroll @query="queryList">
<view>
<statusBar />
<view class="p30">
<view class="order_header">
<view
class="order_header_view"
@click="chanStatus(item.type)"
v-for="(item, index) in status_list"
:key="index"
:class="status == item.type ? 'order_header_active' : ''"
>
{{ item.name }}
<view class="order_header_xian" v-if="item.type == status"></view>
</view>
</view>
</view>
</view>
<view class="p30">
<view class="order_list" v-for="(item, index) in dataList" :key="index" @click="toLink(item)">
<view class="order_list_header">订单编号{{ item.orderNo }}</view>
<view class="order_list_view">
<view>充电时间</view>
<view>{{ item.startTime }}</view>
</view>
<view class="order_list_view">
<view>结束时间</view>
<view>{{ item.endTime }}</view>
</view>
<view class="order_list_view">
<view>充电电量</view>
<view>{{ item.useDegree }}</view>
</view>
<view class="order_list_view">
<view>服务费</view>
<view>{{ item.serviceAmount }}</view>
</view>
<view class="order_list_view">
<view>电费</view>
<view>{{ item.electricityAmount }}</view>
</view>
<view class="order_list_view">
<view>预付金额</view>
<view>{{ item.preAmount }}</view>
</view>
<view class="order_list_total">实付金额{{ item.actuallyAmount }}</view>
</view>
</view>
</z-paging>
<view style="height: 180rpx"></view>
<cc-myTabbar :tabBarShow="3"></cc-myTabbar>
<!-- <tabbar path="/pages/order/order"></tabbar> -->
</view>
</template>
<script setup>
import { ref, reactive } from 'vue';
import { onPullDownRefresh, onPageScroll, onReachBottom, onLoad } from '@dcloudio/uni-app';
import { ordersList } from '@/api/api.js';
const paging = ref(null);
let dataList = ref([]);
let list = ref([]);
let status = ref(1);
let status_list = ref([
{
name: '全部',
type: ''
},
{
name: '进行中',
type: 1
},
{
name: '已完成',
type: 2
},
{
name: '待支付',
type: 3
}
]);
let chanStatus = (e) => {
status.value = e;
paging.value.reload();
};
onLoad(async () => {
// #ifndef MP-WEIXIN
uni.hideTabBar();
// #endif
});
let toLink = (e) => {
// 1-订单初始化;2-启动充电中;3-正在充电;4-充电结束中;5:交易记录确认;-1-启动失败;-2-启动超时
if (e.status == 2 || e.status == 3 || e.status == 4) {
uni.navigateTo({
url: `/pageOrder/recharge/recharge?transactionNo=${e.transactionNo}&type=order`
});
}
};
let isPagingRefNotFound = () => {
return !paging.value;
};
onPullDownRefresh(() => {
if (isPagingRefNotFound()) return;
paging.value.reload().catch(() => {});
});
onPageScroll((e) => {
if (isPagingRefNotFound()) return;
paging.value.updatePageScrollTop(e.scrollTop);
e.scrollTop < 10 && paging.value.doChatRecordLoadMore();
});
onReachBottom(() => {
if (isPagingRefNotFound()) return;
paging.value.pageReachBottom();
});
const upChange = (e) => {
console.log(dataFrom);
paging.value.reload();
};
const queryList = (pageNo, pageSize) => {
const params = {
current: pageNo,
pageSize: pageSize,
type: status.value
};
ordersList(params)
.then((res) => {
paging.value.complete(res);
})
.catch((res) => {
paging.value.complete(false);
});
};
</script>
<style lang="scss" scoped>
.order {
&_header {
@include flex($space: space-between);
font-weight: bold;
font-size: 36rpx;
color: #232323;
border-bottom: 4rpx solid #e9ecf2;
&_view {
padding: 15rpx 0;
position: relative;
view {
position: absolute;
left: calc(50% - 49rpx);
bottom: -4rpx;
width: 98rpx;
height: 8rpx;
background: #4879e6;
border-radius: 8rpx 8rpx 8rpx 8rpx;
}
}
&_active {
color: #4879e6;
}
}
&_list {
padding: 25rpx;
background: #ffffff;
border-radius: 8rpx 8rpx 8rpx 8rpx;
margin-top: 30rpx;
&_header {
font-weight: bold;
font-size: 26rpx;
color: #4879e6;
padding-bottom: 20rpx;
border-bottom: 2rpx solid #ebebeb;
margin-bottom: 20rpx;
}
&_view {
@include flex($space: space-between);
font-weight: 400;
font-size: 26rpx;
color: #232323;
margin-bottom: 20rpx;
}
&_total {
flex: 1;
text-align: right;
font-weight: bold;
font-size: 40rpx;
color: #4879e6;
}
}
}
</style>

132
pages/sweep/sweep.vue Normal file
View File

@@ -0,0 +1,132 @@
<template>
<view class="sweep">
<statusBar />
<view class="sweep_note">
<view class="sweep_note_view">
<view class="sweep_note_view_img">
<image src="/static/image/djk.png" mode="widthFix"></image>
</view>
<view>插上</view>
<view>充电枪</view>
</view>
<view class="sweep_note_view">
<view class="sweep_note_view_img">
<image src="/static/image/djs.png" mode="widthFix"></image>
</view>
<view>点击</view>
<view>扫码充电</view>
</view>
<view class="sweep_note_view">
<view class="sweep_note_view_img">
<image src="/static/image/cs.png" mode="widthFix"></image>
</view>
<view>点击</view>
<view>开始充电</view>
</view>
</view>
<view class="sweep_scan" style="margin-top: 300rpx">
<up-input placeholder="请输入充电枪编号" type="number" border="surround" v-model="value"></up-input>
<view style="width: 100rpx">
<up-button type="primary" text="确定" @click="toCd"></up-button>
</view>
</view>
<view class="sweep_scan" style="margin-top: 150rpx">
<up-button @click="scan" type="primary" shape="circle" text="扫码充电"></up-button>
</view>
<cc-myTabbar :tabBarShow="2"></cc-myTabbar>
<!-- <tabbar path="/pages/sweep/sweep" /> -->
</view>
</template>
<script setup>
import { ref, reactive } from 'vue';
import { onLoad } from '@dcloudio/uni-app';
import { useNav } from '@/hooks/useNav.js';
import { urlQuery } from '@/utils/fun.js';
const { nav, navTo } = useNav();
let value = ref('');
onLoad(() => {
// #ifndef MP-WEIXIN
uni.hideTabBar();
// #endif
});
const scan = async () => {
uni.scanCode({
success: function (res) {
let query = urlQuery(res.result);
if (!query.num) {
uni.showToast({
title: '请扫描正确的设备码',
icon: 'none'
});
} else {
navTo(`/pages/home/star?id=${query.num}`);
}
// navTo(`/pages/home/star?id=${res.result}`);
}
});
};
const toCd = async () => {
if (!value.value) {
uni.showToast({
title: '请输入枪号',
icon: 'none'
});
return;
}
navTo(`/pages/home/star?id=${value.value}`);
};
</script>
<style scoped lang="scss">
.sweep {
&_note {
padding: 0 60rpx;
@include flex($space: space-between);
&_view {
@include flex($direction: column, $space: center);
font-weight: 800;
font-size: 32rpx;
color: #4879e6;
&_img {
display: flex;
align-items: flex-end;
height: 115rpx;
margin-bottom: 30rpx;
}
}
&_view:nth-child(1) {
image {
width: 151rpx;
height: 99rpx;
}
}
&_view:nth-child(2) {
image {
width: 120rpx;
height: 99rpx;
}
}
&_view:nth-child(3) {
image {
width: 106rpx;
height: 113rpx;
}
}
}
&_scan {
@include flex;
padding: 0 120rpx;
}
}
</style>

115
request/index.js Normal file
View File

@@ -0,0 +1,115 @@
import config from '@/config'
import {
toast
} from '@/uni_modules/uview-plus'
export const http = (url, params, method) => {
return new Promise((resolve, reject) => {
let Authorization = uni.getStorageSync('token') || ''
let version = uni.getStorageSync('version') || uni.getSystemInfoSync()
if (!uni.getStorageSync('version')) uni.setStorageSync('version', version);
let {
deviceId,
deviceBrand,
deviceModel,
osVersion,
} = version
let header = {
deviceId,
deviceBrand,
deviceModel,
osVersion,
platform: 1,
Authorization
}
uni.request({
url: config.baseUrl + url,
data: params || {},
method: method || 'POST',
header: header,
success: (res) => {
// uni.hideLoading()
if (res.statusCode == 401) {
uni.removeStorageSync('token');
uni.removeStorageSync('user');
uni.hideLoading()
uni.showModal({
title: '提示',
content: '为提供更好的服务,请前往登录',
success: (res) => {
if (res.confirm) {
uni.navigateTo({
url: '/pages/login/login'
})
} else if (res.cancel) {
console.log('用户点击取消');
}
}
})
return
}
const data = res.data
if (data.code == 10 && !data.success) {
reject(data)
return
}
if (data.code !== 1 && !data.success) {
toast(data.msg)
reject(data)
return
}
resolve(data.data || null)
},
fail: (err) => {
if (err.statusCode == 401) {
uni.removeStorageSync('token');
uni.removeStorageSync('user');
uni.hideLoading()
uni.showModal({
title: '提示',
content: '为提供更好的服务,请前往登录',
success: (res) => {
if (res.confirm) {
uni.navigateTo({
url: '/pages/login/login'
})
} else if (res.cancel) {
console.log('用户点击取消');
}
}
})
return
}
const data = err.data
if (data.code !== 1 && !data.success) {
toast(data.msg)
reject(data)
return
}
uni.hideLoading()
reject(err)
}
})
});
};
// import {requestInterceptors,responseInterceptors} from './interceptors.js'
// // 引入luch-request
// import { http } from '@/uni_modules/uview-plus'
// // 初始化请求配置
// const initRequest=(vm)=>{
// http.setConfig((defaultConfig) => {
// /* defaultConfig 为默认全局配置 */
// defaultConfig.baseURL = config.baseUrl /* 根域名 */
// return defaultConfig
// })
// requestInterceptors()
// responseInterceptors()
// }
// export {
// initRequest
// }

BIN
static/address.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.2 KiB

BIN
static/all.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.2 KiB

BIN
static/gps.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.1 KiB

BIN
static/icon/9you.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 304 B

BIN
static/icon/b1.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.4 KiB

BIN
static/icon/b2.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 11 KiB

BIN
static/icon/cd.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.3 KiB

BIN
static/icon/cd_mine.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.7 KiB

BIN
static/icon/copy.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.7 KiB

BIN
static/icon/dati.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 12 KiB

BIN
static/icon/dd.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.3 KiB

BIN
static/icon/dk_mine.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.6 KiB

BIN
static/icon/dw.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 853 B

BIN
static/icon/ic-copy1.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 275 B

BIN
static/icon/ka.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.5 KiB

BIN
static/icon/kc.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.2 KiB

BIN
static/icon/kf.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.3 KiB

BIN
static/icon/kf_mine.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.4 KiB

BIN
static/icon/kj.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.8 KiB

BIN
static/icon/kp.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.0 KiB

BIN
static/icon/lie1.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.9 KiB

BIN
static/icon/lie2.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 929 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 KiB

BIN
static/icon/mc.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.0 KiB

BIN
static/icon/search.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.4 KiB

BIN
static/icon/sett.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 KiB

BIN
static/icon/tc.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.5 KiB

BIN
static/icon/xai.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 396 B

BIN
static/icon/ye_mine.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.4 KiB

BIN
static/image/cs.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.0 KiB

BIN
static/image/djk.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.1 KiB

BIN
static/image/djs.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.9 KiB

BIN
static/image/login26_bg.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 24 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 20 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 33 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 49 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 57 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 430 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 598 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 544 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.7 KiB

BIN
static/logo.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.9 KiB

BIN
static/tabbar/find.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.7 KiB

BIN
static/tabbar/home.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.0 KiB

BIN
static/tabbar/my.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.7 KiB

BIN
static/tabbar/news.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.6 KiB

BIN
static/tabbar/order.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.0 KiB

Some files were not shown because too many files have changed in this diff Show More