This commit is contained in:
cjb 2025-01-09 17:24:18 +08:00
commit 1910d111de
52 changed files with 12050 additions and 0 deletions

21
.gitignore vendored Normal file
View File

@ -0,0 +1,21 @@
# Logs
logs
*.log
npm-debug.log*
yarn-debug.log*
yarn-error.log*
pnpm-debug.log*
lerna-debug.log*
node_modules
.DS_Store
dist
*.local
# Editor directories and files
.idea
*.suo
*.ntvs*
*.njsproj
*.sln
*.sw?

20
index.html Normal file
View File

@ -0,0 +1,20 @@
<!DOCTYPE html>
<html>
<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="/src/main.ts"></script>
</body>
</html>

73
package.json Normal file
View File

@ -0,0 +1,73 @@
{
"name": "uni-preset-vue",
"version": "0.0.0",
"scripts": {
"dev:custom": "uni -p",
"dev:h5": "uni",
"dev:h5:ssr": "uni --ssr",
"dev:mp-alipay": "uni -p mp-alipay",
"dev:mp-baidu": "uni -p mp-baidu",
"dev:mp-jd": "uni -p mp-jd",
"dev:mp-kuaishou": "uni -p mp-kuaishou",
"dev:mp-lark": "uni -p mp-lark",
"dev:mp-qq": "uni -p mp-qq",
"dev:mp-toutiao": "uni -p mp-toutiao",
"dev:mp-weixin": "uni -p mp-weixin",
"dev:mp-xhs": "uni -p mp-xhs",
"dev:quickapp-webview": "uni -p quickapp-webview",
"dev:quickapp-webview-huawei": "uni -p quickapp-webview-huawei",
"dev:quickapp-webview-union": "uni -p quickapp-webview-union",
"build:custom": "uni build -p",
"build:h5": "uni build",
"build:h5:ssr": "uni build --ssr",
"build:mp-alipay": "uni build -p mp-alipay",
"build:mp-baidu": "uni build -p mp-baidu",
"build:mp-jd": "uni build -p mp-jd",
"build:mp-kuaishou": "uni build -p mp-kuaishou",
"build:mp-lark": "uni build -p mp-lark",
"build:mp-qq": "uni build -p mp-qq",
"build:mp-toutiao": "uni build -p mp-toutiao",
"build:mp-weixin": "uni build -p mp-weixin",
"build:mp-xhs": "uni build -p mp-xhs",
"build:quickapp-webview": "uni build -p quickapp-webview",
"build:quickapp-webview-huawei": "uni build -p quickapp-webview-huawei",
"build:quickapp-webview-union": "uni build -p quickapp-webview-union",
"type-check": "vue-tsc --noEmit"
},
"dependencies": {
"@dcloudio/uni-app": "3.0.0-4030620241128001",
"@dcloudio/uni-app-harmony": "3.0.0-4030620241128001",
"@dcloudio/uni-app-plus": "3.0.0-4030620241128001",
"@dcloudio/uni-components": "3.0.0-4030620241128001",
"@dcloudio/uni-h5": "3.0.0-4030620241128001",
"@dcloudio/uni-mp-alipay": "3.0.0-4030620241128001",
"@dcloudio/uni-mp-baidu": "3.0.0-4030620241128001",
"@dcloudio/uni-mp-jd": "3.0.0-4030620241128001",
"@dcloudio/uni-mp-kuaishou": "3.0.0-4030620241128001",
"@dcloudio/uni-mp-lark": "3.0.0-4030620241128001",
"@dcloudio/uni-mp-qq": "3.0.0-4030620241128001",
"@dcloudio/uni-mp-toutiao": "3.0.0-4030620241128001",
"@dcloudio/uni-mp-weixin": "3.0.0-4030620241128001",
"@dcloudio/uni-mp-xhs": "3.0.0-4030620241128001",
"@dcloudio/uni-quickapp-webview": "3.0.0-4030620241128001",
"clipboard": "^2.0.11",
"dayjs": "^1.11.13",
"uview-plus": "^3.3.54",
"vue": "^3.4.21",
"vue-i18n": "^9.1.9"
},
"devDependencies": {
"@dcloudio/types": "^3.4.8",
"@dcloudio/uni-automator": "3.0.0-4030620241128001",
"@dcloudio/uni-cli-shared": "3.0.0-4030620241128001",
"@dcloudio/uni-stacktracey": "3.0.0-4030620241128001",
"@dcloudio/vite-plugin-uni": "3.0.0-4030620241128001",
"@vue/runtime-core": "^3.4.21",
"@vue/tsconfig": "^0.1.3",
"sass": "1.63.2",
"sass-loader": "10.4.1",
"typescript": "^4.9.4",
"vite": "5.2.8",
"vue-tsc": "^1.0.24"
}
}

8376
pnpm-lock.yaml Normal file

File diff suppressed because it is too large Load Diff

10
shims-uni.d.ts vendored Normal file
View File

@ -0,0 +1,10 @@
/// <reference types='@dcloudio/types' />
import 'vue'
declare module '@vue/runtime-core' {
type Hooks = App.AppInstance & Page.PageInstance;
interface ComponentCustomOptions extends Hooks {
}
}

15
src/App.vue Normal file
View File

@ -0,0 +1,15 @@
<script setup lang="ts">
import { onLaunch, onShow, onHide} from "@dcloudio/uni-app"
onLaunch(() => {
console.log("App Launch");
});
onShow(() => {
console.log("App Show");
});
onHide(() => {
console.log("App Hide");
});
</script>
<style lang="scss">
@import "uview-plus/index.scss";
</style>

38
src/codePages/index.vue Normal file
View File

@ -0,0 +1,38 @@
<template>
<up-navbar
title="扫码换电"
bgColor="#00aa7f"
:autoBack="true"
leftIconColor="#00aa7f"
titleStyle="color:#fff"
:placeholder="true"
/>
<view>扫码换电</view>
<!-- <view>{{JSON.stringify(code)}}</view> -->
</template>
<script setup lang="ts">
import { ref } from 'vue'
import { BarHeight } from '@/utils/commen'
import { onTabItemTap } from '@dcloudio/uni-app'
// let code = ref<any>('')
// onTabItemTap(() => {
// uni.scanCode({
// success(res){
// code.value = res
// console.log('' + res.scanType);
// console.log('' + res.result);
// },
// fail() {
// uni.switchTab({
// url: '/pages/home/index'
// })
// }
// })
// })
</script>
<style>
</style>

8
src/env.d.ts vendored Normal file
View File

@ -0,0 +1,8 @@
/// <reference types="vite/client" />
declare module '*.vue' {
import { DefineComponent } from 'vue'
// eslint-disable-next-line @typescript-eslint/no-explicit-any, @typescript-eslint/ban-types
const component: DefineComponent<{}, {}, any>
export default component
}

View File

@ -0,0 +1,51 @@
<template>
<up-navbar
title="伊特换电协议"
bgColor="#00aa7f"
:autoBack="true"
leftIconColor="#fff"
titleStyle="color:#fff"
/>
<view style="padding: 20rpx;">版本更新日期2024年04月01日
版本生效日期2024年04月01日
蜜雪冰城股份有限公司及其关联公司主要包括蜜雪冰城股份有限公司郑州宝岛科技有限公司以下简称蜜雪冰城我们非常注重保护用户以下或称的个人信息及隐私我们深知个人信息对您的重要性并将按照法律法规要求和业界成熟的安全标准采取相应的安全保护措施来保护您的个人信息我们希望通过本蜜雪冰城用户隐私政策以下简称本隐私政策向您清晰地介绍在您访问蜜雪冰城App和蜜雪冰城手机点餐微信支付宝小程序以下合称应用以及我们通过其他方式向您提供服务时我们如何收集使用保存共享和转让这些信息以及我们为您提供的访问更新删除和保护这些信息的方式
本隐私政策将帮助您了解以下内容
1我们如何收集和使用您的个人信息
2我们如何使用Cookie和同类技术
3我们如何共享转让公开披露您的个人信息
4我们如何保存和保护您的个人信息
5您如何管理您的个人信息
6未成年人的个人信息保护
7通知和修订
8如何联系我们
9附录
特别提示请您在使用我们提供的各项服务前仔细阅读并充分理解本隐私政策重点内容我们以黑体加粗或加下划线的形式提示您重点注意并作出相应选择一旦您选择使用或继续使用我们的服务即意味着您同意我们按照本隐私政策处理您的相关信息如对本隐私政策有任何疑问您可以通过本隐私政策如何联系我们中提供的方式与我们联系
请您注意不同应用的功能可能存在一定的差异具体以您实际使用的功能为准此外针对某些特定的服务我们还将制定单独的隐私政策向您说明这些服务的特殊政策如相关特定的隐私政策与本隐私政策有不一致之处适用相关特定隐私政策</view>
</template>
<script>
</script>
<style>
</style>

View File

@ -0,0 +1,411 @@
<template>
<up-navbar
title="预约"
bgColor="#00aa7f"
:autoBack="true"
leftIconColor="#fff"
titleStyle="color:#fff"
:placeholder="true"
/>
<view style="padding: 30rpx;">
<!-- 注意如果需要兼容微信小程序最好通过setRules方法设置rules规则 -->
<up-form
labelPosition="left"
labelWidth="100"
:model="formdata"
:rules="rules"
ref="uFormRef"
>
<up-form-item
label="姓名"
prop="uname"
borderBottom
>
<up-input v-model="formdata.uname" border="none" placeholder="请输入姓名" clearable />
</up-form-item>
<up-form-item
label="手机号"
prop="phone"
borderBottom
>
<!-- <view v-if="nuindex == 1" style="display: flex;justify-content: space-between;align-items: center;padding-top: 12rpx;">
<up-input maxlength="11" v-model="formdata.phone" readonly border="none" placeholder="请输入手机号" />
<view @tap="sjhshow = true" style="color: #12a018;">修改</view>
</view> -->
<view style="display: flex;justify-content: space-between;">
<button
@tap="actnub(1)"
:class="{actnub:nuindex == 1}"
style="width: 280rpx;font-size: 26rpx;"
open-type="getPhoneNumber"
@getphonenumber="onGetPhoneNumber"
>获取微信手机号</button>
<button :class="{actnub:nuindex == 2}" style="width: 180rpx;font-size: 26rpx;" @tap="actnub(2)">手动输入</button>
</view>
<view v-if="nuindex == 1" style="display: flex;justify-content: space-between;align-items: center;padding-top: 12rpx;">
<up-input maxlength="11" v-model="formdata.phone" readonly border="none" placeholder="请输入手机号" clearable />
</view>
<view v-else-if="nuindex == 2" style="display: flex;justify-content: space-between;align-items: center;padding-top: 12rpx;">
<up-input type="number" maxlength="11" v-model="formdata.phone" border="none" placeholder="请输入手机号" clearable />
<view>获取验证码</view>
</view>
</up-form-item>
<up-form-item
label="车牌号"
prop="plateNum"
borderBottom
>
<up-input v-model="formdata.plateNum" border="none" readonly placeholder="请选择车牌号" suffixIcon="arrow-down" suffixIconStyle="color: #bababa" @tap="cphand" />
</up-form-item>
<up-form-item
label="换电站"
prop="stationName"
borderBottom
>
<up-input v-model="formdata.stationName" readonly border="none" placeholder="请选择换电站" suffixIcon="arrow-down" suffixIconStyle="color: #bababa" @tap="hdzhand" />
</up-form-item>
<up-form-item
label="预约日期"
prop="swapDay"
borderBottom
>
<up-input v-model="formdata.swapDay" readonly border="none" placeholder="请选择预约日期" suffixIcon="arrow-down" suffixIconStyle="color: #bababa" @tap="datehand" />
</up-form-item>
<up-form-item
label="时间段"
prop="swapDuration"
borderBottom
>
<up-input v-model="formdata.swapDuration" readonly border="none" placeholder="请选择时间段" suffixIcon="arrow-down" suffixIconStyle="color: #bababa" @tap="timehand" />
</up-form-item>
<up-button style="margin-top: 100rpx;" type="success" @tap="submit">提交</up-button>
</up-form>
<!--车牌-->
<up-picker
:show="cpshow"
:columns="cpcolumns"
keyName="plateNum"
@confirm="cpconfirm"
@cancel="cpcancel"
/>
<!--换电站-->
<up-picker
:show="hdzshow"
:columns="hdzcolumns"
:defaultIndex="indexarr"
keyName="label"
@confirm="hdzconfirm"
@cancel="hdzcancel"
/>
<!--日期-->
<up-calendar
:show="dateshow"
mode="single"
color="#00aa7f"
@confirm="dateconfirm"
@close="dateclose"
/>
<!--时间段-->
<up-picker
:show="timeshow"
:columns="timecolumns"
@confirm="timeconfirm"
@cancel="timecancel"
/>
<!--修改手机号-->
<!-- <up-popup
:show="sjhshow"
mode="center"
:closeOnClickOverlay="true"
>
<view style="box-sizing: border-box;width:85%;padding: 20rpx;background: #fff;">
<view style="display: flex;justify-content: space-between;">
<button
@tap="actnub(1)"
:class="{actnub:nuindex == 1}"
style="width: 280rpx;font-size: 26rpx;"
open-type="getPhoneNumber"
@getphonenumber="onGetPhoneNumber"
>获取微信手机号</button>
<button :class="{actnub:nuindex == 2}" style="width: 180rpx;font-size: 26rpx;" @tap="actnub(2)">手动输入</button>
</view>
<view v-if="nuindex == 1" style="display: flex;justify-content: space-between;align-items: center;padding-top: 12rpx;">
<up-input maxlength="11" v-model="formdata.phone" readonly border="none" placeholder="请输入手机号" clearable />
</view>
<view v-else-if="nuindex == 2" style="display: flex;justify-content: space-between;align-items: center;padding-top: 12rpx;">
<up-input type="number" maxlength="11" v-model="formdata.phone" border="none" placeholder="请输入手机号" clearable />
<view>获取验证码</view>
</view>
</view>
</up-popup> -->
</view>
</template>
<script setup lang="ts">
import { ref, reactive } from 'vue'
import { addrese,gethdz,getphone,carlist } from '@/utils/service'
import { onLoad } from '@dcloudio/uni-app'
//
let cpcolumns = ref<any[]>([])
carlist(uni.getStorageSync('wxuid')).then((rps:any) => {
if(rps.data && rps.data.length > 0){
cpcolumns.value.push(rps.data)
}
})
//const phoneNumber = uni.getStorageSync('PhoneNumber')
//
let sjhshow = ref(false)
let nuindex = ref(0)
function actnub(n:number) {
nuindex.value = n
}
function onGetPhoneNumber(v:any) {
getphone({
wuid:uni.getStorageSync('wxuid'),
code:v.detail.code
}).then((rps:any) => {
formdata.phone = rps.data
uni.setStorageSync('PhoneNumber', rps.data)
})
}
let formdata = reactive({
source:'1', //1-2-3-
ucode:uni.getStorageSync('wxuid'), //
uname:'', //
phone:'', //
plateNum:'', //
stationCode:'', //
stationName:'', //
swapDay:'', //,(yyyyMMdd)
//reservationTime:'', //
swapDuration:'' //,(8:00-10:00)
})
let hdzcode = ref('')
onLoad((opt:any) => {
hdzcode.value = opt.hdzcode
if(opt.phoneNumber){
formdata.phone = opt.phoneNumber
nuindex.value = 1
}
//formdata.stationCode = hdzcode.value?hdzcode.value:''
})
const rules = {
uname: {
type: 'string',
required: true,
message: '请输入姓名',
trigger: ['blur', 'change'],
},
phone: {
type: 'string',
required: true,
message: '请输入手机号',
trigger: ['blur', 'change'],
},
plateNum:[
{
type: 'string',
required: true,
message: '请选择车牌号',
trigger: ['blur', 'change'],
},
{
//
validator: (rule:any, value:any) => {
const regExp = new RegExp(/^[京津沪渝冀豫云辽黑湘皖鲁新苏浙赣鄂桂甘晋蒙陕吉闽贵粤青藏川宁琼使领A-Z]{1}[A-Z]{1}(([0-9]{5}[DF])|([DF][A-HJ-NP-Z0-9][0-9]{4}))$/)
if (regExp.test(value)) {
return true
}
return false
},
message: '车牌号格式不对',
// blurchange
trigger: ['change','blur'],
}
],
stationName:{
type: 'string',
required: true,
message: '请选择换电站',
trigger: ['blur', 'change'],
},
swapDay:{
type: 'string',
required: true,
message: '请选择预约日期',
trigger: ['blur', 'change'],
}
}
//
let cpshow = ref(false)
function cphand() {
cpshow.value = true
}
let indexarr = ref<any[]>([])
let hdzcolumns = ref<any[]>([])
let ishdz = ref(false)
function cpconfirm(v:any) {
cpshow.value = false
formdata.plateNum = v.value[0].plateNum
//
gethdz({
plateNum:formdata.plateNum
}).then((rps:any) => {
ishdz.value = true
let arr:any[] = rps.data.map((n:any,i:any) => {
if(hdzcode.value == n.code){
indexarr.value = [i]
}
return {
name:n.name,
code:n.code,
label:`${n.name}${n.isSuitable?'':'(不支持)'}`,
isSuitable:n.isSuitable
}
})
hdzcolumns.value.push(arr)
//isSuitable
})
}
function cpcancel() {
cpshow.value = false
}
//
let hdzshow = ref(false)
function hdzhand() {
if(ishdz.value){
hdzshow.value = true
}else{
uni.showToast({
title: '请先选择车牌号',
duration: 2000,
icon:'none'
})
}
}
function hdzconfirm(v:any) {
if(v.value[0].isSuitable){
formdata.stationName = v.value[0].name
formdata.stationCode = v.value[0].code
hdzshow.value = false
}else{
uni.showToast({
title: '不支持此车型',
duration: 2000,
icon:'none'
})
}
}
function hdzcancel() {
hdzshow.value = false
}
//
let timeshow = ref(false)
function timehand() {
timeshow.value = true
}
const timecolumns = ref([
[
'8:00 - 9:00',
'9:00 - 10:00',
'10:00 - 11:00',
'11:00 - 12:00',
'12:00 - 13:00',
'13:00 - 14:00',
'14:00 - 15:00'
]
])
function timeconfirm(v:any) {
formdata.swapDuration = v.value[0]
timeshow.value = false
}
function timecancel() {
timeshow.value = false
}
//
let dateshow = ref(false)
function datehand() {
dateshow.value = true
}
function dateconfirm(v:any) {
formdata.swapDay = v[0]
dateshow.value = false
}
function dateclose() {
dateshow.value = false
}
//
const uFormRef = ref(null)
function submit() {
(uFormRef as any).value.validate().then((valid:any) => {
if(valid){
formdata.swapDay = formdata.swapDay.replaceAll('-','')
//formdata.phone = formdata.phone+''
addrese(formdata).then(() => {
uni.showToast({
title: '预约成功',
duration: 2000
})
setTimeout(() => {
uni.navigateBack()
},2000)
})
}
}).catch(() => {
//
})
}
</script>
<style lang="scss" scoped>
page{
background: #f4f4f4;
}
.content{
margin: 30rpx 20rpx;
padding: 50rpx 20rpx;
border-radius: 20rpx;
background: #fff;
.weidu{
}
.avatar {
width: 130rpx;
height: 130rpx;
padding: 0;
border-radius: 50%;
.img{
width: 100%;
height: 100%;
}
}
}
.actnub{
background: #bcca32;
color: #fff;
}
</style>

12
src/main.ts Normal file
View File

@ -0,0 +1,12 @@
import { createSSRApp } from 'vue'
import uviewPlus from 'uview-plus'
import App from './App.vue'
export function createApp() {
const app = createSSRApp(App)
app.use(uviewPlus)
return {
app,
};
}

85
src/manifest.json Normal file
View File

@ -0,0 +1,85 @@
{
"name" : "换电站",
"appid" : "__UNI__3DDD224",
"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" : "wx2ab384cf1e6f85a1",
"setting" : {
"urlCheck" : false,
"postcss" : true,
"es6" : true,
"minified" : true
},
"usingComponents" : true,
"permission" : {
"scope.userLocation" : {
"desc" : "获取周边换电站"
},
"requiredPrivateInfos": ["getLocation"]
},
"unipush" : {
"enable" : false
},
"mergeVirtualHostAttributes" : true
},
"mp-alipay" : {
"usingComponents" : true
},
"mp-baidu" : {
"usingComponents" : true
},
"mp-toutiao" : {
"usingComponents" : true
},
"uniStatistics" : {
"enable" : false
},
"vueVersion" : "3"
}

View File

@ -0,0 +1,44 @@
<template>
<up-navbar
title="关于我们"
bgColor="#00aa7f"
:autoBack="true"
leftIconColor="#fff"
titleStyle="color:#fff"
:placeholder="true"
/>
<view @tap="agreepage('/minePages/agreement/index?type=1')" class="gnrk" style="border-bottom: 1px solid #f4f4f4;">
<view>服务条款</view>
<up-icon name="arrow-right" color="#b9b9b9" />
</view>
<view @tap="agreepage('/minePages/agreement/index?type=2')" class="gnrk">
<view>隐私协议</view>
<up-icon name="arrow-right" color="#b9b9b9" />
</view>
</template>
<script setup lang="ts">
import { ref,reactive } from 'vue'
import { orderlist,dzbzxq } from '@/utils/service'
function agreepage(url:string){
uni.navigateTo({
url
})
}
</script>
<style lang="scss">
page{
background: #f4f4f4;
}
.gnrk{
display: flex;
padding: 25rpx;
justify-content: space-between;
background: #fff;
}
</style>

View File

@ -0,0 +1,108 @@
<template>
<up-navbar
title="我的钱包"
bgColor="#00aa7f"
:autoBack="true"
leftIconColor="#fff"
titleStyle="color:#fff"
:placeholder="true"
/>
<view class="content">
<view class="jiner">
<view class="num">
<view>余额</view>
<view><text style="font-size: 50rpx;">99.00</text> </view>
</view>
<view class="ctbn" @tap="topage('/minePages/recharge/index')">充值</view>
</view>
<view class="mingxi">
<view class="tit">余额明细</view>
<view>
<view class="mxitem">
<view>
<view style="padding-bottom: 8rpx;font-size: 40rpx;color: #00aa00;">充值</view>
<view style="font-size: 30rpx;color: #ccc;">2024-12-20 11:20:00</view>
</view>
<view style="text-align: right;">
<view style="padding-bottom: 8rpx;font-size: 40rpx;color: #00aa00;">+<text>100</text></view>
<view style="font-size: 30rpx;color: #ccc;">实际到账金额100</view>
</view>
</view>
<view class="mxitem">
<view>
<view style="padding-bottom: 8rpx;font-size: 40rpx;">换电</view>
<view style="font-size: 30rpx;color: #ccc;">2024-10-20 11:20:00</view>
</view>
<view style="text-align: right;">
<view style="padding-bottom: 8rpx;font-size: 40rpx;">-<text>20</text></view>
<view style="font-size: 30rpx;color: #ccc;">实际消费10</view>
</view>
</view>
</view>
</view>
</view>
</template>
<script setup lang="ts">
import {ref} from 'vue'
import { onReachBottom } from '@dcloudio/uni-app'
onReachBottom(() => {
})
function topage(url:string) {
uni.navigateTo({
url
})
}
</script>
<style lang="scss">
page{
background: #f4f4f4;
}
.content{
padding: 30rpx 20rpx;
.jiner{
display: flex;
padding: 28rpx;
align-items: center;
justify-content: space-between;
border-radius: 20rpx;
background: #00aa00;
.num{
color: #fff;
}
.ctbn{
width: 120rpx;
height: 60rpx;
line-height: 60rpx;
text-align: center;
color: #00aa00;
background: #fff;
border-radius: 10rpx;
}
}
.mingxi{
background: #fff;
margin-top: 30rpx;
padding: 25rpx;
border-radius: 10rpx;
.tit{
margin-bottom: 25rpx;
padding-left: 16rpx;
border-left: 4px solid #00aa00;
}
.mxitem{
display: flex;
justify-content: space-between;
margin-bottom: 30rpx;
padding-top: 20rpx;
border-top: 1px dashed #ccc;
>view{
width: 50%;
}
}
}
}
</style>

View File

@ -0,0 +1,46 @@
<template>
<up-navbar
title="伊特换电"
bgColor="#00aa7f"
:autoBack="true"
leftIconColor="#fff"
titleStyle="color:#fff"
:placeholder="true"
/>
<view style="padding: 25rpx 25rpx 50rpx;">
<view style="padding-bottom: 30rpx;font-size: 40rpx;font-weight: bold;text-align: center;">{{xyobj.title}}</view>
<up-parse :content="decodeURIComponent(xyobj.content)"></up-parse>
</view>
</template>
<script setup lang="ts">
import { ref,reactive } from 'vue'
import { agreement } from '@/utils/service'
import { onLoad } from '@dcloudio/uni-app'
let xyobj = ref<any>({})
onLoad((opt:any) => {
agreement({
appid:'wx2ab384cf1e6f85a1', //uni.getStorageSync('wxuid'),
type:opt.type
}).then((rps:any) => {
xyobj.value = rps.data[0]
})
})
</script>
<style lang="scss">
page{
background: #f4f4f4;
}
.gnrk{
display: flex;
padding: 25rpx;
justify-content: space-between;
background: #fff;
}
</style>

View File

@ -0,0 +1,214 @@
<template>
<up-navbar
title="我的订单"
bgColor="#00aa7f"
:autoBack="true"
leftIconColor="#fff"
titleStyle="color:#fff"
:placeholder="true"
/>
<view class="content">
<view class="tabct">
<up-tabs
:list="statelist"
:scrollable="false"
@click="tabshand"
lineColor="#00aa00"
/>
</view>
<view class="lisct">
<view v-for="n in list" :key="n.orderNo" class="list">
<view class="zoddu">
<view>
<view>订单号</view>
<view style="font-size: 28rpx;">{{n.orderNo}}</view>
</view>
<view>
<view>车牌号</view>
<view>{{n.plateNum}}</view>
</view>
<view>
<view>换电站</view>
<view>{{n.stationName}}</view>
</view>
<view v-if="n.status == 6 || n.status == 7">
<view>订单金额</view>
<view>{{n.amount}}</view>
</view>
<view>
<view>订单状态</view>
<view>{{dsta(n.status)}}</view>
</view>
<view>
<view style="color: #5f5f5f;">{{n.orderTime}}</view>
<view style="color: #009688;" @tap="getbz(n.orderNo)">查看换电详情</view>
</view>
</view>
<view v-if="n.status == 6" class="qxyy" @tap="topay(`/minePages/payment/index?orderNo=${n.orderNo}&amount=${n.amount}`)">去支付</view>
</view>
</view>
<up-empty v-if="list.length == 0" mode="list" text="暂无订单" />
<up-loadmore v-else :status="status" color="#c0c4cc" lineColor="#c0c4cc" />
</view>
<up-popup
:show="show"
closeable
mode="center"
@close="bzclose"
>
<view class="hdbzcont">
<up-steps v-if="show" :current="bzlist.length" direction="column">
<up-steps-item v-for="n in bzlist" :title="n.step" :desc="n.stepTime" />
</up-steps>
</view>
</up-popup>
</template>
<script setup lang="ts">
import { ref,reactive } from 'vue'
import { orderlist,dzbzxq } from '@/utils/service'
import { onReachBottom } from '@dcloudio/uni-app'
// 1-2-3-4-5-6-7-9-
const statelist = reactive([
{ name: '全部'},
{ name: '进行中', status:'1,2,3,4,5' },
{ name: '待支付', status:'6' },
{ name: '已完成', status:'7'}
])
let status = ref('nomore') //loadmore loading
let list = ref<any[]>([])
let pageNo = ref(1)
let stanum = ref('')
//tabs
function tabshand(n:any){
pageNo.value = 1
list.value.splice(0)
stanum.value = n.status
getlist()
}
function getlist() {
let qsobj = {
userId:uni.getStorageSync('wxuid'),
pageSize:30,
pageNo:pageNo.value
}
if(stanum.value){
qsobj = Object.assign(qsobj,{status:stanum.value})
}
status.value = 'loading'
orderlist(qsobj).then((rps:any) => {
if(rps.data.total > 0){
list.value = [...list.value,...rps.data.records]
if(list.value.length == rps.data.total){
status.value = 'nomore'
}else{
status.value = 'loadmore'
pageNo.value++
}
}
})
}
//
let show = ref(false)
let bzlist = ref<any[]>([])
function getbz(orderNo:any) {
bzlist.value.splice(0)
show.value = true
dzbzxq(orderNo).then((rps:any) => {
bzlist.value = rps.data
})
}
function bzclose(){
show.value = false
}
function dsta(n:any) {
if(n == 6){
return '待支付'
}
if(n == 7){
return '已完成'
}
if(n == 9){
return '已取消'
}
return '进行中'
}
function topay(url:string) {
uni.navigateTo({
url
})
}
//
getlist()
onReachBottom(() => {
if(status.value == 'loadmore'){
getlist()
}
})
</script>
<style lang="scss">
page{
background: #f4f4f4;
}
.content{
padding-bottom: 30rpx;
.tabct{
position: fixed;
width: 100%;
box-sizing: border-box;
padding-bottom: 10rpx;
background: #fff;
}
.lisct{
padding-top: 130rpx;
.list{
margin:0 25rpx 40rpx;
//padding: 25rpx;
border-radius: 20rpx;
box-shadow: 0 0 10px 2px rgba(190, 190, 190, 0.5);
background: #fff;
.zoddu{
padding: 25rpx;
//margin-bottom: 30rpx;
//padding-top: 20rpx;
//border-top: 1px dashed #ccc;
>view{
display: flex;
padding-bottom: 20rpx;
justify-content: space-between;
>view:last-child{
color: #7a7a7a;
}
}
>view:last-child{
padding-bottom: 0;
}
}
.qxyy{
height: 80rpx;
line-height: 80rpx;
border-radius: 0 0 20rpx 20rpx;
color: #fff;
text-align: center;
background: #00aa00;
}
}
}
}
.hdbzcont{
box-sizing: border-box;
width: 85vw;
padding: 30rpx;
background: #fff;
}
</style>

View File

@ -0,0 +1,106 @@
<template>
<up-navbar
title="支付"
bgColor="#00aa7f"
:autoBack="true"
leftIconColor="#fff"
titleStyle="color:#fff"
:placeholder="true"
/>
<view class="content">
<view style="padding-bottom: 200rpx;text-align: center;">
<text>¥</text>
<text style="font-size: 60rpx;">100</text>
<text></text>
</view>
<view class="qxyy" @tap="payhand">立即支付</view>
</view>
</template>
<script setup lang="ts">
import { ref,reactive } from 'vue'
import { payment } from '@/utils/service'
import { onLoad,onShow } from '@dcloudio/uni-app'
onLoad((opt:any) => {
payqs.money = opt.amount
payqs.detail.costPrice = opt.amount
payqs.detail.goodsDetail.unitPrice = opt.amount
})
let payqs = reactive({
wuid:uni.getStorageSync('wxuid'),
remarks:'',
money:'',
detail:{
costPrice:'', //
invoiceId:'', //ID
goodsDetail:{
merchantGoodsId:'', //
wechatpayGoodsId:'', //
goodsName:'', //
quantity:1, //
unitPrice:'' //
}
}
})
function payhand() {
payment(payqs).then((rps:any) => {
console.log(rps)
// appId: "wx2ab384cf1e6f85a1"
// nonceStr: "WhtgCld5gCTWBDzfFuRcFEhKCYTsIq2f"
// packageVal: "prepay_id=wx091610306843188838925c6a38a9fb0000"
// paySign: "JCWH1qZtgIJx6k+Cah5Js40Bgx9k1sQlvthfsYu3IwexwPX3JXOnEjAHhKSG61iRkcdaxaqtcIxYpXUuiQOwWf4epZE+YTZIJ021eXiM4J/o0NwXXTB7guEDo5MuEFQWsrdyAqhoTD1cziVrKyp/ka1aux5ULOgVfn6FvHRaoEO+YIn71ls9z/sKloJjuCS9bdSppknJwAmmVD+k7Xc/vCiFZ0c7k13JzYWbWCXgHCMNJ02DrP75EuzuDvmN/4U9ABN9z/SN/Roz2fs9/h7DPagICC9oj0oEg80+Y4S84EUFupsR2MCFVQlCF4+dPdCx75JcXId6cSIE+ySJciyjHQ=="
// signType: "RSA"
// timeStamp: "1736410231"
//#ifdef MP-WEIXIN
wx.requestPayment({
timeStamp:rps.data.timeStamp,
nonceStr: rps.data.timeStamp,
package: rps.data.timeStamp,
signType: rps.data.signType,
paySign: rps.data.paySign,
success:function(res){
},
fail:function(res){
}
})
//#endif
})
}
</script>
<style lang="scss">
page{
background: #f4f4f4;
}
.content{
margin:50rpx 30rpx 30rpx;
padding: 40rpx;
border-radius: 20rpx;
background: #fff;
.qxyy{
height: 80rpx;
line-height: 80rpx;
border-radius:20rpx;
color: #fff;
text-align: center;
background: #00aa00;
}
}
.hdbzcont{
box-sizing: border-box;
width: 85vw;
padding: 30rpx;
background: #fff;
}
</style>

View File

@ -0,0 +1,138 @@
<template>
<up-navbar
title="充值"
bgColor="#00aa7f"
:autoBack="true"
leftIconColor="#fff"
titleStyle="color:#fff"
:placeholder="true"
/>
<view class="contet">
<view class="tit">充值金额</view>
<view class="jenr">
<view class="jrnum">
<view @tap="setje(1,50)" :class="{actv:actv == 1}">¥<text>50</text></view>
<view @tap="setje(2,100)" :class="{actv:actv == 2}">¥<text>100</text></view>
<view @tap="setje(3,200)" :class="{actv:actv == 3}">¥<text>200</text></view>
</view>
<view class="jrnum">
<view @tap="setje(4,500)" :class="{actv:actv == 4}">¥<text>500</text></view>
<view @tap="setje(5,1000)" :class="{actv:actv == 5}">¥<text>1000</text></view>
<view @tap="setje(6,1000)">自定义</view>
</view>
</view>
<up-button style="margin-top: 100rpx;" type="success" @tap="save">确认充值</up-button>
</view>
<up-popup
:show="show"
mode="center"
round="10"
closeable
@close="close"
>
<view style="width: 70vw;padding: 100rpx 50rpx 0;">
<up-input
type="number"
maxlength="4"
v-model="zdyjr"
@focus="focus"
placeholder="请输入金额" clearable
/>
<view style="box-sizing: border-box;height: 100rpx;padding-top: 5rpx;font-size: 28rpx;color: #f00;">
<view v-if="errtip">请输入金额</view>
</view>
<view style="padding:30rpx;">
<up-button type="success" @tap="zdysave">确认充值</up-button>
</view>
</view>
</up-popup>
</template>
<script setup lang="ts">
import { ref } from 'vue'
let actv = ref(0)
let jiner = ref<string|number>('')
let show = ref(false)
function setje(n:number,v:number|string){
actv.value = n
jiner.value = v
if(n == 6){
show.value = true
}
}
function close() {
show.value = false
}
function save() {
if(jiner.value == ''){
uni.showToast({
title:'请选择金额',
icon:'none'
})
}
}
//
let zdyjr = ref('')
let errtip = ref(false)
function zdysave() {
if(zdyjr.value == ''){
errtip.value = true
}else{
}
}
function focus() {
errtip.value = false
}
</script>
<style lang="scss">
page{
background: #f4f4f4;
}
.contet{
padding: 25rpx;
.tit{
margin-bottom: 25rpx;
padding-left: 16rpx;
border-left: 4px solid #00aa00;
}
.jenr{
box-sizing: border-box;
margin-top: 30rpx;
padding: 30rpx 5% 0;
border-radius: 20rpx;
background: #fff;
.jrnum{
box-sizing: border-box;
display: flex;
justify-content: space-between;
>view{
box-sizing: border-box;
width: 25%;
height: 80rpx;
line-height: 80rpx;
text-align: center;
margin-bottom: 30rpx;
border-radius: 20rpx;
border: 1px solid #ccc;
text{
font-size: 40rpx;
}
}
.actv{
color: #fff;
background: #5ac725;
border: none;
}
}
}
}
</style>

View File

@ -0,0 +1,118 @@
<template>
<up-navbar
title="预约记录"
bgColor="#00aa7f"
:autoBack="true"
leftIconColor="#fff"
titleStyle="color:#fff"
:placeholder="true"
/>
<view class="content">
<view v-for="n in list" :key="n.pkId" class="list">
<view class="zoddu">
<view>
<view>换电站</view>
<view>{{n.stationName}}</view>
</view>
<view>
<view>车牌号</view>
<view>{{n.plateNum}}</view>
</view>
<view>
<view>手机号</view>
<view>{{n.phone}}</view>
</view>
<view>
<view>预约时间</view>
<view>{{ytime(n.swapDay,n.swapDuration)}}</view>
</view>
</view>
<view v-if="n.status == 1" @tap="cancel(n.pkId)" class="qxyy" style="background: #00aa00;">取消预约</view>
<view v-else-if="n.status == 2" class="qxyy">已使用</view>
<view v-else-if="n.status == 3" class="qxyy">已取消</view>
<view v-else class="qxyy">已过期</view>
</view>
<up-empty v-if="list.length == 0" mode="list" text="暂无预约记录" />
</view>
</template>
<script setup lang="ts">
import { ref } from 'vue'
import { getyylist,cancelrese } from '@/utils/service'
let list = ref<any[]>([])
getlist()
function getlist() {
getyylist({
ucode:uni.getStorageSync('wxuid')
// plateNum:'A12345D',
// status:'1',
// stationCode:'123456789'
}).then((rps:any) => {
list.value = rps.data
})
}
function cancel(id:string) {
uni.showModal({
title: '温馨提示',
content: '确定取消?',
success(res){
if(res.confirm){
cancelrese(id).then(() => {
uni.showToast({
title: '取消成功',
duration: 2000
})
setTimeout(()=>{
getlist()
},2000)
})
}
}
})
}
//
function ytime(n:string,v?:string){
return `${n.substring(0,4)}${n.substring(4,6)}${n.substring(6,8)}${v?v:''}`
}
</script>
<style lang="scss" scoped>
.content{
padding: 25rpx;
.list{
margin-bottom: 40rpx;
border-radius: 20rpx;
box-shadow: 0 0 10px 2px rgba(190, 190, 190, 0.5);
background: #fff;
.zoddu{
padding: 25rpx;
//margin-bottom: 30rpx;
//padding-top: 20rpx;
//border-top: 1px dashed #ccc;
>view{
display: flex;
padding-bottom: 20rpx;
justify-content: space-between;
>view:last-child{
color: #7a7a7a;
}
}
>view:last-child{
padding-bottom: 0;
}
}
.qxyy{
height: 80rpx;
line-height: 80rpx;
border-radius: 0 0 20rpx 20rpx;
color: #fff;
text-align: center;
background: #ccc;
}
}
}
</style>

View File

@ -0,0 +1,263 @@
<template>
<up-navbar
title="个人资料"
bgColor="#00aa7f"
:autoBack="true"
leftIconColor="#fff"
titleStyle="color:#fff"
:placeholder="true"
/>
<view class="content">
<!-- 注意如果需要兼容微信小程序最好通过setRules方法设置rules规则 -->
<up-form
labelPosition="left"
labelWidth="100"
:model="formdata"
:rules="rules"
ref="uFormRef"
>
<up-form-item
label=""
prop="avatar"
borderBottom
>
<!--@chooseavatar="onChooseAvatar"-->
<view style="padding-bottom: 30rpx;">
<button class="avatar" open-type="chooseAvatar" @chooseavatar="onChooseAvatar">
<image class="img" :src="formdata.avatarUrl?formdata.avatarUrl:'../../static/img/toux.png'" />
</button>
</view>
</up-form-item>
<up-form-item
label="昵称"
prop="nickName"
borderBottom
>
<input type="nickname" v-model="formdata.nickName" @blur="bindblur" placeholder="请输入昵称" />
</up-form-item>
<up-form-item
label="用户名"
prop="name"
borderBottom
>
<input v-model="formdata.name" placeholder="请输入用户名" />
</up-form-item>
<up-form-item
label="手机号"
prop="phoneNumber"
borderBottom
>
<up-input type="number" maxlength="11" v-model="formdata.phoneNumber" border="none" placeholder="请输入手机号" clearable />
</up-form-item>
<up-form-item
label="性别"
prop="gender"
borderBottom
>
<up-input
v-model="genderName"
readonly
border="none"
placeholder="请选择性别"
@tap="xbhand"
suffixIcon="arrow-down"
suffixIconStyle="color: #bababa"
/>
</up-form-item>
<up-button style="margin-top: 100rpx;" type="success" @tap="submit">保存</up-button>
</up-form>
<view class="loginout" @tap="logout">退出登录</view>
</view>
<!--性别-->
<up-picker
:show="xbshow"
:columns="xbcolumns"
keyName="label"
@confirm="xbconfirm"
@cancel="xbcancel"
/>
</template>
<script setup lang="ts">
import { ref, reactive } from 'vue'
import { getInfo,inforupdate } from '@/utils/service'
const phoneNumber = uni.getStorageSync('PhoneNumber')
let genderName = ref('')
let formdata = reactive({
phoneNumber:phoneNumber?phoneNumber:'', //
nickName:'', //
avatarUrl:'', //
name:'', //
gender:'' //1-2-
})
getInfo({
wuid:uni.getStorageSync('wxuid')
}).then((rps:any) => {
formdata.nickName = rps.data.nickName?rps.data.nickName:''
formdata.avatarUrl = rps.data.avatarUrl?rps.data.avatarUrl:''
formdata.name = rps.data.name?rps.data.name:''
formdata.gender = rps.data.gender?rps.data.gender:''
})
const rules = {
phoneNumber: {
type: 'string',
required: true,
message: '请输入手机号',
trigger: ['blur', 'change'],
},
name: {
type: 'string',
required: true,
message: '请输入用户名',
trigger: ['blur', 'change'],
}
}
//退
function logout(){
uni.showModal({
title: '提示',
content: '确认退出登录吗',
success: function (res) {
if (res.confirm) {
uni.showToast({
title:'退出登录',
icon:'none'
})
uni.removeStorageSync('wxuid')
uni.removeStorageSync('wxToken')
uni.removeStorageSync('PhoneNumber')
setTimeout(() => {
uni.navigateBack()
},1500)
}
}
})
}
//
function onChooseAvatar (e:any){
console.log(e)
formdata.avatarUrl = e.detail.avatarUrl
//const tempFilePath = e.detail.avatarUrl //
//const maxSizeInBytes = 1024 * 1024 // 1MB
// uni.getFileInfo({
// filePath: tempFilePath,
// success: res => {
// const fileSize = res.size
// if (fileSize > maxSizeInBytes) {
// //1MB
// uni.$showMsg('1MB')
// return
// }
// //
// avatarUrl.value = tempFilePath
// //
// uni.uploadFile({
// url: 'http://...', //url
// filePath: avatarUrl.value,
// name: 'file',
// header: {
// Authorization: 'Bearer ' + token // token header
// },
// success(res) {
// let fileRes = JSON.parse(res.data)
// uni.$showMsg(fileRes.message)
// }
// })
// }
// })
}
//
function bindblur(e:any) {
formdata.nickName = e.detail.value
}
//
let xbshow = ref(false)
const xbcolumns = ref([
[
{
label: '男',
//
id: 1
},
{
label: '女',
id: 2
}
]
])
function xbhand() {
xbshow.value = true
}
function xbconfirm(v:any) {
formdata.gender = v.value[0].id
genderName.value = v.value[0].label
xbshow.value = false
}
function xbcancel() {
xbshow.value = false
}
//
const uFormRef = ref(null)
function submit() {
(uFormRef as any).value.validate().then((valid:any) => {
if (valid) {
inforupdate(formdata).then(() => {
uni.showToast({
title: '保存成功',
duration: 2000
})
})
}
}).catch(() => {
//
});
}
</script>
<style lang="scss">
page{
background: #f4f4f4;
}
.content{
margin: 30rpx 20rpx;
padding: 50rpx 20rpx;
border-radius: 20rpx;
background: #fff;
.weidu{
}
.avatar {
width: 130rpx;
height: 130rpx;
padding: 0;
border-radius: 50%;
.img{
width: 100%;
height: 100%;
}
}
.loginout{
position: absolute;
text-align: center;
color: #737373;
left: 0;
right: 0;
bottom: 10%;
}
}
</style>

View File

@ -0,0 +1,169 @@
<template>
<up-navbar
title="个人资料"
bgColor="#00aa7f"
:autoBack="true"
leftIconColor="#fff"
titleStyle="color:#fff"
:placeholder="true"
/>
<view>
<view class="content">
<up-form
labelPosition="left"
labelWidth="100"
:model="formdata"
:rules="rules"
ref="uFormRef"
>
<up-form-item
label=""
prop="uname"
borderBottom
>
<button class="avatar" open-type="chooseAvatar" @chooseavatar="onChooseAvatar">
<image class="img" src="../../static/img/toux.png" />
</button>
</up-form-item>
<up-form-item
label="昵称"
prop="uname"
borderBottom
>
<input type="nickname" v-model="nickname" @blur="bindblur" placeholder="请输入昵称" />
</up-form-item>
<up-form-item
label="手机号"
prop="phone"
borderBottom
>
<up-input type="number" maxlength="11" v-model="formdata.phone" border="none" placeholder="请输入手机号" clearable />
</up-form-item>
<up-button style="margin-top: 100rpx;" type="success" @tap="submit">提交</up-button>
</up-form>
<view class="weidu">
</view>
</view>
<!-- 内容区域 -->
<!-- <view class="panel-list">
<view class="panel" @click="logout">
<view class="panel-bottom">
<text>退出登录</text>
<uni-icons type="right" size="15"></uni-icons>
</view>
</view>
</view> -->
</view>
</template>
<script setup>
import { ref,reactive } from 'vue'
let formdata = reactive({
nickname:'',
phone:''
})
//退
let logout = () => {
uni.showModal({
title: '提示',
content: '确认退出登录吗',
success: function (res) {
if (res.confirm) {
useStore.userLogout()
}
}
})
}
//
const onChooseAvatar = async e => {
const tempFilePath = e.detail.avatarUrl //
const maxSizeInBytes = 1024 * 1024 // 1MB
uni.getFileInfo({
filePath: tempFilePath,
success: res => {
const fileSize = res.size
if (fileSize > maxSizeInBytes) {
//1MB
uni.$showMsg('请上传小于1MB的图片')
return
}
//
avatarUrl.value = tempFilePath
//
uni.uploadFile({
url: 'http://...', //url
filePath: avatarUrl.value,
name: 'file',
header: {
Authorization: 'Bearer ' + token // token header
},
success(res) {
let fileRes = JSON.parse(res.data)
uni.$showMsg(fileRes.message)
}
})
}
})
}
//
function bindblur(e) {
formdata.nickname = e.detail.value
}
//
const uFormRef = ref(null)
function submit() {
(uFormRef as any).value.validate().then((valid:any) => {
if(valid){
uni.showToast({
title: '预约成功',
duration: 2000
})
}else{
uni.showToast({
title: '失败',
duration: 2000
})
}
}).catch(() => {
//
})
}
//
</script>
<style lang="scss">
page{
background: #f4f4f4;
}
.content{
margin: 30rpx 20rpx;
padding: 50rpx 20rpx;
border-radius: 20rpx;
background: #fff;
.weidu{
}
.avatar {
width: 130rpx;
height: 130rpx;
padding: 0;
border-radius: 50%;
.img{
width: 100%;
height: 100%;
}
}
}
</style>

View File

@ -0,0 +1,83 @@
<template>
<up-navbar
title="车辆管理"
bgColor="#00aa7f"
:autoBack="true"
leftIconColor="#fff"
titleStyle="color:#fff"
:placeholder="true"
/>
<view class="content">
<view v-for="n in list" :key="n.pkId" class="list">
<view class="zoddu">
<!-- <view>
<view>换电站</view>
<view>{{n.stationName}}</view>
</view> -->
<view>
<view>车牌号</view>
<view>{{n.plateNum}}</view>
</view>
<view>
<view>手机号</view>
<view>{{n.phone}}</view>
</view>
</view>
</view>
<up-empty v-if="list.length == 0" mode="list" text="暂无车辆" />
</view>
</template>
<script setup lang="ts">
import { ref } from 'vue'
import { carlist } from '@/utils/service'
getlist()
let list = ref<any[]>([])
function getlist() {
carlist(uni.getStorageSync('wxuid')).then((rps:any) => {
if(rps.data && rps.data.length > 0){
list.value = rps.data
}
})
}
</script>
<style lang="scss" scoped>
.content{
padding: 25rpx;
.list{
margin-bottom: 40rpx;
border-radius: 20rpx;
box-shadow: 0 0 10px 2px rgba(190, 190, 190, 0.5);
background: #fff;
.zoddu{
padding: 25rpx;
//margin-bottom: 30rpx;
//padding-top: 20rpx;
//border-top: 1px dashed #ccc;
>view{
display: flex;
padding-bottom: 20rpx;
justify-content: space-between;
>view:last-child{
color: #7a7a7a;
}
}
>view:last-child{
padding-bottom: 0;
}
}
.qxyy{
height: 80rpx;
line-height: 80rpx;
border-radius: 0 0 20rpx 20rpx;
color: #fff;
text-align: center;
background: #00aa00;
}
}
}
</style>

121
src/pages.json Normal file
View File

@ -0,0 +1,121 @@
{
"pages": [ //pageshttps://uniapp.dcloud.io/collocation/pages
{
//
"path": "pages/home/index"
},
{
//
"path": "pages/scanCode/index"
},
{
//
"path": "pages/mine/index"
},
{
//
"path": "pages/login/index"
}
],
"subPackages": [
{
"root":"homePages",
"pages":[
{
"path": "agreement/index"
},
{
"path": "reservation/index" //
}
]
},
{
"root":"codePages",
"pages":[
{
"path": "index"
}
]
},
{
"root":"minePages",
"pages":[
{
"path": "recharge/index" //
},
{
"path": "userInfor/index" //
},
{
"path": "account/index" //
},
{
"path": "reserlist/index" //
},
{
"path": "vehicle/index" //
},
{
"path": "order/index" //
},
{
"path": "about/index" //
},
{
"path": "agreement/index" //
},
{
"path": "payment/index" //
}
]
}
],
"globalStyle": {
"titleNView": false, // AppH5
"navigationStyle": "custom" //
},
"tabBar": {
//"custom":true,
"color": "#404244",
"selectedColor": "#00aa00",
"borderStyle": "black",
"backgroundColor": "#ffffff",
// "midButton":{ //
// "width": "100px",
// "height": "80px",
// //"pagePath": "pages/scanCode/index",
// "iconPath": "static/img/tabbar/saom.png",
// "backgroundImage":"static/img/tabbar/saom.png",
// //"selectedIconPath": "static/img/tabbar/saom.png",
// "text": "扫码换电"
// },
"list": [{
"pagePath": "pages/home/index",
"iconPath": "static/img/tabbar/home.png",
"selectedIconPath": "static/img/tabbar/home.png",
"text": "首页"
},
// {
// "pagePath":"pages/scanCode/index",
// "iconPath": "static/img/tabbar/saom.png",
// "selectedIconPath": "static/img/tabbar/saom.png",
// "text": "扫码换电"
// },
{
"pagePath": "pages/mine/index",
"iconPath": "static/img/tabbar/wode.png",
"selectedIconPath": "static/img/tabbar/wode.png",
"text": "我的"
}
]
},
"easycom": {
"autoscan": true,
// customhttps://ask.dcloud.net.cn/question/131175
"custom": {
"^u--(.*)": "uview-plus/components/u-$1/u-$1.vue",
"^up-(.*)": "uview-plus/components/u-$1/u-$1.vue",
"^u-([^-].*)": "uview-plus/components/u-$1/u-$1.vue"
}
}
}

471
src/pages/home/index.vue Normal file
View File

@ -0,0 +1,471 @@
<template>
<view id="mancont">
<view>
<up-swiper
height="500rpx"
keyName="picUrl"
:list="imglist"
indicator
indicatorMode="line"
radius="0"
:indicator="false"
circular
/>
</view>
<view v-if="!islogin" class="kuaijrk" style="position: relative;margin-top: -50rpx;background: #fff;">
<view style="display: flex;align-items: center;">
<view style="width: 70rpx;height: 70rpx;border-radius: 50%;overflow: hidden;">
<image style="width: 100%;height: 100%;" src="../../static/img/jrwm.png" />
</view>
<view>未登录</view>
</view>
<!--@tap="getUser"-->
<view @tap="topage('/pages/login/index')" style="width: 180rpx;height:64rpx;background: #00aa7f;text-align:center;color:#fff;border-radius:10rpx;line-height: 64rpx;">去登录</view>
</view>
<view v-else class="kuaijrk" style="position: relative;margin-top: -50rpx;align-items:center;background: #fff;">
<view @tap="topage('/minePages/userInfor/index')" style="display: flex;width:50%;align-items: center;">
<view style="width: 70rpx;height: 70rpx;border-radius: 50%;overflow: hidden;">
<image style="width: 100%;height: 100%;" src="../../static/img/toux.png" />
</view>
<view class="niche">{{username()}}</view>
</view>
<view>
<view style="font-size: 36rpx;">5</view>
<view style="font-size: 26rpx;color: #8e8a8a;">优惠券</view>
</view>
<view @tap="topage('/minePages/account/index')">
<view style="font-size: 36rpx;">66</view>
<view style="font-size: 26rpx;color: #8e8a8a;">余额</view>
</view>
</view>
<view class="kuaijrk">
<template v-if="islogin">
<view @tap="topage('/minePages/order/index')">
<image src="../../static/img/cd2.png" />
<view>我的订单</view>
</view>
<view @tap="topage('/minePages/recharge/index')">
<image src="../../static/img/chongz.png" />
<view>充值中心</view>
</view>
<view @tap="topage('/minePages/reserlist/index')">
<image src="../../static/img/shiyxy.png" />
<view>预约记录</view>
</view>
</template>
<template v-else>
<view @tap="wdltip()">
<image src="../../static/img/cd2.png" />
<view>我的订单</view>
</view>
<view @tap="wdltip()">
<image src="../../static/img/chongz.png" />
<view>充值中心</view>
</view>
<view @tap="topage('/minePages/reserlist/index')">
<image src="../../static/img/shiyxy.png" />
<view>预约记录</view>
</view>
</template>
<view>
<image src="../../static/img/kefu.png" />
<view>客服中心</view>
</view>
<!--topage('/homePages/agreement/index')-->
<!-- <view @tap="showxy()">
<image src="../../static/img/shiyxy.png" />
<view>使用协议</view>
</view> -->
<!-- <view>
<image src="../../static/img/jrwm.png" />
<view>加入我们</view>
</view> -->
</view>
</view>
<!-- @callouttap="getdh()"-->
<map
:style="{width:'100%',height: height}"
:latitude="latitude"
:longitude="longitude"
:markers="covers"
:scale="10"
:show-location="true"
@markertap="markertap"
>
<!-- <template #callout>
<cover-view style="width:200px;height:200px;background:#fff;" :marker-id="0">
<cover-view>1号换电站</cover-view>
<cover-view style="width: 100rpx;height:60rpx;line-height:60rpx;text-align:center;background:#00aa00;color:#fff;">导航</cover-view>
</cover-view>
</template> -->
</map>
<view v-if="showxq" class="dibucoten">
<view style="margin-bottom: 10rpx;padding-bottom:10rpx;font-size: 38rpx;color: #00aa7f;border-bottom:1px #00aa7f dashed;">{{hdzname}}</view>
<view>营业时间<text style="color: #5f5f5f;">8:30 - 17:30</text></view>
<view style="display: flex;justify-content: space-between;">
<view style="padding-top: 8rpx;">距您 <text style="color: #5f5f5f;">4.5km</text></view>
<view @tap="getdh()" style="width: 150rpx;height: 60rpx;line-height: 60rpx;text-align: center;background: #00aa7f;color: #fff;border-radius: 10rpx;">导航</view>
</view>
</view>
<view v-if="islogin" @tap="topage(`/homePages/reservation/index?hdzcode=${hdzcode}&phoneNumber=${userInfo.phoneNumber}`)" class="yuyue"> </view>
<view v-else @tap="wdltip()" class="yuyue">预约</view>
<!--xyshow-->
<up-popup
:show="xyshow"
mode="bottom"
round="50"
:closeOnClickOverlay="true"
>
<view style="box-sizing: border-box;padding: 20rpx;background: #fff;">
<view style="margin-bottom: 20rpx;padding-bottom:20rpx;font-size: 40rpx;text-align: center;color: #00aa7f;border-bottom: 1px #00aa7f dashed;">伊特换电使用协议</view>
<view style="height: 30vh;overflow-y: scroll;">
<view style="padding: 25rpx 25rpx 50rpx;font-size: 26rpx;">
<view style="padding-bottom: 30rpx;font-weight: bold;text-align: center;">{{xyobj.title}}</view>
<up-parse :content="decodeURIComponent(xyobj.content)"></up-parse>
</view>
</view>
<!-- <view style="display: flex;align-items: center;;padding-top: 10rpx;">
<label class="radio"><radio value="r1" checked="true">已阅读并同意</radio></label>
<view @tap="topage('/minePages/agreement/index?type=1')" style="padding: 0 10rpx;color: #ffaa00;">服务条款</view>
<view @tap="topage('/minePages/agreement/index?type=2')" style="color: #ffaa00;">隐私协议</view>
</view> -->
<view class="xybtns">
<view @tap="btnshan(2)" style="background: #fff;border:1px #8e8a8a solid;color: #000;">取消</view>
<view @tap="btnshan(1)">同意</view>
</view>
</view>
</up-popup>
</template>
<script setup lang="ts">
import { ref,reactive,watch,getCurrentInstance } from 'vue'
import { onLoad,onShow } from '@dcloudio/uni-app'
import { login,getUser,gethdz,loginstate,swiperimg,agreement,getInfo } from '@/utils/service'
let height = ref('')
let islogin = ref(false)
let PhoneNumber = ref('')
let covers =ref<any[]>([])
let hdzcode = ref('')
let imglist = ref<any[]>([])
// uni.removeStorageSync('wxuid')
// uni.removeStorageSync('wxToken')
// uni.removeStorageSync('PhoneNumber')
let xyobj = ref<any>({})
onLoad((opt:any) => {
hdzcode.value = opt.hdzcode
})
//
let latitude = ref(37.844522)
let longitude = ref(114.530428)
let hdzname = ref('')
let xyshow = ref(false)
let init = true
let userInfo = reactive<any>({
phoneNumber:'',
avatarUrl:'',
name:'',
nickName:''
})
function username() {
if(userInfo.phoneNumber){
return userInfo.phoneNumber
}else if(userInfo.nickName){
return userInfo.nickName
}else if(userInfo.name){
return userInfo.name
}
return '微信用户'
}
function getinfo(){
//
swiperimg({
appid:'wx2ab384cf1e6f85a1',
type:2
}).then((rps:any) => {
imglist.value = rps.data
})
//
covers.value.splice(0)
gethdz({
//plateNum:formdata.plateNum
}).then((rps:any) => {
if(rps.data && rps.data.length > 0){
rps.data.forEach((n:any,i:any) => {
let jwd = n.locationPoint?n.locationPoint.split(','):[]
covers.value.push({
id:i,
latitude: jwd[0]?jwd[0]:'',
longitude: jwd[1]?jwd[1]:'',
width:20,
height:30,
options: {
isStore: true,
status: 1,
xian: 12,
all: 20
},
callout: {
content: n.name,
bgColor:'#00aa7f',
color:'#fff',
fontSize:'30rpx',
padding:'10rpx',
borderRadius:'20rpx',
display: 'BYCLICK' //
}
})
})
}
})
//
getInfo({
wuid:uni.getStorageSync('wxuid')
}).then((rps:any) => {
userInfo.phoneNumber = rps.data.phoneNumber?rps.data.phoneNumber:''
userInfo.nickName = rps.data.nickName?rps.data.nickName:''
userInfo.avatarUrl = rps.data.avatarUrl?rps.data.avatarUrl:''
userInfo.name = rps.data.name?rps.data.name:''
})
}
onShow(() => {
xyshow.value = false
uni.showTabBar()
//
if(uni.getStorageSync('wxuid')){
islogin.value = true
// let pnum = uni.getStorageSync('PhoneNumber')
// if(pnum){
// PhoneNumber.value = pnum
// }
//??
if(init){
loginstate({
wuid:uni.getStorageSync('wxuid')
}).then((rps:any) => {
uni.setStorageSync('wxToken',rps.data.wxToken)
getinfo()
})
init = false
}else{
getinfo()
}
}else{
islogin.value = false
PhoneNumber.value = ''
covers.value = []
hdzcode.value = ''
imglist.value = []
showxy()
}
const instance = getCurrentInstance()
const query = uni.createSelectorQuery().in((instance as any).proxy)
query.select('#mancont').boundingClientRect(v => {
uni.getSystemInfo({
success: n => {
//
height.value = (n.windowHeight - (v as any).height + 20)+'px'
}
})
})
.exec()
})
//
function topage(url:string){
uni.navigateTo({
url
})
}
function wdltip() {
uni.showToast({
title:'请您先登录',
icon:'none'
})
}
function getdh() {
console.log(latitude.value,longitude.value)
uni.openLocation({
latitude:latitude.value*1,
longitude:longitude.value*1,
address:hdzname.value,
success() {
console.log('success');
},
fail(err) {
console.error('打开地图失败', err);
}
})
}
//
let showxq = ref(false)
function markertap(v:any) {
showxq.value = true
const markerId = v.markerId
// markers
covers.value = covers.value.map((n:any) => {
if(n.id === markerId) {
console.log(n,'123')
//
n.callout.display = 'ALWAYS'
hdzname.value = n.callout.content
latitude.value = n.latitude
longitude.value = n.longitude
}else{
//
n.callout.display = 'BYCLICK'
}
return n
})
}
//
function showxy() {
agreement({
appid:'wx2ab384cf1e6f85a1', //uni.getStorageSync('wxuid'),
type:'1'
}).then((rps:any) => {
xyobj.value = rps.data[0]
uni.hideTabBar()
xyshow.value = true
})
}
function btnshan(type:number = 1) {
if(type == 1){
getUser().then(() => {
xyshow.value = false
uni.showTabBar()
islogin.value = true
getinfo()
setTimeout(()=> {
uni.getLocation({
type: 'wgs84',
success(res) {
longitude.value = res.longitude
latitude.value = res.latitude
},
fail(rps) {
console.log(rps)
}
})
},1000)
})
}else{
uni.exitMiniProgram({
success: function() {
console.log('退出小程序成功')
},
fail: function(err) {
console.log('退出小程序失败', err)
}
})
// xyshow.value = false
// uni.showTabBar()
}
}
</script>
<style lang="scss" scoped>
page{
background: #ccc;
}
.top {
width: 100%;
background: #00aa00;
view{
padding: 30rpx 0;
font-size: 40rpx;
color: #fff;
text-align: center;
}
}
.kuaijrk{
display: flex;
justify-content: space-between;
margin: 20rpx;
padding: 20rpx;
border-radius: 20rpx;
font-size: 30rpx;
box-shadow: 0 0 20px 2px rgba(0, 170, 0, 0.5);
>view{
width: 25%;
text-align: center;
//color: #00aa00;
//font-weight: bold;
image{
width: 70rpx;
height: 70rpx;
}
}
}
.dibucoten{
box-sizing: border-box;
position: fixed;
width: 90%;
//height: 200rpx;
padding: 30rpx;
border-radius: 10rpx;
background:#fff; //#00aa00;
left: 5%;
bottom: 20rpx;
box-shadow: 0 0 20px 2px rgba(0, 170, 0, 0.5);
}
.xybtns{
box-sizing: border-box;
display: flex;
width: 100%;
justify-content: space-between;
padding:20rpx 0 100rpx 0;
>view{
width: 300rpx;
height: 80rpx;
line-height: 80rpx;
border-radius: 50rpx;
text-align: center;
color: #fff;
background: #00aa00;
}
}
.yuyue{
position: fixed;
right: 5%;
bottom: 300rpx;
width: 120rpx;
height: 120rpx;
line-height: 120rpx;
text-align: center;
background: #00aa00;
border-radius: 50%;
color: #fff;
box-shadow: 0 0 20px 2px rgba(0, 170, 0, 0.5);
}
.niche{
width: 200rpx;
padding-left: 20rpx;
text-overflow: ellipsis;
white-space: nowrap;
overflow: hidden;
text-align: left;
}
</style>

133
src/pages/home/set.vue Normal file
View File

@ -0,0 +1,133 @@
<template>
<view class="my-user-info">
<view class="top-box">
<button class="avatar" open-type="chooseAvatar" @chooseavatar="onChooseAvatar">
<image :src="avatarUrl" class="avatar-img"></image>
</button>
<input class="nickname" type="nickname" :value="nickname" @blur="bindblur" placeholder="请输入昵称" />
</view>
<!-- 内容区域 -->
<view class="panel-list">
<view class="panel" @click="logout">
<view class="panel-bottom">
<text>退出登录</text>
<uni-icons type="right" size="15"></uni-icons>
</view>
</view>
</view>
</view>
</template>
<script setup>
import { ref } from 'vue'
import { requestNickname } from '@/utils/api/user.js'
import useUserStore from '@/store/user.js'
let useStore = useUserStore()
let token = useUserStore().token
let nickname = ref('')
let avatarUrl = ref('https://mmbiz.qpic.cn/mmbiz/icTdbqWNOwNRna42FI242Lcia07jQodd2FJGIYQfG0LAJGFxM4FbnQP6yfMxBgJ0F3YRqJCJ1aPAK2dQagdusBZg/0')
//退
let logout = () => {
uni.showModal({
title: '提示',
content: '确认退出登录吗',
success: function (res) {
if (res.confirm) {
useStore.userLogout()
}
}
})
}
//
const onChooseAvatar = async e => {
const tempFilePath = e.detail.avatarUrl //
const maxSizeInBytes = 1024 * 1024 // 1MB
uni.getFileInfo({
filePath: tempFilePath,
success: res => {
const fileSize = res.size
if (fileSize > maxSizeInBytes) {
//1MB
uni.$showMsg('请上传小于1MB的图片')
return
}
//
avatarUrl.value = tempFilePath
//
uni.uploadFile({
url: 'http://...', //url
filePath: avatarUrl.value,
name: 'file',
header: {
Authorization: 'Bearer ' + token // token header
},
success(res) {
let fileRes = JSON.parse(res.data)
uni.$showMsg(fileRes.message)
}
})
}
})
}
//
const bindblur = async e => {
const newNickname = (nickname.value = e.detail.value)
//
let res = await requestNickname({ newNickname })
uni.$showMsg(res.data.message)
}
</script>
<style lang="scss">
.my-user-info {
height: 100vh;
background-color: #f4f4f4;
.top-box {
height: 240rpx;
background-color: #0aa671;
display: flex;
flex-direction: column;
align-items: center;
.avatar {
width: 100rpx;
height: 100rpx;
border-radius: 50rpx;
border: 2rpx solid white;
box-shadow: 0 1rpx 5rpx black;
padding: 0;
.avatar-img {
width: 100%;
height: 100%;
}
}
.nickname {
color: white;
margin-top: 20rpx;
text-align: center;
font-size: 30rpx;
font-weight: bold;
}
}
}
.panel-list {
padding: 0 20rpx;
position: relative;
top: -40rpx;
.panel {
background-color: white;
border-radius: 15rpx;
margin-bottom: 20rpx;
.panel-bottom {
display: flex;
justify-content: space-between;
padding: 35rpx;
font-size: 25rpx;
}
}
}
</style>

124
src/pages/login/index.vue Normal file
View File

@ -0,0 +1,124 @@
<template>
<view class="content">
<image style="width: 200rpx;height: 90rpx;" src="/static/logo.png" />
<view style="padding: 50rpx 50rpx 80rpx;font-size: 50rpx;color: #4CAF50;">伊特换电</view>
<!-- <view @tap="getUser()" style="width: 80%;height: 80rpx;margin-bottom:30rpx;line-height: 80rpx;border-radius:10rpx;color:#fff;text-align:center;background: #4CAF50;">微信授权登录</view> -->
<!-- <button
style="width: 80%;height: 80rpx;line-height: 80rpx;border-radius:10rpx;color:#fff;text-align:center;background: #4CAF50;"
open-type="getPhoneNumber"
@getphonenumber="onGetPhoneNumber"
>手机号快捷登录</button> -->
<button style="width: 80%;height: 80rpx;line-height: 80rpx;border-radius:10rpx;color:#fff;text-align:center;background: #4CAF50;" @tap="login"> </button>
<view style="display: flex;align-items: center;;padding-top: 10rpx;">
<label class="radio"><radio value="r1" :checked="checked" @tap="checked = !checked">已阅读并同意</radio></label>
<view @tap="topage('/minePages/agreement/index?type=1')" style="padding: 0 10rpx;color: #ffaa00;">服务条款</view>
<view @tap="topage('/minePages/agreement/index?type=2')" style="color: #ffaa00;">隐私协议</view>
</view>
<!-- <view class="top-box">
<button class="avatar" open-type="chooseAvatar" @chooseavatar= "onchooseAvatar">
<image style="width: 100%;height: 100%;" :src="avatarUrl" class="avatar_img" />
</button>
<input type="nickname" v-model="nickname" class="weui-input" placeholder="请输入昵称"/>
</view> -->
</view>
</template>
<script setup lang="ts">
import { ref,watch } from 'vue'
import { getphone,getUser } from '@/utils/service'
//codecodeopenid
//code ivencryptedDatacodeopenidsessionKeysessionKeyivencryptedDatatoken
let checked = ref(false)
function login() {
if(checked.value){
getUser().then(() => {
uni.navigateBack()
})
}else{
uni.showToast({
title:'请您先同意相关协议',
icon:'none'
})
}
}
let userinfo = ref({})
let nickname = ref('')
let xiey = ref()
//uni.setStorageSync('TOKEN', '');
watch(() => nickname.value,(v) => {
console.log(v)
})
let avatarUrl = ref('/static/logo.png')
function onchooseAvatar(v:any) {
avatarUrl.value = v.detail.avatarUrl
console.log(v,'头像')
}
function topage(url:string){
uni.navigateTo({
url
})
}
function onGetPhoneNumber(v:any) {
//console.log(v)
getphone({
wuid:uni.getStorageSync('wxuid'),
code:v.detail.code
}).then((rps:any) => {
uni.setStorageSync('PhoneNumber', rps.data)
// uni.switchTab({
// url:'/pages/home/index'
// })
uni.navigateBack()
})
}
</script>
<style lang="scss" scoped>
.content {
display: flex;
flex-direction: column;
align-items: center;
padding-top: 30%;
justify-content: center;
}
.logo {
height: 200rpx;
width: 200rpx;
margin-top: 200rpx;
margin-left: auto;
margin-right: auto;
margin-bottom: 50rpx;
}
.text-area {
display: flex;
justify-content: center;
}
.title {
font-size: 36rpx;
color: #8f8f94;
}
.avatar{
width: 100rpx;
height: 100rpx;
border-radius: 50rpx;
border: 2rpx solid white;
box-shadow: 0 1rpx 5rpx black;
padding: 0;
.avatar-img {
width: 100%;
height: 100%;
}
}
</style>

331
src/pages/mine/index.vue Normal file
View File

@ -0,0 +1,331 @@
<template>
<view class="top">
<image class="bjtp" src="../../static/img/wobg.jpg" />
<view v-if="islogin" class="userinfor">
<view @tap="topage('/minePages/userInfor/index')" class="toux">
<image src="../../static/img/toux.png" />
<view>
<view class="niche">微信用户</view>
<view style="text-align: center;color: #484848;">{{PhoneNumber}}</view>
</view>
</view>
<view @tap="topage('/minePages/account/index')">
<view style="font-size: 36rpx;">186</view>
<view style="color: #848484;">余额</view>
</view>
</view>
<view v-else class="userinfor">
<view class="toux">
<image src="../../static/img/toux.png" />
<view>未登录</view>
</view>
<view class="btn" @tap="topage('/pages/login/index')">登录</view>
</view>
<!-- <up-icon name="arrow-right" color="#bdbdbd" size="20" /> -->
</view>
<view class="gncont">
<template v-if="islogin">
<view class="gnrk" @tap="topage('/minePages/order/index')">
<view>
<image src="../../static/img/cd2.png" />
<view>我的订单</view>
</view>
<up-icon name="arrow-right" color="#b9b9b9" />
</view>
<view class="gnrk" @tap="topage('/minePages/recharge/index')">
<view>
<image src="../../static/img/cd1.png" />
<view>充值中心</view>
</view>
<up-icon name="arrow-right" color="#b9b9b9" />
</view>
<view class="gnrk" @tap="topage('/minePages/reserlist/index')">
<view>
<image src="../../static/img/shiyxy.png" />
<view>预约记录</view>
</view>
<up-icon name="arrow-right" color="#b9b9b9" />
</view>
<view class="gnrk" @tap="topage('/minePages/vehicle/index')">
<view>
<image src="../../static/img/cd3.png" />
<view>我的车辆</view>
</view>
<up-icon name="arrow-right" color="#b9b9b9" />
</view>
</template>
<template v-else>
<view class="gnrk" @tap="wdltip">
<view>
<image src="../../static/img/cd2.png" />
<view>我的订单</view>
</view>
<up-icon name="arrow-right" color="#b9b9b9" />
</view>
<view class="gnrk" @tap="wdltip">
<view>
<image src="../../static/img/cd1.png" />
<view>充值中心</view>
</view>
<up-icon name="arrow-right" color="#b9b9b9" />
</view>
<view class="gnrk" @tap="wdltip">
<view>
<image src="../../static/img/shiyxy.png" />
<view>预约记录</view>
</view>
<up-icon name="arrow-right" color="#b9b9b9" />
</view>
<view class="gnrk" @tap="wdltip">
<view>
<image src="../../static/img/cd3.png" />
<view>我的车辆</view>
</view>
<up-icon name="arrow-right" color="#b9b9b9" />
</view>
</template>
<view class="gnrk">
<view>
<image src="../../static/img/cd4.png" />
<view>优惠活动</view>
</view>
<up-icon name="arrow-right" color="#b9b9b9" />
</view>
<view class="gnrk">
<view>
<image src="../../static/img/shiyxy.png" />
<view>客服中心</view>
</view>
<up-icon name="arrow-right" color="#b9b9b9" />
</view>
<view class="gnrk">
<view>
<image src="../../static/img/jrwm.png" />
<view>加入我们</view>
</view>
<up-icon name="arrow-right" color="#b9b9b9" />
</view>
<view class="gnrk" @tap="topage('/minePages/about/index')">
<view>
<image src="../../static/img/gywm.png" />
<view>关于我们</view>
</view>
<up-icon name="arrow-right" color="#b9b9b9" />
</view>
</view>
<!-- <view v-if="islogin" class="cdrk">
<view @tap="topage('/minePages/recharge/index')">
<image src="../../static/img/cd1.png" />
<view>充值</view>
</view>
<view @tap="topage('/minePages/order/index')">
<image src="../../static/img/cd2.png" />
<view>我的订单</view>
</view>
<view @tap="topage('/minePages/reserlist/index')">
<image src="../../static/img/shiyxy.png" />
<view>预约记录</view>
</view>
<view @tap="topage('/minePages/vehicle/index')">
<image src="../../static/img/cd3.png" />
<view>车辆管理</view>
</view>
</view> -->
<!-- <view v-else @tap="wdltip" class="cdrk">
<view>
<image src="../../static/img/cd1.png" />
<view>充值</view>
</view>
<view>
<image src="../../static/img/cd2.png" />
<view>我的订单</view>
</view>
<view>
<image src="../../static/img/shiyxy.png" />
<view>预约记录</view>
</view>
<view>
<image src="../../static/img/cd3.png" />
<view>车辆管理</view>
</view>
</view> -->
<!-- <view class="cdrk">
<view>
<image src="../../static/img/cd4.png" />
<view>优惠活动</view>
</view>
<view>
<image src="../../static/img/shiyxy.png" />
<view>客服中心</view>
</view>
<view>
<image src="../../static/img/gywm.png" />
<view>加入我们</view>
</view>
<view>
<image src="../../static/img/jrwm.png" />
<view>关于我们</view>
</view>
</view> -->
<!-- <view style="position: absolute;width:100%;bottom: 30rpx;text-align: center;color: #c1c1c1;">关于我们</view> -->
</template>
<script setup lang="ts">
import { ref } from 'vue'
import { onShow } from '@dcloudio/uni-app'
import { login,getUser } from '@/utils/service'
let islogin = ref(false)
let PhoneNumber = ref('')
onShow(() => {
if(uni.getStorageSync('wxuid')){
islogin.value = true
let pnum = uni.getStorageSync('PhoneNumber')
if(pnum){
PhoneNumber.value = pnum
}
}else{
islogin.value = false
PhoneNumber.value = ''
}
})
//
function topage(url:string){
uni.navigateTo({
url
})
}
function wdltip() {
uni.showToast({
title:'请您先登录',
icon:'none'
})
}
</script>
<style lang="scss">
page{
background: #f4f4f4;
}
.top{
box-sizing: border-box;
padding-bottom: 30rpx;
// width: 750rpx;
// height: 450rpx;
//display: flex;
//height: 400rpx;
// padding:200rpx 25rpx 50rpx;
// align-items: center;
// justify-content: space-between;
//background:linear-gradient(to bottom, #00aa7f , #fff);
.bjtp{
width: 750rpx;
height: 450rpx;
}
.userinfor{
position: relative;
display: flex;
margin: -80rpx 20rpx 20rpx;
padding: 20rpx 25rpx;
align-items: center;
justify-content: space-between;
background: #fff;
border-radius: 20rpx;
box-shadow: 0 0 20px 2px rgba(0, 170, 0, 0.5);
.toux{
display: flex;
align-items: center;
image{
width: 100rpx;
height: 100rpx;
border-radius: 50%;
}
view{
padding-left: 10rpx;
//font-size: 40rpx;
//font-weight: bold;
//color: #005500;
}
}
}
}
.gncont{
margin: 0 25rpx;
border-radius: 20rpx;
background: #fff;
.gnrk{
display: flex;
box-sizing: border-box;
padding: 30rpx;
border-bottom: 1px solid #f4f4f4;
justify-content: space-between;
>view:first-child{
display: flex;
align-items:center;
image{
width: 45rpx;
height: 45rpx;
margin-right: 10rpx;
}
}
}
}
.cdrk{
display: flex;
justify-content: space-between;
margin: 10rpx 30rpx 30rpx;
// padding: 20rpx;
// border-radius: 20rpx;
flex-wrap: wrap;
>view{
box-sizing: border-box;
width: 22%;
//margin: 25rpx;
//padding: 25rpx;
//margin-bottom: 50rpx;
text-align: center;
background: #ccc;
//box-shadow: 0 0 20px 2px rgba(221, 221, 221, 0.8);
image{
width: 70rpx;
height: 70rpx;
}
view{
padding-top: 10rpx;
}
}
}
.niche{
width: 200rpx;
padding-left: 20rpx;
text-overflow: ellipsis;
white-space: nowrap;
overflow: hidden;
text-align: left;
font-size: 36rpx;
color: #003829;
}
.btn{
width: 150rpx;
height:64rpx;
background: #00aa7f;
text-align:center;
color:#fff;
border-radius:10rpx;
line-height: 64rpx;
background: #5ac725;
}
</style>

View File

@ -0,0 +1,43 @@
<template>
<up-navbar
title="扫码换电"
bgColor="#00aa7f"
:autoBack="true"
leftIconColor="#00aa7f"
titleStyle="color:#fff"
:placeholder="true"
/>
<view>扫码换电</view>
<view>{{JSON.stringify(code)}}</view>
</template>
<script setup lang="ts">
import { ref } from 'vue'
import { BarHeight } from '@/utils/commen'
import { onTabItemTap } from '@dcloudio/uni-app'
let code = ref<any>('')
onTabItemTap((item) => {
console.log('tabBar item clicked', item);
uni.scanCode({
success(res){
console.log('条码类型:' + res.scanType);
console.log('条码内容:' + res.result);
// uni.navigateTo({
// url:'/codePage/index'
// })
},
fail() {
uni.switchTab({
url: '/pages/home/index'
})
}
})
//
})
</script>
<style>
</style>

6
src/shime-uni.d.ts vendored Normal file
View File

@ -0,0 +1,6 @@
export {}
declare module "vue" {
type Hooks = App.AppInstance & Page.PageInstance;
interface ComponentCustomOptions extends Hooks {}
}

BIN
src/static/img/cd1.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.4 KiB

BIN
src/static/img/cd2.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.4 KiB

BIN
src/static/img/cd3.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.0 KiB

BIN
src/static/img/cd4.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.2 KiB

BIN
src/static/img/chongz.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 673 B

BIN
src/static/img/gywm.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.4 KiB

BIN
src/static/img/jrwm.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 977 B

BIN
src/static/img/kefu.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.6 KiB

BIN
src/static/img/shiyxy.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 758 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.4 KiB

BIN
src/static/img/toux.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 18 KiB

BIN
src/static/img/wobg.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 52 KiB

BIN
src/static/logo.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.3 KiB

BIN
src/static/logo1.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.0 KiB

76
src/uni.scss Normal file
View File

@ -0,0 +1,76 @@
/**
* 这里是uni-app内置的常用样式变量
*
* uni-app 官方扩展插件及插件市场https://ext.dcloud.net.cn上很多三方插件均使用了这些样式变量
* 如果你是插件开发者建议你使用scss预处理并在插件代码中直接使用这些变量无需 import 这个文件方便用户通过搭积木的方式开发整体风格一致的App
*
*/
/**
* 如果你是App开发者插件使用者你可以通过修改这些变量来定制自己的插件主题实现自定义主题功能
*
* 如果你的项目同样使用了scss预处理你也可以直接在你的 scss 代码中使用如下变量同时无需 import 这个文件
*/
@import 'uview-plus/theme.scss';
/* 颜色变量 */
/* 行为相关颜色 */
$uni-color-primary: #007aff;
$uni-color-success: #4cd964;
$uni-color-warning: #f0ad4e;
$uni-color-error: #dd524d;
/* 文字基本颜色 */
$uni-text-color: #333; // 基本色
$uni-text-color-inverse: #fff; // 反色
$uni-text-color-grey: #999; // 辅助灰色如加载更多的提示信息
$uni-text-color-placeholder: #808080;
$uni-text-color-disable: #c0c0c0;
/* 背景颜色 */
$uni-bg-color: #fff;
$uni-bg-color-grey: #f8f8f8;
$uni-bg-color-hover: #f1f1f1; // 点击状态颜色
$uni-bg-color-mask: rgba(0, 0, 0, 0.4); // 遮罩颜色
/* 边框颜色 */
$uni-border-color: #c8c7cc;
/* 尺寸变量 */
/* 文字尺寸 */
$uni-font-size-sm: 12px;
$uni-font-size-base: 14px;
$uni-font-size-lg: 16;
/* 图片尺寸 */
$uni-img-size-sm: 20px;
$uni-img-size-base: 26px;
$uni-img-size-lg: 40px;
/* Border Radius */
$uni-border-radius-sm: 2px;
$uni-border-radius-base: 3px;
$uni-border-radius-lg: 6px;
$uni-border-radius-circle: 50%;
/* 水平间距 */
$uni-spacing-row-sm: 5px;
$uni-spacing-row-base: 10px;
$uni-spacing-row-lg: 15px;
/* 垂直间距 */
$uni-spacing-col-sm: 4px;
$uni-spacing-col-base: 8px;
$uni-spacing-col-lg: 12px;
/* 透明度 */
$uni-opacity-disabled: 0.3; // 组件禁用态的透明度
/* 文章场景相关 */
$uni-color-title: #2c405a; // 文章标题颜色
$uni-font-size-title: 20px;
$uni-color-subtitle: #555; // 二级标题颜色
$uni-font-size-subtitle: 18px;
$uni-color-paragraph: #3f536e; // 文章段落颜色
$uni-font-size-paragraph: 15px;

1
src/utils/commen.ts Normal file
View File

@ -0,0 +1 @@
export const BarHeight = uni.getSystemInfoSync().statusBarHeight

23
src/utils/config.ts Normal file
View File

@ -0,0 +1,23 @@
const ENV = process.env.APP_ENV || process.env.NODE_ENV;
const confing = {
development: {
// #ifdef MP-WEIXIN
//apiBaseUrl:'https://587910rq36.zicp.fun' //'http://192.168.110.73:8082/' //https://xcjf.56365.cc/' //'/fetch'//网站域名接口地址参考发布小程序和APP时使用
// #endif
// #ifdef H5
//apiBaseUrl:'https://587910rq36.zicp.fun' //'/fetch/' //'http://192.168.110.73:8082/' //https://xcjf.56365.cc/' //'/fetch'//网站域名接口地址参考发布小程序和APP时使用
// #endif
apiBaseUrl:'http://192.168.5.213:9100/gateway'
},
production: {
//apiBaseUrl:'http://124.239.176.15:8888',
apiBaseUrl:'https://api.evo-techina.com'
//API_URL:'http://chuangcheng.56365.cc' //测试环境
}
}
export default {
ENV,
...confing[ENV]
}

93
src/utils/request.ts Normal file
View File

@ -0,0 +1,93 @@
//import conf from './config'
let httpList:any[] = []
export function request(method:any,url:string,data?:any,isLoading?:any){
if(isLoading != false){
uni.showLoading({
title: '加载中...',
mask:true
})
}
let headers:any = {}
if(method == 'post_form'){
method = 'POST'
headers['content-type'] = 'application/x-www-form-urlencoded'
}else if(method == 'post_json'){
method = 'POST'
headers['content-type'] = 'application/json'
}
//headers['token'] = '6c878986484a3c23de7fa39c4bf60870' //get('userToken')
headers['wxuid'] = uni.getStorageSync('wxuid')?uni.getStorageSync('wxuid'):''
headers['wxToken'] = uni.getStorageSync('wxToken')?uni.getStorageSync('wxToken'):''
//data = Object.assign({},data,{method:dataMethod})
//headers['Authorization'] = uni.getStorageSync('TOKEN')
return new Promise((resolve,reject) => {
httpList.push(
uni.request({
header:headers,
//url:'http://192.168.5.200:9100/gateway'+ url,//`${conf.apiBaseUrl}${url}`,
//url:'http://192.168.5.213:9100/gateway'+ url,
url:'https://api.evo-techina.com'+url,
method,
data:data,
timeout:30000,
success(rps) {
//console.log(rps)
if(isLoading != false){
uni.hideLoading()
}
if((rps.data as any).code == 1000){
resolve(rps.data)
}else if((rps.data as any).code == 'D0402'){
resolve({data:[]})
}else if((rps.data as any).code == 'W0404'){
resolve({data:[]})
}else if((rps.data as any).code == 'W0405'){
//uni.removeStorageSync('wxToken')
if(url == '/wechat/login/checksessionkey'){
resolve(rps.data)
}else{
uni.setStorageSync('wxToken',(rps.data as any).wxToken)
request(method,url,data,isLoading)
}
}else{
setTimeout(() => {
uni.showToast({
title:(rps.data as any).msg,
icon:'none'
})
},200)
reject(rps.data)
}
},
complete(rps){
if(!(rps as any).statusCode){
if(isLoading != false){
uni.hideLoading()
}
if(rps.errMsg != 'request:fail abort'){
setTimeout(() => {
uni.showToast({
title:'网络错误',
icon:'none'
})
},200)
}
reject((rps as any).statusCode)
}
}
})
)
})
}
//终端请求
export function abort() {
httpList.forEach(n => {
n.abort()
})
httpList.splice(0)
}

196
src/utils/service.ts Normal file
View File

@ -0,0 +1,196 @@
import { request } from './request'
//登录
export function login(parameter:any){
return request('post_form','/wechat/login/xcxlogin',parameter,false)
}
//检查登录状态
export function loginstate(parameter?:any){
return request('post_form','/wechat/login/checksessionkey',parameter,false)
}
//获取手机号
export function getphone(parameter:any){
return request('post_form','/wechat/login/phone',parameter)
}
//查询用户信息
export function getInfo(parameter:any){
return request('post_form','/wechat/wechat/user/userbyuid',parameter)
}
//修改用户信息
interface Infor{
wuid?:String //微信用户id
appid?:String
openid?:String
unionid?:String
phoneNumber?:String //手机号
nickName?:String //用户昵称
avatarUrl?:String //用户头像
name?:String //名称
gender?:String //用户性别1-男2-女
type?:String //类型1-独立账户2-公司员工子账户
pcode?:String //父账户编码
pname?:String //父账户名称
}
export function inforupdate(parameter:Infor){
return request('post_form','/wechat/wechat/user/update',parameter)
}
//预约
interface Ydata{
source:String //来源1-小程序2-云端3-站端
ucode:String //预约人编码
uname:String //预约人姓名
phone:String //手机号码
plateNum:String //车牌号
stationCode:String //换电站编码
stationName:String //换电站名称
swapDay:String //预约换电日期,示例值(yyyyMMdd)
reservationTime?:String //预约时间
swapDuration?:String //预约换电时间段,示例值(8:00-10:00)
}
export function addrese(parameter:Ydata){
return request('post_form','/wechat/cloud/order/swap/pre/add',parameter)
}
//预约记录
export function getyylist(parameter:any){
return request('GET','/wechat/cloud/order/swap/pre/list',parameter)
}
//取消预约
export function cancelrese(id:string){
return request('post_form','/wechat/cloud/order/swap/pre/cancel',{id})
}
//查询换电站
export function gethdz(parameter:any){
return request('GET','/wechat/cloud/station/list',parameter)
}
//微信小程序授权登录
export function getUser() {
return new Promise((rsv,rjt) => {
//微信 小程序 基础库 2.27.1及 以上版本被收回 无法获取昵称和头像
uni.showLoading({
title: '加载中'
})
uni.getUserProfile({
lang: 'zh_CN',
desc: '获取用户相关信息',
success(res) {
console.log(res)
// uni.showLoading({
// title: '加载中'
// });
uni.login({
success:data => {
//用code调接口获取token
login({
js_code:data.code
}).then((rps:any) => {
uni.hideLoading()
uni.setStorageSync('wxuid', rps.data.wuid)
uni.setStorageSync('wxToken', rps.data.wxToken)
rsv('')
//uni.setStorageSync('code', data.code)
// uni.reLaunch({
// url:'/pages/login/index'
// })
// uni.navigateTo({
// url:'/pages/login/index'
// })
}).catch((err:any) => {
uni.hideLoading()
rjt()
})
},
fail() {
rjt()
}
})
},
fail() {
uni.hideLoading()
rjt()
// uni.clearStorageSync()
// uni.clearStorageSync()
console.log('用户拒绝了授权')
}
})
})
}
//查询订单
interface Oderqs{
pageSize:String|Number //每页条数,示例值
pageNo:String|Number //页数,示例值
status?:String|Number //订单状态 1-已创建2-换电中3-换电完成4-充电中5-充电完成6-待结算7-已完成9-已取消
orderNo?:String //订单编码
plateNum?:String //车牌号
plateNums?:String //多车牌号
orderTimeBegin?:String //订单时间开始,示例值(yyyy-MM-dd HH:mm:ss)
orderTimeEnd?:String //订单时间结束
stationCode?:String //换电站编码
stationName?:String //换电站名称
userId?:String //换电车主ID
tradeNo?:String //交易编码
}
export function orderlist(parameter:Oderqs){
return request('GET','/wechat/cloud/order/swap/list',parameter)
}
//查询换电步骤
export function dzbzxq(orderNo:string){
return request('GET','/wechat/cloud/order/swap/step/list',{orderNo})
}
//协议
interface Agrqs{
appid:String,
type:String
}
export function agreement(parameter:Agrqs){
return request('GET','/wechat/resource/agreement/list',parameter)
}
//轮播图
interface Lbtqs{
appid:String,
type:String|Number //1 logo 2 轮播图
}
export function swiperimg(parameter:Lbtqs){
return request('GET','/wechat/resource/swiper/list',parameter)
}
//查询车辆
export function carlist(wuid:String){
return request('GET','/wechat/cloud/wechatuser/carlist',{wuid})
}
//支付
interface Payment{
wuid:String,
remarks:String,
money:String|Number,
detail:{
costPrice:String|Number,
invoiceId:String,
goodsDetail:{
merchantGoodsId:String
wechatpayGoodsId:String
goodsName:String
quantity:String|Number
unitPrice:String|Number
}
}
}
export function payment(parameter:Payment){
return request('post_json','/wechat/wechatpay/xcx/prepay',parameter)
}

13
tsconfig.json Normal file
View File

@ -0,0 +1,13 @@
{
"extends": "@vue/tsconfig/tsconfig.json",
"compilerOptions": {
"sourceMap": true,
"baseUrl": ".",
"paths": {
"@/*": ["./src/*"]
},
"lib": ["esnext", "dom"],
"types": ["@dcloudio/types","uview-plus/types"]
},
"include": ["src/**/*.ts", "src/**/*.d.ts", "src/**/*.tsx", "src/**/*.vue"]
}

10
vite.config.ts Normal file
View File

@ -0,0 +1,10 @@
import { defineConfig } from "vite";
import uni from "@dcloudio/vite-plugin-uni";
// https://vitejs.dev/config/
export default defineConfig({
plugins: [uni()],
server: {
port: 8088
}
});