first commit
21
.gitignore
vendored
Normal 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?
|
||||||
23
.hbuilderx/launch.json
Normal file
@@ -0,0 +1,23 @@
|
|||||||
|
{
|
||||||
|
// 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"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"playground" : "standard",
|
||||||
|
"type" : "uni-app:app-android"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
1
.svn/entries
Normal file
@@ -0,0 +1 @@
|
|||||||
|
12
|
||||||
1
.svn/format
Normal file
@@ -0,0 +1 @@
|
|||||||
|
12
|
||||||
@@ -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>
|
||||||
|
After Width: | Height: | Size: 13 KiB |
@@ -0,0 +1,13 @@
|
|||||||
|
import { createSSRApp } from "vue";
|
||||||
|
import App from "./App.vue";
|
||||||
|
|
||||||
|
import uviewPlus from 'uview-plus'
|
||||||
|
|
||||||
|
export function createApp() {
|
||||||
|
const app = createSSRApp(App);
|
||||||
|
App.mpType = 'app';
|
||||||
|
app.use(uviewPlus)
|
||||||
|
return {
|
||||||
|
app,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
After Width: | Height: | Size: 2.9 KiB |
@@ -0,0 +1,225 @@
|
|||||||
|
<template>
|
||||||
|
<view class="home">
|
||||||
|
<view class=""
|
||||||
|
style=" margin-top: 200rpx; display: flex; flex-direction: column; justify-content: center; align-items: center;">
|
||||||
|
<image :src="Service.GetIconImg('/static/index/logo/logo.png')" style="width: 150rpx; height: 150rpx; "
|
||||||
|
mode=""></image>
|
||||||
|
<view class="" style="font-size: 36rpx; font-weight: 800; margin-top: 20rpx;">
|
||||||
|
菜农·商家端
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
<view class="" style="margin: 30rpx 30rpx; margin-top: 150rpx;">
|
||||||
|
|
||||||
|
<view class="" style="font-size: 34rpx; font-weight: 600; ">
|
||||||
|
欢迎登陆
|
||||||
|
</view>
|
||||||
|
|
||||||
|
<view class="" style="font-size: 28rpx; margin-top: 20rpx; ">
|
||||||
|
手机号登录,安全又便捷
|
||||||
|
</view>
|
||||||
|
|
||||||
|
<view v-if="type" class="" >
|
||||||
|
<view class="" style="margin-top: 30rpx;">
|
||||||
|
<up-input v-model="login.phone" type="number" shape='circle'
|
||||||
|
:customStyle="{'padding':'20rpx 30rpx','font-size':'32rpx'}" placeholder="请输入手机号"
|
||||||
|
clearable='true' border="surround"></up-input>
|
||||||
|
</view>
|
||||||
|
|
||||||
|
<view class="" style="margin-top: 30rpx;">
|
||||||
|
<up-input v-model="login.password" type="password" shape='circle'
|
||||||
|
:customStyle="{'padding':'20rpx 30rpx','font-size':'32rpx'}" placeholder="请输入密码"
|
||||||
|
clearable='true' border="surround"></up-input>
|
||||||
|
</view>
|
||||||
|
|
||||||
|
<view class="" style="margin-top: 30rpx;" v-if="!isLogin">
|
||||||
|
<up-input v-model="qudPow" type="password" shape='circle'
|
||||||
|
:customStyle="{'padding':'20rpx 30rpx','font-size':'32rpx'}" placeholder="确认密码"
|
||||||
|
clearable='true' border="surround"></up-input>
|
||||||
|
</view>
|
||||||
|
|
||||||
|
<!-- <view class=""
|
||||||
|
style=" display: flex; align-items: center; justify-content: space-between; margin-top: 30rpx; border: 1rpx solid #dadbde; box-sizing: border-box; padding: 20rpx 30rpx; border-radius: 200rpx; ">
|
||||||
|
<up-code-input v-model="login.code" mode="line" size='24'></up-code-input>
|
||||||
|
<view class="wrap">
|
||||||
|
<up-toast ref="uToastRef"></up-toast>
|
||||||
|
<up-code :seconds="seconds" @end="end" @start="start" ref="uCodeRef"
|
||||||
|
@change="codeChange"></up-code>
|
||||||
|
<view @click="getCode">{{tips}}</view>
|
||||||
|
</view>
|
||||||
|
</view> -->
|
||||||
|
|
||||||
|
|
||||||
|
</view>
|
||||||
|
<!-- <view v-else class="">
|
||||||
|
<view class="" style="margin-top: 30rpx;">
|
||||||
|
<up-input v-model="login.phone" type="number" shape='circle'
|
||||||
|
:customStyle="{'padding':'20rpx 30rpx','font-size':'32rpx'}" placeholder="请输入账号"
|
||||||
|
clearable='true' border="surround"></up-input>
|
||||||
|
</view>
|
||||||
|
|
||||||
|
<view class="" style="margin-top: 30rpx;">
|
||||||
|
<up-input v-model="login.phone" type="number" shape='circle'
|
||||||
|
:customStyle="{'padding':'20rpx 30rpx','font-size':'32rpx'}" placeholder="请输入密码"
|
||||||
|
clearable='true' border="surround"></up-input>
|
||||||
|
</view>
|
||||||
|
</view> -->
|
||||||
|
|
||||||
|
<view class="" style="margin-top: 40rpx; width: 100%; height: 80rpx; line-height: 80rpx; border-radius: 40rpx; background-color: #FFDE1D; color: #fff; font-size: 30rpx; text-align: center;" @click="loginshop()">
|
||||||
|
登录
|
||||||
|
</view>
|
||||||
|
|
||||||
|
<view class="" style="width: 90%; margin: 0 auto; margin-top: 20rpx; display: flex; justify-content: space-between; color: #999; font-size: 28rpx;">
|
||||||
|
<view class="">
|
||||||
|
忘记密码
|
||||||
|
</view>
|
||||||
|
<view class="" @click="isLogin = !isLogin">
|
||||||
|
{{isLogin?'去注册':'已有账号去登录'}}
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
|
||||||
|
|
||||||
|
<!-- <view class="" @click="type=!type" style="text-align: center; color: #637aff; margin: 50rpx 0; ">
|
||||||
|
{{ !type?'使用验证码登录':'使用密码登录' }}
|
||||||
|
</view> -->
|
||||||
|
|
||||||
|
<view class="" style="display: flex; justify-content: center; align-items: center;color: black; margin-top: 50rpx; " @click="isuser= !isuser">
|
||||||
|
<view class="" style="margin-right: 10rpx;">
|
||||||
|
<up-icon :name="!isuser?'checkmark-circle':'checkmark-circle-fill'" :color="!isuser?'#999':'var(--nav-mian)'" size="20"></up-icon>
|
||||||
|
</view>
|
||||||
|
我同意
|
||||||
|
<text style="color: #FF6B23;">《用户协议》</text>
|
||||||
|
和
|
||||||
|
<text style="color: #FF6B23;">《隐私政策》</text>
|
||||||
|
</view>
|
||||||
|
<view class="" style="text-align: center; margin-top: 20rpx;">
|
||||||
|
<!-- 新用户?系统将自动为您注册 -->
|
||||||
|
</view>
|
||||||
|
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script setup lang="ts">
|
||||||
|
import { onShow, onLoad } from "@dcloudio/uni-app";
|
||||||
|
import { Service ,CNRiderLoginService } from "@/Service/CN/CNRiderLoginService"
|
||||||
|
import { ref } from "vue";
|
||||||
|
|
||||||
|
let qudPow = ref<string>('')
|
||||||
|
|
||||||
|
let login = ref({
|
||||||
|
phone: '',
|
||||||
|
code: '',
|
||||||
|
password:''
|
||||||
|
})
|
||||||
|
|
||||||
|
const tips = ref('');
|
||||||
|
const seconds = ref(60);
|
||||||
|
const uCodeRef = ref(null);
|
||||||
|
|
||||||
|
let type = ref(true)
|
||||||
|
|
||||||
|
let isLogin = ref<boolean>(true)//登录注册状态
|
||||||
|
|
||||||
|
let isuser = ref<boolean>(false)//用户同意协议
|
||||||
|
|
||||||
|
|
||||||
|
onLoad(() => {
|
||||||
|
|
||||||
|
});
|
||||||
|
|
||||||
|
onShow(() => {
|
||||||
|
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
|
//登录
|
||||||
|
const loginshop = () =>{
|
||||||
|
if(login.value.phone==''){
|
||||||
|
return Service.Msg('请输入手机号/账号!')
|
||||||
|
}
|
||||||
|
|
||||||
|
if(login.value.password==''){
|
||||||
|
return Service.Msg('请输入密码!')
|
||||||
|
}
|
||||||
|
|
||||||
|
if(!isLogin.value && qudPow.value==''){
|
||||||
|
return Service.Msg('请确认密码!')
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
if(!isLogin.value && login.value.password!=qudPow.value){
|
||||||
|
return Service.Msg('两次密码不同!')
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
console.log(isuser.value)
|
||||||
|
|
||||||
|
if(!isuser.value){
|
||||||
|
return Service.Msg('请勾选同意用户协议!')
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
CNRiderLoginService.RiderLogin(login.value).then(res=>{
|
||||||
|
if(res.code==0){
|
||||||
|
Service.Msg('登录成功!')
|
||||||
|
Service.SetUserToken(res.data.accToken)
|
||||||
|
if(res.data.type==-1){
|
||||||
|
Service.GoPage('/pages/shop/Apply')
|
||||||
|
}else{
|
||||||
|
Service.GoPageTab('/pages/index/index')
|
||||||
|
}
|
||||||
|
}else{
|
||||||
|
Service.Msg(res.msg)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
const codeChange = (text) => {
|
||||||
|
tips.value = text;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
const getCode = () => {
|
||||||
|
if (uCodeRef.value.canGetCode) {
|
||||||
|
// 模拟向后端请求验证码
|
||||||
|
uni.showLoading({
|
||||||
|
title: '正在获取验证码',
|
||||||
|
});
|
||||||
|
setTimeout(() => {
|
||||||
|
uni.hideLoading();
|
||||||
|
// 这里此提示会被start()方法中的提示覆盖
|
||||||
|
Service.Msg('验证码已发送')
|
||||||
|
// 通知验证码组件内部开始倒计时
|
||||||
|
uCodeRef.value.start();
|
||||||
|
}, 2000);
|
||||||
|
} else {
|
||||||
|
Service.Msg('倒计时结束后再发送')
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
const end = () => {
|
||||||
|
console.log('倒计时结束');
|
||||||
|
};
|
||||||
|
|
||||||
|
const start = () => {
|
||||||
|
console.log('倒计时开始');
|
||||||
|
};
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style lang="scss">
|
||||||
|
.home {
|
||||||
|
width: 100vw;
|
||||||
|
height: 100vh;
|
||||||
|
background: linear-gradient(to bottom, #FFDE1D, #fff 40%);
|
||||||
|
overflow: hidden;
|
||||||
|
}
|
||||||
|
.chen{
|
||||||
|
|
||||||
|
}
|
||||||
|
</style>
|
||||||
@@ -0,0 +1,63 @@
|
|||||||
|
<template>
|
||||||
|
<view style="margin: 20rpx 100rpx;">
|
||||||
|
<up-form labelPosition="left" labelWidth='90' :model="password" ref="form1">
|
||||||
|
<up-form-item label="姓名" prop="userInfo.name" :borderBottom="true" ref="item1">
|
||||||
|
<up-input clearable='true' placeholder="请输入联系人姓名"
|
||||||
|
border="none"></up-input>
|
||||||
|
</up-form-item>
|
||||||
|
<up-form-item label="手机号" prop="userInfo.name" :borderBottom="true" ref="item1">
|
||||||
|
<up-input clearable='true' placeholder="请输入手机号"
|
||||||
|
border="none"></up-input>
|
||||||
|
</up-form-item>
|
||||||
|
</up-form>
|
||||||
|
<view class="" style="margin-top: 20rpx;">
|
||||||
|
<button @click="save()" :disabled='!password.password || !password.code ' class="logout-btn">确认</button>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script setup lang="ts">
|
||||||
|
import { onShow, onLoad } from "@dcloudio/uni-app";
|
||||||
|
import { ref } from "vue";
|
||||||
|
import { Service } from "../../Service/Service";
|
||||||
|
|
||||||
|
|
||||||
|
let password = ref({
|
||||||
|
password: '',
|
||||||
|
code: ''
|
||||||
|
})
|
||||||
|
|
||||||
|
onLoad(() => {
|
||||||
|
|
||||||
|
});
|
||||||
|
|
||||||
|
onShow(() => {
|
||||||
|
|
||||||
|
});
|
||||||
|
|
||||||
|
const save = () => {
|
||||||
|
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style lang="scss">
|
||||||
|
page {
|
||||||
|
background-color: #fff;
|
||||||
|
}
|
||||||
|
|
||||||
|
.logout-btn {
|
||||||
|
background-color: var(--nav-banbacor);
|
||||||
|
color: #fff;
|
||||||
|
font-weight: 500;
|
||||||
|
border-radius: 10rpx;
|
||||||
|
height: 80rpx;
|
||||||
|
line-height: 80rpx;
|
||||||
|
font-size: 30rpx;
|
||||||
|
margin: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.logout-btn:active {
|
||||||
|
background-color: #f7f7f7;
|
||||||
|
color: #000;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
After Width: | Height: | Size: 813 B |
@@ -0,0 +1,234 @@
|
|||||||
|
<template>
|
||||||
|
<view v-if="isLoading" class="skeleton-container" style="padding: 10rpx 30rpx">
|
||||||
|
<!-- 骨架屏记录项 -->
|
||||||
|
<view class="skeleton-record-item" v-for="i in 3" :key="i">
|
||||||
|
<!-- 标题骨架 -->
|
||||||
|
<view class="skeleton-title"></view>
|
||||||
|
|
||||||
|
<!-- 金额区域骨架 -->
|
||||||
|
<view class="skeleton-amount-section">
|
||||||
|
<view class="skeleton-amount-line"></view>
|
||||||
|
<view class="skeleton-amount-value"></view>
|
||||||
|
</view>
|
||||||
|
|
||||||
|
<!-- 信息行骨架 -->
|
||||||
|
<view class="skeleton-info-row">
|
||||||
|
<view class="skeleton-info-label"></view>
|
||||||
|
<view class="skeleton-info-value"></view>
|
||||||
|
</view>
|
||||||
|
|
||||||
|
<view class="skeleton-info-row">
|
||||||
|
<view class="skeleton-info-label"></view>
|
||||||
|
<view class="skeleton-info-value"></view>
|
||||||
|
</view>
|
||||||
|
|
||||||
|
<view class="skeleton-info-row">
|
||||||
|
<view class="skeleton-info-label"></view>
|
||||||
|
<view class="skeleton-info-value"></view>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
|
||||||
|
<!-- 加载更多骨架 -->
|
||||||
|
<view class="skeleton-loadmore"></view>
|
||||||
|
</view>
|
||||||
|
<view v-else style="padding: 10rpx 30rpx;">
|
||||||
|
<view class="" v-for="(item,index) in withdrowList" :key="index"
|
||||||
|
style="margin-top: 20rpx; gap: 20rpx; background-color: #fff; border-radius: 20rpx; padding: 30rpx; ">
|
||||||
|
<view class="" style="font-weight: bold; border-bottom: 1rpx solid #f6f6f6; padding-bottom: 15rpx;">
|
||||||
|
余额提现-{{ item.payway}}
|
||||||
|
</view>
|
||||||
|
<view class=""
|
||||||
|
style="width: 100%; height: 200rpx; display: flex;flex-direction: column; justify-content: center; align-items: center; ">
|
||||||
|
<view class="" style="">
|
||||||
|
提现金额 {{ item.amount}} 元
|
||||||
|
</view>
|
||||||
|
<view class="" style="font-size: 32rpx; font-weight: bold; margin-top: 10rpx; ">
|
||||||
|
实际到账 {{item.withAmount}} 元
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
<view class="" style="display: flex; align-items: center; gap: 30rpx; ">
|
||||||
|
<view class="" style="width: 120rpx;">
|
||||||
|
收款人
|
||||||
|
</view>
|
||||||
|
<view class="" style="">
|
||||||
|
{{ item.name }}
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
<view class="" style="display: flex; align-items: center; gap: 30rpx; margin-top: 10rpx; ">
|
||||||
|
<view class="" style="width: 120rpx;">
|
||||||
|
提现账号
|
||||||
|
</view>
|
||||||
|
<view class="" style="">
|
||||||
|
{{ item.account }}
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
<view class="" style="display: flex; align-items: center; gap: 30rpx; margin-top: 10rpx;">
|
||||||
|
<view class="" style="width: 120rpx;">
|
||||||
|
提现时间
|
||||||
|
</view>
|
||||||
|
<view class="" style="">
|
||||||
|
{{ Service.formatDate(item.addTime,1) }}
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
<up-loadmore :status="status" />
|
||||||
|
</view>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script setup lang="ts">
|
||||||
|
import { onShow, onLoad, onReachBottom } from "@dcloudio/uni-app";
|
||||||
|
import { Service } from '@/Service/Service';
|
||||||
|
import { ref } from "vue";
|
||||||
|
import { CNRiderOrderService } from '@/Service/CN/CNRiderOrderService'
|
||||||
|
|
||||||
|
let isLoading = ref(true)
|
||||||
|
|
||||||
|
let withdrowList = ref<Array<any>>([])
|
||||||
|
let status = ref('nomore')
|
||||||
|
let page = ref(1)
|
||||||
|
|
||||||
|
onLoad(() => {
|
||||||
|
getData()
|
||||||
|
});
|
||||||
|
|
||||||
|
onShow(() => {
|
||||||
|
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
onReachBottom(() => {
|
||||||
|
getList()
|
||||||
|
})
|
||||||
|
|
||||||
|
const getData = () => {
|
||||||
|
status.value = 'loadmore'
|
||||||
|
page.value = 1
|
||||||
|
withdrowList.value = []
|
||||||
|
getList()
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//获取订单
|
||||||
|
const getList = () => {
|
||||||
|
if (status.value == 'nomore' || status.value == 'loading') {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
status.value == 'loadmore'
|
||||||
|
CNRiderOrderService.GetRiderWithList(page.value).then(res => {
|
||||||
|
isLoading.value = false
|
||||||
|
if (res.data) {
|
||||||
|
withdrowList.value = [...withdrowList.value, ...res.data.list]
|
||||||
|
status.value = res.data.list == 10 ? 'loadmore' : 'nomore'
|
||||||
|
page.value++
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style lang="scss">
|
||||||
|
.icon-placeholder {
|
||||||
|
width: 70rpx;
|
||||||
|
height: 70rpx;
|
||||||
|
background-color: #E6F7FF;
|
||||||
|
border-radius: 8rpx;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 骨架屏样式 */
|
||||||
|
.skeleton-record-item {
|
||||||
|
margin-top: 20rpx;
|
||||||
|
background-color: #fff;
|
||||||
|
border-radius: 20rpx;
|
||||||
|
padding: 30rpx;
|
||||||
|
gap: 20rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
.skeleton-title {
|
||||||
|
width: 200rpx;
|
||||||
|
height: 32rpx;
|
||||||
|
background: linear-gradient(90deg, #f0f0f0 25%, #e6e6e6 50%, #f0f0f0 75%);
|
||||||
|
background-size: 200% 100%;
|
||||||
|
border-radius: 4rpx;
|
||||||
|
margin-bottom: 20rpx;
|
||||||
|
animation: skeleton-loading 1.5s infinite ease-in-out;
|
||||||
|
}
|
||||||
|
|
||||||
|
.skeleton-amount-section {
|
||||||
|
width: 100%;
|
||||||
|
height: 200rpx;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
justify-content: center;
|
||||||
|
align-items: center;
|
||||||
|
margin-bottom: 20rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
.skeleton-amount-line {
|
||||||
|
width: 180rpx;
|
||||||
|
height: 28rpx;
|
||||||
|
background: linear-gradient(90deg, #f0f0f0 25%, #e6e6e6 50%, #f0f0f0 75%);
|
||||||
|
background-size: 200% 100%;
|
||||||
|
border-radius: 4rpx;
|
||||||
|
margin-bottom: 10rpx;
|
||||||
|
animation: skeleton-loading 1.5s infinite ease-in-out;
|
||||||
|
}
|
||||||
|
|
||||||
|
.skeleton-amount-value {
|
||||||
|
width: 250rpx;
|
||||||
|
height: 40rpx;
|
||||||
|
background: linear-gradient(90deg, #f0f0f0 25%, #e6e6e6 50%, #f0f0f0 75%);
|
||||||
|
background-size: 200% 100%;
|
||||||
|
border-radius: 4rpx;
|
||||||
|
animation: skeleton-loading 1.5s infinite ease-in-out;
|
||||||
|
}
|
||||||
|
|
||||||
|
.skeleton-info-row {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
gap: 30rpx;
|
||||||
|
margin-top: 10rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
.skeleton-info-label {
|
||||||
|
width: 120rpx;
|
||||||
|
height: 28rpx;
|
||||||
|
background: linear-gradient(90deg, #f0f0f0 25%, #e6e6e6 50%, #f0f0f0 75%);
|
||||||
|
background-size: 200% 100%;
|
||||||
|
border-radius: 4rpx;
|
||||||
|
animation: skeleton-loading 1.5s infinite ease-in-out;
|
||||||
|
}
|
||||||
|
|
||||||
|
.skeleton-info-value {
|
||||||
|
width: 300rpx;
|
||||||
|
height: 28rpx;
|
||||||
|
background: linear-gradient(90deg, #f0f0f0 25%, #e6e6e6 50%, #f0f0f0 75%);
|
||||||
|
background-size: 200% 100%;
|
||||||
|
border-radius: 4rpx;
|
||||||
|
animation: skeleton-loading 1.5s infinite ease-in-out;
|
||||||
|
}
|
||||||
|
|
||||||
|
.skeleton-loadmore {
|
||||||
|
width: 100%;
|
||||||
|
height: 80rpx;
|
||||||
|
background: linear-gradient(90deg, #f0f0f0 25%, #e6e6e6 50%, #f0f0f0 75%);
|
||||||
|
background-size: 200% 100%;
|
||||||
|
border-radius: 4rpx;
|
||||||
|
margin-top: 20rpx;
|
||||||
|
animation: skeleton-loading 1.5s infinite ease-in-out;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 骨架屏动画 */
|
||||||
|
@keyframes skeleton-loading {
|
||||||
|
0% {
|
||||||
|
background-position: -100% 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
100% {
|
||||||
|
background-position: 100% 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</style>
|
||||||
@@ -0,0 +1,625 @@
|
|||||||
|
<template>
|
||||||
|
<view v-if="isLoading" class="rider-home-skeleton">
|
||||||
|
<!-- 用户信息区域骨架 -->
|
||||||
|
<view class="skeleton-user-info">
|
||||||
|
<view class="skeleton-user-header">
|
||||||
|
<view class="skeleton-avatar"></view>
|
||||||
|
<view class="skeleton-user-details">
|
||||||
|
<view class="skeleton-user-name"></view>
|
||||||
|
<view class="skeleton-user-id"></view>
|
||||||
|
</view>
|
||||||
|
<view class="skeleton-setting-icon"></view>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
|
||||||
|
<!-- 统计数据区域骨架 -->
|
||||||
|
<view class="skeleton-stats-section">
|
||||||
|
<view class="skeleton-stat-item">
|
||||||
|
<view class="skeleton-stat-label"></view>
|
||||||
|
<view class="skeleton-stat-value income"></view>
|
||||||
|
</view>
|
||||||
|
<view class="skeleton-stat-item">
|
||||||
|
<view class="skeleton-stat-label"></view>
|
||||||
|
<view class="skeleton-stat-value completed"></view>
|
||||||
|
</view>
|
||||||
|
<view class="skeleton-stat-item">
|
||||||
|
<view class="skeleton-stat-label"></view>
|
||||||
|
<view class="skeleton-stat-value ongoing"></view>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
|
||||||
|
<!-- 接单按钮骨架 -->
|
||||||
|
<view class="skeleton-action-section">
|
||||||
|
<view class="skeleton-accept-orders-btn"></view>
|
||||||
|
</view>
|
||||||
|
|
||||||
|
<!-- 附近高价单骨架 -->
|
||||||
|
<view class="skeleton-high-price-orders">
|
||||||
|
<view class="skeleton-section-title"></view>
|
||||||
|
|
||||||
|
<!-- 循环生成多个订单项骨架 -->
|
||||||
|
<view class="skeleton-order-item" v-for="index in 3" :key="index">
|
||||||
|
<view class="skeleton-order-header">
|
||||||
|
<view class="skeleton-high-price-tag"></view>
|
||||||
|
<view class="skeleton-order-price"></view>
|
||||||
|
</view>
|
||||||
|
<view class="skeleton-order-content">
|
||||||
|
<view class="skeleton-restaurant-name"></view>
|
||||||
|
<view class="skeleton-pickup-time">
|
||||||
|
<view class="skeleton-clock-icon"></view>
|
||||||
|
<view class="skeleton-pickup-time-text"></view>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
<view class="skeleton-distance"></view>
|
||||||
|
<view class="skeleton-address"></view>
|
||||||
|
<view class="skeleton-grab-order-btn"></view>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
|
||||||
|
<!-- 加载更多骨架 -->
|
||||||
|
<view class="skeleton-loadmore"></view>
|
||||||
|
</view>
|
||||||
|
|
||||||
|
<!-- 实际内容 -->
|
||||||
|
<view v-else class="rider-home">
|
||||||
|
<!-- 用户信息区域 -->
|
||||||
|
<view class="user-info">
|
||||||
|
<view class="user-header">
|
||||||
|
<image :src="Service.GetMateUrlByImg('/static/dele/home/test.jpeg')" mode="aspectFit" class="avatar">
|
||||||
|
</image>
|
||||||
|
<view class="user-details">
|
||||||
|
<text class="user-name">大大怪将军</text>
|
||||||
|
<text class="user-id">ID: LN007 · 已下线</text>
|
||||||
|
</view>
|
||||||
|
<up-icon @click="Service.GoPage('/pages/my/edit')" name="setting" size="32rpx" color="#333333"></up-icon>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
|
||||||
|
<!-- 统计数据区域 -->
|
||||||
|
<view class="stats-section">
|
||||||
|
<view class="stat-item">
|
||||||
|
<text class="stat-label">今日收入</text>
|
||||||
|
<text class="stat-value income">¥86.50</text>
|
||||||
|
</view>
|
||||||
|
<view class="stat-item">
|
||||||
|
<text class="stat-label">已完成</text>
|
||||||
|
<text class="stat-value completed">5单</text>
|
||||||
|
</view>
|
||||||
|
<view class="stat-item">
|
||||||
|
<text class="stat-label">进行中</text>
|
||||||
|
<text class="stat-value ongoing">6单</text>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
|
||||||
|
<!-- 接单按钮 -->
|
||||||
|
<view class="action-section">
|
||||||
|
<up-button type="primary" shape="circle" size="default" class="accept-orders-btn"
|
||||||
|
@click="toggleAcceptOrders">{{ userStatus === '已上线' ? '接单中 · 点击暂停' : '点击开始接单' }}</up-button>
|
||||||
|
</view>
|
||||||
|
|
||||||
|
<!-- 附近高价单 -->
|
||||||
|
<view class="high-price-orders">
|
||||||
|
<view class="section-title">附近高价单</view>
|
||||||
|
<view class="order-item" @click="Service.GoPage('/pages/order/grabOrder')" v-for="(order, index) in 3" :key="index">
|
||||||
|
<view class="order-header">
|
||||||
|
<view class="high-price-tag">高价单</view>
|
||||||
|
<text class="order-price">¥20</text>
|
||||||
|
</view>
|
||||||
|
<view class="" style="display: flex; align-items: center; justify-content: space-between;">
|
||||||
|
<text class="restaurant-name">王记炸酱面</text>
|
||||||
|
<view class="pickup-time">
|
||||||
|
<up-icon name="clock" size="24rpx" color="#FF9500"></up-icon>
|
||||||
|
<text class="pickup-time-text">12:30 前取餐</text>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
<text class="distance">距您 0.8km</text>
|
||||||
|
<text class="address">朝阳区三里屯路123号</text>
|
||||||
|
<up-button shape="circle" type="primary" size="mini" class="grab-order-btn"
|
||||||
|
:style="{backgroundColor: '#1890FF'}">立即抢单</up-button>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
<up-loadmore :status="status" />
|
||||||
|
<view class="" style="width: 100%; height: 60rpx; ">
|
||||||
|
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script setup lang="ts">
|
||||||
|
import { onLoad } from '@dcloudio/uni-app';
|
||||||
|
import { ref, onMounted } from 'vue';
|
||||||
|
import { Service } from '@/Service/Service';
|
||||||
|
|
||||||
|
|
||||||
|
// 加载状态
|
||||||
|
const isLoading = ref(true);
|
||||||
|
|
||||||
|
let userStatus = ref('已下线')
|
||||||
|
let status = ref('nomore')
|
||||||
|
|
||||||
|
onLoad(() => {
|
||||||
|
setTimeout(() => {
|
||||||
|
isLoading.value = false
|
||||||
|
}, 1500)
|
||||||
|
})
|
||||||
|
|
||||||
|
// 切换接单状态
|
||||||
|
const toggleAcceptOrders = () => {
|
||||||
|
userStatus.value = userStatus.value === '已上线' ? '已下线' : '已上线';
|
||||||
|
};
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style scoped lang="scss">
|
||||||
|
page{
|
||||||
|
background-color: #F6f6f6;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 骨架屏通用样式 */
|
||||||
|
.skeleton-user-info,
|
||||||
|
.skeleton-stats-section,
|
||||||
|
.skeleton-action-section,
|
||||||
|
.skeleton-high-price-orders,
|
||||||
|
.skeleton-order-item,
|
||||||
|
.skeleton-order-header,
|
||||||
|
.skeleton-order-content,
|
||||||
|
.skeleton-pickup-time {
|
||||||
|
animation: skeleton-loading 1.5s infinite ease-in-out;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 用户信息区域骨架 */
|
||||||
|
.skeleton-user-info {
|
||||||
|
background-color: #E6F7FF;
|
||||||
|
padding: 40rpx 30rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
.skeleton-user-header {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.skeleton-avatar {
|
||||||
|
width: 100rpx;
|
||||||
|
height: 100rpx;
|
||||||
|
border-radius: 50%;
|
||||||
|
background-color: #d0d0d0;
|
||||||
|
border: 1px solid #fff;
|
||||||
|
animation: skeleton-loading 1.5s infinite ease-in-out;
|
||||||
|
}
|
||||||
|
|
||||||
|
.skeleton-user-details {
|
||||||
|
margin-left: 20rpx;
|
||||||
|
flex: 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
.skeleton-user-name {
|
||||||
|
width: 200rpx;
|
||||||
|
height: 36rpx;
|
||||||
|
background-color: #d0d0d0;
|
||||||
|
border-radius: 6rpx;
|
||||||
|
margin-bottom: 8rpx;
|
||||||
|
animation: skeleton-loading 1.5s infinite ease-in-out;
|
||||||
|
}
|
||||||
|
|
||||||
|
.skeleton-user-id {
|
||||||
|
width: 250rpx;
|
||||||
|
height: 28rpx;
|
||||||
|
background-color: #d0d0d0;
|
||||||
|
border-radius: 6rpx;
|
||||||
|
animation: skeleton-loading 1.5s infinite ease-in-out;
|
||||||
|
}
|
||||||
|
|
||||||
|
.skeleton-setting-icon {
|
||||||
|
width: 32rpx;
|
||||||
|
height: 32rpx;
|
||||||
|
background-color: #d0d0d0;
|
||||||
|
border-radius: 6rpx;
|
||||||
|
animation: skeleton-loading 1.5s infinite ease-in-out;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 统计数据区域骨架 */
|
||||||
|
.skeleton-stats-section {
|
||||||
|
background-color: #ffffff;
|
||||||
|
margin: 20rpx;
|
||||||
|
border-radius: 16rpx;
|
||||||
|
display: flex;
|
||||||
|
justify-content: space-around;
|
||||||
|
padding: 30rpx 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.skeleton-stat-item {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
align-items: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.skeleton-stat-label {
|
||||||
|
width: 120rpx;
|
||||||
|
height: 28rpx;
|
||||||
|
background-color: #d0d0d0;
|
||||||
|
border-radius: 6rpx;
|
||||||
|
margin-bottom: 10rpx;
|
||||||
|
animation: skeleton-loading 1.5s infinite ease-in-out;
|
||||||
|
}
|
||||||
|
|
||||||
|
.skeleton-stat-value {
|
||||||
|
width: 150rpx;
|
||||||
|
height: 36rpx;
|
||||||
|
background-color: #d0d0d0;
|
||||||
|
border-radius: 6rpx;
|
||||||
|
animation: skeleton-loading 1.5s infinite ease-in-out;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 接单按钮骨架 */
|
||||||
|
.skeleton-action-section {
|
||||||
|
margin: 0 20rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
.skeleton-accept-orders-btn {
|
||||||
|
width: 100%;
|
||||||
|
height: 90rpx;
|
||||||
|
background-color: #d0d0d0;
|
||||||
|
border-radius: 45rpx;
|
||||||
|
animation: skeleton-loading 1.5s infinite ease-in-out;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 附近高价单骨架 */
|
||||||
|
.skeleton-high-price-orders {
|
||||||
|
margin-top: 20rpx;
|
||||||
|
padding: 0 20rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
.skeleton-section-title {
|
||||||
|
width: 200rpx;
|
||||||
|
height: 32rpx;
|
||||||
|
background-color: #d0d0d0;
|
||||||
|
border-radius: 6rpx;
|
||||||
|
margin-bottom: 20rpx;
|
||||||
|
animation: skeleton-loading 1.5s infinite ease-in-out;
|
||||||
|
}
|
||||||
|
|
||||||
|
.skeleton-order-item {
|
||||||
|
background-color: #ffffff;
|
||||||
|
border-radius: 16rpx;
|
||||||
|
padding: 25rpx;
|
||||||
|
margin-bottom: 20rpx;
|
||||||
|
position: relative;
|
||||||
|
}
|
||||||
|
|
||||||
|
.skeleton-order-header {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: space-between;
|
||||||
|
margin-bottom: 15rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
.skeleton-high-price-tag {
|
||||||
|
width: 100rpx;
|
||||||
|
height: 32rpx;
|
||||||
|
background-color: #d0d0d0;
|
||||||
|
border-radius: 16rpx;
|
||||||
|
animation: skeleton-loading 1.5s infinite ease-in-out;
|
||||||
|
}
|
||||||
|
|
||||||
|
.skeleton-order-price {
|
||||||
|
width: 80rpx;
|
||||||
|
height: 32rpx;
|
||||||
|
background-color: #d0d0d0;
|
||||||
|
border-radius: 6rpx;
|
||||||
|
animation: skeleton-loading 1.5s infinite ease-in-out;
|
||||||
|
}
|
||||||
|
|
||||||
|
.skeleton-order-content {
|
||||||
|
margin-bottom: 12rpx;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: space-between;
|
||||||
|
}
|
||||||
|
|
||||||
|
.skeleton-restaurant-name {
|
||||||
|
width: 200rpx;
|
||||||
|
height: 30rpx;
|
||||||
|
background-color: #d0d0d0;
|
||||||
|
border-radius: 6rpx;
|
||||||
|
margin-bottom: 12rpx;
|
||||||
|
animation: skeleton-loading 1.5s infinite ease-in-out;
|
||||||
|
}
|
||||||
|
|
||||||
|
.skeleton-pickup-time {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
margin-bottom: 12rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
.skeleton-clock-icon {
|
||||||
|
width: 24rpx;
|
||||||
|
height: 24rpx;
|
||||||
|
background-color: #d0d0d0;
|
||||||
|
border-radius: 4rpx;
|
||||||
|
margin-right: 8rpx;
|
||||||
|
animation: skeleton-loading 1.5s infinite ease-in-out;
|
||||||
|
}
|
||||||
|
|
||||||
|
.skeleton-pickup-time-text {
|
||||||
|
width: 200rpx;
|
||||||
|
height: 26rpx;
|
||||||
|
background-color: #d0d0d0;
|
||||||
|
border-radius: 4rpx;
|
||||||
|
animation: skeleton-loading 1.5s infinite ease-in-out;
|
||||||
|
}
|
||||||
|
|
||||||
|
.skeleton-distance {
|
||||||
|
width: 150rpx;
|
||||||
|
height: 26rpx;
|
||||||
|
background-color: #d0d0d0;
|
||||||
|
border-radius: 4rpx;
|
||||||
|
margin-bottom: 12rpx;
|
||||||
|
animation: skeleton-loading 1.5s infinite ease-in-out;
|
||||||
|
}
|
||||||
|
|
||||||
|
.skeleton-address {
|
||||||
|
width: 400rpx;
|
||||||
|
height: 26rpx;
|
||||||
|
background-color: #d0d0d0;
|
||||||
|
border-radius: 4rpx;
|
||||||
|
margin-bottom: 20rpx;
|
||||||
|
animation: skeleton-loading 1.5s infinite ease-in-out;
|
||||||
|
}
|
||||||
|
|
||||||
|
.skeleton-grab-order-btn {
|
||||||
|
width: 160rpx;
|
||||||
|
height: 60rpx;
|
||||||
|
background-color: #d0d0d0;
|
||||||
|
border-radius: 30rpx;
|
||||||
|
position: absolute;
|
||||||
|
bottom: 25rpx;
|
||||||
|
right: 25rpx;
|
||||||
|
animation: skeleton-loading 1.5s infinite ease-in-out;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 加载更多骨架 */
|
||||||
|
.skeleton-loadmore {
|
||||||
|
margin: 0 250rpx;
|
||||||
|
height: 40rpx;
|
||||||
|
background-color: #d0d0d0;
|
||||||
|
margin-bottom: 20rpx;
|
||||||
|
opacity: 0.6;
|
||||||
|
animation: skeleton-loading 1.5s infinite ease-in-out;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/* 骨架屏加载动画 */
|
||||||
|
@keyframes skeleton-loading {
|
||||||
|
0% {
|
||||||
|
opacity: 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
50% {
|
||||||
|
opacity: 0.5;
|
||||||
|
}
|
||||||
|
|
||||||
|
100% {
|
||||||
|
opacity: 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 设置延迟,让骨架屏各部分加载动画错开 */
|
||||||
|
.skeleton-user-info {
|
||||||
|
animation-delay: 0s;
|
||||||
|
}
|
||||||
|
|
||||||
|
.skeleton-stats-section {
|
||||||
|
animation-delay: 0.1s;
|
||||||
|
}
|
||||||
|
|
||||||
|
.skeleton-action-section {
|
||||||
|
animation-delay: 0.2s;
|
||||||
|
}
|
||||||
|
|
||||||
|
.skeleton-high-price-orders {
|
||||||
|
animation-delay: 0.3s;
|
||||||
|
}
|
||||||
|
|
||||||
|
.skeleton-order-item:nth-child(2) {
|
||||||
|
animation-delay: 0.4s;
|
||||||
|
}
|
||||||
|
|
||||||
|
.skeleton-order-item:nth-child(3) {
|
||||||
|
animation-delay: 0.5s;
|
||||||
|
}
|
||||||
|
|
||||||
|
.skeleton-order-item:nth-child(4) {
|
||||||
|
animation-delay: 0.6s;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 骨架屏end
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
.rider-home {
|
||||||
|
background-color: #f5f5f5;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 用户信息区域 */
|
||||||
|
.user-info {
|
||||||
|
background-color: #E6F7FF;
|
||||||
|
padding: 30rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
.user-header {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.avatar {
|
||||||
|
width: 100rpx;
|
||||||
|
height: 100rpx;
|
||||||
|
border-radius: 50%;
|
||||||
|
border: 1px solid #fff;
|
||||||
|
}
|
||||||
|
|
||||||
|
.user-details {
|
||||||
|
margin-left: 20rpx;
|
||||||
|
flex: 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
.user-name {
|
||||||
|
font-size: 36rpx;
|
||||||
|
font-weight: 600;
|
||||||
|
color: #333333;
|
||||||
|
display: block;
|
||||||
|
margin-bottom: 8rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
.user-id {
|
||||||
|
font-size: 28rpx;
|
||||||
|
color: #666666;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 统计数据区域 */
|
||||||
|
.stats-section {
|
||||||
|
background-color: #ffffff;
|
||||||
|
margin: 20rpx;
|
||||||
|
border-radius: 16rpx;
|
||||||
|
display: flex;
|
||||||
|
justify-content: space-around;
|
||||||
|
padding: 30rpx 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.stat-item {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
align-items: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.stat-label {
|
||||||
|
font-size: 28rpx;
|
||||||
|
color: #666666;
|
||||||
|
margin-bottom: 10rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
.stat-value {
|
||||||
|
font-size: 36rpx;
|
||||||
|
font-weight: 600;
|
||||||
|
}
|
||||||
|
|
||||||
|
.income {
|
||||||
|
color: var(--nav-diluted);
|
||||||
|
}
|
||||||
|
|
||||||
|
.completed {
|
||||||
|
color: var(--nav-vice);
|
||||||
|
}
|
||||||
|
|
||||||
|
.ongoing {
|
||||||
|
color: #FF9500;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 接单按钮 */
|
||||||
|
.action-section {
|
||||||
|
margin: 0 20rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
.accept-orders-btn {
|
||||||
|
width: 100%;
|
||||||
|
height: 90rpx;
|
||||||
|
font-size: 32rpx;
|
||||||
|
background-color: #52C41A;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 附近高价单 */
|
||||||
|
.high-price-orders {
|
||||||
|
margin-top: 20rpx;
|
||||||
|
padding: 0 20rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
.section-title {
|
||||||
|
font-size: 32rpx;
|
||||||
|
font-weight: 600;
|
||||||
|
color: #333333;
|
||||||
|
margin-bottom: 20rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
.order-item {
|
||||||
|
background-color: #ffffff;
|
||||||
|
border-radius: 16rpx;
|
||||||
|
padding: 25rpx;
|
||||||
|
margin-bottom: 20rpx;
|
||||||
|
position: relative;
|
||||||
|
}
|
||||||
|
|
||||||
|
.order-header {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: space-between;
|
||||||
|
margin-bottom: 15rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
.high-price-tag {
|
||||||
|
background-color: #FFF1F0;
|
||||||
|
color: #FF4D4F;
|
||||||
|
font-size: 24rpx;
|
||||||
|
padding: 4rpx 16rpx;
|
||||||
|
border-radius: 12rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
.order-price {
|
||||||
|
font-size: 32rpx;
|
||||||
|
font-weight: 600;
|
||||||
|
color: #FF4D4F;
|
||||||
|
}
|
||||||
|
|
||||||
|
.restaurant-name {
|
||||||
|
font-size: 30rpx;
|
||||||
|
color: #333333;
|
||||||
|
display: block;
|
||||||
|
margin-bottom: 12rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
.pickup-time {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
margin-bottom: 12rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
.pickup-time-text {
|
||||||
|
font-size: 26rpx;
|
||||||
|
color: #666666;
|
||||||
|
margin-left: 8rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
.distance {
|
||||||
|
font-size: 26rpx;
|
||||||
|
color: #999999;
|
||||||
|
display: block;
|
||||||
|
margin-bottom: 12rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
.address {
|
||||||
|
font-size: 26rpx;
|
||||||
|
color: #666666;
|
||||||
|
display: block;
|
||||||
|
margin-bottom: 20rpx;
|
||||||
|
line-height: 1.4;
|
||||||
|
}
|
||||||
|
|
||||||
|
.grab-order-btn {
|
||||||
|
width: 160rpx;
|
||||||
|
height: 60rpx;
|
||||||
|
font-size: 26rpx;
|
||||||
|
position: absolute;
|
||||||
|
bottom: 25rpx;
|
||||||
|
right: 25rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* uview组件样式覆盖 */
|
||||||
|
::v-deep .u-button--primary {
|
||||||
|
background-color: var(--nav-vice);
|
||||||
|
border-color: var(--nav-vice);
|
||||||
|
}
|
||||||
|
|
||||||
|
::v-deep .u-button--mini {
|
||||||
|
background-color: var(--nav-mian);
|
||||||
|
border-color: var(--nav-mian);
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
After Width: | Height: | Size: 278 B |
@@ -0,0 +1,727 @@
|
|||||||
|
/**
|
||||||
|
* 图片编辑器-手势监听
|
||||||
|
* 1. wxs 暂不支持 es6 语法
|
||||||
|
* 2. 支持编译到微信小程序、QQ小程序、app-vue、H5上(uni-app 2.2.5及以上版本)
|
||||||
|
*/
|
||||||
|
/** 图片偏移量 */
|
||||||
|
var offset = { x: 0, y: 0 };
|
||||||
|
/** 图片缩放比例 */
|
||||||
|
var scale = 1;
|
||||||
|
/** 图片最小缩放比例 */
|
||||||
|
var minScale = 1;
|
||||||
|
/** 图片旋转角度 */
|
||||||
|
var rotate = 0;
|
||||||
|
/** 触摸点 */
|
||||||
|
var touches = [];
|
||||||
|
/** 图片布局信息 */
|
||||||
|
var img = {};
|
||||||
|
/** 系统信息 */
|
||||||
|
var sys = {};
|
||||||
|
/** 裁剪区域布局信息 */
|
||||||
|
var area = {};
|
||||||
|
/** 触摸行为类型 */
|
||||||
|
var touchType = '';
|
||||||
|
/** 操作角的位置 */
|
||||||
|
var activeAngle = 0;
|
||||||
|
/** 裁剪区域布局信息偏移量 */
|
||||||
|
var areaOffset = { left: 0, right: 0, top: 0, bottom: 0 };
|
||||||
|
/** 容错值 */
|
||||||
|
var fault = 0.000001;
|
||||||
|
/**
|
||||||
|
* 获取a、b两数中的最小正数
|
||||||
|
* @param a
|
||||||
|
* @param b
|
||||||
|
*/
|
||||||
|
function minimum(a, b) {
|
||||||
|
if (a > 0 && b < 0) return a;
|
||||||
|
if (a < 0 && b > 0) return b;
|
||||||
|
if (a > 0 && b > 0) return Math.min(a, b);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* 在容错访问内获取n近似值
|
||||||
|
* @param n
|
||||||
|
*/
|
||||||
|
function num(n) {
|
||||||
|
var m = parseFloat((n).toFixed(6));
|
||||||
|
return m === fault || m === -fault ? 0 : m;
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* 比较a值在容错值范围内是否等于b值
|
||||||
|
* @param a
|
||||||
|
* @param b
|
||||||
|
*/
|
||||||
|
function equalsByFault(a, b) {
|
||||||
|
return Math.abs(a - b) <= fault;
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* 比较a值在容错值范围内是否小于b值
|
||||||
|
* @param a
|
||||||
|
* @param b
|
||||||
|
*/
|
||||||
|
function lessThanByFault(a, b) {
|
||||||
|
var c = a - b;
|
||||||
|
return c < 0 ? c < -fault : c < fault;
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* 验证并获取有效最大值
|
||||||
|
* @param v
|
||||||
|
* @param max
|
||||||
|
* @param isInclude
|
||||||
|
* @param x
|
||||||
|
* @param y
|
||||||
|
* @param rate
|
||||||
|
* @returns
|
||||||
|
*/
|
||||||
|
function validMax(v, max, isInclude, x, y, rate) {
|
||||||
|
if(typeof max === 'number') {
|
||||||
|
if(isInclude && equalsByFault(max, y)) { // 宽高不等时,x轴用y轴值要做等比例转换
|
||||||
|
var n = num(max * rate);
|
||||||
|
if (n <= x) return n; // 转化后值在x轴最大值范围内
|
||||||
|
return x; // 转化后值超出x轴最大值范围则用最大值
|
||||||
|
}
|
||||||
|
return max;
|
||||||
|
}
|
||||||
|
return v;
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* 计算两点间距
|
||||||
|
* @param {Object} touches 触摸点信息
|
||||||
|
*/
|
||||||
|
function getDistanceByTouches(touches) {
|
||||||
|
// 根据勾股定理求两点间距离
|
||||||
|
var a = touches[1].pageX - touches[0].pageX;
|
||||||
|
var b = touches[1].pageY - touches[0].pageY;
|
||||||
|
var c = Math.sqrt(Math.pow(a, 2) + Math.pow(b, 2));
|
||||||
|
// 求两点间的中点坐标
|
||||||
|
// 1. a、b可能为负值
|
||||||
|
// 2. 在求a、b时,如用touches[1]减touches[0],则求中点坐标也得用touches[1]减a/2、b/2
|
||||||
|
// 3. 同理,在求a、b时,也可用touches[0]减touches[1],则求中点坐标也得用touches[0]减a/2、b/2
|
||||||
|
var x = touches[1].pageX - a / 2;
|
||||||
|
var y = touches[1].pageY - b / 2;
|
||||||
|
return { c, x, y };
|
||||||
|
};
|
||||||
|
/**
|
||||||
|
* 修正取值
|
||||||
|
* @param {Object} a
|
||||||
|
* @param {Object} b
|
||||||
|
* @param {Object} c
|
||||||
|
* @param {Object} reverse 是否反向
|
||||||
|
*/
|
||||||
|
function correctValue(a, b, c, reverse) {
|
||||||
|
return num(reverse ? Math.max(Math.min(a, b), c) : Math.min(Math.max(a, b), c));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 旋转90°或270°时检查边界:限制 x、y 拖动范围,禁止滑出边界
|
||||||
|
* @param {Object} e 点坐标
|
||||||
|
* @param {Object} xReverse x是否反向
|
||||||
|
* @param {Object} yReverse y是否反向
|
||||||
|
*/
|
||||||
|
function checkRotateRange(e, xReverse, yReverse) {
|
||||||
|
var o = num((img.height - img.width) / 2); // 宽高差值一半
|
||||||
|
return {
|
||||||
|
x: correctValue(e.x, -img.height + o + area.width + area.left, area.left + o, xReverse),
|
||||||
|
y: correctValue(e.y, -img.width - o + area.height + area.top, area.top - o, yReverse)
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 检查边界:限制 x、y 拖动范围,禁止滑出边界
|
||||||
|
* @param {Object} e 点坐标
|
||||||
|
*/
|
||||||
|
function checkRange(e) {
|
||||||
|
var r = rotate / 90 % 2;
|
||||||
|
if(r === 1) { // 因图片宽高可能不等,翻转 90° 或 270° 后图片宽高需反着计算,且左右和上下边界要根据差值做偏移
|
||||||
|
if (area.width === area.height) {
|
||||||
|
return checkRotateRange(e, img.height < area.height, img.width < area.width);
|
||||||
|
}
|
||||||
|
var isInclude = img.height < area.width && img.width < area.height; // 图片是否包含在裁剪区域内
|
||||||
|
if (img.width < area.height || img.height < area.width) {
|
||||||
|
if (area.width < area.height && img.width < img.height) {
|
||||||
|
return isInclude
|
||||||
|
? checkRotateRange(e, area.width < area.height, area.width < area.height)
|
||||||
|
: checkRotateRange(e, false, true);
|
||||||
|
}
|
||||||
|
if (area.height < area.width && img.height < img.width) {
|
||||||
|
return isInclude
|
||||||
|
? checkRotateRange(e, area.height < area.width, area.height < area.width)
|
||||||
|
: checkRotateRange(e, true, false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (img.height >= area.width && img.width >= area.height) {
|
||||||
|
return checkRotateRange(e, false, false);
|
||||||
|
}
|
||||||
|
if (isInclude) {
|
||||||
|
return area.height < area.width
|
||||||
|
? checkRotateRange(e, true, true)
|
||||||
|
: checkRotateRange(e, area.width < area.height, area.width < area.height);
|
||||||
|
}
|
||||||
|
if (img.height < area.width && !img.width < area.height) {
|
||||||
|
return checkRotateRange(e, true, false);
|
||||||
|
}
|
||||||
|
if (!img.height < area.width && img.width < area.height) {
|
||||||
|
return checkRotateRange(e, false, true);
|
||||||
|
}
|
||||||
|
return checkRotateRange(e, img.height < area.height, img.width < area.width);
|
||||||
|
}
|
||||||
|
return {
|
||||||
|
x: correctValue(e.x, -img.width + area.width + area.left, area.left, img.width < area.width),
|
||||||
|
y: correctValue(e.y, -img.height + area.height + area.top, area.top, img.height < area.height)
|
||||||
|
};
|
||||||
|
};
|
||||||
|
/**
|
||||||
|
* 变更图片布局信息
|
||||||
|
* @param {Object} e 布局信息
|
||||||
|
*/
|
||||||
|
function changeImageRect(e) {
|
||||||
|
offset.x += e.x || 0;
|
||||||
|
offset.y += e.y || 0;
|
||||||
|
var image = e.instance.selectComponent('.crop-image');
|
||||||
|
if(e.check && area.checkRange) { // 检查边界
|
||||||
|
var point = checkRange(offset);
|
||||||
|
if(offset.x !== point.x || offset.y !== point.y) {
|
||||||
|
offset = point;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// image.setStyle({
|
||||||
|
// width: img.width + 'px',
|
||||||
|
// height: img.height + 'px',
|
||||||
|
// transform: 'translate(' + offset.x + 'px, ' + offset.y + 'px) rotate(' + rotate +'deg)'
|
||||||
|
// });
|
||||||
|
var ox = (img.width - img.oldWidth) / 2;
|
||||||
|
var oy = (img.height - img.oldHeight) / 2;
|
||||||
|
image.setStyle({
|
||||||
|
width: img.oldWidth + 'px',
|
||||||
|
height: img.oldHeight + 'px',
|
||||||
|
transform: (img.gpu ? 'translateZ(0) ' : '') + 'translate(' + (offset.x + ox) + 'px, ' + (offset.y + oy) + 'px) rotate(' + rotate +'deg) scale(' + scale + ')'
|
||||||
|
});
|
||||||
|
|
||||||
|
e.instance.callMethod('dataChange', {
|
||||||
|
width: img.width,
|
||||||
|
height: img.height,
|
||||||
|
x: offset.x,
|
||||||
|
y: offset.y,
|
||||||
|
rotate: rotate
|
||||||
|
});
|
||||||
|
};
|
||||||
|
/**
|
||||||
|
* 变更裁剪区域布局信息
|
||||||
|
* @param {Object} e 布局信息
|
||||||
|
*/
|
||||||
|
function changeAreaRect(e) {
|
||||||
|
// 变更蒙版样式
|
||||||
|
var masks = e.instance.selectAllComponents('.crop-mask-block');
|
||||||
|
var maskStyles = [
|
||||||
|
{
|
||||||
|
left: 0,
|
||||||
|
width: (area.left + areaOffset.left) + 'px',
|
||||||
|
top: 0,
|
||||||
|
bottom: 0,
|
||||||
|
'z-index': area.zIndex + 2
|
||||||
|
},
|
||||||
|
{
|
||||||
|
left: (area.right + areaOffset.right) + 'px',
|
||||||
|
right: 0,
|
||||||
|
top: 0,
|
||||||
|
bottom: 0,
|
||||||
|
'z-index': area.zIndex + 2
|
||||||
|
},
|
||||||
|
{
|
||||||
|
left: (area.left + areaOffset.left) + 'px',
|
||||||
|
width: (area.width + areaOffset.right - areaOffset.left) + 'px',
|
||||||
|
top: 0,
|
||||||
|
height: (area.top + areaOffset.top) + 'px',
|
||||||
|
'z-index': area.zIndex + 2
|
||||||
|
},
|
||||||
|
{
|
||||||
|
left: (area.left + areaOffset.left) + 'px',
|
||||||
|
width: (area.width + areaOffset.right - areaOffset.left) + 'px',
|
||||||
|
top: (area.bottom + areaOffset.bottom) + 'px',
|
||||||
|
// height: (area.top - areaOffset.bottom + sys.offsetBottom) + 'px',
|
||||||
|
bottom: 0,
|
||||||
|
'z-index': area.zIndex + 2
|
||||||
|
}
|
||||||
|
];
|
||||||
|
var len = masks.length;
|
||||||
|
for (var i = 0; i < len; i++) {
|
||||||
|
masks[i].setStyle(maskStyles[i]);
|
||||||
|
}
|
||||||
|
|
||||||
|
// 变更边框样式
|
||||||
|
if(area.showBorder) {
|
||||||
|
var border = e.instance.selectComponent('.crop-border');
|
||||||
|
border.setStyle({
|
||||||
|
left: (area.left + areaOffset.left) + 'px',
|
||||||
|
top: (area.top + areaOffset.top) + 'px',
|
||||||
|
width: (area.width + areaOffset.right - areaOffset.left) + 'px',
|
||||||
|
height: (area.height + areaOffset.bottom - areaOffset.top) + 'px',
|
||||||
|
'z-index': area.zIndex + 3
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
// 变更参考线样式
|
||||||
|
if(area.showGrid) {
|
||||||
|
var grids = e.instance.selectAllComponents('.crop-grid');
|
||||||
|
var gridStyles = [
|
||||||
|
{
|
||||||
|
'border-width': '1px 0 0 0',
|
||||||
|
left: (area.left + areaOffset.left) + 'px',
|
||||||
|
right: (area.right + areaOffset.right) + 'px',
|
||||||
|
top: (area.top + areaOffset.top + (area.height + areaOffset.bottom - areaOffset.top) / 3 - 0.5) + 'px',
|
||||||
|
width: (area.width + areaOffset.right - areaOffset.left) + 'px',
|
||||||
|
'z-index': area.zIndex + 3
|
||||||
|
},
|
||||||
|
{
|
||||||
|
'border-width': '1px 0 0 0',
|
||||||
|
left: (area.left + areaOffset.left) + 'px',
|
||||||
|
right: (area.right + areaOffset.right) + 'px',
|
||||||
|
top: (area.top + areaOffset.top + (area.height + areaOffset.bottom - areaOffset.top) * 2 / 3 - 0.5) + 'px',
|
||||||
|
width: (area.width + areaOffset.right - areaOffset.left) + 'px',
|
||||||
|
'z-index': area.zIndex + 3
|
||||||
|
},
|
||||||
|
{
|
||||||
|
'border-width': '0 1px 0 0',
|
||||||
|
top: (area.top + areaOffset.top) + 'px',
|
||||||
|
bottom: (area.bottom + areaOffset.bottom) + 'px',
|
||||||
|
left: (area.left + areaOffset.left + (area.width + areaOffset.right - areaOffset.left) / 3 - 0.5) + 'px',
|
||||||
|
height: (area.height + areaOffset.bottom - areaOffset.top) + 'px',
|
||||||
|
'z-index': area.zIndex + 3
|
||||||
|
},
|
||||||
|
{
|
||||||
|
'border-width': '0 1px 0 0',
|
||||||
|
top: (area.top + areaOffset.top) + 'px',
|
||||||
|
bottom: (area.bottom + areaOffset.bottom) + 'px',
|
||||||
|
left: (area.left + areaOffset.left + (area.width + areaOffset.right - areaOffset.left) * 2 / 3 - 0.5) + 'px',
|
||||||
|
height: (area.height + areaOffset.bottom - areaOffset.top) + 'px',
|
||||||
|
'z-index': area.zIndex + 3
|
||||||
|
}
|
||||||
|
];
|
||||||
|
var len = grids.length;
|
||||||
|
for (var i = 0; i < len; i++) {
|
||||||
|
grids[i].setStyle(gridStyles[i]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 变更四个伸缩角样式
|
||||||
|
if(area.showAngle) {
|
||||||
|
var angles = e.instance.selectAllComponents('.crop-angle');
|
||||||
|
var angleStyles = [
|
||||||
|
{
|
||||||
|
'border-width': area.angleBorderWidth + 'px 0 0 ' + area.angleBorderWidth + 'px',
|
||||||
|
left: (area.left + areaOffset.left - area.angleBorderWidth) + 'px',
|
||||||
|
top: (area.top + areaOffset.top - area.angleBorderWidth) + 'px',
|
||||||
|
'z-index': area.zIndex + 3
|
||||||
|
},
|
||||||
|
{
|
||||||
|
'border-width': area.angleBorderWidth + 'px ' + area.angleBorderWidth + 'px 0 0',
|
||||||
|
left: (area.right + areaOffset.right - area.angleSize) + 'px',
|
||||||
|
top: (area.top + areaOffset.top - area.angleBorderWidth) + 'px',
|
||||||
|
'z-index': area.zIndex + 3
|
||||||
|
},
|
||||||
|
{
|
||||||
|
'border-width': '0 0 ' + area.angleBorderWidth + 'px ' + area.angleBorderWidth + 'px',
|
||||||
|
left: (area.left + areaOffset.left - area.angleBorderWidth) + 'px',
|
||||||
|
top: (area.bottom + areaOffset.bottom - area.angleSize) + 'px',
|
||||||
|
'z-index': area.zIndex + 3
|
||||||
|
},
|
||||||
|
{
|
||||||
|
'border-width': '0 ' + area.angleBorderWidth + 'px ' + area.angleBorderWidth + 'px 0',
|
||||||
|
left: (area.right + areaOffset.right - area.angleSize) + 'px',
|
||||||
|
top: (area.bottom + areaOffset.bottom - area.angleSize) + 'px',
|
||||||
|
'z-index': area.zIndex + 3
|
||||||
|
}
|
||||||
|
];
|
||||||
|
var len = angles.length;
|
||||||
|
for (var i = 0; i < len; i++) {
|
||||||
|
angles[i].setStyle(angleStyles[i]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 变更圆角样式
|
||||||
|
if(area.radius > 0) {
|
||||||
|
var circleBox = e.instance.selectComponent('.crop-circle-box');
|
||||||
|
var circle = e.instance.selectComponent('.crop-circle');
|
||||||
|
var radius = area.radius;
|
||||||
|
if(area.width === area.height && area.radius >= area.width / 2) { // 圆形
|
||||||
|
radius = (area.width / 2);
|
||||||
|
} else { // 圆角矩形
|
||||||
|
if(area.width !== area.height) { // 限制圆角半径不能超过短边的一半
|
||||||
|
radius = Math.min(area.width / 2, area.height / 2, radius);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
circleBox.setStyle({
|
||||||
|
left: (area.left + areaOffset.left) + 'px',
|
||||||
|
top: (area.top + areaOffset.top) + 'px',
|
||||||
|
width: (area.width + areaOffset.right - areaOffset.left) + 'px',
|
||||||
|
height: (area.height + areaOffset.bottom - areaOffset.top) + 'px',
|
||||||
|
'z-index': area.zIndex + 2
|
||||||
|
});
|
||||||
|
circle.setStyle({
|
||||||
|
'box-shadow': '0 0 0 ' + Math.max(area.width, area.height) + 'px rgba(51, 51, 51, 0.8)',
|
||||||
|
'border-radius': radius + 'px'
|
||||||
|
});
|
||||||
|
}
|
||||||
|
};
|
||||||
|
/**
|
||||||
|
* 缩放图片
|
||||||
|
* @param {Object} e 布局信息
|
||||||
|
*/
|
||||||
|
function scaleImage(e) {
|
||||||
|
var last = scale;
|
||||||
|
scale = Math.min(Math.max(e.scale + scale, minScale), img.maxScale);
|
||||||
|
if(last !== scale) {
|
||||||
|
img.width = num(img.oldWidth * scale);
|
||||||
|
img.height = num(img.oldHeight * scale);
|
||||||
|
// 参考问题:有一个长4000px、宽4000px的四方形ABCD,A点的坐标固定在(-2000,-2000),
|
||||||
|
// 该四边形上有一个点E,坐标为(-100,-300),将该四方形复制一份并缩小到90%后,
|
||||||
|
// 新四边形的A点坐标为多少时可使新四边形的E点与原四边形的E点重合?
|
||||||
|
// 预期效果:从图中选取某点(参照物)为中心点进行缩放,缩放时无论图像怎么变化,该点位置始终固定不变
|
||||||
|
// 计算方法:以相同起点先计算缩放前后两点间的距离,再加上原图像偏移量即可
|
||||||
|
e.x = num((e.x - offset.x) * (1 - scale / last));
|
||||||
|
e.y = num((e.y - offset.y) * (1 - scale / last));
|
||||||
|
changeImageRect(e);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
};
|
||||||
|
/**
|
||||||
|
* 获取触摸点在哪个角
|
||||||
|
* @param {number} x 触摸点x轴坐标
|
||||||
|
* @param {number} y 触摸点y轴坐标
|
||||||
|
* @return {number} 角的位置:0=无;1=左上;2=右上;3=左下;4=右下;
|
||||||
|
*/
|
||||||
|
function getToucheAngle(x, y) {
|
||||||
|
// console.log('getToucheAngle', x, y, JSON.stringify(area))
|
||||||
|
var o = area.angleBorderWidth; // 需扩大触发范围则把 o 值加大即可
|
||||||
|
if(y >= area.top - o && y <= area.top + area.angleSize + o) {
|
||||||
|
if(x >= area.left - o && x <= area.left + area.angleSize + o) {
|
||||||
|
return 1; // 左上角
|
||||||
|
} else if(x >= area.right - area.angleSize - o && x <= area.right + o) {
|
||||||
|
return 2; // 右上角
|
||||||
|
}
|
||||||
|
} else if(y >= area.bottom - area.angleSize - o && y <= area.bottom + o) {
|
||||||
|
if(x >= area.left - o && x <= area.left + area.angleSize + o) {
|
||||||
|
return 3; // 左下角
|
||||||
|
} else if(x >= area.right - area.angleSize - o && x <= area.right + o) {
|
||||||
|
return 4; // 右下角
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return 0; // 无触摸到角
|
||||||
|
};
|
||||||
|
/**
|
||||||
|
* 重置数据
|
||||||
|
*/
|
||||||
|
function resetData() {
|
||||||
|
offset = { x: 0, y: 0 };
|
||||||
|
scale = 1;
|
||||||
|
minScale = img.minScale;
|
||||||
|
rotate = 0;
|
||||||
|
};
|
||||||
|
/**
|
||||||
|
* 顺时针翻转图片90°
|
||||||
|
* @param {Object} e 事件对象
|
||||||
|
* @param {Object} o 组件实例对象
|
||||||
|
*/
|
||||||
|
function rotateImage(e, o, r) {
|
||||||
|
rotate = (rotate + r) % 360;
|
||||||
|
if(img.minScale >= 1 && area.checkRange) {
|
||||||
|
// 因图片宽高可能不等,翻转后图片宽高需足够填满裁剪区域
|
||||||
|
minScale = 1;
|
||||||
|
if(img.width < area.height) {
|
||||||
|
minScale = area.height / img.oldWidth;
|
||||||
|
} else if(img.height < area.width) {
|
||||||
|
minScale = area.width / img.oldHeight;
|
||||||
|
}
|
||||||
|
if(minScale !== 1) {
|
||||||
|
scaleImage({
|
||||||
|
instance: o,
|
||||||
|
scale: minScale - scale,
|
||||||
|
x: sys.windowWidth / 2,
|
||||||
|
y: (sys.windowHeight - sys.offsetBottom) / 2
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 由于拖动画布后会导致图片位置偏移,翻转时的旋转中心点需是图片区域+偏移区域的中心点
|
||||||
|
// 翻转x轴中心点 = (超出裁剪区域右侧的图片宽度 - 超出裁剪区域左侧的图片宽度) / 2
|
||||||
|
// 翻转y轴中心点 = (超出裁剪区域下方的图片宽度 - 超出裁剪区域上方的图片宽度) / 2
|
||||||
|
var ox = ((offset.x + img.width - area.right) - (area.left - offset.x)) / 2;
|
||||||
|
var oy = ((offset.y + img.height - area.bottom) - (area.top - offset.y)) / 2;
|
||||||
|
changeImageRect({
|
||||||
|
instance: o,
|
||||||
|
check: true,
|
||||||
|
x: -ox - oy,
|
||||||
|
y: -oy + ox
|
||||||
|
});
|
||||||
|
};
|
||||||
|
module.exports = {
|
||||||
|
/**
|
||||||
|
* 初始化:观察数据变更
|
||||||
|
* @param {Object} newVal 新数据
|
||||||
|
* @param {Object} oldVal 旧数据
|
||||||
|
* @param {Object} o 组件实例对象
|
||||||
|
*/
|
||||||
|
initObserver: function(newVal, oldVal, o, i) {
|
||||||
|
if(newVal) {
|
||||||
|
img = newVal.img;
|
||||||
|
sys = newVal.sys;
|
||||||
|
area = newVal.area;
|
||||||
|
minScale = img.minScale;
|
||||||
|
resetData();
|
||||||
|
img.src && changeImageRect({
|
||||||
|
instance: o,
|
||||||
|
x: (sys.windowWidth - img.width) / 2,
|
||||||
|
y: (sys.windowHeight - sys.offsetBottom - img.height) / 2
|
||||||
|
});
|
||||||
|
changeAreaRect({
|
||||||
|
instance: o
|
||||||
|
});
|
||||||
|
// console.log('initRect', JSON.stringify(newVal))
|
||||||
|
}
|
||||||
|
},
|
||||||
|
/**
|
||||||
|
* 鼠标滚轮滚动
|
||||||
|
* @param {Object} e 事件对象
|
||||||
|
* @param {Object} o 组件实例对象
|
||||||
|
*/
|
||||||
|
mousewheel: function(e, o) {
|
||||||
|
if(!img.src) return;
|
||||||
|
scaleImage({
|
||||||
|
instance: o,
|
||||||
|
check: true,
|
||||||
|
// 鼠标向上滚动时,deltaY 固定 -100,鼠标向下滚动时,deltaY 固定 100
|
||||||
|
scale: e.detail.deltaY > 0 ? -0.05 : 0.05,
|
||||||
|
x: e.touches[0].pageX,
|
||||||
|
y: e.touches[0].pageY
|
||||||
|
});
|
||||||
|
},
|
||||||
|
/**
|
||||||
|
* 触摸开始
|
||||||
|
* @param {Object} e 事件对象
|
||||||
|
* @param {Object} o 组件实例对象
|
||||||
|
*/
|
||||||
|
touchstart: function(e, o) {
|
||||||
|
if(!img.src) return;
|
||||||
|
touches = e.touches;
|
||||||
|
activeAngle = area.showAngle ? getToucheAngle(touches[0].pageX, touches[0].pageY) : 0;
|
||||||
|
if(touches.length === 1 && activeAngle !== 0) {
|
||||||
|
touchType = 'stretch'; // 伸缩裁剪区域
|
||||||
|
} else {
|
||||||
|
touchType = '';
|
||||||
|
}
|
||||||
|
// console.log('touchstart', JSON.stringify(e), activeAngle)
|
||||||
|
},
|
||||||
|
/**
|
||||||
|
* 触摸移动
|
||||||
|
* @param {Object} e 事件对象
|
||||||
|
* @param {Object} o 组件实例对象
|
||||||
|
*/
|
||||||
|
touchmove: function(e, o) {
|
||||||
|
if(!img.src) return;
|
||||||
|
// console.log('touchmove', JSON.stringify(e), JSON.stringify(o))
|
||||||
|
if(touchType === 'stretch') { // 触摸四个角进行拉伸
|
||||||
|
var point = e.touches[0];
|
||||||
|
var start = touches[0];
|
||||||
|
var x = point.pageX - start.pageX;
|
||||||
|
var y = point.pageY - start.pageY;
|
||||||
|
if(x !== 0 || y !== 0) {
|
||||||
|
var maxX = num(area.width * (1 - area.minScale));
|
||||||
|
var maxY = num(area.height * (1 - area.minScale));
|
||||||
|
// console.log(x, y, maxX, maxY, offset, area)
|
||||||
|
touches[0] = point;
|
||||||
|
var r = rotate / 90 % 2;
|
||||||
|
var m = r === 1 ? num((img.height - img.width) / 2) : 0; // 宽高差值一半
|
||||||
|
var xCompare = r === 1 ? lessThanByFault(img.height, area.width) : lessThanByFault(img.width, area.width);
|
||||||
|
var yCompare = r === 1 ? lessThanByFault(img.width, area.height) : lessThanByFault(img.height, area.height)
|
||||||
|
var isInclude = xCompare && yCompare;
|
||||||
|
var isIntersect = area.checkRange && (xCompare || yCompare); // 图片是否包含在裁剪区域内
|
||||||
|
var isReverse = !isInclude || num((offset.x - area.left) / area.width) <= num((offset.y - area.top) / area.height) || (area.width > area.height && img.width < img.height && r === 1);
|
||||||
|
switch(activeAngle) {
|
||||||
|
case 1: // 左上角
|
||||||
|
x = num(x + areaOffset.left);
|
||||||
|
y = num(y + areaOffset.top);
|
||||||
|
if(x >= 0 && y >= 0) { // 有效滑动
|
||||||
|
var t = num(offset.y + m - area.top);
|
||||||
|
var l = num(offset.x - m - area.left);
|
||||||
|
// && (offset.x + img.width < area.right || offset.y + img.height < area.bottom)
|
||||||
|
var max = isIntersect && ((l >= 0) || (t >= 0))
|
||||||
|
? minimum(t, l)
|
||||||
|
: false;
|
||||||
|
if(x > y && isReverse) { // 以x轴滑动距离为缩放基准
|
||||||
|
maxX = validMax(maxX, max, isInclude, l, t, area.width / area.height);
|
||||||
|
if(x > maxX) x = maxX;
|
||||||
|
y = num(x * area.height / area.width);
|
||||||
|
} else { // 以y轴滑动距离为缩放基准
|
||||||
|
maxY = validMax(maxY, max, isInclude, t, l, area.height / area.width);
|
||||||
|
if(y > maxY) y = maxY;
|
||||||
|
x = num(y * area.width / area.height);
|
||||||
|
}
|
||||||
|
areaOffset.left = x;
|
||||||
|
areaOffset.top = y;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case 2: // 右上角
|
||||||
|
x = num(x + areaOffset.right);
|
||||||
|
y = num(y + areaOffset.top);
|
||||||
|
if(x <= 0 && y >= 0) { // 有效滑动
|
||||||
|
var w = (r === 1 ? img.height : img.width);
|
||||||
|
var t = num(offset.y + m - area.top);
|
||||||
|
var l = num(area.right + m - offset.x - w);
|
||||||
|
var max = isIntersect && ((t >= 0) || (l >= 0))
|
||||||
|
? minimum(t, l)
|
||||||
|
: false;
|
||||||
|
// var max = isInclude && ((offset.x > 0 && offset.x + img.width <= area.right) || (offset.y > 0 && offset.y >= area.top))
|
||||||
|
// ? minimum(offset.y - area.top, area.right - offset.x - img.width)
|
||||||
|
// : false;
|
||||||
|
// console.log(offset.x, offset.y, img.width, img.height, area.top, area.right, m, max)
|
||||||
|
// console.log(offset.y + m - area.top, area.right + m - offset.x - w)
|
||||||
|
if(-x > y && isReverse) { // 以x轴滑动距离为缩放基准
|
||||||
|
maxX = validMax(maxX, max, isInclude, l, t, area.width / area.height);
|
||||||
|
if(-x > maxX) x = -maxX;
|
||||||
|
y = num(-x * area.height / area.width);
|
||||||
|
} else { // 以y轴滑动距离为缩放基准
|
||||||
|
maxY = validMax(maxY, max, isInclude, t, l, area.height / area.width);
|
||||||
|
if(y > maxY) y = maxY;
|
||||||
|
x = num(-y * area.width / area.height);
|
||||||
|
}
|
||||||
|
areaOffset.right = x;
|
||||||
|
areaOffset.top = y;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case 3: // 左下角
|
||||||
|
x += num(x + areaOffset.left);
|
||||||
|
y += num(y + areaOffset.bottom);
|
||||||
|
if(x >= 0 && y <= 0) { // 有效滑动
|
||||||
|
var w = (r === 1 ? img.width : img.height);
|
||||||
|
var t = num(area.bottom - m - offset.y - w);
|
||||||
|
var l = num(offset.x - m - area.left);
|
||||||
|
var max = isIntersect && ((l >= 0) || (t >= 0))
|
||||||
|
? minimum(t, l)
|
||||||
|
: false;
|
||||||
|
if(x > -y && isReverse) { // 以x轴滑动距离为缩放基准
|
||||||
|
maxX = validMax(maxX, max, isInclude, l, t, area.width / area.height);
|
||||||
|
if(x > maxX) x = maxX;
|
||||||
|
y = num(-x * area.height / area.width);
|
||||||
|
} else { // 以y轴滑动距离为缩放基准
|
||||||
|
maxY = validMax(maxY, max, isInclude, t, l, area.height / area.width);
|
||||||
|
if(-y > maxY) y = -maxY;
|
||||||
|
x = num(-y * area.width / area.height);
|
||||||
|
}
|
||||||
|
areaOffset.left = x;
|
||||||
|
areaOffset.bottom = y;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case 4: // 右下角
|
||||||
|
x = num(x + areaOffset.right);
|
||||||
|
y = num(y + areaOffset.bottom);
|
||||||
|
if(x <= 0 && y <= 0) { // 有效滑动
|
||||||
|
var w = (r === 1 ? img.height : img.width);
|
||||||
|
var h = (r === 1 ? img.width : img.height);
|
||||||
|
var t = num(area.bottom - offset.y - h - m);
|
||||||
|
var l = num(area.right + m - offset.x - w);
|
||||||
|
var max = isIntersect && ((l >= 0) || (t >= 0))
|
||||||
|
? minimum(t, l)
|
||||||
|
: false;
|
||||||
|
if(-x > -y && isReverse) { // 以x轴滑动距离为缩放基准
|
||||||
|
maxX = validMax(maxX, max, isInclude, l, t, area.width / area.height);
|
||||||
|
if(-x > maxX) x = -maxX;
|
||||||
|
y = num(x * area.height / area.width);
|
||||||
|
} else { // 以y轴滑动距离为缩放基准
|
||||||
|
maxY = validMax(maxY, max, isInclude, t, l, area.height / area.width);
|
||||||
|
if(-y > maxY) y = -maxY;
|
||||||
|
x = num(y * area.width / area.height);
|
||||||
|
}
|
||||||
|
areaOffset.right = x;
|
||||||
|
areaOffset.bottom = y;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
// console.log(x, y, JSON.stringify(areaOffset))
|
||||||
|
changeAreaRect({
|
||||||
|
instance: o,
|
||||||
|
});
|
||||||
|
// this.draw();
|
||||||
|
}
|
||||||
|
} else if (e.touches.length == 2) { // 双点触摸缩放
|
||||||
|
var start = getDistanceByTouches(touches);
|
||||||
|
var end = getDistanceByTouches(e.touches);
|
||||||
|
scaleImage({
|
||||||
|
instance: o,
|
||||||
|
check: !area.bounce,
|
||||||
|
scale: (end.c - start.c) / 100,
|
||||||
|
x: end.x,
|
||||||
|
y: end.y
|
||||||
|
});
|
||||||
|
touchType = 'scale';
|
||||||
|
} else if(touchType === 'scale') {// 从双点触摸变成单点触摸 / 从缩放变成拖动
|
||||||
|
touchType = 'move';
|
||||||
|
} else {
|
||||||
|
changeImageRect({
|
||||||
|
instance: o,
|
||||||
|
check: !area.bounce,
|
||||||
|
x: e.touches[0].pageX - touches[0].pageX,
|
||||||
|
y: e.touches[0].pageY - touches[0].pageY
|
||||||
|
});
|
||||||
|
touchType = 'move';
|
||||||
|
}
|
||||||
|
touches = e.touches;
|
||||||
|
},
|
||||||
|
/**
|
||||||
|
* 触摸结束
|
||||||
|
* @param {Object} e 事件对象
|
||||||
|
* @param {Object} o 组件实例对象
|
||||||
|
*/
|
||||||
|
touchend: function(e, o) {
|
||||||
|
if(!img.src) return;
|
||||||
|
if(touchType === 'stretch') { // 拉伸裁剪区域的四个角缩放
|
||||||
|
// 裁剪区域宽度被缩放到多少
|
||||||
|
var left = areaOffset.left;
|
||||||
|
var right = areaOffset.right;
|
||||||
|
var top = areaOffset.top;
|
||||||
|
var bottom = areaOffset.bottom;
|
||||||
|
var w = area.width + right - left;
|
||||||
|
var h = area.height + bottom - top;
|
||||||
|
// 图像放大倍数
|
||||||
|
var p = scale * (area.width / w) - scale;
|
||||||
|
// 复原裁剪区域
|
||||||
|
areaOffset = { left: 0, right: 0, top: 0, bottom: 0 };
|
||||||
|
changeAreaRect({
|
||||||
|
instance: o,
|
||||||
|
});
|
||||||
|
scaleImage({
|
||||||
|
instance: o,
|
||||||
|
scale: p,
|
||||||
|
x: area.left + left + (1 === activeAngle || 3 === activeAngle ? w : 0),
|
||||||
|
y: area.top + top + (1 === activeAngle || 2 === activeAngle ? h : 0)
|
||||||
|
});
|
||||||
|
} else if (area.bounce) { // 检查边界并矫正,实现拖动到边界时有回弹效果
|
||||||
|
changeImageRect({
|
||||||
|
instance: o,
|
||||||
|
check: true
|
||||||
|
});
|
||||||
|
}
|
||||||
|
},
|
||||||
|
/**
|
||||||
|
* 顺时针翻转图片90°
|
||||||
|
* @param {Object} e 事件对象
|
||||||
|
* @param {Object} o 组件实例对象
|
||||||
|
*/
|
||||||
|
rotateImage: function(e, o) {
|
||||||
|
rotateImage(e, o, 90);
|
||||||
|
},
|
||||||
|
rotateImage90: function(e, o) {
|
||||||
|
rotateImage(e, o, 90)
|
||||||
|
},
|
||||||
|
rotateImage270: function(e, o) {
|
||||||
|
rotateImage(e, o, 270)
|
||||||
|
},
|
||||||
|
// 此处只用于对齐其他平台端的样式参数,防止异常,无作用
|
||||||
|
imageStyles: '',
|
||||||
|
maskStylesList: ['', '', '', ''],
|
||||||
|
borderStyles: '',
|
||||||
|
gridStylesList: ['', '', '', ''],
|
||||||
|
angleStylesList: ['', '', '', ''],
|
||||||
|
circleBoxStyles: '',
|
||||||
|
circleStyles: '',
|
||||||
|
}
|
||||||
@@ -0,0 +1,238 @@
|
|||||||
|
<template>
|
||||||
|
<!-- <UpApp :show="upShow" :url="url" /> -->
|
||||||
|
<view class="borybac" v-if="upShow">
|
||||||
|
<view class="up_box">
|
||||||
|
|
||||||
|
<view class="mt50">
|
||||||
|
<view class="text">
|
||||||
|
版本更新
|
||||||
|
</view>
|
||||||
|
<view class="text">
|
||||||
|
{{remark}}
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
|
||||||
|
<view class="jdBox">
|
||||||
|
<view class="jd">
|
||||||
|
<view class="jdbfb">
|
||||||
|
{{sum}}%
|
||||||
|
</view>
|
||||||
|
<view class="jdt">
|
||||||
|
<view class="jdn" :style="'width:'+sum+'%'">
|
||||||
|
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
<view class="jddx">
|
||||||
|
{{datacl(beg)}}/{{datacl(downlog)}}
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
|
||||||
|
<view class="" v-if="force==0" style="width: 95%; height: 60rpx; margin: 40rpx auto; display: flex; justify-content: space-between;">
|
||||||
|
<view class="" style="width: 70rpx;" >
|
||||||
|
|
||||||
|
</view>
|
||||||
|
<view class="" style="width: 240rpx; height: 60rpx; line-height: 60rpx; border-radius: 30rpx; text-align: center; color: #fff; font-size: 24rpx; background-color: var(--nav-mian);" @click="delUpApp">
|
||||||
|
开始更新
|
||||||
|
</view>
|
||||||
|
<view class="" style="font-size: 22rpx; line-height: 80rpx; color: #999;" @click="goindex">
|
||||||
|
暂不更新
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script setup lang="ts">
|
||||||
|
import { onLoad } from '@dcloudio/uni-app';
|
||||||
|
|
||||||
|
|
||||||
|
import { ref } from 'vue';
|
||||||
|
|
||||||
|
let url = ref('')
|
||||||
|
let force = ref('0')
|
||||||
|
|
||||||
|
// 控制热更新
|
||||||
|
let upShow = ref(true)
|
||||||
|
let sum = ref(0)
|
||||||
|
let downlog = ref(0)
|
||||||
|
let beg = ref(15642544)
|
||||||
|
let remark = ref('')
|
||||||
|
let type = ref('')
|
||||||
|
|
||||||
|
//模拟请求
|
||||||
|
onLoad((data:any) => {
|
||||||
|
// getdata()
|
||||||
|
url.value=data.url
|
||||||
|
});
|
||||||
|
|
||||||
|
const goindex = function () {
|
||||||
|
uni.navigateBack({
|
||||||
|
delta: 1
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
const getdata = function(){
|
||||||
|
// RegisterService.GetNewVersion().then((res:any)=>{
|
||||||
|
// url.value = res.data.path
|
||||||
|
// downlog.value = res.data.size
|
||||||
|
// force.value = res.data.force
|
||||||
|
// remark.value = res.data.remark
|
||||||
|
// type.value = res.data.type
|
||||||
|
// if(res.data.force=='1'){
|
||||||
|
// delUpApp()
|
||||||
|
// }
|
||||||
|
// })
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
const datacl = function(e:any){
|
||||||
|
if(e>1024){
|
||||||
|
let sl = ((e/1024)/1024).toFixed(1)
|
||||||
|
return sl+'MB'
|
||||||
|
}else{
|
||||||
|
return (e/1024).toFixed(1)+'KB'
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
const delUpApp = function () {
|
||||||
|
// 1.开始请求下载
|
||||||
|
const downloadTask = uni.downloadFile({
|
||||||
|
url: url.value,
|
||||||
|
success: (downloadResult) => {
|
||||||
|
if (downloadResult.statusCode === 200) {
|
||||||
|
plus.runtime.install(downloadResult.tempFilePath, {
|
||||||
|
force: false
|
||||||
|
}, function() {
|
||||||
|
uni.hideLoading()
|
||||||
|
uni.showToast({
|
||||||
|
title: "下载成功",
|
||||||
|
complete() {
|
||||||
|
if(type.value=='Bulking'){
|
||||||
|
setTimeout(function() {
|
||||||
|
plus.runtime.restart();
|
||||||
|
}, 2000)
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
})
|
||||||
|
console.log('install success...');
|
||||||
|
}, function(e) {
|
||||||
|
uni.hideLoading()
|
||||||
|
console.log(e,'失败')
|
||||||
|
// uni.$u.toast('下载失败!')
|
||||||
|
// console.error('install fail...');
|
||||||
|
});
|
||||||
|
}
|
||||||
|
},
|
||||||
|
fail(downloadResult) {
|
||||||
|
console.log(downloadResult,'失败')
|
||||||
|
// console.log('下载失败');
|
||||||
|
// uni.$u.toast('下载失败')
|
||||||
|
}
|
||||||
|
});
|
||||||
|
downloadTask.onProgressUpdate((res) => {
|
||||||
|
downlog.value = res.totalBytesExpectedToWrite
|
||||||
|
beg.value = res.totalBytesWritten
|
||||||
|
sum.value =res.progress
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style lang="scss" setup>
|
||||||
|
.borybac {
|
||||||
|
width: 100vw;
|
||||||
|
height: 100vh;
|
||||||
|
position: fixed;
|
||||||
|
top: 0;
|
||||||
|
left: 0;
|
||||||
|
background-color: rgba(0, 0, 0, 0.3);
|
||||||
|
display: flex;
|
||||||
|
overflow: hidden;
|
||||||
|
|
||||||
|
.up_box {
|
||||||
|
width: 513rpx;
|
||||||
|
height: 680rpx;
|
||||||
|
margin: 300rpx auto;
|
||||||
|
border-radius: 20rpx;
|
||||||
|
overflow: hidden;
|
||||||
|
position: relative;
|
||||||
|
background-image: url(@/static/index/system/upapphed.png);
|
||||||
|
background-repeat: no-repeat;
|
||||||
|
background-size: cover;
|
||||||
|
|
||||||
|
.mt50 {
|
||||||
|
display: block;
|
||||||
|
margin-top: 200rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
.jdBox {
|
||||||
|
overflow: hidden;
|
||||||
|
margin-top: 120rpx;
|
||||||
|
display: block;
|
||||||
|
width: 100%;
|
||||||
|
|
||||||
|
.jd {
|
||||||
|
display: block;
|
||||||
|
width: 90%;
|
||||||
|
height: 100%;
|
||||||
|
margin: 0 auto;
|
||||||
|
|
||||||
|
.jdbfb {
|
||||||
|
display: block;
|
||||||
|
width: 100%;
|
||||||
|
height: 40rpx;
|
||||||
|
line-height: 40rpx;
|
||||||
|
font-size: 30rpx;
|
||||||
|
color: var(--nav-mian);
|
||||||
|
font-weight: 600;
|
||||||
|
}
|
||||||
|
|
||||||
|
.jdt {
|
||||||
|
margin-top: 10rpx;
|
||||||
|
display: block;
|
||||||
|
width: 100%;
|
||||||
|
height: 23rpx;
|
||||||
|
border-radius: 15rpx;
|
||||||
|
background-color: #E5E5E5;
|
||||||
|
|
||||||
|
.jdn {
|
||||||
|
display: block;
|
||||||
|
height: 23rpx;
|
||||||
|
border-radius: 15rpx;
|
||||||
|
background: radial-gradient(#8370F8 0%, #455FF8 100%);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.jddx {
|
||||||
|
width: 100%;
|
||||||
|
font-size: 24rpx;
|
||||||
|
margin-top: 20rpx;
|
||||||
|
font-weight: 600;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.text {
|
||||||
|
display: block;
|
||||||
|
text-align: center;
|
||||||
|
margin-top: 30rpx;
|
||||||
|
width: 100%;
|
||||||
|
height: 40rpx;
|
||||||
|
font-size: 32rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
</style>
|
||||||
@@ -0,0 +1,241 @@
|
|||||||
|
{
|
||||||
|
"easycom": {
|
||||||
|
// 注意一定要放在custom里,否则无效,https://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"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"pages": [ //pages数组中第一项表示应用启动页,参考:https://uniapp.dcloud.io/collocation/pages
|
||||||
|
|
||||||
|
{
|
||||||
|
|
||||||
|
"path": "pages/index/index",
|
||||||
|
"style": {
|
||||||
|
"navigationBarTitleText": "门店运营",
|
||||||
|
"navigationBarBackgroundColor": "#36394D",
|
||||||
|
"navigationStyle": "custom",
|
||||||
|
"backgroundColor": "#F8F8F8"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"path": "pages/index/task",
|
||||||
|
"style": {
|
||||||
|
"navigationBarTitleText": "任务",
|
||||||
|
"navigationBarBackgroundColor": "#36394D",
|
||||||
|
"navigationStyle": "custom",
|
||||||
|
"backgroundColor": "#F8F8F8"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"path": "pages/index/income",
|
||||||
|
"style": {
|
||||||
|
"navigationBarTitleText": "我的收入",
|
||||||
|
"navigationBarBackgroundColor": "#36394D",
|
||||||
|
"navigationStyle": "custom",
|
||||||
|
"backgroundColor": "#F8F8F8"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"path": "pages/index/user",
|
||||||
|
"style": {
|
||||||
|
"navigationBarTitleText": "我的",
|
||||||
|
"navigationBarBackgroundColor": "#36394D",
|
||||||
|
"navigationStyle": "custom",
|
||||||
|
"backgroundColor": "#F8F8F8"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"globalStyle": {
|
||||||
|
"navigationBarTextStyle": "black",
|
||||||
|
"navigationBarTitleText": "v派商家",
|
||||||
|
"navigationBarBackgroundColor": "#fff",
|
||||||
|
"backgroundColor": "#000"
|
||||||
|
},
|
||||||
|
"subPackages": [{
|
||||||
|
"root": "pages/order",
|
||||||
|
"pages": [{
|
||||||
|
"path": "orderDetail",
|
||||||
|
"style": {
|
||||||
|
"navigationBarTitleText": "订单详情"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"path": "navigation",
|
||||||
|
"style": {
|
||||||
|
"navigationBarTitleText": "导航",
|
||||||
|
"navigationStyle": "custom"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"path": "abnormal",
|
||||||
|
"style": {
|
||||||
|
"navigationBarTitleText": "上报异常"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"path": "grabOrder",
|
||||||
|
"style": {
|
||||||
|
"navigationBarTitleText": "订单详情"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"path": "incomeDetail",
|
||||||
|
"style": {
|
||||||
|
"navigationBarTitleText": "收入详情",
|
||||||
|
"navigationStyle": "custom"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"path": "withdraw",
|
||||||
|
"style": {
|
||||||
|
"navigationBarTitleText": "提现申请"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"path": "finish",
|
||||||
|
"style": {
|
||||||
|
"navigationBarTitleText": "订单完成"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"path": "upAbnormal",
|
||||||
|
"style": {
|
||||||
|
"navigationBarTitleText": "异常上报"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"path": "orderMap",
|
||||||
|
"style": {
|
||||||
|
"navigationBarTitleText": "订单地图"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"path": "orderChat",
|
||||||
|
"style": {
|
||||||
|
"navigationBarTitleText": "联系客户"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"root": "pages/my",
|
||||||
|
"pages": [{
|
||||||
|
"path": "edit",
|
||||||
|
"style": {
|
||||||
|
"navigationBarTitleText": "编辑资料"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"path": "statusContro",
|
||||||
|
"style": {
|
||||||
|
"navigationBarTitleText": "上线管理"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"path": "myKF",
|
||||||
|
"style": {
|
||||||
|
"navigationBarTitleText": "联系客服"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"path": "AbnormalList",
|
||||||
|
"style": {
|
||||||
|
"navigationBarTitleText": "异常订单"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"path": "check",
|
||||||
|
"style": {
|
||||||
|
"navigationBarTitleText": "签到奖励"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"path": "abnormalDetail",
|
||||||
|
"style": {
|
||||||
|
"navigationBarTitleText": "异常详情"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"path": "security",
|
||||||
|
"style": {
|
||||||
|
"navigationBarTitleText": "账号与安全"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"path": "authentication",
|
||||||
|
"style": {
|
||||||
|
"navigationBarTitleText": "实名认证"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"path": "login",
|
||||||
|
"style": {
|
||||||
|
"navigationBarTitleText": "登录",
|
||||||
|
"navigationStyle": "custom"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"path": "noticeList",
|
||||||
|
"style": {
|
||||||
|
"navigationBarTitleText": "消息通知",
|
||||||
|
"navigationStyle": "custom"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"path": "setConnect",
|
||||||
|
"style": {
|
||||||
|
"navigationBarTitleText": "紧急联系人"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"path": "evaluate",
|
||||||
|
"style": {
|
||||||
|
"navigationBarTitleText": "评价中心"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"path": "completeData",
|
||||||
|
"style": {
|
||||||
|
"navigationBarTitleText": "完善信息"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"path": "withDrowList",
|
||||||
|
"style": {
|
||||||
|
"navigationBarTitleText": "提现列表"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
]
|
||||||
|
}
|
||||||
|
],
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
"tabBar": {
|
||||||
|
"color": "#000",
|
||||||
|
"selectedColor": "#000",
|
||||||
|
"backgroundColor": "#FFFFFF",
|
||||||
|
"list": [{
|
||||||
|
"pagePath": "pages/index/index",
|
||||||
|
"iconPath": "static/tab/home.png",
|
||||||
|
"selectedIconPath": "/static/tab/homed.png",
|
||||||
|
"text": "主页"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"pagePath": "pages/index/income",
|
||||||
|
"iconPath": "static/tab/income.png",
|
||||||
|
"selectedIconPath": "static/tab/incomed.png",
|
||||||
|
"text": "收入"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"pagePath": "pages/index/user",
|
||||||
|
"iconPath": "static/tab/user.png",
|
||||||
|
"selectedIconPath": "static/tab/usered.png",
|
||||||
|
"text": "我的"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,43 @@
|
|||||||
|
import { Service } from '@/Service/Service';
|
||||||
|
/*****代理端接口*****/
|
||||||
|
class NvpAgentService {
|
||||||
|
private static LoginPath: string = '/Agent/Login';
|
||||||
|
/*****登录接口*****/
|
||||||
|
static Login(name: string, pwd: string) {
|
||||||
|
var result = Service.Request(this.LoginPath, "POST", { name, pwd });
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static GetAgentAccInfoPath: string = '/Agent/GetAgentAccInfo';
|
||||||
|
/*****账户接口*****/
|
||||||
|
static GetAgentAccInfo() {
|
||||||
|
var result = Service.Request(this.GetAgentAccInfoPath, "GET", "");
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static GetAgentAccLogPath: string = '/Agent/GetAgentAccLog';
|
||||||
|
/*****账户记录*****/
|
||||||
|
static GetAgentAccLog(code: string, page: number) {
|
||||||
|
var result = Service.Request(this.GetAgentAccLogPath, "GET", { code, page });
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static GetAgentMerchPath: string = '/Agent/GetAgentMerch';
|
||||||
|
/*****获取代理开通商家*****/
|
||||||
|
static GetAgentMerch(type: number, page: number) {
|
||||||
|
var result = Service.Request(this.GetAgentMerchPath, "GET", { type, page });
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static GetAgentHomePath: string = '/Agent/GetAgentHome';
|
||||||
|
/*****代理主页*****/
|
||||||
|
static GetAgentHome() {
|
||||||
|
var result = Service.Request(this.GetAgentHomePath, "GET", { });
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
export {
|
||||||
|
Service,
|
||||||
|
NvpAgentService
|
||||||
|
}
|
||||||
|
After Width: | Height: | Size: 8.7 KiB |
@@ -0,0 +1,30 @@
|
|||||||
|
## 1.4.12(2024-09-21)
|
||||||
|
- 修复 calendar在选择日期范围后重新选择日期需要点两次的Bug
|
||||||
|
## 1.4.11(2024-01-10)
|
||||||
|
- 修复 回到今天时,月份显示不一致问题
|
||||||
|
## 1.4.10(2023-04-10)
|
||||||
|
- 修复 某些情况 monthSwitch 未触发的Bug
|
||||||
|
## 1.4.9(2023-02-02)
|
||||||
|
- 修复 某些情况切换月份错误的Bug
|
||||||
|
## 1.4.8(2023-01-30)
|
||||||
|
- 修复 某些情况切换月份错误的Bug [详情](https://ask.dcloud.net.cn/question/161964)
|
||||||
|
## 1.4.7(2022-09-16)
|
||||||
|
- 优化 支持使用 uni-scss 控制主题色
|
||||||
|
## 1.4.6(2022-09-08)
|
||||||
|
- 修复 表头年月切换,导致改变当前日期为选择月1号,且未触发change事件的Bug
|
||||||
|
## 1.4.5(2022-02-25)
|
||||||
|
- 修复 条件编译 nvue 不支持的 css 样式的Bug
|
||||||
|
## 1.4.4(2022-02-25)
|
||||||
|
- 修复 条件编译 nvue 不支持的 css 样式的Bug
|
||||||
|
## 1.4.3(2021-09-22)
|
||||||
|
- 修复 startDate、 endDate 属性失效的Bug
|
||||||
|
## 1.4.2(2021-08-24)
|
||||||
|
- 新增 支持国际化
|
||||||
|
## 1.4.1(2021-08-05)
|
||||||
|
- 修复 弹出层被 tabbar 遮盖的Bug
|
||||||
|
## 1.4.0(2021-07-30)
|
||||||
|
- 组件兼容 vue3,如何创建vue3项目,详见 [uni-app 项目支持 vue3 介绍](https://ask.dcloud.net.cn/article/37834)
|
||||||
|
## 1.3.16(2021-05-12)
|
||||||
|
- 新增 组件示例地址
|
||||||
|
## 1.3.15(2021-02-04)
|
||||||
|
- 调整为uni_modules目录规范
|
||||||
@@ -0,0 +1,714 @@
|
|||||||
|
<template>
|
||||||
|
<!-- 导航栏 -->
|
||||||
|
<view class=""
|
||||||
|
style="padding:50rpx 20rpx 18rpx; box-sizing: border-box; position: fixed;top: 0; left: 0; width: 100vw; background-color: #fff; display: flex; align-items: center; justify-content: space-between;">
|
||||||
|
<view class="" @click="Service.GoPageBack()">
|
||||||
|
<up-icon name="arrow-left" size="32rpx"></up-icon>
|
||||||
|
</view>
|
||||||
|
<view class="">
|
||||||
|
收入详情
|
||||||
|
</view>
|
||||||
|
<view class="" style="color: var(--nav-banbacor);">
|
||||||
|
<image :src="Service.GetIconImg('/static/index/order/message.png')" style="width: 32rpx; height: 32rpx; "
|
||||||
|
mode=""></image>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
<view class="" style="width: 100%; height: 100rpx; ">
|
||||||
|
|
||||||
|
</view>
|
||||||
|
<view v-if="loading" class="skeleton-container">
|
||||||
|
<!-- 标题骨架屏 -->
|
||||||
|
<view class="skeleton-section-title"></view>
|
||||||
|
|
||||||
|
<!-- 收入卡片骨架屏 -->
|
||||||
|
<view class="skeleton-card">
|
||||||
|
<view class="skeleton-row">
|
||||||
|
<view class="skeleton-order-id"></view>
|
||||||
|
<view class="skeleton-status"></view>
|
||||||
|
</view>
|
||||||
|
<view class="skeleton-row" v-for="item in 3" >
|
||||||
|
<view class="skeleton-order-id" style="width: 30%;" ></view>
|
||||||
|
<view class="skeleton-status"></view>
|
||||||
|
</view>
|
||||||
|
<view class="skeleton-total-row">
|
||||||
|
<view class="skeleton-total-label"></view>
|
||||||
|
<view class="skeleton-total-amount"></view>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
|
||||||
|
<!-- 配送信息标题骨架屏 -->
|
||||||
|
<view class="skeleton-section-title"></view>
|
||||||
|
|
||||||
|
<!-- 订单信息卡片骨架屏 -->
|
||||||
|
<view class="skeleton-card">
|
||||||
|
<!-- 商家信息骨架屏 -->
|
||||||
|
<view class="skeleton-address-item">
|
||||||
|
<view class="skeleton-address-content">
|
||||||
|
<view class="skeleton-address-text">
|
||||||
|
<view class="skeleton-name"></view>
|
||||||
|
<view class="skeleton-address-line"></view>
|
||||||
|
</view>
|
||||||
|
<view class="skeleton-call-btn"></view>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
|
||||||
|
<!-- 用户信息骨架屏 -->
|
||||||
|
<view class="skeleton-address-item">
|
||||||
|
<view class="skeleton-address-content">
|
||||||
|
<view class="skeleton-address-text">
|
||||||
|
<view class="skeleton-name"></view>
|
||||||
|
<view class="skeleton-address-line"></view>
|
||||||
|
</view>
|
||||||
|
<view class="skeleton-call-btn"></view>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
|
||||||
|
<!-- 时间信息骨架屏 -->
|
||||||
|
<view class="skeleton-time"></view>
|
||||||
|
</view>
|
||||||
|
|
||||||
|
<!-- 底部提示骨架屏 -->
|
||||||
|
<view class="skeleton-bottom-tip"></view>
|
||||||
|
</view>
|
||||||
|
|
||||||
|
<!-- 实际内容 -->
|
||||||
|
<view class="order-detail-container">
|
||||||
|
<view class="section-title" style="margin: 20rpx 0;" >订单信息</view>
|
||||||
|
<!-- 订单收入信息卡片 -->
|
||||||
|
<view class="income-card">
|
||||||
|
<view class="income-header">
|
||||||
|
<text class="order-id">订单 MT20251017123456</text>
|
||||||
|
<text class="status">已到账</text>
|
||||||
|
</view>
|
||||||
|
|
||||||
|
<view class="income-details">
|
||||||
|
<view class="income-item">
|
||||||
|
<text class="income-type">配送费</text>
|
||||||
|
<text class="income-amount blue">+¥5.50</text>
|
||||||
|
</view>
|
||||||
|
<view class="income-item">
|
||||||
|
<text class="income-type">冲单奖</text>
|
||||||
|
<text class="income-amount orange">+¥3.00</text>
|
||||||
|
</view>
|
||||||
|
<view class="income-item">
|
||||||
|
<text class="income-type">恶劣天气补贴</text>
|
||||||
|
<text class="income-amount green">+¥2.00</text>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
|
||||||
|
<view class="total-income">
|
||||||
|
<text class="total-label">总计收入</text>
|
||||||
|
<text class="total-amount">¥10.50</text>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
|
||||||
|
<!-- 订单信息卡片 -->
|
||||||
|
<view class="section-title">配送信息</view>
|
||||||
|
<view class="info-card">
|
||||||
|
<!-- 商家信息 -->
|
||||||
|
<view class="merchant-info">
|
||||||
|
<view class="merchant-detail">
|
||||||
|
<view class="merchant-text">
|
||||||
|
<text class="merchant-name">张亮麻辣烫 (五道口店)</text>
|
||||||
|
<text class="merchant-address">成府路28号</text>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
<view class="call-btn" @click="callMerchant">
|
||||||
|
<up-icon name="phone" color="var(--nav-mian)" size="28rpx"></up-icon>
|
||||||
|
<text class="call-text">拨打商家</text>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
|
||||||
|
<!-- 用户信息 -->
|
||||||
|
<view class="user-info">
|
||||||
|
<view class="user-detail">
|
||||||
|
<view class="user-text">
|
||||||
|
<text class="user-name">张*</text>
|
||||||
|
<text class="user-address">XX小区3栋502</text>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
<view class="call-btn" @click="callUser">
|
||||||
|
<up-icon name="phone" color="var(--nav-mian)" size="28rpx"></up-icon>
|
||||||
|
<text class="call-text">拨打用户</text>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
|
||||||
|
<!-- 订单时间信息 -->
|
||||||
|
<view class="order-time-info">
|
||||||
|
<text class="time-text">2025-10-17 18:30 下单 · 19:15 送达</text>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
|
||||||
|
<!-- 底部提示 -->
|
||||||
|
<view class="bottom-tip">
|
||||||
|
<text class="tip-text">收入明细如有疑问,请联系客服</text>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script setup lang="ts">
|
||||||
|
import { ref, onMounted } from 'vue'
|
||||||
|
import { Service } from '@/Service/Service'
|
||||||
|
// 加载状态
|
||||||
|
const loading = ref(true)
|
||||||
|
|
||||||
|
|
||||||
|
// 拨打商家电话
|
||||||
|
const callMerchant = () => {
|
||||||
|
uni.makePhoneCall({
|
||||||
|
phoneNumber: '13800138000'
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
// 拨打用户电话
|
||||||
|
const callUser = () => {
|
||||||
|
uni.makePhoneCall({
|
||||||
|
phoneNumber: '13900139000'
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
onMounted(() => {
|
||||||
|
// 模拟数据加载
|
||||||
|
setTimeout(() => {
|
||||||
|
loading.value = false
|
||||||
|
}, 1500)
|
||||||
|
})
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style scoped>
|
||||||
|
|
||||||
|
|
||||||
|
/* 实际内容样式 */
|
||||||
|
.order-detail-container {
|
||||||
|
background-color: #f5f5f5;
|
||||||
|
padding: 0 20rpx ;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 订单收入信息卡片 */
|
||||||
|
.income-card {
|
||||||
|
background-color: #fff;
|
||||||
|
border-radius: 20rpx;
|
||||||
|
padding: 30rpx;
|
||||||
|
margin-bottom: 20rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
.income-header {
|
||||||
|
display: flex;
|
||||||
|
justify-content: space-between;
|
||||||
|
align-items: center;
|
||||||
|
margin-bottom: 20rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
.order-id {
|
||||||
|
font-size: 32rpx;
|
||||||
|
color: #333;
|
||||||
|
}
|
||||||
|
|
||||||
|
.status {
|
||||||
|
font-size: 28rpx;
|
||||||
|
color: #52c41a;
|
||||||
|
}
|
||||||
|
|
||||||
|
.income-details {
|
||||||
|
margin-bottom: 20rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
.income-item {
|
||||||
|
display: flex;
|
||||||
|
justify-content: space-between;
|
||||||
|
align-items: center;
|
||||||
|
margin-bottom: 20rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
.income-type {
|
||||||
|
font-size: 28rpx;
|
||||||
|
color: #666;
|
||||||
|
}
|
||||||
|
|
||||||
|
.income-amount {
|
||||||
|
font-size: 32rpx;
|
||||||
|
font-weight: 600;
|
||||||
|
}
|
||||||
|
|
||||||
|
.income-amount.blue {
|
||||||
|
color: #1890ff;
|
||||||
|
}
|
||||||
|
|
||||||
|
.income-amount.orange {
|
||||||
|
color: #fa8c16;
|
||||||
|
}
|
||||||
|
|
||||||
|
.income-amount.green {
|
||||||
|
color: #52c41a;
|
||||||
|
}
|
||||||
|
|
||||||
|
.total-income {
|
||||||
|
display: flex;
|
||||||
|
justify-content: space-between;
|
||||||
|
align-items: center;
|
||||||
|
padding-top: 20rpx;
|
||||||
|
border-top: 1rpx solid #f0f0f0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.total-label {
|
||||||
|
font-size: 30rpx;
|
||||||
|
color: #333;
|
||||||
|
font-weight: 600;
|
||||||
|
}
|
||||||
|
|
||||||
|
.total-amount {
|
||||||
|
font-size: 36rpx;
|
||||||
|
color: #ff4d4f;
|
||||||
|
font-weight: 700;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 订单信息卡片 */
|
||||||
|
.info-card {
|
||||||
|
margin-top: 20rpx;
|
||||||
|
background-color: #fff;
|
||||||
|
border-radius: 20rpx;
|
||||||
|
padding: 30rpx;
|
||||||
|
margin-bottom: 20rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
.section-title {
|
||||||
|
font-size: 34rpx;
|
||||||
|
color: #333;
|
||||||
|
font-weight: 600;
|
||||||
|
margin-bottom: 30rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 商家信息 */
|
||||||
|
.merchant-info {
|
||||||
|
display: flex;
|
||||||
|
align-items: baseline;
|
||||||
|
margin-bottom: 30rpx;
|
||||||
|
border-bottom: 1rpx solid #f0f0f0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.merchant-detail {
|
||||||
|
flex: 1;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
margin-bottom: 20rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
.merchant-text {
|
||||||
|
flex: 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
.merchant-name {
|
||||||
|
display: block;
|
||||||
|
font-size: 30rpx;
|
||||||
|
color: #333;
|
||||||
|
margin-bottom: 10rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
.merchant-address {
|
||||||
|
display: block;
|
||||||
|
font-size: 26rpx;
|
||||||
|
color: #666;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 用户信息 */
|
||||||
|
.user-info {
|
||||||
|
margin-bottom: 20rpx;
|
||||||
|
display: flex;
|
||||||
|
align-items: baseline;
|
||||||
|
}
|
||||||
|
|
||||||
|
.user-detail {
|
||||||
|
flex: 1;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
margin-bottom: 20rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
.user-text {
|
||||||
|
flex: 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
.user-name {
|
||||||
|
display: block;
|
||||||
|
font-size: 30rpx;
|
||||||
|
color: #333;
|
||||||
|
margin-bottom: 10rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
.user-address {
|
||||||
|
display: block;
|
||||||
|
font-size: 26rpx;
|
||||||
|
color: #666;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/* 拨打电话按钮 */
|
||||||
|
.call-btn {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
padding: 10rpx 20rpx;
|
||||||
|
border-radius: 20rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
.call-text {
|
||||||
|
font-size: 24rpx;
|
||||||
|
color: #1890ff;
|
||||||
|
margin-left: 6rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 订单时间信息 */
|
||||||
|
.time-text {
|
||||||
|
font-size: 26rpx;
|
||||||
|
color: #999;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 底部提示 */
|
||||||
|
.bottom-tip {
|
||||||
|
text-align: center;
|
||||||
|
margin-top: 30rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
.tip-text {
|
||||||
|
font-size: 24rpx;
|
||||||
|
color: #999;
|
||||||
|
}
|
||||||
|
.order-detail {
|
||||||
|
min-height: 100vh;
|
||||||
|
background-color: #f5f5f5;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 订单状态样式 */
|
||||||
|
.order-status {
|
||||||
|
background-color: #fff;
|
||||||
|
padding: 30rpx;
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 订单基本信息样式 */
|
||||||
|
.order-basic-info {
|
||||||
|
background-color: #fff;
|
||||||
|
margin: 20rpx 20rpx;
|
||||||
|
padding: 30rpx;
|
||||||
|
border-radius: 20rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
.info-item {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
margin-bottom: 20rpx;
|
||||||
|
font-size: 28rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
.info-item:last-child {
|
||||||
|
margin-bottom: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.label {
|
||||||
|
color: #666;
|
||||||
|
margin-right: 10rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
.value {
|
||||||
|
color: #333;
|
||||||
|
}
|
||||||
|
|
||||||
|
.value.highlight {
|
||||||
|
color: var(--nav-diluted);
|
||||||
|
font-weight: 500;
|
||||||
|
}
|
||||||
|
|
||||||
|
.value.price {
|
||||||
|
color: var(--nav-diluted);
|
||||||
|
font-weight: 700;
|
||||||
|
}
|
||||||
|
|
||||||
|
.clock-icon {
|
||||||
|
color: #666;
|
||||||
|
margin-right: 8rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 地图区域样式 */
|
||||||
|
.map-section {
|
||||||
|
margin: 20rpx;
|
||||||
|
border-radius: 20rpx;
|
||||||
|
overflow: hidden;
|
||||||
|
}
|
||||||
|
|
||||||
|
.map-placeholder {
|
||||||
|
width: 100%;
|
||||||
|
height: 400rpx;
|
||||||
|
background-color: #f0f0f0;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
position: relative;
|
||||||
|
border: 1rpx solid #e8e8e8;
|
||||||
|
}
|
||||||
|
|
||||||
|
.map-placeholder::before {
|
||||||
|
content: '';
|
||||||
|
position: absolute;
|
||||||
|
top: 0;
|
||||||
|
left: 0;
|
||||||
|
right: 0;
|
||||||
|
bottom: 0;
|
||||||
|
background: linear-gradient(135deg, #f5f5f5 25%, #e6e6e6 25%, #e6e6e6 50%, #f5f5f5 50%, #f5f5f5 75%, #e6e6e6 75%, #e6e6e6 100%);
|
||||||
|
background-size: 20rpx 20rpx;
|
||||||
|
opacity: 0.3;
|
||||||
|
}
|
||||||
|
|
||||||
|
.map-hint {
|
||||||
|
font-size: 28rpx;
|
||||||
|
color: #666;
|
||||||
|
position: relative;
|
||||||
|
z-index: 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 地址区域样式 */
|
||||||
|
.address-section {
|
||||||
|
background-color: #fff;
|
||||||
|
margin: 20rpx;
|
||||||
|
padding: 30rpx;
|
||||||
|
border-radius: 20rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
.section-title {
|
||||||
|
font-size: 30rpx;
|
||||||
|
font-weight: 800;
|
||||||
|
color: #333;
|
||||||
|
margin-bottom: 25rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
.address-content {
|
||||||
|
position: relative;
|
||||||
|
}
|
||||||
|
|
||||||
|
.store-name,
|
||||||
|
.user-name {
|
||||||
|
font-size: 34rpx;
|
||||||
|
font-weight: 600;
|
||||||
|
margin-bottom: 15rpx;
|
||||||
|
display: block;
|
||||||
|
}
|
||||||
|
|
||||||
|
.address {
|
||||||
|
font-size: 26rpx;
|
||||||
|
color: #666;
|
||||||
|
line-height: 1.5;
|
||||||
|
margin-bottom: 25rpx;
|
||||||
|
display: block;
|
||||||
|
}
|
||||||
|
|
||||||
|
.pickup-code,
|
||||||
|
.remark {
|
||||||
|
font-size: 26rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
.code-label,
|
||||||
|
.code-value {
|
||||||
|
color: var(--nav-mian);
|
||||||
|
font-weight: 600;
|
||||||
|
}
|
||||||
|
|
||||||
|
.remark-label,
|
||||||
|
.remark-content {
|
||||||
|
color: #faad14;
|
||||||
|
font-weight: 600;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 底部按钮样式 */
|
||||||
|
.bottom-action {
|
||||||
|
background-color: #fff;
|
||||||
|
width: 100vw;
|
||||||
|
position: fixed;
|
||||||
|
bottom: 0;
|
||||||
|
left: 0;
|
||||||
|
padding: 20rpx 30rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
.confirm-btn {
|
||||||
|
width: 100%;
|
||||||
|
height: 90rpx;
|
||||||
|
font-size: 32rpx;
|
||||||
|
line-height: 90rpx;
|
||||||
|
border-radius: 45rpx;
|
||||||
|
}
|
||||||
|
/* 骨架屏样式 */
|
||||||
|
.skeleton-container {
|
||||||
|
min-height: 100vh;
|
||||||
|
background-color: #f5f5f5;
|
||||||
|
padding: 0 20rpx 60rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 标题骨架屏 */
|
||||||
|
.skeleton-section-title {
|
||||||
|
width: 160rpx;
|
||||||
|
height: 34rpx;
|
||||||
|
background-color: #e6e6e6;
|
||||||
|
margin: 30rpx 0;
|
||||||
|
border-radius: 4rpx;
|
||||||
|
animation: shimmer 1.5s infinite;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 卡片骨架屏 */
|
||||||
|
.skeleton-card {
|
||||||
|
background-color: #fff;
|
||||||
|
border-radius: 20rpx;
|
||||||
|
padding: 30rpx;
|
||||||
|
margin-bottom: 20rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 收入卡片骨架屏 */
|
||||||
|
.skeleton-row {
|
||||||
|
display: flex;
|
||||||
|
justify-content: space-between;
|
||||||
|
align-items: center;
|
||||||
|
margin-bottom: 20rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
.skeleton-order-id {
|
||||||
|
width: 60%;
|
||||||
|
height: 32rpx;
|
||||||
|
background-color: #e6e6e6;
|
||||||
|
border-radius: 4rpx;
|
||||||
|
animation: shimmer 1.5s infinite;
|
||||||
|
}
|
||||||
|
|
||||||
|
.skeleton-status {
|
||||||
|
width: 15%;
|
||||||
|
height: 28rpx;
|
||||||
|
background-color: #e6e6e6;
|
||||||
|
border-radius: 4rpx;
|
||||||
|
animation: shimmer 1.5s infinite;
|
||||||
|
}
|
||||||
|
|
||||||
|
.skeleton-line {
|
||||||
|
width: 100%;
|
||||||
|
height: 28rpx;
|
||||||
|
background-color: #e6e6e6;
|
||||||
|
margin-bottom: 20rpx;
|
||||||
|
border-radius: 4rpx;
|
||||||
|
animation: shimmer 1.5s infinite;
|
||||||
|
}
|
||||||
|
|
||||||
|
.skeleton-total-row {
|
||||||
|
display: flex;
|
||||||
|
justify-content: space-between;
|
||||||
|
align-items: center;
|
||||||
|
padding-top: 20rpx;
|
||||||
|
border-top: 1rpx solid #f0f0f0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.skeleton-total-label {
|
||||||
|
width: 40%;
|
||||||
|
height: 30rpx;
|
||||||
|
background-color: #e6e6e6;
|
||||||
|
border-radius: 4rpx;
|
||||||
|
animation: shimmer 1.5s infinite;
|
||||||
|
}
|
||||||
|
|
||||||
|
.skeleton-total-amount {
|
||||||
|
width: 25%;
|
||||||
|
height: 36rpx;
|
||||||
|
background-color: #e6e6e6;
|
||||||
|
border-radius: 4rpx;
|
||||||
|
animation: shimmer 1.5s infinite;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 地址信息骨架屏 */
|
||||||
|
.skeleton-address-item {
|
||||||
|
margin-bottom: 30rpx;
|
||||||
|
padding-bottom: 30rpx;
|
||||||
|
border-bottom: 1rpx solid #f0f0f0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.skeleton-address-item:last-child {
|
||||||
|
margin-bottom: 20rpx;
|
||||||
|
padding-bottom: 0;
|
||||||
|
border-bottom: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
.skeleton-address-content {
|
||||||
|
display: flex;
|
||||||
|
justify-content: space-between;
|
||||||
|
align-items: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.skeleton-address-text {
|
||||||
|
flex: 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
.skeleton-name {
|
||||||
|
width: 60%;
|
||||||
|
height: 30rpx;
|
||||||
|
background-color: #e6e6e6;
|
||||||
|
margin-bottom: 10rpx;
|
||||||
|
border-radius: 4rpx;
|
||||||
|
animation: shimmer 1.5s infinite;
|
||||||
|
}
|
||||||
|
|
||||||
|
.skeleton-address-line {
|
||||||
|
width: 80%;
|
||||||
|
height: 26rpx;
|
||||||
|
background-color: #e6e6e6;
|
||||||
|
border-radius: 4rpx;
|
||||||
|
animation: shimmer 1.5s infinite;
|
||||||
|
}
|
||||||
|
|
||||||
|
.skeleton-call-btn {
|
||||||
|
width: 150rpx;
|
||||||
|
height: 50rpx;
|
||||||
|
background-color: #e6e6e6;
|
||||||
|
border-radius: 25rpx;
|
||||||
|
animation: shimmer 1.5s infinite;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 时间信息骨架屏 */
|
||||||
|
.skeleton-time {
|
||||||
|
width: 70%;
|
||||||
|
height: 26rpx;
|
||||||
|
background-color: #e6e6e6;
|
||||||
|
margin-top: 20rpx;
|
||||||
|
border-radius: 4rpx;
|
||||||
|
animation: shimmer 1.5s infinite;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 底部提示骨架屏 */
|
||||||
|
.skeleton-bottom-tip {
|
||||||
|
margin: 0 100rpx;
|
||||||
|
height: 24rpx;
|
||||||
|
background-color: #e6e6e6;
|
||||||
|
margin-top: 30rpx;
|
||||||
|
border-radius: 4rpx;
|
||||||
|
animation: shimmer 1.5s infinite;
|
||||||
|
opacity: 0.6;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 骨架屏动画 */
|
||||||
|
@keyframes shimmer {
|
||||||
|
0% {
|
||||||
|
background-position: -1000px 0;
|
||||||
|
}
|
||||||
|
100% {
|
||||||
|
background-position: 1000px 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 为骨架屏元素添加渐变背景 */
|
||||||
|
.skeleton-section-title,
|
||||||
|
.skeleton-order-id,
|
||||||
|
.skeleton-status,
|
||||||
|
.skeleton-line,
|
||||||
|
.skeleton-total-label,
|
||||||
|
.skeleton-total-amount,
|
||||||
|
.skeleton-name,
|
||||||
|
.skeleton-address-line,
|
||||||
|
.skeleton-call-btn,
|
||||||
|
.skeleton-time,
|
||||||
|
.skeleton-bottom-tip {
|
||||||
|
background-image: linear-gradient(90deg, #f0f0f0 25%, #e0e0e0 50%, #f0f0f0 75%);
|
||||||
|
background-size: 1000px 100%;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
After Width: | Height: | Size: 387 B |
@@ -0,0 +1,662 @@
|
|||||||
|
<template>
|
||||||
|
<!-- 导航栏 -->
|
||||||
|
<view class=""
|
||||||
|
style="padding:50rpx 20rpx 18rpx; box-sizing: border-box; position: fixed;top: 0; left: 0; width: 100vw; background-color: #fff; display: flex; align-items: center; justify-content: space-between;">
|
||||||
|
<view class="" @click="Service.GoPageBack()">
|
||||||
|
<up-icon name="arrow-left" size="32rpx"></up-icon>
|
||||||
|
</view>
|
||||||
|
<view class="">
|
||||||
|
订单详情
|
||||||
|
</view>
|
||||||
|
<view class="" @click="Service.GoPage('/pages/my/myKF')" style="color: var(--nav-banbacor);">
|
||||||
|
<image :src="Service.GetIconImg('/static/index/order/message.png')" style="width: 32rpx; height: 32rpx; "
|
||||||
|
mode=""></image>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
<view class="" style="width: 100%; height: 88rpx; ">
|
||||||
|
|
||||||
|
</view>
|
||||||
|
|
||||||
|
<!-- 骨架屏 -->
|
||||||
|
<view v-if="loading" class="skeleton-container">
|
||||||
|
<!-- 骨架屏订单状态 -->
|
||||||
|
<view class="skeleton-status"></view>
|
||||||
|
|
||||||
|
<!-- 骨架屏订单基本信息 -->
|
||||||
|
<view class="skeleton-basic-info">
|
||||||
|
<view class="skeleton-row">
|
||||||
|
<view class="skeleton-info-half"></view>
|
||||||
|
<view class="skeleton-info-half skeleton-right"></view>
|
||||||
|
</view>
|
||||||
|
<view class="skeleton-line"></view>
|
||||||
|
<view class="skeleton-line"></view>
|
||||||
|
<view class="skeleton-line"></view>
|
||||||
|
<view class="skeleton-row">
|
||||||
|
<view class="skeleton-info-third"></view>
|
||||||
|
<view class="skeleton-info-btn"></view>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
|
||||||
|
<!-- 骨架屏物品清单 -->
|
||||||
|
<view class="skeleton-basic-info">
|
||||||
|
<view class="skeleton-row">
|
||||||
|
<view class="" style="width: 45%;height: 40rpx;border-radius: 4rpx;animation: shimmer 1.5s infinite;" >
|
||||||
|
<view class="" style="background-color: #e6e6e6; width: 60%;height: 40rpx; " >
|
||||||
|
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
<view class="skeleton-info-half skeleton-right"></view>
|
||||||
|
<view class="skeleton-info-half skeleton-right"></view>
|
||||||
|
</view>
|
||||||
|
<view class="skeleton-row" v-for="(item,index) in 3" :key="index" >
|
||||||
|
<view class="" style="width: 45%;height: 40rpx;border-radius: 4rpx;animation: shimmer 1.5s infinite;" >
|
||||||
|
<view class="" style="background-color: #e6e6e6; width: 90%;height: 40rpx; " >
|
||||||
|
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
<view class="skeleton-info-half skeleton-right"></view>
|
||||||
|
<view class="skeleton-info-half skeleton-right"></view>
|
||||||
|
</view>
|
||||||
|
<view class="skeleton-list-status"></view>
|
||||||
|
</view>
|
||||||
|
|
||||||
|
<!-- 骨架屏地图区域 -->
|
||||||
|
<view class="skeleton-map"></view>
|
||||||
|
|
||||||
|
<!-- 骨架屏取餐地址 -->
|
||||||
|
<view class="skeleton-address">
|
||||||
|
<view class="skeleton-title"></view>
|
||||||
|
<view class="skeleton-store-name"></view>
|
||||||
|
<view class="skeleton-address-line"></view>
|
||||||
|
<view class="skeleton-btn"></view>
|
||||||
|
<view class="skeleton-code"></view>
|
||||||
|
</view>
|
||||||
|
|
||||||
|
<!-- 骨架屏送餐地址 -->
|
||||||
|
<view class="skeleton-address">
|
||||||
|
<view class="skeleton-title"></view>
|
||||||
|
<view class="skeleton-store-name"></view>
|
||||||
|
<view class="skeleton-address-line"></view>
|
||||||
|
<view class="skeleton-btn"></view>
|
||||||
|
<view class="skeleton-remark"></view>
|
||||||
|
</view>
|
||||||
|
|
||||||
|
<!-- 骨架屏底部按钮 -->
|
||||||
|
<view class="skeleton-bottom">
|
||||||
|
<view class="skeleton-bottom-btn"></view>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
<!-- 实际内容 -->
|
||||||
|
<view v-else class="order-detail">
|
||||||
|
<!-- 订单状态 -->
|
||||||
|
<view class="order-status"
|
||||||
|
:style="{ 'background-color':orderStatus==0?'#E6F7FF':(orderStatus==1?'#FFFBE6':'#FFF2F0') }">
|
||||||
|
<text :style="{ 'color':orderStatus==0?'#1890FF':(orderStatus==1?'#FAAD14':'#FF4D4F') }"
|
||||||
|
style="font-size: 34rpx; font-weight: 600;">待取餐 · 请尽快到店取餐</text>
|
||||||
|
|
||||||
|
</view>
|
||||||
|
|
||||||
|
<!-- 订单基本信息 -->
|
||||||
|
<view class="order-basic-info">
|
||||||
|
<view class="" style="display: flex; align-items: center; justify-content: space-between;">
|
||||||
|
<view class="info-item">
|
||||||
|
<view class="label">剩余</view>
|
||||||
|
<view class="value highlight">10分钟</view>
|
||||||
|
<view class="label">(19:30前送达)</view>
|
||||||
|
</view>
|
||||||
|
<view class="info-item">
|
||||||
|
<text class="label" style="font-weight: 700;">配送费</text>
|
||||||
|
<text class="value price">¥5.50</text>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
<view class="info-item">
|
||||||
|
<text class="label">订单编号 : </text>
|
||||||
|
<text class="value">20251021123456</text>
|
||||||
|
</view>
|
||||||
|
<view class="info-item" style=" justify-content: space-between;">
|
||||||
|
<view class="">
|
||||||
|
<text class="label">物品明细 : </text>
|
||||||
|
<text class="value">食物</text>
|
||||||
|
</view>
|
||||||
|
<view class="label">共3件商品</view>
|
||||||
|
</view>
|
||||||
|
<view class="info-item">
|
||||||
|
<text class="label">物品重量 : </text>
|
||||||
|
<text class="value">0.5kg</text>
|
||||||
|
</view>
|
||||||
|
<view class="info-item" style="justify-content: space-between; ">
|
||||||
|
<view class="label" style="display: flex; align-items: baseline;">
|
||||||
|
<u-icon name="clock" size="24rpx" class="clock-icon"></u-icon>
|
||||||
|
2025-10-17 18:30下单
|
||||||
|
</view>
|
||||||
|
<view class="info-item">
|
||||||
|
<up-button @click.stop="Service.GoPage('/pages/order/abnormal')" type="warning"
|
||||||
|
color='var(--nav-diluted)' shape='circle' size="mini">提交异常</up-button>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
|
||||||
|
</view>
|
||||||
|
|
||||||
|
<!-- 物品清单 -->
|
||||||
|
<view class="order-basic-info">
|
||||||
|
<view class="" style="display: flex; align-items: center; ">
|
||||||
|
<view class="" style="flex: 1; font-size: 34rpx; font-weight: 600; ">
|
||||||
|
物品清单
|
||||||
|
</view>
|
||||||
|
<view class="" style="width: 100rpx; text-align: right; font-size: 30rpx; ">
|
||||||
|
5件
|
||||||
|
</view>
|
||||||
|
<view class="" style="width: 120rpx; text-align: right; font-size: 30rpx; ">
|
||||||
|
¥16
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
<!-- 商品列表 -->
|
||||||
|
<view class="" :style="{'height':isShow?'190rpx':'fit-content' }" style="overflow: hidden;">
|
||||||
|
<view class="" v-for="(goodsItem,goodsIndex) in 5 " :key="goodsIndex"
|
||||||
|
style="display: flex; align-items: center; margin-top: 15rpx; ">
|
||||||
|
<view class="" style="flex: 1; ">
|
||||||
|
康师傅 大食桶红烧牛肉143g/桶 经典红烧酱香免洗桶装速食泡面
|
||||||
|
</view>
|
||||||
|
<view class="" style="width: 100rpx; text-align: right; ">
|
||||||
|
×4
|
||||||
|
</view>
|
||||||
|
<view class="" style="width: 120rpx; text-align: right; ">
|
||||||
|
¥16
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
<view class="" @click="isShow=!isShow"
|
||||||
|
style=" margin-top: 20rpx; display: flex; align-items: center; justify-content: center; color: #666; ">
|
||||||
|
<up-icon :name="isShow?'arrow-down':'arrow-up'" color="#666" size="18"></up-icon>
|
||||||
|
{{isShow?'展开':'收入'}}
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
<!-- 地图区域 -->
|
||||||
|
<view class="map-section">
|
||||||
|
<view class="map-placeholder">
|
||||||
|
<text @click="Service.GoPage('/pages/order/navigation')" class="map-hint">点击查看完整导航</text>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
|
||||||
|
<!-- 取餐地址 -->
|
||||||
|
<view class="address-section">
|
||||||
|
<text class="section-title">取餐地址</text>
|
||||||
|
<view class="address-content">
|
||||||
|
<text class="store-name">张亮麻辣烫(五道口店)</text>
|
||||||
|
<text class="address">北京市海淀区成府路28号</text>
|
||||||
|
<view class="" style="margin-bottom: 20rpx;">
|
||||||
|
<up-button icon="phone" type="primary" shape="circle" text="拨打商家"></up-button>
|
||||||
|
</view>
|
||||||
|
<view class="pickup-code">
|
||||||
|
<text class="code-label">取餐号:</text>
|
||||||
|
<text class="code-value">A123</text>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
|
||||||
|
<!-- 送餐地址 -->
|
||||||
|
<view class="address-section">
|
||||||
|
<text class="section-title">送餐地址</text>
|
||||||
|
<view class="address-content">
|
||||||
|
<text class="user-name">张*</text>
|
||||||
|
<text class="address">XX小区3栋502室</text>
|
||||||
|
<view class="" style="margin-bottom: 20rpx;">
|
||||||
|
<up-button icon="phone" type="primary" shape="circle" text="拨打商家"></up-button>
|
||||||
|
</view>
|
||||||
|
<view class="remark">
|
||||||
|
<text class="remark-label">备注:</text>
|
||||||
|
<text class="remark-content">请放门口,勿按门铃</text>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
|
||||||
|
<view class="" style="width: 100vw; height: 140rpx; ">
|
||||||
|
|
||||||
|
</view>
|
||||||
|
|
||||||
|
<!-- 底部按钮 -->
|
||||||
|
<view class="bottom-action">
|
||||||
|
<up-button color="var(--nav-vice)" class="confirm-btn">我已取餐</up-button>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script setup lang="ts">
|
||||||
|
import { onLoad } from '@dcloudio/uni-app';
|
||||||
|
import { ref, onMounted } from 'vue';
|
||||||
|
import { Service } from '@/Service/Service';
|
||||||
|
|
||||||
|
// 加载状态
|
||||||
|
const loading = ref(true);
|
||||||
|
|
||||||
|
let orderStatus = ref(0)
|
||||||
|
|
||||||
|
let isShow = ref(true)
|
||||||
|
|
||||||
|
onLoad(() => {
|
||||||
|
setTimeout(() => {
|
||||||
|
loading.value = false
|
||||||
|
}, 1000)
|
||||||
|
})
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style scoped>
|
||||||
|
/* 骨架屏样式 */
|
||||||
|
.skeleton-container {
|
||||||
|
min-height: 100vh;
|
||||||
|
background-color: #f5f5f5;
|
||||||
|
padding-bottom: 140rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 骨架屏导航栏 */
|
||||||
|
.skeleton-nav {
|
||||||
|
height: 88rpx;
|
||||||
|
position: fixed;
|
||||||
|
top: 0;
|
||||||
|
left: 0;
|
||||||
|
width: 100vw;
|
||||||
|
background-color: #fff;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: space-between;
|
||||||
|
padding: 0 20rpx;
|
||||||
|
z-index: 100;
|
||||||
|
}
|
||||||
|
|
||||||
|
.skeleton-nav-item {
|
||||||
|
width: 32rpx;
|
||||||
|
height: 32rpx;
|
||||||
|
background-color: #e6e6e6;
|
||||||
|
border-radius: 4rpx;
|
||||||
|
animation: shimmer 1.5s infinite;
|
||||||
|
}
|
||||||
|
|
||||||
|
.skeleton-nav-title {
|
||||||
|
width: 180rpx;
|
||||||
|
height: 36rpx;
|
||||||
|
background-color: #e6e6e6;
|
||||||
|
border-radius: 4rpx;
|
||||||
|
animation: shimmer 1.5s infinite;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 骨架屏订单状态 */
|
||||||
|
.skeleton-status {
|
||||||
|
height: 100rpx;
|
||||||
|
background-color: #fff;
|
||||||
|
padding: 30rpx;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.skeleton-status::after {
|
||||||
|
content: '';
|
||||||
|
width: 350rpx;
|
||||||
|
height: 45rpx;
|
||||||
|
background-color: #e6e6e6;
|
||||||
|
border-radius: 4rpx;
|
||||||
|
animation: shimmer 1.5s infinite;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 骨架屏订单基本信息 */
|
||||||
|
.skeleton-basic-info {
|
||||||
|
background-color: #fff;
|
||||||
|
margin: 20rpx 20rpx;
|
||||||
|
padding: 30rpx;
|
||||||
|
border-radius: 20rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
.skeleton-row {
|
||||||
|
display: flex;
|
||||||
|
justify-content: space-between;
|
||||||
|
margin-bottom: 20rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
.skeleton-info-half {
|
||||||
|
width: 45%;
|
||||||
|
height: 40rpx;
|
||||||
|
background-color: #e6e6e6;
|
||||||
|
border-radius: 4rpx;
|
||||||
|
animation: shimmer 1.5s infinite;
|
||||||
|
}
|
||||||
|
|
||||||
|
.skeleton-right {
|
||||||
|
width: 10%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.skeleton-line {
|
||||||
|
width: 60%;
|
||||||
|
height: 40rpx;
|
||||||
|
background-color: #e6e6e6;
|
||||||
|
border-radius: 4rpx;
|
||||||
|
margin-bottom: 20rpx;
|
||||||
|
animation: shimmer 1.5s infinite;
|
||||||
|
}
|
||||||
|
|
||||||
|
.skeleton-info-third {
|
||||||
|
width: 60%;
|
||||||
|
height: 40rpx;
|
||||||
|
background-color: #e6e6e6;
|
||||||
|
border-radius: 4rpx;
|
||||||
|
animation: shimmer 1.5s infinite;
|
||||||
|
}
|
||||||
|
|
||||||
|
.skeleton-info-btn {
|
||||||
|
width: 20%;
|
||||||
|
height: 50rpx;
|
||||||
|
background-color: #e6e6e6;
|
||||||
|
border-radius: 25rpx;
|
||||||
|
animation: shimmer 1.5s infinite;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 列表状态 */
|
||||||
|
.skeleton-list-status {
|
||||||
|
height: 60rpx;
|
||||||
|
background-color: #fff;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.skeleton-list-status::after {
|
||||||
|
content: '';
|
||||||
|
width: 200rpx;
|
||||||
|
height: 45rpx;
|
||||||
|
background-color: #e6e6e6;
|
||||||
|
border-radius: 4rpx;
|
||||||
|
animation: shimmer 1.5s infinite;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 骨架屏地图区域 */
|
||||||
|
.skeleton-map {
|
||||||
|
margin: 20rpx;
|
||||||
|
height: 400rpx;
|
||||||
|
background-color: #e6e6e6;
|
||||||
|
border-radius: 20rpx;
|
||||||
|
animation: shimmer 1.5s infinite;
|
||||||
|
position: relative;
|
||||||
|
overflow: hidden;
|
||||||
|
}
|
||||||
|
|
||||||
|
.skeleton-map::after {
|
||||||
|
content: '';
|
||||||
|
position: absolute;
|
||||||
|
top: 0;
|
||||||
|
left: 0;
|
||||||
|
right: 0;
|
||||||
|
bottom: 0;
|
||||||
|
background: linear-gradient(135deg, transparent 25%, rgba(255, 255, 255, 0.2) 25%, rgba(255, 255, 255, 0.2) 50%, transparent 50%, transparent 75%, rgba(255, 255, 255, 0.2) 75%, rgba(255, 255, 255, 0.2));
|
||||||
|
background-size: 100rpx 100rpx;
|
||||||
|
animation: shimmer 1.5s infinite linear;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 骨架屏地址区域 */
|
||||||
|
.skeleton-address {
|
||||||
|
background-color: #fff;
|
||||||
|
margin: 20rpx;
|
||||||
|
padding: 30rpx;
|
||||||
|
border-radius: 20rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
.skeleton-title {
|
||||||
|
width: 120rpx;
|
||||||
|
height: 30rpx;
|
||||||
|
background-color: #e6e6e6;
|
||||||
|
border-radius: 4rpx;
|
||||||
|
margin-bottom: 25rpx;
|
||||||
|
animation: shimmer 1.5s infinite;
|
||||||
|
}
|
||||||
|
|
||||||
|
.skeleton-store-name {
|
||||||
|
width: 70%;
|
||||||
|
height: 50rpx;
|
||||||
|
background-color: #e6e6e6;
|
||||||
|
border-radius: 4rpx;
|
||||||
|
margin-bottom: 15rpx;
|
||||||
|
animation: shimmer 1.5s infinite;
|
||||||
|
}
|
||||||
|
|
||||||
|
.skeleton-address-line {
|
||||||
|
width: 90%;
|
||||||
|
height: 26rpx;
|
||||||
|
background-color: #e6e6e6;
|
||||||
|
border-radius: 4rpx;
|
||||||
|
margin-bottom: 15rpx;
|
||||||
|
animation: shimmer 1.5s infinite;
|
||||||
|
}
|
||||||
|
|
||||||
|
.skeleton-btn {
|
||||||
|
height: 70rpx;
|
||||||
|
background-color: #e6e6e6;
|
||||||
|
border-radius: 35rpx;
|
||||||
|
margin: 20rpx 0;
|
||||||
|
animation: shimmer 1.5s infinite;
|
||||||
|
}
|
||||||
|
|
||||||
|
.skeleton-code {
|
||||||
|
width: 50%;
|
||||||
|
height: 26rpx;
|
||||||
|
background-color: #e6e6e6;
|
||||||
|
border-radius: 4rpx;
|
||||||
|
animation: shimmer 1.5s infinite;
|
||||||
|
}
|
||||||
|
|
||||||
|
.skeleton-remark {
|
||||||
|
width: 80%;
|
||||||
|
height: 26rpx;
|
||||||
|
background-color: #e6e6e6;
|
||||||
|
border-radius: 4rpx;
|
||||||
|
animation: shimmer 1.5s infinite;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 骨架屏底部按钮 */
|
||||||
|
.skeleton-bottom {
|
||||||
|
background-color: #fff;
|
||||||
|
width: 100vw;
|
||||||
|
position: fixed;
|
||||||
|
bottom: 0;
|
||||||
|
left: 0;
|
||||||
|
padding: 20rpx 30rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
.skeleton-bottom-btn {
|
||||||
|
width: 100%;
|
||||||
|
height: 90rpx;
|
||||||
|
background-color: #e6e6e6;
|
||||||
|
border-radius: 45rpx;
|
||||||
|
animation: shimmer 1.5s infinite;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 骨架屏动画 */
|
||||||
|
@keyframes shimmer {
|
||||||
|
0% {
|
||||||
|
opacity: 0.6;
|
||||||
|
}
|
||||||
|
|
||||||
|
50% {
|
||||||
|
opacity: 0.8;
|
||||||
|
}
|
||||||
|
|
||||||
|
100% {
|
||||||
|
opacity: 0.6;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 骨架屏滑动动画 */
|
||||||
|
@keyframes shimmer-slide {
|
||||||
|
0% {
|
||||||
|
transform: translateX(-100%);
|
||||||
|
}
|
||||||
|
|
||||||
|
100% {
|
||||||
|
transform: translateX(100%);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* end */
|
||||||
|
|
||||||
|
.order-detail {
|
||||||
|
min-height: 100vh;
|
||||||
|
background-color: #f5f5f5;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 订单状态样式 */
|
||||||
|
.order-status {
|
||||||
|
background-color: #fff;
|
||||||
|
padding: 30rpx;
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* 订单基本信息样式 */
|
||||||
|
.order-basic-info {
|
||||||
|
background-color: #fff;
|
||||||
|
margin: 20rpx 20rpx;
|
||||||
|
padding: 30rpx;
|
||||||
|
border-radius: 20rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
.info-item {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
margin-bottom: 20rpx;
|
||||||
|
font-size: 28rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
.info-item:last-child {
|
||||||
|
margin-bottom: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.label {
|
||||||
|
color: #666;
|
||||||
|
margin-right: 10rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
.value {
|
||||||
|
color: #333;
|
||||||
|
}
|
||||||
|
|
||||||
|
.value.highlight {
|
||||||
|
color: var(--nav-diluted);
|
||||||
|
font-weight: 500;
|
||||||
|
}
|
||||||
|
|
||||||
|
.value.price {
|
||||||
|
color: var(--nav-diluted);
|
||||||
|
font-weight: 700;
|
||||||
|
}
|
||||||
|
|
||||||
|
.clock-icon {
|
||||||
|
color: #666;
|
||||||
|
margin-right: 8rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 地图区域样式 */
|
||||||
|
.map-section {
|
||||||
|
margin: 20rpx;
|
||||||
|
border-radius: 20rpx;
|
||||||
|
overflow: hidden;
|
||||||
|
}
|
||||||
|
|
||||||
|
.map-placeholder {
|
||||||
|
width: 100%;
|
||||||
|
height: 400rpx;
|
||||||
|
background-color: #f0f0f0;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
position: relative;
|
||||||
|
border: 1rpx solid #e8e8e8;
|
||||||
|
}
|
||||||
|
|
||||||
|
.map-placeholder::before {
|
||||||
|
content: '';
|
||||||
|
position: absolute;
|
||||||
|
top: 0;
|
||||||
|
left: 0;
|
||||||
|
right: 0;
|
||||||
|
bottom: 0;
|
||||||
|
background: linear-gradient(135deg, #f5f5f5 25%, #e6e6e6 25%, #e6e6e6 50%, #f5f5f5 50%, #f5f5f5 75%, #e6e6e6 75%, #e6e6e6 100%);
|
||||||
|
background-size: 20rpx 20rpx;
|
||||||
|
opacity: 0.3;
|
||||||
|
}
|
||||||
|
|
||||||
|
.map-hint {
|
||||||
|
font-size: 28rpx;
|
||||||
|
color: #666;
|
||||||
|
position: relative;
|
||||||
|
z-index: 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 地址区域样式 */
|
||||||
|
.address-section {
|
||||||
|
background-color: #fff;
|
||||||
|
margin: 20rpx;
|
||||||
|
padding: 30rpx;
|
||||||
|
border-radius: 20rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
.section-title {
|
||||||
|
font-size: 30rpx;
|
||||||
|
font-weight: 800;
|
||||||
|
color: #333;
|
||||||
|
margin-bottom: 25rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
.address-content {
|
||||||
|
position: relative;
|
||||||
|
}
|
||||||
|
|
||||||
|
.store-name,
|
||||||
|
.user-name {
|
||||||
|
font-size: 34rpx;
|
||||||
|
font-weight: 600;
|
||||||
|
margin-bottom: 15rpx;
|
||||||
|
display: block;
|
||||||
|
}
|
||||||
|
|
||||||
|
.address {
|
||||||
|
font-size: 26rpx;
|
||||||
|
color: #666;
|
||||||
|
line-height: 1.5;
|
||||||
|
margin-bottom: 25rpx;
|
||||||
|
display: block;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
.pickup-code,
|
||||||
|
.remark {
|
||||||
|
font-size: 26rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
.code-label,
|
||||||
|
.code-value {
|
||||||
|
color: var(--nav-mian);
|
||||||
|
font-weight: 600;
|
||||||
|
}
|
||||||
|
|
||||||
|
.remark-label,
|
||||||
|
.remark-content {
|
||||||
|
color: #FAAD14;
|
||||||
|
font-weight: 600;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 底部按钮样式 */
|
||||||
|
.bottom-action {
|
||||||
|
background-color: #fff;
|
||||||
|
width: 100vw;
|
||||||
|
position: fixed;
|
||||||
|
bottom: 0;
|
||||||
|
left: 0;
|
||||||
|
padding: 20rpx 30rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
.confirm-btn {
|
||||||
|
width: 100%;
|
||||||
|
height: 90rpx;
|
||||||
|
font-size: 32rpx;
|
||||||
|
line-height: 90rpx;
|
||||||
|
border-radius: 45rpx;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
@@ -0,0 +1,145 @@
|
|||||||
|
{
|
||||||
|
"name" : "骑手端",
|
||||||
|
"appid" : "__UNI__06C2D6A",
|
||||||
|
"description" : "",
|
||||||
|
"versionName" : "1.0.8",
|
||||||
|
"versionCode" : 108,
|
||||||
|
"transformPx" : false,
|
||||||
|
/* 5+App特有相关 */
|
||||||
|
"app-plus" : {
|
||||||
|
"compatible" : {
|
||||||
|
"ignoreVersion" : true //true表示忽略版本检查提示框,HBuilderX1.9.0及以上版本支持
|
||||||
|
},
|
||||||
|
"usingComponents" : true,
|
||||||
|
"nvueStyleCompiler" : "uni-app",
|
||||||
|
"compilerVersion" : 3,
|
||||||
|
"splashscreen" : {
|
||||||
|
"alwaysShowBeforeRender" : false,
|
||||||
|
"waiting" : false,
|
||||||
|
"autoclose" : true,
|
||||||
|
"delay" : 0
|
||||||
|
},
|
||||||
|
/* 模块配置 */
|
||||||
|
"modules" : {
|
||||||
|
"Barcode" : {},
|
||||||
|
"Maps" : {},
|
||||||
|
"Geolocation" : {},
|
||||||
|
"Camera" : {},
|
||||||
|
"Contacts" : {}
|
||||||
|
},
|
||||||
|
/* 应用发布信息 */
|
||||||
|
"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\"/>"
|
||||||
|
],
|
||||||
|
"minSdkVersion" : 25,
|
||||||
|
"targetSdkVersion" : 25,
|
||||||
|
"abiFilters" : [ "armeabi-v7a", "arm64-v8a", "x86" ]
|
||||||
|
},
|
||||||
|
/* ios打包配置 */
|
||||||
|
"ios" : {
|
||||||
|
"idfa" : false,
|
||||||
|
"dSYMs" : false
|
||||||
|
},
|
||||||
|
/* SDK配置 */
|
||||||
|
"sdkConfigs" : {
|
||||||
|
"ad" : {},
|
||||||
|
"maps" : {
|
||||||
|
"amap" : {
|
||||||
|
"name" : "amapZAvZjTHj",
|
||||||
|
"appkey_ios" : "3caf9e6f01b0085be1e75e0d0e281fe7",
|
||||||
|
"appkey_android" : "3caf9e6f01b0085be1e75e0d0e281fe7"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"geolocation" : {
|
||||||
|
"amap" : {
|
||||||
|
"name" : "amapZAvZjTHj",
|
||||||
|
"__platform__" : [ "android" ],
|
||||||
|
"appkey_ios" : "",
|
||||||
|
"appkey_android" : "3caf9e6f01b0085be1e75e0d0e281fe7"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"icons" : {
|
||||||
|
"android" : {
|
||||||
|
"hdpi" : "unpackage/res/icons/72x72.png",
|
||||||
|
"xhdpi" : "unpackage/res/icons/96x96.png",
|
||||||
|
"xxhdpi" : "unpackage/res/icons/144x144.png",
|
||||||
|
"xxxhdpi" : "unpackage/res/icons/192x192.png"
|
||||||
|
},
|
||||||
|
"ios" : {
|
||||||
|
"appstore" : "unpackage/res/icons/1024x1024.png",
|
||||||
|
"ipad" : {
|
||||||
|
"app" : "unpackage/res/icons/76x76.png",
|
||||||
|
"app@2x" : "unpackage/res/icons/152x152.png",
|
||||||
|
"notification" : "unpackage/res/icons/20x20.png",
|
||||||
|
"notification@2x" : "unpackage/res/icons/40x40.png",
|
||||||
|
"proapp@2x" : "unpackage/res/icons/167x167.png",
|
||||||
|
"settings" : "unpackage/res/icons/29x29.png",
|
||||||
|
"settings@2x" : "unpackage/res/icons/58x58.png",
|
||||||
|
"spotlight" : "unpackage/res/icons/40x40.png",
|
||||||
|
"spotlight@2x" : "unpackage/res/icons/80x80.png"
|
||||||
|
},
|
||||||
|
"iphone" : {
|
||||||
|
"app@2x" : "unpackage/res/icons/120x120.png",
|
||||||
|
"app@3x" : "unpackage/res/icons/180x180.png",
|
||||||
|
"notification@2x" : "unpackage/res/icons/40x40.png",
|
||||||
|
"notification@3x" : "unpackage/res/icons/60x60.png",
|
||||||
|
"settings@2x" : "unpackage/res/icons/58x58.png",
|
||||||
|
"settings@3x" : "unpackage/res/icons/87x87.png",
|
||||||
|
"spotlight@2x" : "unpackage/res/icons/80x80.png",
|
||||||
|
"spotlight@3x" : "unpackage/res/icons/120x120.png"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
/* 快应用特有相关 */
|
||||||
|
"quickapp" : {},
|
||||||
|
/* 小程序特有相关 */
|
||||||
|
"mp-weixin" : {
|
||||||
|
"appid" : "wx6ef5a6a74620a3e8",
|
||||||
|
"setting" : {
|
||||||
|
"urlCheck" : false
|
||||||
|
},
|
||||||
|
"usingComponents" : true
|
||||||
|
},
|
||||||
|
"mp-alipay" : {
|
||||||
|
"usingComponents" : true
|
||||||
|
},
|
||||||
|
"mp-baidu" : {
|
||||||
|
"usingComponents" : true
|
||||||
|
},
|
||||||
|
"mp-toutiao" : {
|
||||||
|
"usingComponents" : true
|
||||||
|
},
|
||||||
|
"uniStatistics" : {
|
||||||
|
"enable" : false
|
||||||
|
},
|
||||||
|
"vueVersion" : "3",
|
||||||
|
"h5" : {
|
||||||
|
"sdkConfigs" : {
|
||||||
|
"maps" : {
|
||||||
|
"qqmap" : {
|
||||||
|
"key" : "7DIBZ-K4HCJ-ZR2FE-FOOOP-SALFT-RLFYW"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,156 @@
|
|||||||
|
import { Service } from '@/Service/Service';
|
||||||
|
/*****用户接口*****/
|
||||||
|
class NvpApplyService {
|
||||||
|
// private static WithDrawPath: string = '/With/WithDraw';
|
||||||
|
// /*****佣金提现*****/
|
||||||
|
// static WithDraw(money: number, name: string, account: string) {
|
||||||
|
// var result = Service.Request(this.WithDrawPath, "POST", { money, name, account });
|
||||||
|
// return result;
|
||||||
|
// }
|
||||||
|
|
||||||
|
private static GetSiteMccCodeListPath: string = '/Apply/GetSiteMccCodeList';
|
||||||
|
/*****获取mcc列表*****/
|
||||||
|
static GetSiteMccCodeList(mercType:string, mchType: string) {
|
||||||
|
var result = Service.Request(this.GetSiteMccCodeListPath, "GET", {mercType, mchType });
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
private static GetBankTypeListPath: string = '/Apply/GetBankTypeList';
|
||||||
|
/*****获取银行列表*****/
|
||||||
|
static GetBankTypeList(name:string) {
|
||||||
|
var result = Service.Request(this.GetBankTypeListPath, "GET", {name});
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
private static GetAreaListPath: string = '/Apply/GetAreaList';
|
||||||
|
/*****获取银行地区列表*****/
|
||||||
|
static GetAreaList(areaCode:string) {
|
||||||
|
var result = Service.Request(this.GetAreaListPath, "GET", { areaCode});
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
private static GetBankCodeListPath: string = '/Apply/GetBankCodeList';
|
||||||
|
/*****获取银行代码列表*****/
|
||||||
|
static GetBankCodeList(bankType:string,cityCode:string,name:string) {
|
||||||
|
var result = Service.Request(this.GetBankCodeListPath, "GET", {bankType,cityCode,name});
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
private static SendApplyMerchPath: string = '/Apply/SendApplyMerch';
|
||||||
|
/*****进价提交*****/
|
||||||
|
static SendApplyMerch(para:any) {
|
||||||
|
var result = Service.Request(this.SendApplyMerchPath, "POST", para);
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static GetAgentMerchLogPath: string = '/Apply/GetAgentMerchLog';
|
||||||
|
/*****获取待审核*****/
|
||||||
|
static GetAgentMerchLog() {
|
||||||
|
var result = Service.Request(this.GetAgentMerchLogPath, "GET", {});
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
private static AuditApplyPath: string = '/Apply/AuditApply';
|
||||||
|
/*****确认资料*****/
|
||||||
|
static AuditApply(outId:string) {
|
||||||
|
var result = Service.Request(this.AuditApplyPath, "POST", {outId});
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static SetPayFeePath: string = '/Apply/SetPayFee';
|
||||||
|
/*****确认资料*****/
|
||||||
|
static SetPayFee(outId:string) {
|
||||||
|
var result = Service.Request(this.SetPayFeePath, "POST", {outId});
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
private static GetAssortListPath: string = '/Apply/GetAssortList';
|
||||||
|
/*****获取v派分类*****/
|
||||||
|
static GetAssortList(code:string) {
|
||||||
|
var result = Service.Request(this.GetAssortListPath, "GET", {code,parent:'0'});
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
private static GetAgentMerchPath: string = '/Agent/GetAgentMerch';
|
||||||
|
/*****获取已开通商家*****/
|
||||||
|
static GetAgentMerch(type:number,page:number) {
|
||||||
|
var result = Service.Request(this.GetAgentMerchPath, "GET", {type,page});
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
private static GetAppMerchInfoPath: string = '/Apply/GetAppMerchInfo';
|
||||||
|
/*****获取银盛已填写信息*****/
|
||||||
|
static GetAppMerchInfo(outId:string) {
|
||||||
|
var result = Service.Request(this.GetAppMerchInfoPath, "GET", {outId});
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
private static UpdateMerchPath: string = '/Apply/UpdateMerch';
|
||||||
|
/*****修改银盛信息*****/
|
||||||
|
static UpdateMerch(obj:any) {
|
||||||
|
var result = Service.Request(this.UpdateMerchPath, "POST", obj);
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
private static UploadImgPath: string = '/Apply/UploadImg';
|
||||||
|
/*****修改银盛图片*****/
|
||||||
|
static UploadImg(outId:string,picType:string,img:string) {
|
||||||
|
var result = Service.Request(this.UploadImgPath, "POST", {outId,picType,img});
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
private static GetAgentApplyPath: string = '/Apply/GetAgentApply';
|
||||||
|
/*****获取添加的商家*****/
|
||||||
|
static GetAgentApply(serch:string,page:number) {
|
||||||
|
var result = Service.Request(this.GetAgentApplyPath, "GET", {serch,page});
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static GetCategoryPath: string = '/Apply/GetCategory';
|
||||||
|
/*****获取商家类型*****/
|
||||||
|
static GetCategory() {
|
||||||
|
var result = Service.Request(this.GetCategoryPath, "GET", {});
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
private static AddMerchInfoPath: string = '/Apply/AddMerchInfo';
|
||||||
|
/*****添加商户*****/
|
||||||
|
static AddMerchInfo(obj:any) {
|
||||||
|
var result = Service.Request(this.AddMerchInfoPath, "POST", obj);
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
private static BandAppIdPath: string = '/Agent/BandAppId';
|
||||||
|
/*****绑定appid*****/
|
||||||
|
static BandAppId(merchId:string) {
|
||||||
|
var result = Service.Request(this.BandAppIdPath, "POST", {merchId});
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
export {
|
||||||
|
Service,
|
||||||
|
NvpApplyService
|
||||||
|
}
|
||||||
@@ -0,0 +1,315 @@
|
|||||||
|
<template>
|
||||||
|
|
||||||
|
<view v-if="loading" class="skeleton-container">
|
||||||
|
<!-- 成功提示区域骨架 -->
|
||||||
|
<view class="success-section skeleton-success-section">
|
||||||
|
<view class="skeleton-success-icon"></view>
|
||||||
|
<view class="skeleton-line skeleton-success-title"></view>
|
||||||
|
<view class="skeleton-line skeleton-success-desc"></view>
|
||||||
|
</view>
|
||||||
|
|
||||||
|
<!-- 订单信息卡片骨架 -->
|
||||||
|
<view class="order-card skeleton-order-card">
|
||||||
|
<view class="order-item" v-for="i in 4" :key="i">
|
||||||
|
<view class="skeleton-line skeleton-order-label"></view>
|
||||||
|
<view class="skeleton-line skeleton-order-value"></view>
|
||||||
|
</view>
|
||||||
|
|
||||||
|
<!-- 查看详情按钮骨架 -->
|
||||||
|
<view class="skeleton-line skeleton-view-detail-btn"></view>
|
||||||
|
</view>
|
||||||
|
|
||||||
|
<!-- 底部占位 -->
|
||||||
|
<view class="bottom-space"></view>
|
||||||
|
|
||||||
|
<!-- 底部按钮区域骨架 -->
|
||||||
|
<view class="bottom-buttons skeleton-bottom-buttons">
|
||||||
|
<view class="skeleton-line skeleton-continue-btn"></view>
|
||||||
|
<view class="skeleton-line skeleton-view-progress-btn"></view>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
|
||||||
|
<view v-else class="abnormal-reported-page">
|
||||||
|
<!-- 成功提示区域 -->
|
||||||
|
<view class="success-section">
|
||||||
|
<view class="success-icon">
|
||||||
|
<up-icon name="checkmark-circle-fill" size="80" color="#4CD964"></up-icon>
|
||||||
|
</view>
|
||||||
|
<view class="success-title">异常已上报!</view>
|
||||||
|
<view class="success-desc">配送计时已暂停,不影响您的准时率</view>
|
||||||
|
</view>
|
||||||
|
|
||||||
|
<!-- 订单信息卡片 -->
|
||||||
|
<view class="order-card">
|
||||||
|
<view class="order-item">
|
||||||
|
<text class="order-label">订单号</text>
|
||||||
|
<text class="order-value" style="font-weight: 600;">MT20251017123456</text>
|
||||||
|
</view>
|
||||||
|
<view class="order-item">
|
||||||
|
<text class="order-label">商品信息</text>
|
||||||
|
<text class="order-value">共3件商品</text>
|
||||||
|
</view>
|
||||||
|
<view class="order-item">
|
||||||
|
<text class="order-label">配送地址</text>
|
||||||
|
<text class="order-value">XX小区3栋502室</text>
|
||||||
|
</view>
|
||||||
|
<view class="order-item">
|
||||||
|
<text class="order-label">用户备注</text>
|
||||||
|
<text class="order-value remark-text">请放门口,勿按门铃</text>
|
||||||
|
</view>
|
||||||
|
|
||||||
|
<!-- 查看详情按钮 -->
|
||||||
|
<view @click="Service.GoPage('/pages/my/abnormalDetail')" class="view-detail-btn">
|
||||||
|
<text>查看详情</text>
|
||||||
|
<up-icon name="arrow-right" size="20" color="#999"></up-icon>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
|
||||||
|
<!-- 底部占位 -->
|
||||||
|
<view class="bottom-space"></view>
|
||||||
|
|
||||||
|
<!-- 底部按钮区域 -->
|
||||||
|
<view class="bottom-buttons">
|
||||||
|
<up-button @click="Service.GoPageTab('/pages/index/task')" type="primary" size="default" class="continue-btn">
|
||||||
|
继续接单
|
||||||
|
</up-button>
|
||||||
|
<up-button @click="Service.GoPage('/pages/my/abnormalDetail')" type="default" size="default" class="view-progress-btn">
|
||||||
|
查看异常进度
|
||||||
|
</up-button>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script setup lang="ts">
|
||||||
|
import { onLoad } from '@dcloudio/uni-app'
|
||||||
|
import { ref } from 'vue';
|
||||||
|
import { Service } from '@/Service/Service';
|
||||||
|
|
||||||
|
let loading = ref(true)
|
||||||
|
// 页面加载时的逻辑
|
||||||
|
onLoad(() => {
|
||||||
|
setTimeout(() => {
|
||||||
|
loading.value = false
|
||||||
|
}, 1000)
|
||||||
|
})
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style lang="scss">
|
||||||
|
page {
|
||||||
|
background-color: #fff;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// 成功提示区域样式
|
||||||
|
.success-section {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
padding: 60rpx 30rpx;
|
||||||
|
background-color: #F6FFFB;
|
||||||
|
margin: 20rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
.success-icon {
|
||||||
|
margin-bottom: 30rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
.success-title {
|
||||||
|
font-size: 36rpx;
|
||||||
|
font-weight: 600;
|
||||||
|
color: #333;
|
||||||
|
margin-bottom: 16rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
.success-desc {
|
||||||
|
font-size: 28rpx;
|
||||||
|
color: #999;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 订单卡片样式
|
||||||
|
.order-card {
|
||||||
|
background-color: #fff;
|
||||||
|
padding: 30rpx;
|
||||||
|
border-radius: 12rpx;
|
||||||
|
margin: 0 30rpx;
|
||||||
|
box-shadow: 0 0 10rpx 0 #e2e2e2;
|
||||||
|
}
|
||||||
|
|
||||||
|
.order-item {
|
||||||
|
display: flex;
|
||||||
|
justify-content: space-between;
|
||||||
|
align-items: center;
|
||||||
|
margin-bottom: 24rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
.order-item:last-child {
|
||||||
|
margin-bottom: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.order-label {
|
||||||
|
font-size: 28rpx;
|
||||||
|
color: #666;
|
||||||
|
}
|
||||||
|
|
||||||
|
.order-value {
|
||||||
|
font-size: 28rpx;
|
||||||
|
color: #333;
|
||||||
|
text-align: right;
|
||||||
|
flex: 1;
|
||||||
|
margin-left: 30rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
.remark-text {
|
||||||
|
color: #FF6F00;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 查看详情按钮样式
|
||||||
|
.view-detail-btn {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: space-between;
|
||||||
|
margin-top: 30rpx;
|
||||||
|
padding-top: 30rpx;
|
||||||
|
border-top: 1rpx solid #f0f0f0;
|
||||||
|
color: #999;
|
||||||
|
font-size: 28rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 底部占位
|
||||||
|
.bottom-space {
|
||||||
|
height: 280rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 底部按钮区域样式
|
||||||
|
.bottom-buttons {
|
||||||
|
position: fixed;
|
||||||
|
bottom: 0;
|
||||||
|
left: 0;
|
||||||
|
right: 0;
|
||||||
|
gap: 20rpx;
|
||||||
|
padding: 20rpx;
|
||||||
|
background-color: #fff;
|
||||||
|
box-shadow: 0 -2rpx 20rpx rgba(0, 0, 0, 0.05);
|
||||||
|
display: flex;
|
||||||
|
}
|
||||||
|
|
||||||
|
.continue-btn {
|
||||||
|
border-radius: 50rpx;
|
||||||
|
height: 100rpx;
|
||||||
|
line-height: 100rpx;
|
||||||
|
font-size: 32rpx;
|
||||||
|
background-color: #007AFF;
|
||||||
|
margin-bottom: 20rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
.view-progress-btn {
|
||||||
|
border-radius: 50rpx;
|
||||||
|
height: 100rpx;
|
||||||
|
line-height: 98rpx;
|
||||||
|
font-size: 32rpx;
|
||||||
|
color: #007AFF;
|
||||||
|
border: 1rpx solid #007AFF;
|
||||||
|
background-color: #fff;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// 骨架屏基础样式和动画
|
||||||
|
.skeleton-line,
|
||||||
|
.skeleton-success-icon,
|
||||||
|
.skeleton-loading {
|
||||||
|
background: linear-gradient(90deg, #f0f0f0 25%, #e0e0e0 50%, #f0f0f0 75%);
|
||||||
|
background-size: 200% 100%;
|
||||||
|
animation: skeleton-loading 1.5s infinite;
|
||||||
|
border-radius: 8rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
@keyframes skeleton-loading {
|
||||||
|
0% {
|
||||||
|
background-position: 200% 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
100% {
|
||||||
|
background-position: -200% 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 骨架屏公共样式
|
||||||
|
.skeleton-line {
|
||||||
|
background-color: #f0f0f0;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 骨架屏容器
|
||||||
|
.skeleton-container {
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 成功提示区域骨架样式
|
||||||
|
.skeleton-success-section {
|
||||||
|
background-color: #f5f5f5;
|
||||||
|
}
|
||||||
|
|
||||||
|
.skeleton-success-icon {
|
||||||
|
width: 80rpx;
|
||||||
|
height: 80rpx;
|
||||||
|
border-radius: 50%;
|
||||||
|
background-color: #f0f0f0;
|
||||||
|
margin-bottom: 30rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
.skeleton-success-title {
|
||||||
|
width: 40%;
|
||||||
|
height: 40rpx;
|
||||||
|
margin-bottom: 16rpx;
|
||||||
|
border-radius: 20rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
.skeleton-success-desc {
|
||||||
|
width: 70%;
|
||||||
|
height: 30rpx;
|
||||||
|
border-radius: 15rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 订单卡片骨架样式
|
||||||
|
.skeleton-order-card {
|
||||||
|
background-color: #f8f8f8;
|
||||||
|
}
|
||||||
|
|
||||||
|
.skeleton-order-label {
|
||||||
|
width: 20%;
|
||||||
|
height: 32rpx;
|
||||||
|
border-radius: 16rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
.skeleton-order-value {
|
||||||
|
width: 50%;
|
||||||
|
height: 32rpx;
|
||||||
|
border-radius: 16rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
.skeleton-view-detail-btn {
|
||||||
|
width: 25%;
|
||||||
|
height: 32rpx;
|
||||||
|
border-radius: 16rpx;
|
||||||
|
margin-top: 30rpx;
|
||||||
|
margin-left: auto;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 底部按钮区域骨架样式
|
||||||
|
.skeleton-bottom-buttons {
|
||||||
|
background-color: #fff;
|
||||||
|
}
|
||||||
|
|
||||||
|
.skeleton-continue-btn {
|
||||||
|
width: 49%;
|
||||||
|
height: 100rpx;
|
||||||
|
border-radius: 50rpx;
|
||||||
|
margin-bottom: 20rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
.skeleton-view-progress-btn {
|
||||||
|
width: 49%;
|
||||||
|
height: 100rpx;
|
||||||
|
border-radius: 50rpx;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
@@ -0,0 +1,218 @@
|
|||||||
|
<template>
|
||||||
|
<view class="home">
|
||||||
|
<view class=""
|
||||||
|
style=" margin-top: 200rpx; display: flex; flex-direction: column; justify-content: center; align-items: center;">
|
||||||
|
<image :src="Service.GetIconImg('/static/index/logo/logo.png')" style="width: 150rpx; height: 150rpx; "
|
||||||
|
mode="">
|
||||||
|
</image>
|
||||||
|
<view class="" style="font-size: 36rpx; font-weight: 800; margin-top: 20rpx;">
|
||||||
|
确菜农·骑手端
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
<view class="" style="margin: 30rpx 30rpx; margin-top: 150rpx;">
|
||||||
|
|
||||||
|
<view class="" style="font-size: 34rpx; font-weight: 600; ">
|
||||||
|
欢迎登陆
|
||||||
|
</view>
|
||||||
|
|
||||||
|
<view class="" style="font-size: 28rpx; margin-top: 20rpx; ">
|
||||||
|
手机号登录,安全又便捷
|
||||||
|
</view>
|
||||||
|
|
||||||
|
<view class="">
|
||||||
|
<view class="" style="margin-top: 30rpx;">
|
||||||
|
<up-input v-model="login.phone" type="number" shape='circle'
|
||||||
|
:customStyle="{'padding':'20rpx 30rpx','font-size':'32rpx'}" placeholder="请输入手机号"
|
||||||
|
clearable='true' border="surround"></up-input>
|
||||||
|
</view>
|
||||||
|
|
||||||
|
<view v-if="!type" class="" style="margin-top: 30rpx;">
|
||||||
|
<up-input v-model="login.password" type="password" shape='circle'
|
||||||
|
:customStyle="{'padding':'20rpx 30rpx','font-size':'32rpx'}" placeholder="请输入密码"
|
||||||
|
clearable='true' border="surround"></up-input>
|
||||||
|
</view>
|
||||||
|
<view v-else class=""
|
||||||
|
style=" display: flex; align-items: center; justify-content: space-between; margin-top: 30rpx; border: 1rpx solid #dadbde; box-sizing: border-box; padding: 20rpx 30rpx; border-radius: 200rpx; ">
|
||||||
|
<view class="" style="">
|
||||||
|
<up-code-input v-model="login.code" :maxlength="4" mode="line" size='24'></up-code-input>
|
||||||
|
</view>
|
||||||
|
<view class="wrap">
|
||||||
|
<up-toast ref="uToastRef"></up-toast>
|
||||||
|
<up-code :seconds="seconds" @end="end" @start="start" ref="uCodeRef"
|
||||||
|
@change="codeChange"></up-code>
|
||||||
|
<view @click="getCode">{{tips}}</view>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
|
||||||
|
|
||||||
|
</view>
|
||||||
|
|
||||||
|
|
||||||
|
<view class=""
|
||||||
|
style="margin-top: 40rpx; width: 100%; height: 80rpx; line-height: 80rpx; border-radius: 40rpx; background-color: #FFD700; color: #000; font-weight: bold; font-size: 30rpx; text-align: center;"
|
||||||
|
@click="loginshop()">
|
||||||
|
登录
|
||||||
|
|
||||||
|
</view>
|
||||||
|
|
||||||
|
<view class="" style="text-align: center; color: #637aff; margin: 50rpx 0; ">
|
||||||
|
<text @click="type=!type,login.password='',login.code=''">{{ !type?'使用验证码登录':'使用密码登录' }}</text>
|
||||||
|
</view>
|
||||||
|
|
||||||
|
<view class=""
|
||||||
|
style="display: flex; justify-content: center; align-items: center;color: black; margin-top: 50rpx; "
|
||||||
|
@click="isuser= !isuser">
|
||||||
|
<view class="" style="margin-right: 10rpx;">
|
||||||
|
<up-icon :name="!isuser?'checkmark-circle':'checkmark-circle-fill'"
|
||||||
|
:color="!isuser?'#999':'var(--nav-mian)'" size="20"></up-icon>
|
||||||
|
</view>
|
||||||
|
我同意
|
||||||
|
<a @click.stop style="color: #FF6B23; text-decoration: none; " :href="userUrl">《用户协议》</a>
|
||||||
|
和
|
||||||
|
<a @click.stop style="color: #FF6B23; text-decoration: none; " :href="userUrl">《隐私政策》</a>
|
||||||
|
</view>
|
||||||
|
<view class="" style="text-align: center; margin-top: 20rpx;">
|
||||||
|
新用户?系统将自动为您注册
|
||||||
|
</view>
|
||||||
|
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script setup lang="ts">
|
||||||
|
import { onShow, onLoad } from "@dcloudio/uni-app";
|
||||||
|
import { Service, CNRiderLoginService } from "@/Service/CN/CNRiderLoginService"
|
||||||
|
import { ref } from "vue";
|
||||||
|
import { WebSocket } from '@/Service/Comm/TwWebSocket';
|
||||||
|
let qudPow = ref<string>('')
|
||||||
|
|
||||||
|
let login = ref({
|
||||||
|
phone: '',
|
||||||
|
code: '',
|
||||||
|
password: ''
|
||||||
|
})
|
||||||
|
|
||||||
|
const tips = ref('');
|
||||||
|
const seconds = ref(60);
|
||||||
|
const uCodeRef = ref(null);
|
||||||
|
|
||||||
|
let type = ref(false)
|
||||||
|
|
||||||
|
let isLogin = ref<boolean>(true)//登录注册状态
|
||||||
|
|
||||||
|
let isuser = ref<boolean>(false)//用户同意协议
|
||||||
|
|
||||||
|
let userUrl = ref('')
|
||||||
|
let other = ref('')
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
onLoad(() => {
|
||||||
|
getData()
|
||||||
|
});
|
||||||
|
|
||||||
|
onShow(() => {
|
||||||
|
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
|
const getData = () => {
|
||||||
|
CNRiderLoginService.GetPrivacy(1).then(res => {
|
||||||
|
userUrl.value = res.data.url
|
||||||
|
})
|
||||||
|
|
||||||
|
CNRiderLoginService.GetPrivacy(4).then(res => {
|
||||||
|
other.value = res.data.url
|
||||||
|
})
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//登录
|
||||||
|
const loginshop = () => {
|
||||||
|
if (login.value.phone == '') {
|
||||||
|
return Service.Msg('请输入手机号/账号!')
|
||||||
|
}
|
||||||
|
|
||||||
|
if (login.value.password == '' && !type.value) {
|
||||||
|
return Service.Msg('请输入密码!')
|
||||||
|
}
|
||||||
|
|
||||||
|
if (login.value.code == '' && type.value) {
|
||||||
|
return Service.Msg('请输入验证码!')
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!isuser.value) {
|
||||||
|
return Service.Msg('请勾选同意用户协议!')
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
CNRiderLoginService.RiderLogin(login.value).then(res => {
|
||||||
|
if (res.code == 0) {
|
||||||
|
Service.Msg('登录成功!')
|
||||||
|
Service.SetUserToken(res.data.accToken)
|
||||||
|
uni.$emit('ImCom')
|
||||||
|
setTimeout(() => {
|
||||||
|
isuser.value = false
|
||||||
|
Service.GoPageTab('/pages/index/index')
|
||||||
|
}, 1000)
|
||||||
|
|
||||||
|
|
||||||
|
} else {
|
||||||
|
Service.Msg(res.msg)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
const codeChange = (text) => {
|
||||||
|
tips.value = text;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
const getCode = () => {
|
||||||
|
if (!login.value.phone) {
|
||||||
|
Service.Msg('请输入手机号')
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if (uCodeRef.value.canGetCode) {
|
||||||
|
// 模拟向后端请求验证码
|
||||||
|
uni.showLoading({
|
||||||
|
title: '正在获取验证码',
|
||||||
|
});
|
||||||
|
setTimeout(() => {
|
||||||
|
uni.hideLoading();
|
||||||
|
CNRiderLoginService.SendUserSms(login.value.phone, 'RiderReg').then(res => {
|
||||||
|
|
||||||
|
})
|
||||||
|
uCodeRef.value.start();
|
||||||
|
}, 2000);
|
||||||
|
} else {
|
||||||
|
Service.Msg('倒计时结束后再发送')
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
const end = () => {
|
||||||
|
console.log('倒计时结束');
|
||||||
|
};
|
||||||
|
|
||||||
|
const start = () => {
|
||||||
|
console.log('倒计时开始');
|
||||||
|
};
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style lang="scss">
|
||||||
|
.home {
|
||||||
|
width: 100vw;
|
||||||
|
height: 100vh;
|
||||||
|
background: linear-gradient(to bottom, #FFD700, #fff 40%);
|
||||||
|
overflow: hidden;
|
||||||
|
}
|
||||||
|
|
||||||
|
.chen {}
|
||||||
|
</style>
|
||||||
@@ -0,0 +1,369 @@
|
|||||||
|
<template>
|
||||||
|
<view class="income-container">
|
||||||
|
<!-- 收入概览区域 -->
|
||||||
|
<view class="income-overview">
|
||||||
|
<view class="income-header">
|
||||||
|
<text class="income-title">今日已赚</text>
|
||||||
|
<text class="income-amount">¥86.50</text>
|
||||||
|
</view>
|
||||||
|
|
||||||
|
<!-- 时间选择标签 -->
|
||||||
|
<view class="time-tabs">
|
||||||
|
<text v-for="(item ,index) in timeList" :key="index" @click="changeTab(index)"
|
||||||
|
:class="{ 'active':currentTime==index }" class="tab-item">{{item}}</text>
|
||||||
|
</view>
|
||||||
|
<text class="month-total">本月累计¥1,240.00</text>
|
||||||
|
</view>
|
||||||
|
|
||||||
|
<!-- 收入构成区域 -->
|
||||||
|
<view class="income-composition">
|
||||||
|
<!-- 饼图占位区域 -->
|
||||||
|
<view class="pie-chart-placeholder">
|
||||||
|
<view id="cahrt" class="pie-chart">
|
||||||
|
<!-- 黑边白底的饼图占位 -->
|
||||||
|
</view>
|
||||||
|
<view class="chart-legend">
|
||||||
|
<view class="legend-item">
|
||||||
|
<view class="legend-dot blue"></view>
|
||||||
|
<text class="legend-text">配送费¥60.50</text>
|
||||||
|
</view>
|
||||||
|
<view class="legend-item">
|
||||||
|
<view class="legend-dot orange"></view>
|
||||||
|
<text class="legend-text">冲单奖¥20.00</text>
|
||||||
|
</view>
|
||||||
|
<view class="legend-item">
|
||||||
|
<view class="legend-dot green"></view>
|
||||||
|
<text class="legend-text">恶劣天气补贴¥6.00</text>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
|
||||||
|
<!-- 钱包区域 -->
|
||||||
|
<view class="wallet-section">
|
||||||
|
<view class="wallet-header">
|
||||||
|
<text class="wallet-title">钱包余额</text>
|
||||||
|
<text class="wallet-amount">¥86.50</text>
|
||||||
|
</view>
|
||||||
|
<u-button class="withdraw-button" type="primary">立即提现</u-button>
|
||||||
|
<text class="withdraw-tip">提现到账时间: T+1工作日</text>
|
||||||
|
</view>
|
||||||
|
|
||||||
|
<!-- 收入明细区域 -->
|
||||||
|
<view class="detail-header">
|
||||||
|
<text class="detail-title">收入明细</text>
|
||||||
|
</view>
|
||||||
|
<view class="detail-list" v-for="(item, index) in 3" :key="index">
|
||||||
|
<view class="detail-content">
|
||||||
|
<view class="icon-placeholder">
|
||||||
|
<image src="/static/index/income/order.png"
|
||||||
|
style="width: 55rpx; height: 55rpx;" mode=""></image>
|
||||||
|
</view>
|
||||||
|
<view class="detail-info">
|
||||||
|
<text class="order-id">订单 MT20251020123456</text>
|
||||||
|
<text class="order-time">10-20 18:35</text>
|
||||||
|
</view>
|
||||||
|
<text class="order-amount">+¥5.50</text>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script setup lang="ts">
|
||||||
|
import { onLoad } from '@dcloudio/uni-app';
|
||||||
|
import { ref, onMounted } from 'vue';
|
||||||
|
import * as echarts from 'echarts';
|
||||||
|
import { Service } from '@/Service/Service';
|
||||||
|
|
||||||
|
let timeList = ref([
|
||||||
|
'今日',
|
||||||
|
'本周',
|
||||||
|
'本月'
|
||||||
|
])
|
||||||
|
|
||||||
|
let currentTime = ref(0)
|
||||||
|
|
||||||
|
let option = ref({
|
||||||
|
tooltip: {
|
||||||
|
trigger: 'item'
|
||||||
|
},
|
||||||
|
legend: {
|
||||||
|
top: '5%',
|
||||||
|
left: 'center'
|
||||||
|
},
|
||||||
|
series: [
|
||||||
|
{
|
||||||
|
name: 'Access From',
|
||||||
|
type: 'pie',
|
||||||
|
radius: ['40%', '70%'],
|
||||||
|
avoidLabelOverlap: true,
|
||||||
|
label: {
|
||||||
|
show: false,
|
||||||
|
position: 'center'
|
||||||
|
},
|
||||||
|
emphasis: {
|
||||||
|
label: {
|
||||||
|
show: false,
|
||||||
|
fontSize: 40,
|
||||||
|
fontWeight: 'bold'
|
||||||
|
}
|
||||||
|
},
|
||||||
|
labelLine: {
|
||||||
|
show: false
|
||||||
|
},
|
||||||
|
data: [
|
||||||
|
{ value: 1048 },
|
||||||
|
{ value: 735 },
|
||||||
|
{ value: 580 },
|
||||||
|
{ value: 484},
|
||||||
|
{ value: 300 }
|
||||||
|
]
|
||||||
|
}
|
||||||
|
]
|
||||||
|
})
|
||||||
|
|
||||||
|
onLoad(() => {
|
||||||
|
|
||||||
|
})
|
||||||
|
onMounted(()=>{
|
||||||
|
let chartDom =ref( document.getElementById('cahrt'))
|
||||||
|
let myChart = ref(echarts.init(chartDom.value))
|
||||||
|
myChart.value.setOption(option.value);
|
||||||
|
})
|
||||||
|
const changeTab = (index : number) => {
|
||||||
|
currentTime.value = index
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style scoped>
|
||||||
|
.income-container {
|
||||||
|
padding: 20rpx;
|
||||||
|
background-color: #f5f5f5;
|
||||||
|
min-height: 100vh;
|
||||||
|
box-sizing: border-box;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 收入概览区域 */
|
||||||
|
.income-overview {
|
||||||
|
background-color: #fff;
|
||||||
|
border-radius: 20rpx;
|
||||||
|
padding: 30rpx;
|
||||||
|
margin-bottom: 20rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
.income-header {
|
||||||
|
margin-bottom: 20rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
.income-title {
|
||||||
|
font-size: 28rpx;
|
||||||
|
color: #666;
|
||||||
|
display: block;
|
||||||
|
margin-bottom: 10rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
.income-amount {
|
||||||
|
font-size: 48rpx;
|
||||||
|
font-weight: bold;
|
||||||
|
color: #ff4d4f;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 时间标签 */
|
||||||
|
.time-tabs {
|
||||||
|
display: flex;
|
||||||
|
margin-bottom: 20rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
.tab-item {
|
||||||
|
font-size: 28rpx;
|
||||||
|
color: #666;
|
||||||
|
margin-right: 40rpx;
|
||||||
|
padding-bottom: 10rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
.tab-item.active {
|
||||||
|
color: #1890ff;
|
||||||
|
border-bottom: 3rpx solid #1890ff;
|
||||||
|
}
|
||||||
|
|
||||||
|
.month-total {
|
||||||
|
font-size: 26rpx;
|
||||||
|
color: #666;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 收入构成区域 */
|
||||||
|
.income-composition {
|
||||||
|
background-color: #fff;
|
||||||
|
border-radius: 20rpx;
|
||||||
|
padding: 30rpx;
|
||||||
|
margin-bottom: 20rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 饼图占位 */
|
||||||
|
.pie-chart-placeholder {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.pie-chart {
|
||||||
|
width: 200rpx;
|
||||||
|
height: 200rpx;
|
||||||
|
margin-right: 30rpx;
|
||||||
|
position: relative;
|
||||||
|
overflow: hidden;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
.chart-legend {
|
||||||
|
flex: 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
.legend-item {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
margin-bottom: 15rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
.legend-dot {
|
||||||
|
width: 16rpx;
|
||||||
|
height: 16rpx;
|
||||||
|
border-radius: 50%;
|
||||||
|
margin-right: 10rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
.legend-dot.blue {
|
||||||
|
background-color: #1890ff;
|
||||||
|
}
|
||||||
|
|
||||||
|
.legend-dot.orange {
|
||||||
|
background-color: #fa8c16;
|
||||||
|
}
|
||||||
|
|
||||||
|
.legend-dot.green {
|
||||||
|
background-color: #52c41a;
|
||||||
|
}
|
||||||
|
|
||||||
|
.legend-text {
|
||||||
|
font-size: 26rpx;
|
||||||
|
color: #666;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 钱包区域 */
|
||||||
|
.wallet-section {
|
||||||
|
background-color: #fff;
|
||||||
|
border-radius: 20rpx;
|
||||||
|
padding: 30rpx;
|
||||||
|
margin-bottom: 20rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
.wallet-header {
|
||||||
|
display: flex;
|
||||||
|
justify-content: space-between;
|
||||||
|
align-items: center;
|
||||||
|
margin-bottom: 20rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
.wallet-title {
|
||||||
|
font-size: 28rpx;
|
||||||
|
color: #333;
|
||||||
|
}
|
||||||
|
|
||||||
|
.wallet-amount {
|
||||||
|
font-size: 36rpx;
|
||||||
|
font-weight: bold;
|
||||||
|
color: #ff4d4f;
|
||||||
|
}
|
||||||
|
|
||||||
|
.withdraw-button {
|
||||||
|
width: 100%;
|
||||||
|
height: 80rpx;
|
||||||
|
line-height: 80rpx;
|
||||||
|
font-size: 32rpx;
|
||||||
|
border-radius: 40rpx;
|
||||||
|
background-color: #1890ff;
|
||||||
|
color: #fff;
|
||||||
|
margin-bottom: 10rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
.withdraw-tip {
|
||||||
|
display: block;
|
||||||
|
font-size: 22rpx;
|
||||||
|
color: #999;
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 收入明细区域 */
|
||||||
|
.income-detail {
|
||||||
|
background-color: #fff;
|
||||||
|
border-radius: 20rpx;
|
||||||
|
padding: 30rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
.detail-header {
|
||||||
|
margin-bottom: 20rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
.detail-title {
|
||||||
|
font-size: 28rpx;
|
||||||
|
font-weight: bold;
|
||||||
|
color: #333;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
.detail-content {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.detail-list {
|
||||||
|
margin: 15rpx 0 0;
|
||||||
|
background-color: #fff;
|
||||||
|
padding: 20rpx 30rpx;
|
||||||
|
border-radius: 20rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 图标占位符 - 黑边白底 */
|
||||||
|
.icon-placeholder {
|
||||||
|
width: 70rpx;
|
||||||
|
height: 70rpx;
|
||||||
|
background-color: #E6F7FF;
|
||||||
|
border-radius: 8rpx;
|
||||||
|
margin-right: 20rpx;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.detail-info {
|
||||||
|
flex: 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
.order-id {
|
||||||
|
display: block;
|
||||||
|
font-size: 26rpx;
|
||||||
|
color: #333;
|
||||||
|
margin-bottom: 5rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
.order-time {
|
||||||
|
font-size: 24rpx;
|
||||||
|
color: #999;
|
||||||
|
}
|
||||||
|
|
||||||
|
.order-amount {
|
||||||
|
font-size: 32rpx;
|
||||||
|
font-weight: bold;
|
||||||
|
color: #ff4d4f;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 没有更多记录 */
|
||||||
|
.no-more {
|
||||||
|
text-align: center;
|
||||||
|
padding: 40rpx 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.no-more-text {
|
||||||
|
font-size: 24rpx;
|
||||||
|
color: #999;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
After Width: | Height: | Size: 474 B |
@@ -0,0 +1,655 @@
|
|||||||
|
<template>
|
||||||
|
|
||||||
|
<!-- 骨架屏状态 -->
|
||||||
|
<view v-if="loading" class="skeleton-loading">
|
||||||
|
<!-- 收入概览骨架屏 -->
|
||||||
|
<view class="skeleton-card income-overview">
|
||||||
|
<view class="skeleton-income-title"></view>
|
||||||
|
<view class="skeleton-income-amount"></view>
|
||||||
|
<view class="skeleton-time-tabs">
|
||||||
|
<view class="skeleton-tab-item"></view>
|
||||||
|
<view class="skeleton-tab-item"></view>
|
||||||
|
<view class="skeleton-tab-item"></view>
|
||||||
|
</view>
|
||||||
|
<view class="skeleton-month-total"></view>
|
||||||
|
</view>
|
||||||
|
|
||||||
|
<!-- 收入构成骨架屏 -->
|
||||||
|
<view class="skeleton-card income-composition">
|
||||||
|
<view class="skeleton-pie-container">
|
||||||
|
<view class="skeleton-pie-chart"></view>
|
||||||
|
<view class="skeleton-legend-list">
|
||||||
|
<view class="skeleton-legend-item" v-for="item in 3">
|
||||||
|
<view class="skeleton-legend-dot"></view>
|
||||||
|
<view class="skeleton-legend-text"></view>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
|
||||||
|
<!-- 钱包区域骨架屏 -->
|
||||||
|
<view class="skeleton-card wallet-section">
|
||||||
|
<view class="skeleton-wallet-header">
|
||||||
|
<view class="skeleton-wallet-title"></view>
|
||||||
|
<view class="skeleton-wallet-amount"></view>
|
||||||
|
</view>
|
||||||
|
<view class="skeleton-withdraw-button"></view>
|
||||||
|
<view class="skeleton-withdraw-tip"></view>
|
||||||
|
</view>
|
||||||
|
|
||||||
|
<!-- 收入明细骨架屏 -->
|
||||||
|
<view class="skeleton-card">
|
||||||
|
<view class="skeleton-detail-title"></view>
|
||||||
|
</view>
|
||||||
|
|
||||||
|
<!-- 明细项骨架屏 -->
|
||||||
|
<view v-for="index in 3" :key="index" class="skeleton-card detail-list">
|
||||||
|
<view class="skeleton-detail-content">
|
||||||
|
<view class="skeleton-icon-placeholder"></view>
|
||||||
|
<view class="skeleton-detail-info">
|
||||||
|
<view class="skeleton-order-id"></view>
|
||||||
|
<view class="skeleton-order-time"></view>
|
||||||
|
</view>
|
||||||
|
<view class="skeleton-order-amount"></view>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
<!-- 加载更多 -->
|
||||||
|
<view class="skeleton-card" style="display: flex; justify-content: center; ">
|
||||||
|
<view class="skeleton-detail-title"></view>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
|
||||||
|
<!-- 收入概览区域 -->
|
||||||
|
<view v-else class="income-container">
|
||||||
|
<view class="income-overview">
|
||||||
|
<view class="income-header">
|
||||||
|
<text class="income-title">今日已赚</text>
|
||||||
|
<text class="income-amount">¥86.50</text>
|
||||||
|
</view>
|
||||||
|
|
||||||
|
<!-- 时间选择标签 -->
|
||||||
|
<view class="time-tabs">
|
||||||
|
<text v-for="(item ,index) in timeList" :key="index" @click="changeTab(index)"
|
||||||
|
:class="{ 'active':currentTime==index }" class="tab-item">{{item}}</text>
|
||||||
|
</view>
|
||||||
|
<text class="month-total">本月累计¥1,240.00</text>
|
||||||
|
</view>
|
||||||
|
|
||||||
|
<!-- 收入构成区域 -->
|
||||||
|
<view class="income-composition">
|
||||||
|
<!-- 饼图占位区域 -->
|
||||||
|
<view class="pie-chart-placeholder">
|
||||||
|
<view id="cahrt" class="pie-chart">
|
||||||
|
<!-- 黑边白底的饼图占位 -->
|
||||||
|
</view>
|
||||||
|
<view class="chart-legend">
|
||||||
|
<view class="legend-item">
|
||||||
|
<view class="legend-dot blue"></view>
|
||||||
|
<text class="legend-text">配送费¥60.50</text>
|
||||||
|
</view>
|
||||||
|
<view class="legend-item">
|
||||||
|
<view class="legend-dot orange"></view>
|
||||||
|
<text class="legend-text">冲单奖¥20.00</text>
|
||||||
|
</view>
|
||||||
|
<view class="legend-item">
|
||||||
|
<view class="legend-dot green"></view>
|
||||||
|
<text class="legend-text">恶劣天气补贴¥6.00</text>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
|
||||||
|
<!-- 钱包区域 -->
|
||||||
|
<view class="wallet-section">
|
||||||
|
<view class="wallet-header">
|
||||||
|
<text class="wallet-title">钱包余额</text>
|
||||||
|
<text class="wallet-amount">¥86.50</text>
|
||||||
|
</view>
|
||||||
|
<u-button class="withdraw-button" @click="Service.GoPage('/pages/order/withdraw')" type="primary">立即提现</u-button>
|
||||||
|
<text class="withdraw-tip">提现到账时间: T+1工作日</text>
|
||||||
|
</view>
|
||||||
|
|
||||||
|
<!-- 收入明细区域 -->
|
||||||
|
<view class="detail-header">
|
||||||
|
<text class="detail-title">收入明细</text>
|
||||||
|
</view>
|
||||||
|
<view class="detail-list" @click="Service.GoPage('/pages/order/incomeDetail')" v-for="(item, index) in 3"
|
||||||
|
:key="index">
|
||||||
|
<view class="detail-content">
|
||||||
|
<view class="icon-placeholder">
|
||||||
|
<image :src="Service.GetIconImg('/static/index/income/order.png')"
|
||||||
|
style="width: 55rpx; height: 55rpx;" mode=""></image>
|
||||||
|
</view>
|
||||||
|
<view class="detail-info">
|
||||||
|
<text class="order-id">订单 MT20251020123456</text>
|
||||||
|
<text class="order-time">10-20 18:35</text>
|
||||||
|
</view>
|
||||||
|
<text class="order-amount">+¥5.50</text>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
<up-loadmore :status="status" />
|
||||||
|
<view class="" style="width: 100vw; height: 100rpx; ">
|
||||||
|
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script setup lang="ts">
|
||||||
|
import { onLoad } from '@dcloudio/uni-app';
|
||||||
|
import { ref, onMounted } from 'vue';
|
||||||
|
import * as echarts from 'echarts';
|
||||||
|
import { Service } from '@/Service/Service';
|
||||||
|
|
||||||
|
let loading = ref(true)
|
||||||
|
|
||||||
|
let timeList = ref([
|
||||||
|
'今日',
|
||||||
|
'本周',
|
||||||
|
'本月'
|
||||||
|
])
|
||||||
|
|
||||||
|
let currentTime = ref(0)
|
||||||
|
|
||||||
|
let status = ref('nomore')
|
||||||
|
|
||||||
|
let test = ref(10)
|
||||||
|
|
||||||
|
let option = ref({
|
||||||
|
tooltip: {
|
||||||
|
'show': false
|
||||||
|
},
|
||||||
|
legend: {
|
||||||
|
'show': false
|
||||||
|
},
|
||||||
|
series: [
|
||||||
|
{
|
||||||
|
name: 'Access From',
|
||||||
|
type: 'pie',
|
||||||
|
radius: ['40%', '70%'],
|
||||||
|
avoidLabelOverlap: true,
|
||||||
|
label: {
|
||||||
|
show: false,
|
||||||
|
position: 'center'
|
||||||
|
},
|
||||||
|
emphasis: {
|
||||||
|
label: {
|
||||||
|
show: false,
|
||||||
|
fontSize: 40,
|
||||||
|
fontWeight: 'bold'
|
||||||
|
}
|
||||||
|
},
|
||||||
|
labelLine: {
|
||||||
|
show: false
|
||||||
|
},
|
||||||
|
data: [
|
||||||
|
{ value: test.value, name: "配送奖", itemStyle: { color: '#1890FF' } },
|
||||||
|
{ value: 735, name: "冲单奖", itemStyle: { color: '#52C41A' } },
|
||||||
|
{ value: 580, name: "恶劣天气奖", itemStyle: { color: '#FF4D4F' } }
|
||||||
|
]
|
||||||
|
}
|
||||||
|
]
|
||||||
|
})
|
||||||
|
|
||||||
|
onLoad(() => {
|
||||||
|
setTimeout(() => {
|
||||||
|
loading.value = false
|
||||||
|
setTimeout(() => {
|
||||||
|
draw()
|
||||||
|
}, 1000)
|
||||||
|
}, 1000)
|
||||||
|
})
|
||||||
|
onMounted(() => {
|
||||||
|
})
|
||||||
|
|
||||||
|
const draw = () => {
|
||||||
|
let chartDom = ref(document.getElementById('cahrt'))
|
||||||
|
let myChart = ref(echarts.init(chartDom.value))
|
||||||
|
myChart.value.setOption(option.value)
|
||||||
|
}
|
||||||
|
|
||||||
|
const changeTab = (index : number) => {
|
||||||
|
currentTime.value = index
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
<style scoped>
|
||||||
|
.income-container {
|
||||||
|
padding: 20rpx;
|
||||||
|
background-color: #f5f5f5;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 收入概览区域 */
|
||||||
|
.income-overview {
|
||||||
|
background-color: #fff;
|
||||||
|
border-radius: 20rpx;
|
||||||
|
padding: 30rpx;
|
||||||
|
margin-bottom: 20rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
.income-header {
|
||||||
|
margin-bottom: 20rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
.income-title {
|
||||||
|
font-size: 28rpx;
|
||||||
|
color: #666;
|
||||||
|
display: block;
|
||||||
|
margin-bottom: 10rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
.income-amount {
|
||||||
|
font-size: 48rpx;
|
||||||
|
font-weight: bold;
|
||||||
|
color: #ff4d4f;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 时间标签 */
|
||||||
|
.time-tabs {
|
||||||
|
display: flex;
|
||||||
|
margin-bottom: 20rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
.tab-item {
|
||||||
|
font-size: 28rpx;
|
||||||
|
color: #666;
|
||||||
|
margin-right: 40rpx;
|
||||||
|
padding-bottom: 10rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
.tab-item.active {
|
||||||
|
color: #1890ff;
|
||||||
|
border-bottom: 3rpx solid #1890ff;
|
||||||
|
}
|
||||||
|
|
||||||
|
.month-total {
|
||||||
|
font-size: 26rpx;
|
||||||
|
color: #666;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 收入构成区域 */
|
||||||
|
.income-composition {
|
||||||
|
background-color: #fff;
|
||||||
|
border-radius: 20rpx;
|
||||||
|
padding: 30rpx;
|
||||||
|
margin-bottom: 20rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 饼图占位 */
|
||||||
|
.pie-chart-placeholder {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.pie-chart {
|
||||||
|
width: 200rpx;
|
||||||
|
height: 200rpx;
|
||||||
|
margin-right: 30rpx;
|
||||||
|
position: relative;
|
||||||
|
overflow: hidden;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
.chart-legend {
|
||||||
|
flex: 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
.legend-item {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
margin-bottom: 15rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
.legend-dot {
|
||||||
|
width: 16rpx;
|
||||||
|
height: 16rpx;
|
||||||
|
border-radius: 50%;
|
||||||
|
margin-right: 10rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
.legend-dot.blue {
|
||||||
|
background-color: var(--nav-mian);
|
||||||
|
}
|
||||||
|
|
||||||
|
.legend-dot.orange {
|
||||||
|
background-color: var(--nav-vice);
|
||||||
|
}
|
||||||
|
|
||||||
|
.legend-dot.green {
|
||||||
|
background-color: var(--nav-diluted);
|
||||||
|
}
|
||||||
|
|
||||||
|
.legend-text {
|
||||||
|
font-size: 26rpx;
|
||||||
|
color: #666;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 钱包区域 */
|
||||||
|
.wallet-section {
|
||||||
|
background-color: #fff;
|
||||||
|
border-radius: 20rpx;
|
||||||
|
padding: 30rpx;
|
||||||
|
margin-bottom: 20rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
.wallet-header {
|
||||||
|
display: flex;
|
||||||
|
justify-content: space-between;
|
||||||
|
align-items: center;
|
||||||
|
margin-bottom: 20rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
.wallet-title {
|
||||||
|
font-size: 28rpx;
|
||||||
|
color: #333;
|
||||||
|
}
|
||||||
|
|
||||||
|
.wallet-amount {
|
||||||
|
font-size: 36rpx;
|
||||||
|
font-weight: bold;
|
||||||
|
color: #ff4d4f;
|
||||||
|
}
|
||||||
|
|
||||||
|
.withdraw-button {
|
||||||
|
width: 100%;
|
||||||
|
height: 80rpx;
|
||||||
|
line-height: 80rpx;
|
||||||
|
font-size: 32rpx;
|
||||||
|
border-radius: 40rpx;
|
||||||
|
background-color: #1890ff;
|
||||||
|
color: #fff;
|
||||||
|
margin-bottom: 10rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
.withdraw-tip {
|
||||||
|
display: block;
|
||||||
|
font-size: 22rpx;
|
||||||
|
color: #999;
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 收入明细区域 */
|
||||||
|
.income-detail {
|
||||||
|
background-color: #fff;
|
||||||
|
border-radius: 20rpx;
|
||||||
|
padding: 30rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
.detail-header {
|
||||||
|
margin-bottom: 20rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
.detail-title {
|
||||||
|
font-size: 28rpx;
|
||||||
|
font-weight: bold;
|
||||||
|
color: #333;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
.detail-content {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.detail-list {
|
||||||
|
margin: 15rpx 0 0;
|
||||||
|
background-color: #fff;
|
||||||
|
padding: 20rpx 30rpx;
|
||||||
|
border-radius: 20rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 图标占位符 - 黑边白底 */
|
||||||
|
.icon-placeholder {
|
||||||
|
width: 70rpx;
|
||||||
|
height: 70rpx;
|
||||||
|
background-color: #E6F7FF;
|
||||||
|
border-radius: 8rpx;
|
||||||
|
margin-right: 20rpx;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.detail-info {
|
||||||
|
flex: 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
.order-id {
|
||||||
|
display: block;
|
||||||
|
font-size: 26rpx;
|
||||||
|
color: #333;
|
||||||
|
margin-bottom: 5rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
.order-time {
|
||||||
|
font-size: 24rpx;
|
||||||
|
color: #999;
|
||||||
|
}
|
||||||
|
|
||||||
|
.order-amount {
|
||||||
|
font-size: 32rpx;
|
||||||
|
font-weight: bold;
|
||||||
|
color: #ff4d4f;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 没有更多记录 */
|
||||||
|
.no-more {
|
||||||
|
text-align: center;
|
||||||
|
padding: 40rpx 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.no-more-text {
|
||||||
|
font-size: 24rpx;
|
||||||
|
color: #999;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 骨架屏样式 */
|
||||||
|
.skeleton-loading .skeleton-card {
|
||||||
|
background-color: #fff;
|
||||||
|
border-radius: 20rpx;
|
||||||
|
padding: 30rpx;
|
||||||
|
margin-bottom: 20rpx;
|
||||||
|
position: relative;
|
||||||
|
overflow: hidden;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 收入概览骨架屏 */
|
||||||
|
.skeleton-income-title {
|
||||||
|
width: 100rpx;
|
||||||
|
height: 30rpx;
|
||||||
|
background-color: #f0f0f0;
|
||||||
|
border-radius: 4rpx;
|
||||||
|
margin-bottom: 15rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
.skeleton-income-amount {
|
||||||
|
width: 200rpx;
|
||||||
|
height: 50rpx;
|
||||||
|
background-color: #f0f0f0;
|
||||||
|
border-radius: 4rpx;
|
||||||
|
margin-bottom: 20rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
.skeleton-time-tabs {
|
||||||
|
display: flex;
|
||||||
|
margin-bottom: 20rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
.skeleton-tab-item {
|
||||||
|
width: 80rpx;
|
||||||
|
height: 30rpx;
|
||||||
|
background-color: #f0f0f0;
|
||||||
|
border-radius: 4rpx;
|
||||||
|
margin-right: 40rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
.skeleton-month-total {
|
||||||
|
width: 200rpx;
|
||||||
|
height: 30rpx;
|
||||||
|
background-color: #f0f0f0;
|
||||||
|
border-radius: 4rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 收入构成骨架屏 */
|
||||||
|
.skeleton-pie-container {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.skeleton-pie-chart {
|
||||||
|
width: 200rpx;
|
||||||
|
height: 200rpx;
|
||||||
|
background-color: #f0f0f0;
|
||||||
|
border-radius: 50%;
|
||||||
|
margin-right: 30rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
.skeleton-legend-list {
|
||||||
|
flex: 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
.skeleton-legend-item {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
margin-bottom: 15rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
.skeleton-legend-dot {
|
||||||
|
width: 16rpx;
|
||||||
|
height: 16rpx;
|
||||||
|
background-color: #f0f0f0;
|
||||||
|
border-radius: 50%;
|
||||||
|
margin-right: 10rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
.skeleton-legend-text {
|
||||||
|
width: 200rpx;
|
||||||
|
height: 30rpx;
|
||||||
|
background-color: #f0f0f0;
|
||||||
|
border-radius: 4rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 钱包区域骨架屏 */
|
||||||
|
.skeleton-wallet-header {
|
||||||
|
display: flex;
|
||||||
|
justify-content: space-between;
|
||||||
|
align-items: center;
|
||||||
|
margin-bottom: 20rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
.skeleton-wallet-title {
|
||||||
|
width: 120rpx;
|
||||||
|
height: 30rpx;
|
||||||
|
background-color: #f0f0f0;
|
||||||
|
border-radius: 4rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
.skeleton-wallet-amount {
|
||||||
|
width: 150rpx;
|
||||||
|
height: 40rpx;
|
||||||
|
background-color: #f0f0f0;
|
||||||
|
border-radius: 4rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
.skeleton-withdraw-button {
|
||||||
|
width: 100%;
|
||||||
|
height: 80rpx;
|
||||||
|
background-color: #f0f0f0;
|
||||||
|
border-radius: 40rpx;
|
||||||
|
margin-bottom: 10rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
.skeleton-withdraw-tip {
|
||||||
|
width: 300rpx;
|
||||||
|
height: 24rpx;
|
||||||
|
background-color: #f0f0f0;
|
||||||
|
border-radius: 4rpx;
|
||||||
|
margin: 0 auto;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 收入明细骨架屏 */
|
||||||
|
.skeleton-detail-title {
|
||||||
|
width: 150rpx;
|
||||||
|
height: 30rpx;
|
||||||
|
background-color: #f0f0f0;
|
||||||
|
border-radius: 4rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
.skeleton-detail-content {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.skeleton-icon-placeholder {
|
||||||
|
width: 70rpx;
|
||||||
|
height: 70rpx;
|
||||||
|
background-color: #f0f0f0;
|
||||||
|
border-radius: 8rpx;
|
||||||
|
margin-right: 20rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
.skeleton-detail-info {
|
||||||
|
flex: 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
.skeleton-order-id {
|
||||||
|
width: 300rpx;
|
||||||
|
height: 30rpx;
|
||||||
|
background-color: #f0f0f0;
|
||||||
|
border-radius: 4rpx;
|
||||||
|
margin-bottom: 10rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
.skeleton-order-time {
|
||||||
|
width: 200rpx;
|
||||||
|
height: 26rpx;
|
||||||
|
background-color: #f0f0f0;
|
||||||
|
border-radius: 4rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
.skeleton-order-amount {
|
||||||
|
width: 100rpx;
|
||||||
|
height: 36rpx;
|
||||||
|
background-color: #f0f0f0;
|
||||||
|
border-radius: 4rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 骨架屏动画 */
|
||||||
|
.skeleton-loading .skeleton-income-title::after,
|
||||||
|
.skeleton-loading .skeleton-income-amount::after,
|
||||||
|
.skeleton-loading .skeleton-tab-item::after,
|
||||||
|
.skeleton-loading .skeleton-month-total::after,
|
||||||
|
.skeleton-loading .skeleton-pie-chart::after,
|
||||||
|
.skeleton-loading .skeleton-legend-dot::after,
|
||||||
|
.skeleton-loading .skeleton-legend-text::after,
|
||||||
|
.skeleton-loading .skeleton-wallet-title::after,
|
||||||
|
.skeleton-loading .skeleton-wallet-amount::after,
|
||||||
|
.skeleton-loading .skeleton-withdraw-button::after,
|
||||||
|
.skeleton-loading .skeleton-withdraw-tip::after,
|
||||||
|
.skeleton-loading .skeleton-detail-title::after,
|
||||||
|
.skeleton-loading .skeleton-icon-placeholder::after,
|
||||||
|
.skeleton-loading .skeleton-order-id::after,
|
||||||
|
.skeleton-loading .skeleton-order-time::after,
|
||||||
|
.skeleton-loading .skeleton-order-amount::after {
|
||||||
|
content: '';
|
||||||
|
position: absolute;
|
||||||
|
top: 0;
|
||||||
|
left: 0;
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
background: linear-gradient(90deg, transparent, rgba(255, 255, 255, 0.2), transparent);
|
||||||
|
animation: shimmer 1.5s infinite;
|
||||||
|
}
|
||||||
|
|
||||||
|
@keyframes shimmer {
|
||||||
|
0% {
|
||||||
|
transform: translateX(-100%);
|
||||||
|
}
|
||||||
|
|
||||||
|
100% {
|
||||||
|
transform: translateX(100%);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</style>
|
||||||
@@ -0,0 +1,445 @@
|
|||||||
|
<template>
|
||||||
|
|
||||||
|
<view v-if="loading" class="">
|
||||||
|
<view class="tab-bar-skeleton">
|
||||||
|
<view class="skeleton-slot skeleton-tab-item"></view>
|
||||||
|
<view class="skeleton-slot skeleton-tab-item"></view>
|
||||||
|
</view>
|
||||||
|
<view class="skeleton-container">
|
||||||
|
<view class="skeleton-order-item" v-for="index in 3" :key="'skeleton-' + index">
|
||||||
|
<!-- 订单头部骨架 -->
|
||||||
|
<view class="skeleton-header">
|
||||||
|
<view class="skeleton-slot skeleton-order-number"></view>
|
||||||
|
<view class="skeleton-slot skeleton-status-badge"></view>
|
||||||
|
</view>
|
||||||
|
|
||||||
|
<!-- 异常类型骨架 -->
|
||||||
|
<view class="skeleton-slot skeleton-type"></view>
|
||||||
|
|
||||||
|
<!-- 异常描述骨架 -->
|
||||||
|
<view class="skeleton-slot skeleton-description"></view>
|
||||||
|
|
||||||
|
<!-- 底部信息骨架 -->
|
||||||
|
<view class="skeleton-footer">
|
||||||
|
<view class="skeleton-slot skeleton-time"></view>
|
||||||
|
<view class="skeleton-actions">
|
||||||
|
<view class="skeleton-slot skeleton-btn"></view>
|
||||||
|
<view class="skeleton-slot skeleton-btn"></view>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
<view class="" style="width: 100vw; display: flex; justify-content: center; ">
|
||||||
|
<view class="skeleton-slot " style="width: 160rpx; height: 30rpx; "></view>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
|
||||||
|
|
||||||
|
<view v-else class="abnormal-orders-page">
|
||||||
|
<!-- 选项卡 -->
|
||||||
|
<view class="tab-bar">
|
||||||
|
<view class="tab-item" :class="{ active: activeTab === 0 }" @click="switchTab(0)">
|
||||||
|
<text class="tab-text" :class="{ active: activeTab === 0 }">待处理</text>
|
||||||
|
</view>
|
||||||
|
<view class="tab-item" :class="{ active: activeTab === 1 }" @click="switchTab(1)">
|
||||||
|
<text class="tab-text" :class="{ active: activeTab === 1 }">已处理</text>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
|
||||||
|
<!-- 订单列表 -->
|
||||||
|
<view class="order-list">
|
||||||
|
<view class="order-item" v-for="(orderItem,orederIndex) in dataList" :key="orederIndex">
|
||||||
|
<!-- 订单头部 -->
|
||||||
|
<view class="order-header">
|
||||||
|
<text class="order-number">订单号: {{ orderItem.orderId}}</text>
|
||||||
|
<view class="order-status pending">
|
||||||
|
<text class="status-text">{{ orderItem.status===0?'待处理':'已处理' }}</text>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
|
||||||
|
<!-- 订单内容 -->
|
||||||
|
<view class="">
|
||||||
|
<text class="abnormal-type">{{orderItem.type }}</text>
|
||||||
|
<text class="abnormal-description">{{ orderItem.remark }}</text>
|
||||||
|
<view class="" style="display: flex; align-items: center; justify-content: space-between;">
|
||||||
|
<text class="order-time"
|
||||||
|
style="font-size: 26rpx; color: #666;">{{ Service.formatDate(orderItem.addTime,1) }}</text>
|
||||||
|
<!-- 操作按钮 -->
|
||||||
|
<view class="order-actions">
|
||||||
|
<text @click="Service.GoPage('/pages/my/abnormalDetail?orderId='+orderItem.orderId)"
|
||||||
|
class="action-btn detail-btn">查看详情</text>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
<up-loadmore :status="status" />
|
||||||
|
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script setup lang="ts">
|
||||||
|
import { onLoad } from '@dcloudio/uni-app';
|
||||||
|
import { ref, computed } from 'vue';
|
||||||
|
import { Service } from "@/Service/Service"
|
||||||
|
import { CNRiderOrderService } from '@/Service/CN/CNRiderOrderService'
|
||||||
|
|
||||||
|
|
||||||
|
let loading = ref(true)
|
||||||
|
// 响应式数据
|
||||||
|
const activeTab = ref(0);
|
||||||
|
|
||||||
|
let status = ref('nomore')
|
||||||
|
let page = ref(1)
|
||||||
|
let dataList = ref<Array<any>>([])
|
||||||
|
onLoad(() => {
|
||||||
|
getData()
|
||||||
|
})
|
||||||
|
|
||||||
|
|
||||||
|
const getData = () => {
|
||||||
|
dataList.value = []
|
||||||
|
page.value = 1
|
||||||
|
status.value = 'loadmore'
|
||||||
|
getList()
|
||||||
|
}
|
||||||
|
|
||||||
|
const getList = () => {
|
||||||
|
if (status.value == 'nomore' || status.value == 'loading') {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
status.value == 'loadmore'
|
||||||
|
CNRiderOrderService.GetRiderOrderServiceList(activeTab.value, page.value).then(res => {
|
||||||
|
loading.value = false
|
||||||
|
if (res.data) {
|
||||||
|
dataList.value = [...dataList.value, ...res.data.list]
|
||||||
|
status.value = res.data.list == 10 ? 'loadmore' : 'nomore'
|
||||||
|
page.value++
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
// 切换选项卡
|
||||||
|
const switchTab = (tab : any) => {
|
||||||
|
activeTab.value = tab;
|
||||||
|
getData()
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
// 重新上报
|
||||||
|
const reportAgain = (orderNo : string) => {
|
||||||
|
uni.showModal({
|
||||||
|
title: '重新上报',
|
||||||
|
content: '确定要重新上报此订单异常吗?',
|
||||||
|
success: (res) => {
|
||||||
|
if (res.confirm) {
|
||||||
|
// 模拟重新上报
|
||||||
|
uni.showToast({
|
||||||
|
title: '已提交重新上报申请',
|
||||||
|
icon: 'success'
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
};
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style scoped lang="scss">
|
||||||
|
/* 页面基础样式 */
|
||||||
|
.abnormal-orders-page {
|
||||||
|
min-height: 100vh;
|
||||||
|
background-color: #f5f5f5;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 顶部导航栏 */
|
||||||
|
.nav-bar {
|
||||||
|
height: 100rpx;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: space-between;
|
||||||
|
background-color: #fff;
|
||||||
|
padding: 0 30rpx;
|
||||||
|
box-shadow: 0 2rpx 10rpx rgba(0, 0, 0, 0.05);
|
||||||
|
position: sticky;
|
||||||
|
top: 0;
|
||||||
|
z-index: 100;
|
||||||
|
}
|
||||||
|
|
||||||
|
.nav-left,
|
||||||
|
.nav-right {
|
||||||
|
width: 60rpx;
|
||||||
|
display: flex;
|
||||||
|
justify-content: center;
|
||||||
|
align-items: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.nav-center {
|
||||||
|
flex: 1;
|
||||||
|
display: flex;
|
||||||
|
justify-content: center;
|
||||||
|
align-items: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.nav-title {
|
||||||
|
font-size: 34rpx;
|
||||||
|
color: #333;
|
||||||
|
font-weight: 500;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 选项卡 */
|
||||||
|
.tab-bar {
|
||||||
|
height: 88rpx;
|
||||||
|
display: flex;
|
||||||
|
background-color: #fff;
|
||||||
|
margin-bottom: 20rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
.tab-item {
|
||||||
|
flex: 1;
|
||||||
|
display: flex;
|
||||||
|
justify-content: center;
|
||||||
|
align-items: center;
|
||||||
|
position: relative;
|
||||||
|
}
|
||||||
|
|
||||||
|
.tab-item.active::after {
|
||||||
|
content: '';
|
||||||
|
position: absolute;
|
||||||
|
bottom: 0;
|
||||||
|
left: 50%;
|
||||||
|
transform: translateX(-50%);
|
||||||
|
width: 50rpx;
|
||||||
|
height: 6rpx;
|
||||||
|
background-color: #1890ff;
|
||||||
|
border-radius: 3rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
.tab-text {
|
||||||
|
font-size: 28rpx;
|
||||||
|
color: #666;
|
||||||
|
}
|
||||||
|
|
||||||
|
.tab-text.active {
|
||||||
|
color: #1890ff;
|
||||||
|
font-weight: 500;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 订单列表 */
|
||||||
|
.order-list {
|
||||||
|
padding: 0 20rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
.order-item {
|
||||||
|
background-color: #fff;
|
||||||
|
border-radius: 16rpx;
|
||||||
|
padding: 30rpx;
|
||||||
|
margin-bottom: 20rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 订单头部 */
|
||||||
|
.order-header {
|
||||||
|
display: flex;
|
||||||
|
justify-content: space-between;
|
||||||
|
align-items: center;
|
||||||
|
margin-bottom: 20rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
.order-number {
|
||||||
|
font-size: 28rpx;
|
||||||
|
color: #333;
|
||||||
|
font-weight: 500;
|
||||||
|
}
|
||||||
|
|
||||||
|
.order-status {
|
||||||
|
padding: 4rpx 16rpx;
|
||||||
|
border-radius: 20rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
.order-status.pending {
|
||||||
|
background-color: #fff2e8;
|
||||||
|
}
|
||||||
|
|
||||||
|
.order-status.processed {
|
||||||
|
background-color: #f6ffed;
|
||||||
|
}
|
||||||
|
|
||||||
|
.status-text {
|
||||||
|
font-size: 24rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
.order-status.pending .status-text {
|
||||||
|
color: #fa5151;
|
||||||
|
}
|
||||||
|
|
||||||
|
.order-status.processed .status-text {
|
||||||
|
color: #52c41a;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
.abnormal-type {
|
||||||
|
font-size: 28rpx;
|
||||||
|
color: #333;
|
||||||
|
font-weight: 500;
|
||||||
|
display: block;
|
||||||
|
margin-bottom: 12rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
.abnormal-description {
|
||||||
|
font-size: 26rpx;
|
||||||
|
color: #666;
|
||||||
|
display: block;
|
||||||
|
margin-bottom: 12rpx;
|
||||||
|
line-height: 1.5;
|
||||||
|
}
|
||||||
|
|
||||||
|
.order-time {
|
||||||
|
font-size: 24rpx;
|
||||||
|
color: #999;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 操作按钮 */
|
||||||
|
.order-actions {
|
||||||
|
display: flex;
|
||||||
|
justify-content: flex-end;
|
||||||
|
gap: 20rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
.action-btn {
|
||||||
|
font-size: 26rpx;
|
||||||
|
padding: 8rpx 20rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
.detail-btn {
|
||||||
|
color: #1890ff;
|
||||||
|
}
|
||||||
|
|
||||||
|
.report-btn {
|
||||||
|
color: #52c41a;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 空状态 */
|
||||||
|
.empty-state {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
padding: 100rpx 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.empty-icon {
|
||||||
|
margin-bottom: 30rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
.empty-text {
|
||||||
|
font-size: 28rpx;
|
||||||
|
color: #999;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 骨架屏样式 - 纯CSS实现 */
|
||||||
|
/* 选项卡骨架屏 */
|
||||||
|
.tab-bar-skeleton {
|
||||||
|
height: 88rpx;
|
||||||
|
display: flex;
|
||||||
|
background-color: #fff;
|
||||||
|
margin-bottom: 20rpx;
|
||||||
|
padding: 0 40rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
.skeleton-tab-item {
|
||||||
|
flex: 1;
|
||||||
|
height: 36rpx;
|
||||||
|
align-self: center;
|
||||||
|
margin: 0 20rpx;
|
||||||
|
border-radius: 18rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 订单列表骨架屏 */
|
||||||
|
.skeleton-container {
|
||||||
|
padding: 0 20rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 订单项骨架 */
|
||||||
|
.skeleton-order-item {
|
||||||
|
background-color: #ffffff;
|
||||||
|
border-radius: 16rpx;
|
||||||
|
padding: 30rpx;
|
||||||
|
margin-bottom: 20rpx;
|
||||||
|
overflow: hidden;
|
||||||
|
box-shadow: 0 2rpx 8rpx rgba(0, 0, 0, 0.05);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 订单头部布局 */
|
||||||
|
.skeleton-header {
|
||||||
|
display: flex;
|
||||||
|
justify-content: space-between;
|
||||||
|
align-items: center;
|
||||||
|
margin-bottom: 20rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 底部布局 */
|
||||||
|
.skeleton-footer {
|
||||||
|
display: flex;
|
||||||
|
justify-content: space-between;
|
||||||
|
align-items: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 操作按钮区域 */
|
||||||
|
.skeleton-actions {
|
||||||
|
display: flex;
|
||||||
|
gap: 20rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 通用骨架占位元素 */
|
||||||
|
.skeleton-slot {
|
||||||
|
background: linear-gradient(90deg, #f0f0f0 25%, #e0e0e0 50%, #f0f0f0 75%);
|
||||||
|
background-size: 200% 100%;
|
||||||
|
animation: skeleton-loading 1.5s infinite ease-in-out;
|
||||||
|
border-radius: 8rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 特定元素尺寸 */
|
||||||
|
.skeleton-order-number {
|
||||||
|
width: 60%;
|
||||||
|
height: 36rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
.skeleton-status-badge {
|
||||||
|
width: 120rpx;
|
||||||
|
height: 40rpx;
|
||||||
|
border-radius: 20rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
.skeleton-type {
|
||||||
|
width: 30%;
|
||||||
|
height: 36rpx;
|
||||||
|
margin-bottom: 16rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
.skeleton-description {
|
||||||
|
width: 100%;
|
||||||
|
height: 32rpx;
|
||||||
|
margin-bottom: 16rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
.skeleton-time {
|
||||||
|
width: 25%;
|
||||||
|
height: 30rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
.skeleton-btn {
|
||||||
|
width: 100rpx;
|
||||||
|
height: 30rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 骨架屏动画 */
|
||||||
|
@keyframes skeleton-loading {
|
||||||
|
0% {
|
||||||
|
background-position: 200% 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
100% {
|
||||||
|
background-position: -200% 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</style>
|
||||||
@@ -0,0 +1,86 @@
|
|||||||
|
{
|
||||||
|
"id": "uni-calendar",
|
||||||
|
"displayName": "uni-calendar 日历",
|
||||||
|
"version": "1.4.12",
|
||||||
|
"description": "日历组件",
|
||||||
|
"keywords": [
|
||||||
|
"uni-ui",
|
||||||
|
"uniui",
|
||||||
|
"日历",
|
||||||
|
"",
|
||||||
|
"打卡",
|
||||||
|
"日历选择"
|
||||||
|
],
|
||||||
|
"repository": "https://github.com/dcloudio/uni-ui",
|
||||||
|
"engines": {
|
||||||
|
"HBuilderX": ""
|
||||||
|
},
|
||||||
|
"directories": {
|
||||||
|
"example": "../../temps/example_temps"
|
||||||
|
},
|
||||||
|
"dcloudext": {
|
||||||
|
"sale": {
|
||||||
|
"regular": {
|
||||||
|
"price": "0.00"
|
||||||
|
},
|
||||||
|
"sourcecode": {
|
||||||
|
"price": "0.00"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"contact": {
|
||||||
|
"qq": ""
|
||||||
|
},
|
||||||
|
"declaration": {
|
||||||
|
"ads": "无",
|
||||||
|
"data": "无",
|
||||||
|
"permissions": "无"
|
||||||
|
},
|
||||||
|
"npmurl": "https://www.npmjs.com/package/@dcloudio/uni-ui",
|
||||||
|
"type": "component-vue"
|
||||||
|
},
|
||||||
|
"uni_modules": {
|
||||||
|
"dependencies": [],
|
||||||
|
"encrypt": [],
|
||||||
|
"platforms": {
|
||||||
|
"cloud": {
|
||||||
|
"tcb": "y",
|
||||||
|
"aliyun": "y",
|
||||||
|
"alipay": "n"
|
||||||
|
},
|
||||||
|
"client": {
|
||||||
|
"App": {
|
||||||
|
"app-vue": "y",
|
||||||
|
"app-nvue": "y"
|
||||||
|
},
|
||||||
|
"H5-mobile": {
|
||||||
|
"Safari": "y",
|
||||||
|
"Android Browser": "y",
|
||||||
|
"微信浏览器(Android)": "y",
|
||||||
|
"QQ浏览器(Android)": "y"
|
||||||
|
},
|
||||||
|
"H5-pc": {
|
||||||
|
"Chrome": "y",
|
||||||
|
"IE": "y",
|
||||||
|
"Edge": "y",
|
||||||
|
"Firefox": "y",
|
||||||
|
"Safari": "y"
|
||||||
|
},
|
||||||
|
"小程序": {
|
||||||
|
"微信": "y",
|
||||||
|
"阿里": "y",
|
||||||
|
"百度": "y",
|
||||||
|
"字节跳动": "y",
|
||||||
|
"QQ": "y"
|
||||||
|
},
|
||||||
|
"快应用": {
|
||||||
|
"华为": "u",
|
||||||
|
"联盟": "u"
|
||||||
|
},
|
||||||
|
"Vue": {
|
||||||
|
"vue2": "y",
|
||||||
|
"vue3": "y"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
After Width: | Height: | Size: 456 B |
@@ -0,0 +1,97 @@
|
|||||||
|
# qf-image-cropper
|
||||||
|
## 图片裁剪插件
|
||||||
|
uniapp微信小程序图片裁剪插件,支持自定义尺寸、定点等比例缩放、拖动、图片翻转、剪切圆形/圆角图片、定制样式,功能多性能高体验好注释全。
|
||||||
|
|
||||||
|
### 平台支持:
|
||||||
|
1. 支持微信小程序:移动端、PC端、开发者工具
|
||||||
|
2. 支持H5平台(2.1.0版本起)
|
||||||
|
3. 支持APP平台(2.1.5版本起):Android、IOS
|
||||||
|
4. 其他平台暂未测试兼容性未知
|
||||||
|
|
||||||
|
### 支持功能:
|
||||||
|
1. 自定义裁剪尺寸
|
||||||
|
2. 定点等比例缩放:移动端以双指触摸中心点为缩放中心点,PC端以鼠标所在点为缩放中心点
|
||||||
|
3. 自由拖动:支持限制滑出边界,也支持回弹效果(滑动时可滑出边界,释放时回弹到边界)
|
||||||
|
4. 图片翻转:在裁剪尺寸非 1:1 的情况下,翻转时宽高无法铺满裁剪区域时,图片会自动放大到合适尺寸
|
||||||
|
5. 裁剪生成新图片
|
||||||
|
6. 本地选择图片
|
||||||
|
7. 可定制样式:可自由选择是否渲染裁剪边框、可伸缩裁剪顶角、参考线
|
||||||
|
8. 裁剪圆角图片:圆形、圆角矩形
|
||||||
|
|
||||||
|
### 属性说明
|
||||||
|
| 属性名 | 类型 | 默认值 | 说明 |
|
||||||
|
|:---|:---|:---|:---|
|
||||||
|
| src | String | | 图片资源地址 |
|
||||||
|
| width | Number | 300 | 裁剪宽度 |
|
||||||
|
| height | Number | 300 | 裁剪高度 |
|
||||||
|
| showBorder | Boolean | true | 是否绘制裁剪区域边框 |
|
||||||
|
| showGrid | Boolean | true | 是否绘制裁剪区域网格参考线 |
|
||||||
|
| showAngle | Boolean | true | 是否展示四个支持伸缩的角 |
|
||||||
|
| areaScale | Number | 0.3 | 裁剪区域最小缩放倍数 |
|
||||||
|
| minScale | Number | 1 | 图片最小缩放倍数 |
|
||||||
|
| maxScale | Number | 5 | 图片最大缩放倍数 |
|
||||||
|
| checkRange | Boolean | true | 检查图片位置是否超出裁剪边界,如果超出则会矫正位置 |
|
||||||
|
| backgroundColor | String | | 生成图片背景色:如果裁剪区域没有完全包含在图片中时,不设置该属性则生成图片存在一定的透明块 |
|
||||||
|
| bounce | Boolean | true | 是否有回弹效果:当 checkRange 为 true 时有效,拖动时可以拖出边界,释放时会弹回边界 |
|
||||||
|
| rotatable | Boolean | true | 是否支持翻转 |
|
||||||
|
| reverseRotatable | Boolean | false | 是否支持逆向翻转 |
|
||||||
|
| choosable | Boolean | true | 是否支持从本地选择素材 |
|
||||||
|
| gpu | Boolean | false | 是否开启硬件加速,图片缩放过程中如果出现元素的“留影”或“重影”效果,可通过该方式解决或减轻这一问题 |
|
||||||
|
| angleSize | Number | 20 | 四个角尺寸,单位px |
|
||||||
|
| angleBorderWidth | Number | 2 | 四个角边框宽度,单位px |
|
||||||
|
| zIndex | Number/String | | 调整组件层级 |
|
||||||
|
| radius | Number | | 裁剪图片圆角半径,单位px |
|
||||||
|
| fileType | String | png | 生成文件的类型,只支持 'jpg' 或 'png'。默认为 'png' |
|
||||||
|
| delay | Number | 1000 | 图片从绘制到生成所需时间,单位ms<br>微信小程序平台使用 `Canvas 2D` 绘制时有效<br>如绘制大图或出现裁剪图片空白等情况应适当调大该值,因 `Canvas 2d` 采用同步绘制,需自己把控绘制完成时间 |
|
||||||
|
| navigation | Boolean | true | 页面是否是原生标题栏:<br>H5平台当 showAngle 为 true 时,使用插件的页面在 `page.json` 中配置了 `"navigationStyle": "custom"` 时,必须将此值设为 false ,否则四个可拉伸角的触发位置会有偏差。<br>注:因H5平台的窗口高度是包含标题栏的,而屏幕触摸点的坐标是不包含的 |
|
||||||
|
| @crop | EventHandle | | 剪裁完成后触发,event = { tempFilePath }。在H5平台下,tempFilePath 为 base64 |
|
||||||
|
|
||||||
|
### 基本用法
|
||||||
|
```
|
||||||
|
<template>
|
||||||
|
<div>
|
||||||
|
<qf-image-cropper :width="500" :height="500" :radius="30" @crop="handleCrop"></qf-image-cropper>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
import QfImageCropper from '@/components/qf-image-cropper/qf-image-cropper.vue';
|
||||||
|
export default {
|
||||||
|
components: {
|
||||||
|
QfImageCropper
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
handleCrop(e) {
|
||||||
|
uni.previewImage({
|
||||||
|
urls: [e.tempFilePath],
|
||||||
|
current: 0
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
```
|
||||||
|
通过ref组件实例可在进入页面后直接打开相册选择图片
|
||||||
|
```
|
||||||
|
mounted() {
|
||||||
|
this.$refs.qfImageCropper.chooseImage({ sourceType: ['album'] });
|
||||||
|
}
|
||||||
|
```
|
||||||
|
### 使用说明
|
||||||
|
1.建议在`pages.json`中将引用插件的页面添加一下配置禁止下拉刷新和禁止页面滑动,防止出现性能或页面抖动等问题。
|
||||||
|
```
|
||||||
|
{
|
||||||
|
"enablePullDownRefresh": false,
|
||||||
|
"disableScroll": true
|
||||||
|
}
|
||||||
|
```
|
||||||
|
2.建议使用本插件不要设置过大宽高的目标图片尺寸,建议1365x1365以内,否则可能会导致如下问题:
|
||||||
|
```
|
||||||
|
1.界面卡顿,内存占用过高
|
||||||
|
2.生成图片失真(模糊)
|
||||||
|
3.确定裁剪后一直显示 `裁剪中...`,该问题是由 `uni.canvasToTempFilePath` 无法回调导致,不同平台不同设备限制可能有所不同。
|
||||||
|
```
|
||||||
|
3.如裁剪后的图片存在偏移的问题,请检查是否受自己项目中父组件或全局样式影响。
|
||||||
|
4.src属性设置网络图片时,图片资源必须是能触发 `getImageInfo` API 的 success 回调才可用于插件裁剪。因此小程序平台获取网络图片信息需先配置download域名白名单才能生效。
|
||||||
|
5.如果组件无法正常渲染且使用了 `v-if` 时,可尝试将 `v-if` 替换为 `v-show`
|
||||||
|
6.如果App端导入组件后无法正常渲染,请尝试重新运行
|
||||||
@@ -0,0 +1,126 @@
|
|||||||
|
{
|
||||||
|
"easycom": {
|
||||||
|
// 注意一定要放在custom里,否则无效,https://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"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"pages": [ //pages数组中第一项表示应用启动页,参考:https://uniapp.dcloud.io/collocation/pages
|
||||||
|
|
||||||
|
{
|
||||||
|
|
||||||
|
"path": "pages/index/index",
|
||||||
|
"style": {
|
||||||
|
"navigationBarTitleText": "门店运营",
|
||||||
|
"navigationBarBackgroundColor": "#36394D",
|
||||||
|
"navigationStyle": "custom",
|
||||||
|
"backgroundColor": "#F8F8F8"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"path": "pages/index/task",
|
||||||
|
"style": {
|
||||||
|
"navigationBarTitleText": "任务",
|
||||||
|
"navigationBarBackgroundColor": "#36394D",
|
||||||
|
"navigationStyle": "custom",
|
||||||
|
"backgroundColor": "#F8F8F8"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"path": "pages/index/income",
|
||||||
|
"style": {
|
||||||
|
"navigationBarTitleText": "我的收入",
|
||||||
|
"navigationBarBackgroundColor": "#36394D",
|
||||||
|
"navigationStyle": "custom",
|
||||||
|
"backgroundColor": "#F8F8F8"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"path": "pages/index/user",
|
||||||
|
"style": {
|
||||||
|
"navigationBarTitleText": "我的",
|
||||||
|
"navigationBarBackgroundColor": "#36394D",
|
||||||
|
"navigationStyle": "custom",
|
||||||
|
"backgroundColor": "#F8F8F8"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"globalStyle": {
|
||||||
|
"navigationBarTextStyle": "black",
|
||||||
|
"navigationBarTitleText": "v派商家",
|
||||||
|
"navigationBarBackgroundColor": "#fff",
|
||||||
|
"backgroundColor": "#000"
|
||||||
|
},
|
||||||
|
"subPackages": [
|
||||||
|
{
|
||||||
|
"root": "pages/order",
|
||||||
|
"pages": [
|
||||||
|
{
|
||||||
|
"path": "orderDetail",
|
||||||
|
"style": {
|
||||||
|
"navigationBarTitleText": "项目中心",
|
||||||
|
"navigationStyle": "custom"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"path" : "navigation",
|
||||||
|
"style" :
|
||||||
|
{
|
||||||
|
"navigationBarTitleText" : "导航",
|
||||||
|
"navigationStyle": "custom"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"path" : "abnormal",
|
||||||
|
"style" :
|
||||||
|
{
|
||||||
|
"navigationBarTitleText" : "上报异常",
|
||||||
|
"navigationStyle": "custom"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"path" : "grabOrder",
|
||||||
|
"style" :
|
||||||
|
{
|
||||||
|
"navigationBarTitleText" : "订单详情"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
],
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
"tabBar": {
|
||||||
|
"color": "#000",
|
||||||
|
"selectedColor": "#000",
|
||||||
|
"backgroundColor": "#FFFFFF",
|
||||||
|
"list": [{
|
||||||
|
"pagePath": "pages/index/index",
|
||||||
|
"iconPath": "static/tab/home.png",
|
||||||
|
"selectedIconPath": "/static/tab/homed.png",
|
||||||
|
"text": "主页"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"pagePath": "pages/index/task",
|
||||||
|
"iconPath": "static/tab/task.png",
|
||||||
|
"selectedIconPath": "static/tab/tasked.png",
|
||||||
|
"text": "任务"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"pagePath": "pages/index/income",
|
||||||
|
"iconPath": "static/tab/income.png",
|
||||||
|
"selectedIconPath": "static/tab/incomed.png",
|
||||||
|
"text": "收入"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"pagePath": "pages/index/user",
|
||||||
|
"iconPath": "static/tab/user.png",
|
||||||
|
"selectedIconPath": "static/tab/usered.png",
|
||||||
|
"text": "我的"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
3912
.svn/pristine/12/12e3d1ab0fd1e1053a2010ad29a968c5bbb700a4.svn-base
Normal file
@@ -0,0 +1,380 @@
|
|||||||
|
<template>
|
||||||
|
|
||||||
|
<!-- 实际内容 -->
|
||||||
|
<view class="rider-home">
|
||||||
|
<!-- 统计数据区域 -->
|
||||||
|
<view class="stats-section">
|
||||||
|
<view class="stat-item">
|
||||||
|
<text class="stat-label">今日收入</text>
|
||||||
|
<text class="stat-value income">¥86.50</text>
|
||||||
|
</view>
|
||||||
|
<view class="stat-item">
|
||||||
|
<text class="stat-label">已完成</text>
|
||||||
|
<text class="stat-value completed">5单</text>
|
||||||
|
</view>
|
||||||
|
<view class="stat-item">
|
||||||
|
<text class="stat-label">进行中</text>
|
||||||
|
<text class="stat-value ongoing">6单</text>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
|
||||||
|
<!-- 接单按钮 -->
|
||||||
|
<view class="action-section">
|
||||||
|
<up-button type="primary" shape="circle" size="default" class="accept-orders-btn"
|
||||||
|
@click="toggleAcceptOrders">{{ userStatus === '已上线' ? '接单中 · 点击暂停' : '点击开始接单' }}</up-button>
|
||||||
|
</view>
|
||||||
|
|
||||||
|
<view class="tab-bar">
|
||||||
|
<view v-for="(tab, index) in tabs" :key="index" class="tab-item" :class="{ active: activeTab === index }"
|
||||||
|
@click="switchTab(index)">
|
||||||
|
<text class="tab-text">{{ tab }}</text>
|
||||||
|
<view v-if="activeTab === index" class="active-line"></view>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
|
||||||
|
<view class="" style="padding: 0 30rpx;">
|
||||||
|
<view @click="gopage()" v-for="(orderItem,orderIndex) in 3 " :key="orderIndex" class="task-section">
|
||||||
|
<!-- 高价单标签 -->
|
||||||
|
<view class="" style="display: flex; align-items: center; justify-content: space-between;">
|
||||||
|
|
||||||
|
<view class="high-price-tag" :style="{'border':activeTab==0?'1rpx solid #52C41A':'1rpx solid #FAAD14','color':activeTab==0?'#52C41A':'#FAAD14' }" style="background-color: #fff;" >
|
||||||
|
<text class="high-price-text">{{activeTab==0?'待取单':'配送中'}}</text>
|
||||||
|
</view>
|
||||||
|
<view class="" style="display: flex; align-items: baseline;">
|
||||||
|
<up-icon name="phone" color="var(--nav-mian)" size="20"></up-icon>
|
||||||
|
<text style="margin-left: 10rpx; color: var(--nav-mian); ">拨打商家</text>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
|
||||||
|
<!-- 商家信息 -->
|
||||||
|
<view class="merchant-info">
|
||||||
|
<text class="merchant-name">老北京炸酱面</text>
|
||||||
|
<text v-if="activeTab==0" class="distance">500m</text>
|
||||||
|
</view>
|
||||||
|
|
||||||
|
<!-- 地址信息 -->
|
||||||
|
<view class="address-info">
|
||||||
|
<up-icon name="map" color="#999" size="24rpx" />
|
||||||
|
<text class="address-text">北京市朝阳区三里屯SOHO</text>
|
||||||
|
<text v-if="activeTab!==0" class="address-text">共3件商品</text>
|
||||||
|
</view>
|
||||||
|
<!-- 商品次数-->
|
||||||
|
<view class="address-info">
|
||||||
|
<text class="address-text">共3件商品</text>
|
||||||
|
<view class="">
|
||||||
|
<text class="price">¥5.50</text>
|
||||||
|
<text style="color: var(--nav-mian); font-weight: 600; margin-left: 10rpx; ">/单</text>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
|
||||||
|
<!-- 价格和取餐时间 -->
|
||||||
|
<view class="price-time-row">
|
||||||
|
<view v-if="activeTab==0" class="">
|
||||||
|
<text style="font-size: 30rpx; font-weight: 600; color: #1890FF; ">取件码: </text>
|
||||||
|
<text style="color: var(--nav-mian); font-weight: 600; margin-left: 10rpx; ">A121</text>
|
||||||
|
</view>
|
||||||
|
<view v-if="activeTab==1" class="">
|
||||||
|
<text class="address-text">据您1.2km</text>
|
||||||
|
</view>
|
||||||
|
<view class="pickup-time">
|
||||||
|
<up-icon name="clock" color="#FF9500" size="24rpx" />
|
||||||
|
<text class="time-text" :style="{'color':activeTab==0?'#FAAD14':'#FF0000'}" >{{activeTab==0?'12:30 前取餐':'12:30 前送达'}}</text>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
|
||||||
|
<!-- 立即抢单按钮 -->
|
||||||
|
<up-button type="primary" :color="activeTab==0?'#1890FF':'#52C41A'" size="large" class="grab-btn">{{ activeTab==0?'我已取餐':'确认送达'}}</up-button>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
|
||||||
|
|
||||||
|
<up-loadmore :status="status" />
|
||||||
|
<view class="" style="width: 100%; height: 60rpx; ">
|
||||||
|
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script setup lang="ts">
|
||||||
|
import { onLoad } from '@dcloudio/uni-app';
|
||||||
|
import { ref, onMounted } from 'vue';
|
||||||
|
import { Service } from '@/Service/Service';
|
||||||
|
|
||||||
|
|
||||||
|
// 加载状态
|
||||||
|
const isLoading = ref(true);
|
||||||
|
|
||||||
|
let userStatus = ref('已下线')
|
||||||
|
let status = ref('nomore')
|
||||||
|
const tabs = ['待取货', '配送中']
|
||||||
|
const activeTab = ref(0)
|
||||||
|
|
||||||
|
onLoad(() => {
|
||||||
|
setTimeout(() => {
|
||||||
|
isLoading.value = false
|
||||||
|
}, 1500)
|
||||||
|
})
|
||||||
|
|
||||||
|
// 切换标签
|
||||||
|
const switchTab = (index : number) => {
|
||||||
|
activeTab.value = index
|
||||||
|
}
|
||||||
|
|
||||||
|
// 切换接单状态
|
||||||
|
const toggleAcceptOrders = () => {
|
||||||
|
userStatus.value = userStatus.value === '已上线' ? '已下线' : '已上线';
|
||||||
|
};
|
||||||
|
|
||||||
|
// 页面跳转
|
||||||
|
const gopage = () => {
|
||||||
|
if (activeTab.value == 0) {
|
||||||
|
Service.GoPage('/pages/order/grabOrder')
|
||||||
|
} else {
|
||||||
|
Service.GoPage('/pages/order/orderDetail')
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style scoped lang="scss">
|
||||||
|
page {
|
||||||
|
background-color: #F6f6f6;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* 统计数据区域 */
|
||||||
|
.stats-section {
|
||||||
|
background-color: #ffffff;
|
||||||
|
margin: 20rpx;
|
||||||
|
border-radius: 16rpx;
|
||||||
|
display: flex;
|
||||||
|
justify-content: space-around;
|
||||||
|
padding: 30rpx 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.stat-item {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
align-items: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.stat-label {
|
||||||
|
font-size: 28rpx;
|
||||||
|
color: #666666;
|
||||||
|
margin-bottom: 10rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
.stat-value {
|
||||||
|
font-size: 36rpx;
|
||||||
|
font-weight: 600;
|
||||||
|
}
|
||||||
|
|
||||||
|
.income {
|
||||||
|
color: var(--nav-diluted);
|
||||||
|
}
|
||||||
|
|
||||||
|
.completed {
|
||||||
|
color: var(--nav-vice);
|
||||||
|
}
|
||||||
|
|
||||||
|
.ongoing {
|
||||||
|
color: #FF9500;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 接单按钮 */
|
||||||
|
.action-section {
|
||||||
|
margin: 0 20rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
.accept-orders-btn {
|
||||||
|
width: 100%;
|
||||||
|
height: 90rpx;
|
||||||
|
font-size: 32rpx;
|
||||||
|
background-color: #52C41A;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* 顶部标签栏 */
|
||||||
|
.tab-bar {
|
||||||
|
margin-top: 20rpx;
|
||||||
|
display: flex;
|
||||||
|
background-color: #FFFFFF;
|
||||||
|
padding: 20rpx 0 0;
|
||||||
|
border-bottom: 1rpx solid #E5E5E5;
|
||||||
|
width: 100vw;
|
||||||
|
background-color: #fff;
|
||||||
|
}
|
||||||
|
|
||||||
|
.tab-item {
|
||||||
|
flex: 1;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
align-items: center;
|
||||||
|
padding: 20rpx 0;
|
||||||
|
position: relative;
|
||||||
|
}
|
||||||
|
|
||||||
|
.tab-text {
|
||||||
|
font-size: 28rpx;
|
||||||
|
color: #666666;
|
||||||
|
}
|
||||||
|
|
||||||
|
.tab-item.active .tab-text {
|
||||||
|
color: var(--nav-mian);
|
||||||
|
font-weight: 600;
|
||||||
|
}
|
||||||
|
|
||||||
|
.active-line {
|
||||||
|
position: absolute;
|
||||||
|
bottom: 0;
|
||||||
|
width: 110rpx;
|
||||||
|
height: 6rpx;
|
||||||
|
background-color: var(--nav-mian);
|
||||||
|
border-radius: 3rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
.task-section {
|
||||||
|
margin-top: 20rpx;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
background-color: #fff;
|
||||||
|
border-radius: 20rpx;
|
||||||
|
padding: 20rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* 标签样式 */
|
||||||
|
.high-price-tag {
|
||||||
|
width: fit-content;
|
||||||
|
background-color: #FF7875;
|
||||||
|
color: #FFFFFF;
|
||||||
|
padding: 5rpx 20rpx;
|
||||||
|
border-radius: 20rpx;
|
||||||
|
font-size: 24rpx;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.status-tag {
|
||||||
|
position: absolute;
|
||||||
|
top: 20rpx;
|
||||||
|
left: 20rpx;
|
||||||
|
padding: 5rpx 20rpx;
|
||||||
|
border-radius: 20rpx;
|
||||||
|
font-size: 24rpx;
|
||||||
|
z-index: 10;
|
||||||
|
}
|
||||||
|
|
||||||
|
.status-tag.pending {
|
||||||
|
background-color: #4CD964;
|
||||||
|
color: #FFFFFF;
|
||||||
|
}
|
||||||
|
|
||||||
|
.status-tag.delivering {
|
||||||
|
background-color: #FF9500;
|
||||||
|
color: #FFFFFF;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 右侧操作按钮 */
|
||||||
|
.right-action {
|
||||||
|
position: absolute;
|
||||||
|
top: 20rpx;
|
||||||
|
right: 20rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
.call-btn {
|
||||||
|
padding: 5rpx 15rpx;
|
||||||
|
font-size: 24rpx;
|
||||||
|
line-height: 36rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 信息展示 */
|
||||||
|
.merchant-info {
|
||||||
|
margin-top: 20rpx;
|
||||||
|
display: flex;
|
||||||
|
justify-content: space-between;
|
||||||
|
align-items: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.merchant-name {
|
||||||
|
font-size: 34rpx;
|
||||||
|
font-weight: 600;
|
||||||
|
color: #333333;
|
||||||
|
}
|
||||||
|
|
||||||
|
.distance {
|
||||||
|
font-size: 28rpx;
|
||||||
|
color: #666666;
|
||||||
|
}
|
||||||
|
|
||||||
|
.address-info {
|
||||||
|
display: flex;
|
||||||
|
align-items: baseline;
|
||||||
|
margin-top: 15rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
.address-text {
|
||||||
|
margin-left: 10rpx;
|
||||||
|
font-size: 28rpx;
|
||||||
|
color: #666666;
|
||||||
|
flex: 1;
|
||||||
|
overflow: hidden;
|
||||||
|
text-overflow: ellipsis;
|
||||||
|
white-space: nowrap;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 价格和时间 */
|
||||||
|
.price-time-row {
|
||||||
|
margin-top: 20rpx;
|
||||||
|
display: flex;
|
||||||
|
justify-content: space-between;
|
||||||
|
align-items: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.price {
|
||||||
|
font-size: 36rpx;
|
||||||
|
font-weight: 600;
|
||||||
|
color: #FF3B30;
|
||||||
|
}
|
||||||
|
|
||||||
|
.pickup-code {
|
||||||
|
font-size: 28rpx;
|
||||||
|
color: #333333;
|
||||||
|
font-weight: 500;
|
||||||
|
}
|
||||||
|
|
||||||
|
.pickup-time {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.time-text {
|
||||||
|
margin-left: 8rpx;
|
||||||
|
font-size: 26rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 按钮样式 */
|
||||||
|
.grab-btn {
|
||||||
|
margin-top: 25rpx;
|
||||||
|
height: 80rpx;
|
||||||
|
line-height: 80rpx;
|
||||||
|
border-radius: 40rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
.grab-btn {
|
||||||
|
background-color: #007AFF;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/* uview组件样式覆盖 */
|
||||||
|
::v-deep .u-button--primary {
|
||||||
|
background-color: var(--nav-vice);
|
||||||
|
border-color: var(--nav-vice);
|
||||||
|
}
|
||||||
|
|
||||||
|
::v-deep .u-button--mini {
|
||||||
|
background-color: var(--nav-mian);
|
||||||
|
border-color: var(--nav-mian);
|
||||||
|
}
|
||||||
|
</style>
|
||||||
@@ -0,0 +1,703 @@
|
|||||||
|
<template>
|
||||||
|
<!-- 导航栏 -->
|
||||||
|
<view class=""
|
||||||
|
style=" z-index: 100; padding:50rpx 20rpx 18rpx; box-sizing: border-box; position: fixed;top: 0; left: 0; width: 100vw; background-color: #fff; display: flex; align-items: center; justify-content: space-between;">
|
||||||
|
<view class="" @click="Service.GoPageBack()">
|
||||||
|
<up-icon name="arrow-left" size="32rpx"></up-icon>
|
||||||
|
</view>
|
||||||
|
<view class="">
|
||||||
|
订单详情
|
||||||
|
</view>
|
||||||
|
<view class="" @click="Service.GoPage('/pages/my/myKF')" style="color: var(--nav-banbacor);">
|
||||||
|
<image :src="Service.GetIconImg('/static/index/order/message.png')" style="width: 32rpx; height: 32rpx; "
|
||||||
|
mode=""></image>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
<view class="" style="width: 100%; height: 88rpx; ">
|
||||||
|
|
||||||
|
</view>
|
||||||
|
|
||||||
|
<!-- 骨架屏 -->
|
||||||
|
<view v-if="loading" class="skeleton-container">
|
||||||
|
<!-- 骨架屏订单状态 -->
|
||||||
|
<view class="skeleton-status"></view>
|
||||||
|
|
||||||
|
<!-- 骨架屏订单基本信息 -->
|
||||||
|
<view class="skeleton-basic-info">
|
||||||
|
<view class="skeleton-row">
|
||||||
|
<view class="skeleton-info-half"></view>
|
||||||
|
<view class="skeleton-info-half skeleton-right"></view>
|
||||||
|
</view>
|
||||||
|
<view class="skeleton-line"></view>
|
||||||
|
<view class="skeleton-line"></view>
|
||||||
|
<view class="skeleton-line"></view>
|
||||||
|
<view class="skeleton-row">
|
||||||
|
<view class="skeleton-info-third"></view>
|
||||||
|
<view class="skeleton-info-btn"></view>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
|
||||||
|
<!-- 骨架屏物品清单 -->
|
||||||
|
<view class="skeleton-basic-info">
|
||||||
|
<view class="skeleton-row">
|
||||||
|
<view class="" style="width: 45%;height: 40rpx;border-radius: 4rpx;animation: shimmer 1.5s infinite;">
|
||||||
|
<view class="" style="background-color: #e6e6e6; width: 60%;height: 40rpx; ">
|
||||||
|
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
<view class="skeleton-info-half skeleton-right"></view>
|
||||||
|
<view class="skeleton-info-half skeleton-right"></view>
|
||||||
|
</view>
|
||||||
|
<view class="skeleton-row" v-for="(item,index) in 3" :key="index">
|
||||||
|
<view class="" style="width: 45%;height: 40rpx;border-radius: 4rpx;animation: shimmer 1.5s infinite;">
|
||||||
|
<view class="" style="background-color: #e6e6e6; width: 90%;height: 40rpx; ">
|
||||||
|
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
<view class="skeleton-info-half skeleton-right"></view>
|
||||||
|
<view class="skeleton-info-half skeleton-right"></view>
|
||||||
|
</view>
|
||||||
|
<view class="skeleton-list-status"></view>
|
||||||
|
</view>
|
||||||
|
|
||||||
|
<!-- 骨架屏地图区域 -->
|
||||||
|
<view class="skeleton-map"></view>
|
||||||
|
|
||||||
|
<!-- 骨架屏取餐地址 -->
|
||||||
|
<view class="skeleton-address">
|
||||||
|
<view class="skeleton-title"></view>
|
||||||
|
<view class="skeleton-store-name"></view>
|
||||||
|
<view class="skeleton-address-line"></view>
|
||||||
|
<view class="skeleton-btn"></view>
|
||||||
|
<view class="skeleton-code"></view>
|
||||||
|
</view>
|
||||||
|
|
||||||
|
<!-- 骨架屏送餐地址 -->
|
||||||
|
<view class="skeleton-address">
|
||||||
|
<view class="skeleton-title"></view>
|
||||||
|
<view class="skeleton-store-name"></view>
|
||||||
|
<view class="skeleton-address-line"></view>
|
||||||
|
<view class="skeleton-btn"></view>
|
||||||
|
<view class="skeleton-remark"></view>
|
||||||
|
</view>
|
||||||
|
|
||||||
|
<!-- 骨架屏底部按钮 -->
|
||||||
|
<view class="skeleton-bottom">
|
||||||
|
<view class="skeleton-bottom-btn"></view>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
<!-- 实际内容 -->
|
||||||
|
<view v-else class="order-detail">
|
||||||
|
<!-- 订单状态 -->
|
||||||
|
<view class="order-status"
|
||||||
|
:style="{ 'background-color':orderStatus==0?'#E6F7FF':(orderStatus==1?'#FFFBE6':'#FFF2F0') }">
|
||||||
|
<text :style="{ 'color':orderStatus==0?'#1890FF':(orderStatus==1?'#FAAD14':'#FF4D4F') }"
|
||||||
|
style="font-size: 34rpx; font-weight: 600;">待取餐 · 请尽快到店取餐</text>
|
||||||
|
|
||||||
|
</view>
|
||||||
|
|
||||||
|
<!-- 订单基本信息 -->
|
||||||
|
<view class="order-basic-info">
|
||||||
|
<view class="info-item">
|
||||||
|
<view class="label" style="font-weight: 700; font-size: 30rpx;">
|
||||||
|
{{ orderInfo.distribution=='预约订单'?'预计'+orderInfo.makeTime.split(' ')[1]+'送达':orderInfo.makeTime }}
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
<view class="info-item">
|
||||||
|
<text class="label">订单编号 : </text>
|
||||||
|
<text class="value">{{ orderId }}</text>
|
||||||
|
</view>
|
||||||
|
|
||||||
|
<view class="info-item" style="justify-content: space-between;">
|
||||||
|
<view class="label" style="display: flex; align-items: baseline;">
|
||||||
|
<u-icon name="clock" size="16" class="clock-icon"></u-icon>
|
||||||
|
{{ Service.formatDate(orderInfo.addTime,1) }} 下单
|
||||||
|
</view>
|
||||||
|
<view class="">
|
||||||
|
<button @click="Service.GoPage('/pages/order/abnormal?orderId='+orderInfo.orderId)" class=""
|
||||||
|
style="padding: 0rpx 30rpx; height: 60rpx; font-size: 24rpx; border-radius: 40rpx; background-color: red; color: #fff; ">提交异常</button>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
|
||||||
|
</view>
|
||||||
|
|
||||||
|
<!-- 物品清单 -->
|
||||||
|
<view class="order-basic-info">
|
||||||
|
<view class="" style="display: flex; align-items: center; ">
|
||||||
|
<view class="" style="flex: 1; font-size: 34rpx; font-weight: 600; ">
|
||||||
|
物品清单
|
||||||
|
</view>
|
||||||
|
<view class="" style="width: 100rpx; text-align: right; font-size: 30rpx; ">
|
||||||
|
数量
|
||||||
|
</view>
|
||||||
|
<view class="" style="width: 120rpx; text-align: right; font-size: 30rpx; ">
|
||||||
|
金额
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
<!-- 商品列表 -->
|
||||||
|
<view class="" :style="{'height':isShow?'110rpx':'fit-content' }" style="overflow: hidden;">
|
||||||
|
<view class="" v-for="(goodsItem,goodsIndex) in JSON.parse(orderInfo.detail) " :key="goodsIndex"
|
||||||
|
style="display: flex; align-items: center; margin-top: 15rpx; ">
|
||||||
|
<view class="" style="flex: 1; ">
|
||||||
|
{{goodsItem.goodsName}}
|
||||||
|
</view>
|
||||||
|
<view class="" style="width: 100rpx; text-align: right; ">
|
||||||
|
×{{ goodsItem.count }}
|
||||||
|
</view>
|
||||||
|
<view class="" style="width: 120rpx; text-align: right; ">
|
||||||
|
¥{{ goodsItem.count*goodsItem.price }}
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
<view class=""
|
||||||
|
style="display: flex; align-items: center;justify-content: space-between; margin-top: 10rpx; ">
|
||||||
|
<view class="">
|
||||||
|
|
||||||
|
</view>
|
||||||
|
<view class="info-item">
|
||||||
|
<text class="label" style="font-weight: 700;">配送费</text>
|
||||||
|
<text class="value price">¥{{ Number(orderInfo.postage).toFixed(2) }}</text>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
<view class="" v-if="JSON.parse(orderInfo.detail).length>2" @click="isShow=!isShow"
|
||||||
|
style=" margin-top: 20rpx; display: flex; align-items: center; justify-content: center; color: #666; ">
|
||||||
|
<up-icon :name="isShow?'arrow-down':'arrow-up'" color="#666" size="18"></up-icon>
|
||||||
|
{{isShow?'展开':'收入'}}
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
<!-- 取餐地址 -->
|
||||||
|
<view class="address-section">
|
||||||
|
<text class="section-title">取餐地址</text>
|
||||||
|
<view class="address-content">
|
||||||
|
<view class="store-name">{{ storeInfo.name }}</view>
|
||||||
|
<text class="address">{{ storeInfo.city }}{{storeInfo.region }}{{ storeInfo.address }}</text>
|
||||||
|
<view class="" style="margin-bottom: 20rpx;">
|
||||||
|
<up-button @click="call(storeInfo.phone)" icon="phone" type="primary" shape="circle"
|
||||||
|
text="拨打商家"></up-button>
|
||||||
|
</view>
|
||||||
|
<view class="pickup-code">
|
||||||
|
<text class="code-label">取餐号:</text>
|
||||||
|
<text class="code-value">A123</text>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
|
||||||
|
<!-- 送餐地址 -->
|
||||||
|
<view class="address-section">
|
||||||
|
<text class="section-title">送餐地址</text>
|
||||||
|
<view class="address-content">
|
||||||
|
<text class="user-name">{{ JSON.parse(orderInfo.address).realName }}</text>
|
||||||
|
<text class="address">{{ JSON.parse(orderInfo.address).address }}</text>
|
||||||
|
<view class="" style="margin-bottom: 20rpx;">
|
||||||
|
<up-button @click="call(JSON.parse(orderInfo.address).phone)" icon="phone" type="primary"
|
||||||
|
shape="circle" text="拨打商家"></up-button>
|
||||||
|
</view>
|
||||||
|
<view v-if="orderInfo.remark" class="remark">
|
||||||
|
<text class="remark-label">备注:</text>
|
||||||
|
<text class="remark-content">{{ orderInfo.remark }}</text>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
|
||||||
|
<view class="" style="width: 100vw; height: 140rpx; ">
|
||||||
|
|
||||||
|
</view>
|
||||||
|
|
||||||
|
<!-- 底部按钮 -->
|
||||||
|
<view class="bottom-action" style="display: flex; justify-content: space-between;'">
|
||||||
|
<up-button @click="upGoods()" color="var(--nav-vice)" class="confirm-btn">{{type==1?'我已取货':'订单完成'}}</up-button>
|
||||||
|
<view class="" style="width: 40rpx;">
|
||||||
|
|
||||||
|
</view>
|
||||||
|
<up-button @click="Service.GoPage('/pages/order/orderChat?orderId='+orderId)" color="#6868ee" class="confirm-btn">联系商家</up-button>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script setup lang="ts">
|
||||||
|
import { onLoad } from '@dcloudio/uni-app';
|
||||||
|
import { ref, onMounted } from 'vue';
|
||||||
|
import { Service } from '@/Service/Service';
|
||||||
|
import { CNRiderOrderService } from '@/Service/CN/CNRiderOrderService'
|
||||||
|
|
||||||
|
// 加载状态
|
||||||
|
const loading = ref(true);
|
||||||
|
|
||||||
|
let orderStatus = ref(0)
|
||||||
|
|
||||||
|
let isShow = ref(true)
|
||||||
|
|
||||||
|
let deliveryTime = ref('')
|
||||||
|
|
||||||
|
let orderInfo = ref<any>({})
|
||||||
|
let storeInfo = ref<any>({})
|
||||||
|
let storeLocation = ref<any>({})
|
||||||
|
|
||||||
|
let type = ref(1)
|
||||||
|
let orderId = ref('')
|
||||||
|
onLoad((data : any) => {
|
||||||
|
orderId.value = data.orderId
|
||||||
|
type.value = data.type
|
||||||
|
getData()
|
||||||
|
})
|
||||||
|
|
||||||
|
|
||||||
|
const getData = () => {
|
||||||
|
CNRiderOrderService.GetUnitOrderInfo(orderId.value).then(res => {
|
||||||
|
loading.value = false
|
||||||
|
if (res.data) {
|
||||||
|
deliveryTime.value = res.data.deliveryTime
|
||||||
|
orderInfo.value = res.data.orderInfo
|
||||||
|
storeInfo.value = res.data.storeInfo
|
||||||
|
storeLocation.value = res.data.storeLocation
|
||||||
|
}
|
||||||
|
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
const call = (phone : string) => {
|
||||||
|
uni.makePhoneCall({
|
||||||
|
phoneNumber: phone,
|
||||||
|
fail(e) {
|
||||||
|
console.log( e);
|
||||||
|
},
|
||||||
|
success(e) {
|
||||||
|
console.log('1111', e);
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
const upGoods = () => {
|
||||||
|
CNRiderOrderService.UpdateRiderOrderTake(orderId.value, type.value).then(res => {
|
||||||
|
if (res.data) {
|
||||||
|
Service.Msg('取餐成功!')
|
||||||
|
setTimeout(() => {
|
||||||
|
Service.GoPageBack()
|
||||||
|
}, 1000)
|
||||||
|
} else {
|
||||||
|
Service.Msg(res.msg)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style scoped>
|
||||||
|
/* 骨架屏样式 */
|
||||||
|
.skeleton-container {
|
||||||
|
min-height: 100vh;
|
||||||
|
background-color: #f5f5f5;
|
||||||
|
padding-bottom: 140rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 骨架屏导航栏 */
|
||||||
|
.skeleton-nav {
|
||||||
|
height: 88rpx;
|
||||||
|
position: fixed;
|
||||||
|
top: 0;
|
||||||
|
left: 0;
|
||||||
|
width: 100vw;
|
||||||
|
background-color: #fff;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: space-between;
|
||||||
|
padding: 0 20rpx;
|
||||||
|
z-index: 100;
|
||||||
|
}
|
||||||
|
|
||||||
|
.skeleton-nav-item {
|
||||||
|
width: 32rpx;
|
||||||
|
height: 32rpx;
|
||||||
|
background-color: #e6e6e6;
|
||||||
|
border-radius: 4rpx;
|
||||||
|
animation: shimmer 1.5s infinite;
|
||||||
|
}
|
||||||
|
|
||||||
|
.skeleton-nav-title {
|
||||||
|
width: 180rpx;
|
||||||
|
height: 36rpx;
|
||||||
|
background-color: #e6e6e6;
|
||||||
|
border-radius: 4rpx;
|
||||||
|
animation: shimmer 1.5s infinite;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 骨架屏订单状态 */
|
||||||
|
.skeleton-status {
|
||||||
|
height: 100rpx;
|
||||||
|
background-color: #fff;
|
||||||
|
padding: 30rpx;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.skeleton-status::after {
|
||||||
|
content: '';
|
||||||
|
width: 350rpx;
|
||||||
|
height: 45rpx;
|
||||||
|
background-color: #e6e6e6;
|
||||||
|
border-radius: 4rpx;
|
||||||
|
animation: shimmer 1.5s infinite;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 骨架屏订单基本信息 */
|
||||||
|
.skeleton-basic-info {
|
||||||
|
background-color: #fff;
|
||||||
|
margin: 20rpx 20rpx;
|
||||||
|
padding: 30rpx;
|
||||||
|
border-radius: 20rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
.skeleton-row {
|
||||||
|
display: flex;
|
||||||
|
justify-content: space-between;
|
||||||
|
margin-bottom: 20rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
.skeleton-info-half {
|
||||||
|
width: 45%;
|
||||||
|
height: 40rpx;
|
||||||
|
background-color: #e6e6e6;
|
||||||
|
border-radius: 4rpx;
|
||||||
|
animation: shimmer 1.5s infinite;
|
||||||
|
}
|
||||||
|
|
||||||
|
.skeleton-right {
|
||||||
|
width: 10%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.skeleton-line {
|
||||||
|
width: 60%;
|
||||||
|
height: 40rpx;
|
||||||
|
background-color: #e6e6e6;
|
||||||
|
border-radius: 4rpx;
|
||||||
|
margin-bottom: 20rpx;
|
||||||
|
animation: shimmer 1.5s infinite;
|
||||||
|
}
|
||||||
|
|
||||||
|
.skeleton-info-third {
|
||||||
|
width: 60%;
|
||||||
|
height: 40rpx;
|
||||||
|
background-color: #e6e6e6;
|
||||||
|
border-radius: 4rpx;
|
||||||
|
animation: shimmer 1.5s infinite;
|
||||||
|
}
|
||||||
|
|
||||||
|
.skeleton-info-btn {
|
||||||
|
width: 20%;
|
||||||
|
height: 50rpx;
|
||||||
|
background-color: #e6e6e6;
|
||||||
|
border-radius: 25rpx;
|
||||||
|
animation: shimmer 1.5s infinite;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 列表状态 */
|
||||||
|
.skeleton-list-status {
|
||||||
|
height: 60rpx;
|
||||||
|
background-color: #fff;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.skeleton-list-status::after {
|
||||||
|
content: '';
|
||||||
|
width: 200rpx;
|
||||||
|
height: 45rpx;
|
||||||
|
background-color: #e6e6e6;
|
||||||
|
border-radius: 4rpx;
|
||||||
|
animation: shimmer 1.5s infinite;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 骨架屏地图区域 */
|
||||||
|
.skeleton-map {
|
||||||
|
margin: 20rpx;
|
||||||
|
height: 400rpx;
|
||||||
|
background-color: #e6e6e6;
|
||||||
|
border-radius: 20rpx;
|
||||||
|
animation: shimmer 1.5s infinite;
|
||||||
|
position: relative;
|
||||||
|
overflow: hidden;
|
||||||
|
}
|
||||||
|
|
||||||
|
.skeleton-map::after {
|
||||||
|
content: '';
|
||||||
|
position: absolute;
|
||||||
|
top: 0;
|
||||||
|
left: 0;
|
||||||
|
right: 0;
|
||||||
|
bottom: 0;
|
||||||
|
background: linear-gradient(135deg, transparent 25%, rgba(255, 255, 255, 0.2) 25%, rgba(255, 255, 255, 0.2) 50%, transparent 50%, transparent 75%, rgba(255, 255, 255, 0.2) 75%, rgba(255, 255, 255, 0.2));
|
||||||
|
background-size: 100rpx 100rpx;
|
||||||
|
animation: shimmer 1.5s infinite linear;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 骨架屏地址区域 */
|
||||||
|
.skeleton-address {
|
||||||
|
background-color: #fff;
|
||||||
|
margin: 20rpx;
|
||||||
|
padding: 30rpx;
|
||||||
|
border-radius: 20rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
.skeleton-title {
|
||||||
|
width: 120rpx;
|
||||||
|
height: 30rpx;
|
||||||
|
background-color: #e6e6e6;
|
||||||
|
border-radius: 4rpx;
|
||||||
|
margin-bottom: 25rpx;
|
||||||
|
animation: shimmer 1.5s infinite;
|
||||||
|
}
|
||||||
|
|
||||||
|
.skeleton-store-name {
|
||||||
|
width: 70%;
|
||||||
|
height: 50rpx;
|
||||||
|
background-color: #e6e6e6;
|
||||||
|
border-radius: 4rpx;
|
||||||
|
margin-bottom: 15rpx;
|
||||||
|
animation: shimmer 1.5s infinite;
|
||||||
|
}
|
||||||
|
|
||||||
|
.skeleton-address-line {
|
||||||
|
width: 90%;
|
||||||
|
height: 26rpx;
|
||||||
|
background-color: #e6e6e6;
|
||||||
|
border-radius: 4rpx;
|
||||||
|
margin-bottom: 15rpx;
|
||||||
|
animation: shimmer 1.5s infinite;
|
||||||
|
}
|
||||||
|
|
||||||
|
.skeleton-btn {
|
||||||
|
height: 70rpx;
|
||||||
|
background-color: #e6e6e6;
|
||||||
|
border-radius: 35rpx;
|
||||||
|
margin: 20rpx 0;
|
||||||
|
animation: shimmer 1.5s infinite;
|
||||||
|
}
|
||||||
|
|
||||||
|
.skeleton-code {
|
||||||
|
width: 50%;
|
||||||
|
height: 26rpx;
|
||||||
|
background-color: #e6e6e6;
|
||||||
|
border-radius: 4rpx;
|
||||||
|
animation: shimmer 1.5s infinite;
|
||||||
|
}
|
||||||
|
|
||||||
|
.skeleton-remark {
|
||||||
|
width: 80%;
|
||||||
|
height: 26rpx;
|
||||||
|
background-color: #e6e6e6;
|
||||||
|
border-radius: 4rpx;
|
||||||
|
animation: shimmer 1.5s infinite;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 骨架屏底部按钮 */
|
||||||
|
.skeleton-bottom {
|
||||||
|
background-color: #fff;
|
||||||
|
width: 100vw;
|
||||||
|
position: fixed;
|
||||||
|
bottom: 0;
|
||||||
|
left: 0;
|
||||||
|
padding: 20rpx 30rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
.skeleton-bottom-btn {
|
||||||
|
width: 100%;
|
||||||
|
height: 90rpx;
|
||||||
|
background-color: #e6e6e6;
|
||||||
|
border-radius: 45rpx;
|
||||||
|
animation: shimmer 1.5s infinite;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 骨架屏动画 */
|
||||||
|
@keyframes shimmer {
|
||||||
|
0% {
|
||||||
|
opacity: 0.6;
|
||||||
|
}
|
||||||
|
|
||||||
|
50% {
|
||||||
|
opacity: 0.8;
|
||||||
|
}
|
||||||
|
|
||||||
|
100% {
|
||||||
|
opacity: 0.6;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 骨架屏滑动动画 */
|
||||||
|
@keyframes shimmer-slide {
|
||||||
|
0% {
|
||||||
|
transform: translateX(-100%);
|
||||||
|
}
|
||||||
|
|
||||||
|
100% {
|
||||||
|
transform: translateX(100%);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* end */
|
||||||
|
|
||||||
|
.order-detail {
|
||||||
|
min-height: 100vh;
|
||||||
|
background-color: #f5f5f5;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 订单状态样式 */
|
||||||
|
.order-status {
|
||||||
|
background-color: #fff;
|
||||||
|
padding: 30rpx;
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* 订单基本信息样式 */
|
||||||
|
.order-basic-info {
|
||||||
|
background-color: #fff;
|
||||||
|
margin: 20rpx 20rpx;
|
||||||
|
padding: 30rpx;
|
||||||
|
border-radius: 20rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
.info-item {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
margin-bottom: 20rpx;
|
||||||
|
font-size: 28rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
.info-item:last-child {
|
||||||
|
margin-bottom: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.label {
|
||||||
|
color: #666;
|
||||||
|
margin-right: 10rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
.value {
|
||||||
|
color: #333;
|
||||||
|
}
|
||||||
|
|
||||||
|
.value.highlight {
|
||||||
|
color: var(--nav-diluted);
|
||||||
|
font-weight: 500;
|
||||||
|
}
|
||||||
|
|
||||||
|
.value.price {
|
||||||
|
color: var(--nav-diluted);
|
||||||
|
font-weight: 700;
|
||||||
|
}
|
||||||
|
|
||||||
|
.clock-icon {
|
||||||
|
color: #666;
|
||||||
|
margin-right: 8rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 地图区域样式 */
|
||||||
|
.map-section {
|
||||||
|
margin: 20rpx;
|
||||||
|
border-radius: 20rpx;
|
||||||
|
overflow: hidden;
|
||||||
|
}
|
||||||
|
|
||||||
|
.map-placeholder {
|
||||||
|
width: 100%;
|
||||||
|
height: 400rpx;
|
||||||
|
background-color: #f0f0f0;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
position: relative;
|
||||||
|
border: 1rpx solid #e8e8e8;
|
||||||
|
}
|
||||||
|
|
||||||
|
.map-placeholder::before {
|
||||||
|
content: '';
|
||||||
|
position: absolute;
|
||||||
|
top: 0;
|
||||||
|
left: 0;
|
||||||
|
right: 0;
|
||||||
|
bottom: 0;
|
||||||
|
background: linear-gradient(135deg, #f5f5f5 25%, #e6e6e6 25%, #e6e6e6 50%, #f5f5f5 50%, #f5f5f5 75%, #e6e6e6 75%, #e6e6e6 100%);
|
||||||
|
background-size: 20rpx 20rpx;
|
||||||
|
opacity: 0.3;
|
||||||
|
}
|
||||||
|
|
||||||
|
.map-hint {
|
||||||
|
font-size: 28rpx;
|
||||||
|
color: #666;
|
||||||
|
position: relative;
|
||||||
|
z-index: 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 地址区域样式 */
|
||||||
|
.address-section {
|
||||||
|
background-color: #fff;
|
||||||
|
margin: 20rpx;
|
||||||
|
padding: 30rpx;
|
||||||
|
border-radius: 20rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
.section-title {
|
||||||
|
font-size: 30rpx;
|
||||||
|
font-weight: 800;
|
||||||
|
color: #333;
|
||||||
|
margin-bottom: 25rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
.address-content {
|
||||||
|
position: relative;
|
||||||
|
}
|
||||||
|
|
||||||
|
.store-name,
|
||||||
|
.user-name {
|
||||||
|
font-size: 34rpx;
|
||||||
|
font-weight: 600;
|
||||||
|
margin: 10rpx 0;
|
||||||
|
display: block;
|
||||||
|
}
|
||||||
|
|
||||||
|
.address {
|
||||||
|
font-size: 26rpx;
|
||||||
|
color: #666;
|
||||||
|
line-height: 1.5;
|
||||||
|
margin-bottom: 25rpx;
|
||||||
|
display: block;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
.pickup-code,
|
||||||
|
.remark {
|
||||||
|
font-size: 26rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
.code-label,
|
||||||
|
.code-value {
|
||||||
|
color: var(--nav-mian);
|
||||||
|
font-weight: 600;
|
||||||
|
}
|
||||||
|
|
||||||
|
.remark-label,
|
||||||
|
.remark-content {
|
||||||
|
color: #FAAD14;
|
||||||
|
font-weight: 600;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 底部按钮样式 */
|
||||||
|
.bottom-action {
|
||||||
|
background-color: #fff;
|
||||||
|
width: 100vw;
|
||||||
|
position: fixed;
|
||||||
|
bottom: 0;
|
||||||
|
left: 0;
|
||||||
|
padding: 20rpx 30rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
.confirm-btn {
|
||||||
|
width: 100%;
|
||||||
|
height: 90rpx;
|
||||||
|
font-size: 32rpx;
|
||||||
|
line-height: 90rpx;
|
||||||
|
border-radius: 45rpx;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
@@ -0,0 +1,506 @@
|
|||||||
|
<template>
|
||||||
|
|
||||||
|
<view class="skeleton-container" v-if="isLoading">
|
||||||
|
<!-- 顶部提示栏骨架 -->
|
||||||
|
<view class="skeleton-top-tip"></view>
|
||||||
|
|
||||||
|
<!-- 身份信息区域骨架 -->
|
||||||
|
<view class="skeleton-section">
|
||||||
|
<view class="skeleton-title"></view>
|
||||||
|
<view class="skeleton-form-item">
|
||||||
|
<view class="skeleton-label"></view>
|
||||||
|
<view class="skeleton-input"></view>
|
||||||
|
</view>
|
||||||
|
<view class="skeleton-form-item">
|
||||||
|
<view class="skeleton-label"></view>
|
||||||
|
<view class="skeleton-input"></view>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
|
||||||
|
<!-- 身份证照片区域骨架 -->
|
||||||
|
<view class="skeleton-section">
|
||||||
|
<view class="skeleton-title"></view>
|
||||||
|
<view class="skeleton-upload-item"></view>
|
||||||
|
<view class="skeleton-upload-item"></view>
|
||||||
|
</view>
|
||||||
|
|
||||||
|
|
||||||
|
<!-- 协议勾选骨架 -->
|
||||||
|
<view class="skeleton-agreement"></view>
|
||||||
|
|
||||||
|
<!-- 提交按钮骨架 -->
|
||||||
|
<view class="skeleton-submit"></view>
|
||||||
|
</view>
|
||||||
|
|
||||||
|
|
||||||
|
<view v-else class="real-name-auth-container">
|
||||||
|
<!-- 顶部提示栏 -->
|
||||||
|
<view class="top-tip">
|
||||||
|
<text class="tip-text">修改实名认证将重新审核,大约1~2工作日</text>
|
||||||
|
</view>
|
||||||
|
|
||||||
|
<!-- 表单内容 -->
|
||||||
|
<view class="form-content">
|
||||||
|
<!-- 身份信息区域 -->
|
||||||
|
<view class="section">
|
||||||
|
<view class="section-title">身份信息</view>
|
||||||
|
|
||||||
|
<!-- 姓名输入 -->
|
||||||
|
<view class="form-item">
|
||||||
|
<view class="label">姓名</view>
|
||||||
|
<u-input v-model="formData.nick" placeholder="请输入身份证姓名" placeholder-color="#999" border="none"
|
||||||
|
class="input" input-align="right" />
|
||||||
|
</view>
|
||||||
|
|
||||||
|
<!-- 身份证号输入 -->
|
||||||
|
<view class="form-item">
|
||||||
|
<view class="label">身份证号</view>
|
||||||
|
<u-input v-model="formData.idenNumber" placeholder="请输入18位身份证号" placeholder-color="#999" border="none"
|
||||||
|
class="input" input-align="right" maxlength="18" />
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
|
||||||
|
<!-- 身份证照片区域 -->
|
||||||
|
<view class="section">
|
||||||
|
<view class="section-title">身份证照片</view>
|
||||||
|
|
||||||
|
<!-- 上传身份证正面 -->
|
||||||
|
<view class="upload-item">
|
||||||
|
<view @click="uploadFImg(1)" class="upload-area bordered-area">
|
||||||
|
<view v-if="!formData.identityA" class="upload-content">
|
||||||
|
<view class="upload-icon">+</view>
|
||||||
|
<view class="upload-text">上传身份证正面</view>
|
||||||
|
</view>
|
||||||
|
<!-- 显示上传后的占位图 -->
|
||||||
|
<view v-else class="uploaded-placeholder">
|
||||||
|
<image :src="Service.GetMateUrlByImg(formData.identityA)" style="width: 100%; height: 100%;" mode=""></image>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
|
||||||
|
<!-- 上传身份证反面 -->
|
||||||
|
<view class="upload-item">
|
||||||
|
<view @click="uploadFImg(2)" class="upload-area bordered-area">
|
||||||
|
<view v-if="!formData.identityB" class="upload-content">
|
||||||
|
<view class="upload-icon">+</view>
|
||||||
|
<view class="upload-text">上传身份证反面</view>
|
||||||
|
</view>
|
||||||
|
<!-- 显示上传后的占位图 -->
|
||||||
|
<view v-else class="uploaded-placeholder">
|
||||||
|
<image :src="Service.GetMateUrlByImg(formData.identityB)" style="width: 100%; height: 100%;" mode=""></image>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
|
||||||
|
|
||||||
|
<!-- 协议勾选 -->
|
||||||
|
<view class="agreement-section">
|
||||||
|
<u-checkbox v-model="formData.agreed" shape="circle" class="checkbox" />
|
||||||
|
<text class="agreement-text">我已阅读并同意</text>
|
||||||
|
<text class="agreement-link" @click="handleAgreementClick">《骑手实名认证协议》</text>
|
||||||
|
</view>
|
||||||
|
|
||||||
|
<!-- 提交按钮 -->
|
||||||
|
<view class="submit-section">
|
||||||
|
<u-button @click="save()" type="primary" class="submit-btn" size="large">
|
||||||
|
提交认证
|
||||||
|
</u-button>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script setup lang="ts">
|
||||||
|
import { onLoad } from '@dcloudio/uni-app';
|
||||||
|
import { ref, computed } from 'vue';
|
||||||
|
import { CNRiderDataService , Service } from "@/Service/CN/CNRiderDataService"
|
||||||
|
|
||||||
|
let isLoading = ref(true)
|
||||||
|
|
||||||
|
// 表单数据
|
||||||
|
const formData = ref<any>({});
|
||||||
|
|
||||||
|
|
||||||
|
onLoad(() => {
|
||||||
|
getData()
|
||||||
|
})
|
||||||
|
|
||||||
|
const getData = () => {
|
||||||
|
CNRiderDataService.GetRiderInfo().then(res => {
|
||||||
|
isLoading.value = false
|
||||||
|
if(res.data){
|
||||||
|
formData.value=res.data.riderInfo
|
||||||
|
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
const uploadFImg = (index:number) => {
|
||||||
|
uni.chooseImage({
|
||||||
|
count: 1, // 最多选择3张图片
|
||||||
|
sizeType: ['original', 'compressed'], // 支持原图和压缩图
|
||||||
|
sourceType: ['album', 'camera'], // 可从相册选择或使用相机拍照
|
||||||
|
success: function (res) {
|
||||||
|
let path = res.tempFiles[0].path
|
||||||
|
Service.uploadH5(path, 'Avatar', data => {
|
||||||
|
if(index==1){
|
||||||
|
formData.value.identityA=data
|
||||||
|
}else{
|
||||||
|
formData.value.identityB=data
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
},
|
||||||
|
fail: function (err) {
|
||||||
|
console.error('选择失败:', err.errMsg);
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// 处理协议点击
|
||||||
|
const handleAgreementClick = () => {
|
||||||
|
// 打开协议详情
|
||||||
|
console.log('打开协议详情');
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
const save=()=>{
|
||||||
|
// if(!formData.value.agreed){
|
||||||
|
// Service.Msg('请同意骑手实名认证协议')
|
||||||
|
// return
|
||||||
|
// }
|
||||||
|
if(!formData.value.nick){
|
||||||
|
Service.Msg('请输入姓名')
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if(!formData.value.idenNumber){
|
||||||
|
Service.Msg('请输入身份证号')
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
CNRiderDataService.UpdateRiderIdentity(formData.value.nick,formData.value.idenNumber,formData.value.identityA,formData.value.identityB).then(res=>{
|
||||||
|
if(res.data){
|
||||||
|
Service.Msg('上传成功!')
|
||||||
|
}else{
|
||||||
|
Service.Msg(res.msg)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style scoped lang="scss">
|
||||||
|
page {
|
||||||
|
background-color: #f5f5f5;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 骨架屏样式 */
|
||||||
|
.skeleton-container {
|
||||||
|
padding: 0 30rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
.skeleton-top-tip {
|
||||||
|
height: 70rpx;
|
||||||
|
width: 100%;
|
||||||
|
background-color: #e6f7ff;
|
||||||
|
margin: 20rpx 0;
|
||||||
|
border-radius: 10rpx;
|
||||||
|
animation: skeleton-loading 1.5s infinite ease-in-out;
|
||||||
|
}
|
||||||
|
|
||||||
|
.skeleton-section {
|
||||||
|
margin-bottom: 40rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
.skeleton-title {
|
||||||
|
height: 32rpx;
|
||||||
|
width: 160rpx;
|
||||||
|
background-color: #e6e6e6;
|
||||||
|
border-radius: 16rpx;
|
||||||
|
margin-bottom: 20rpx;
|
||||||
|
animation: skeleton-loading 1.5s infinite ease-in-out;
|
||||||
|
}
|
||||||
|
|
||||||
|
.skeleton-form-item {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
background-color: #fff;
|
||||||
|
padding: 30rpx;
|
||||||
|
border-bottom: 1rpx solid #f0f0f0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.skeleton-form-item:last-child {
|
||||||
|
border-bottom: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
.skeleton-label {
|
||||||
|
height: 28rpx;
|
||||||
|
width: 120rpx;
|
||||||
|
background-color: #e6e6e6;
|
||||||
|
border-radius: 14rpx;
|
||||||
|
animation: skeleton-loading 1.5s infinite ease-in-out;
|
||||||
|
}
|
||||||
|
|
||||||
|
.skeleton-input {
|
||||||
|
height: 28rpx;
|
||||||
|
width: calc(100% - 140rpx);
|
||||||
|
background-color: #e6e6e6;
|
||||||
|
margin-left: 20rpx;
|
||||||
|
border-radius: 14rpx;
|
||||||
|
animation: skeleton-loading 1.5s infinite ease-in-out;
|
||||||
|
}
|
||||||
|
|
||||||
|
.skeleton-upload-item {
|
||||||
|
height: 200rpx;
|
||||||
|
width: 100%;
|
||||||
|
background-color: #fff;
|
||||||
|
border: 2rpx solid #000;
|
||||||
|
border-radius: 20rpx;
|
||||||
|
margin-bottom: 20rpx;
|
||||||
|
animation: skeleton-loading 1.5s infinite ease-in-out;
|
||||||
|
}
|
||||||
|
|
||||||
|
.skeleton-face-area {
|
||||||
|
height: 240rpx;
|
||||||
|
background-color: #fff;
|
||||||
|
border-radius: 8rpx;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.skeleton-face-icon {
|
||||||
|
width: 120rpx;
|
||||||
|
height: 120rpx;
|
||||||
|
border-radius: 50%;
|
||||||
|
background-color: #e6e6e6;
|
||||||
|
margin-bottom: 20rpx;
|
||||||
|
animation: skeleton-loading 1.5s infinite ease-in-out;
|
||||||
|
}
|
||||||
|
|
||||||
|
.skeleton-face-text {
|
||||||
|
height: 28rpx;
|
||||||
|
width: 200rpx;
|
||||||
|
background-color: #e6e6e6;
|
||||||
|
border-radius: 14rpx;
|
||||||
|
animation: skeleton-loading 1.5s infinite ease-in-out;
|
||||||
|
}
|
||||||
|
|
||||||
|
.skeleton-agreement {
|
||||||
|
height: 30rpx;
|
||||||
|
width: 60%;
|
||||||
|
background-color: #e6e6e6;
|
||||||
|
border-radius: 15rpx;
|
||||||
|
margin-bottom: 40rpx;
|
||||||
|
animation: skeleton-loading 1.5s infinite ease-in-out;
|
||||||
|
}
|
||||||
|
|
||||||
|
.skeleton-submit {
|
||||||
|
height: 92rpx;
|
||||||
|
width: 100%;
|
||||||
|
background-color: #e6e6e6;
|
||||||
|
border-radius: 46rpx;
|
||||||
|
animation: skeleton-loading 1.5s infinite ease-in-out;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 骨架屏动画 */
|
||||||
|
@keyframes skeleton-loading {
|
||||||
|
0% {
|
||||||
|
opacity: 0.6;
|
||||||
|
}
|
||||||
|
|
||||||
|
50% {
|
||||||
|
opacity: 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
100% {
|
||||||
|
opacity: 0.6;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.top-tip {
|
||||||
|
background-color: #E6F7FF;
|
||||||
|
padding: 20rpx 30rpx;
|
||||||
|
margin: 20rpx;
|
||||||
|
border-radius: 20rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
.tip-text {
|
||||||
|
color: #1890ff;
|
||||||
|
font-size: 28rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
.form-content {
|
||||||
|
padding: 0 30rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
.section {
|
||||||
|
margin-bottom: 40rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
.section-title {
|
||||||
|
font-size: 32rpx;
|
||||||
|
font-weight: bold;
|
||||||
|
color: #333;
|
||||||
|
margin-bottom: 20rpx;
|
||||||
|
padding-left: 10rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
.form-item {
|
||||||
|
background-color: #fff;
|
||||||
|
padding: 30rpx;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
border-bottom: 1rpx solid #f0f0f0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.form-item:last-child {
|
||||||
|
border-bottom: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
.label {
|
||||||
|
width: 120rpx;
|
||||||
|
font-size: 28rpx;
|
||||||
|
color: #333;
|
||||||
|
}
|
||||||
|
|
||||||
|
.input {
|
||||||
|
flex: 1;
|
||||||
|
font-size: 28rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
.upload-item {
|
||||||
|
margin-bottom: 20rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
.upload-area {
|
||||||
|
height: 350rpx;
|
||||||
|
border-radius: 8rpx;
|
||||||
|
overflow: hidden;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
justify-content: center;
|
||||||
|
align-items: center;
|
||||||
|
cursor: pointer;
|
||||||
|
position: relative;
|
||||||
|
}
|
||||||
|
|
||||||
|
.bordered-area {
|
||||||
|
background-color: #fff;
|
||||||
|
border-radius: 20rpx;
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.upload-content {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
justify-content: center;
|
||||||
|
align-items: center;
|
||||||
|
height: 100%;
|
||||||
|
z-index: 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
.upload-icon {
|
||||||
|
font-size: 60rpx;
|
||||||
|
color: #1890ff;
|
||||||
|
margin-bottom: 10rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
.upload-text {
|
||||||
|
font-size: 28rpx;
|
||||||
|
color: #1890ff;
|
||||||
|
}
|
||||||
|
|
||||||
|
.uploaded-placeholder {
|
||||||
|
position: absolute;
|
||||||
|
top: 0;
|
||||||
|
left: 0;
|
||||||
|
right: 0;
|
||||||
|
bottom: 0;
|
||||||
|
background-color: #fff;
|
||||||
|
display: flex;
|
||||||
|
justify-content: center;
|
||||||
|
align-items: center;
|
||||||
|
color: #333;
|
||||||
|
font-size: 28rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
.face-verify-area {
|
||||||
|
background-color: #fff;
|
||||||
|
height: 240rpx;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
justify-content: center;
|
||||||
|
align-items: center;
|
||||||
|
cursor: pointer;
|
||||||
|
border-radius: 8rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
.face-icon {
|
||||||
|
width: 120rpx;
|
||||||
|
height: 120rpx;
|
||||||
|
border-radius: 50%;
|
||||||
|
background-color: #e6f7ff;
|
||||||
|
display: flex;
|
||||||
|
justify-content: center;
|
||||||
|
align-items: center;
|
||||||
|
margin-bottom: 20rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
.face-text {
|
||||||
|
font-size: 28rpx;
|
||||||
|
color: #1890ff;
|
||||||
|
font-weight: 500;
|
||||||
|
}
|
||||||
|
|
||||||
|
.agreement-section {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
margin-bottom: 40rpx;
|
||||||
|
padding: 0 10rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
.checkbox {
|
||||||
|
margin-right: 10rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
.agreement-text {
|
||||||
|
font-size: 26rpx;
|
||||||
|
color: #666;
|
||||||
|
}
|
||||||
|
|
||||||
|
.agreement-link {
|
||||||
|
font-size: 26rpx;
|
||||||
|
color: #1890ff;
|
||||||
|
margin-left: 4rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
.input {
|
||||||
|
flex: 1;
|
||||||
|
font-size: 28rpx;
|
||||||
|
color: #333;
|
||||||
|
}
|
||||||
|
|
||||||
|
.submit-section {
|
||||||
|
margin-top: 60rpx;
|
||||||
|
padding: 0 0rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
.submit-btn {
|
||||||
|
height: 92rpx;
|
||||||
|
font-size: 32rpx;
|
||||||
|
border-radius: 46rpx;
|
||||||
|
background-color: #1890ff;
|
||||||
|
}
|
||||||
|
|
||||||
|
.submit-btn[disabled] {
|
||||||
|
background-color: #a0cfff;
|
||||||
|
color: #ffffff;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
@@ -0,0 +1,13 @@
|
|||||||
|
// import { createPinia, defineStore } from "pinia";
|
||||||
|
// import piniaPluginPersistedstate from "pinia-plugin-persistedstate";
|
||||||
|
// export class StoreAssist{
|
||||||
|
// private pinia:any=createPinia();
|
||||||
|
// constructor() {
|
||||||
|
// this.pinia.use(piniaPluginPersistedstate);
|
||||||
|
// }
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// }
|
||||||
|
|
||||||
|
|
||||||
@@ -0,0 +1,421 @@
|
|||||||
|
<template>
|
||||||
|
|
||||||
|
<view v-if="loading" class="">
|
||||||
|
<view class="tab-bar-skeleton">
|
||||||
|
<view class="skeleton-slot skeleton-tab-item"></view>
|
||||||
|
<view class="skeleton-slot skeleton-tab-item"></view>
|
||||||
|
</view>
|
||||||
|
<view class="skeleton-container">
|
||||||
|
<view class="skeleton-order-item" v-for="index in 3" :key="'skeleton-' + index">
|
||||||
|
<!-- 订单头部骨架 -->
|
||||||
|
<view class="skeleton-header">
|
||||||
|
<view class="skeleton-slot skeleton-order-number"></view>
|
||||||
|
<view class="skeleton-slot skeleton-status-badge"></view>
|
||||||
|
</view>
|
||||||
|
|
||||||
|
<!-- 异常类型骨架 -->
|
||||||
|
<view class="skeleton-slot skeleton-type"></view>
|
||||||
|
|
||||||
|
<!-- 异常描述骨架 -->
|
||||||
|
<view class="skeleton-slot skeleton-description"></view>
|
||||||
|
|
||||||
|
<!-- 底部信息骨架 -->
|
||||||
|
<view class="skeleton-footer">
|
||||||
|
<view class="skeleton-slot skeleton-time"></view>
|
||||||
|
<view class="skeleton-actions">
|
||||||
|
<view class="skeleton-slot skeleton-btn"></view>
|
||||||
|
<view class="skeleton-slot skeleton-btn"></view>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
<view class="" style="width: 100vw; display: flex; justify-content: center; " >
|
||||||
|
<view class="skeleton-slot " style="width: 160rpx; height: 30rpx; " ></view>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
|
||||||
|
|
||||||
|
<view v-else class="abnormal-orders-page">
|
||||||
|
<!-- 选项卡 -->
|
||||||
|
<view class="tab-bar">
|
||||||
|
<view class="tab-item" :class="{ active: activeTab === 'pending' }" @click="switchTab('pending')">
|
||||||
|
<text class="tab-text" :class="{ active: activeTab === 'pending' }">待处理</text>
|
||||||
|
</view>
|
||||||
|
<view class="tab-item" :class="{ active: activeTab === 'processed' }" @click="switchTab('processed')">
|
||||||
|
<text class="tab-text" :class="{ active: activeTab === 'processed' }">已处理</text>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
|
||||||
|
<!-- 订单列表 -->
|
||||||
|
<view class="order-list">
|
||||||
|
<view class="order-item" v-for="(orderItem,orederIndex) in 3" :key="orederIndex">
|
||||||
|
<!-- 订单头部 -->
|
||||||
|
<view class="order-header">
|
||||||
|
<text class="order-number">订单号: MT20251017123456</text>
|
||||||
|
<view class="order-status pending">
|
||||||
|
<text class="status-text">待处理</text>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
|
||||||
|
<!-- 订单内容 -->
|
||||||
|
<view class="">
|
||||||
|
<text class="abnormal-type">配送超时</text>
|
||||||
|
<text class="abnormal-description">订单配送时间超过预估时间25分钟</text>
|
||||||
|
<view class="" style="display: flex; align-items: center; justify-content: space-between;">
|
||||||
|
<text class="order-time">今天14:30</text>
|
||||||
|
<!-- 操作按钮 -->
|
||||||
|
<view class="order-actions">
|
||||||
|
<text @click="Service.GoPage('/pages/my/abnormalDetail')" class="action-btn detail-btn">查看详情</text>
|
||||||
|
<text @click="Service.GoPage('/pages/order/abnormal')" class="action-btn report-btn">
|
||||||
|
重新上报
|
||||||
|
</text>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
<up-loadmore :status="status" />
|
||||||
|
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script setup lang="ts">
|
||||||
|
import { onLoad } from '@dcloudio/uni-app';
|
||||||
|
import { ref, computed } from 'vue';
|
||||||
|
import { Service } from "@/Service/Service"
|
||||||
|
|
||||||
|
let loading = ref(true)
|
||||||
|
// 响应式数据
|
||||||
|
const activeTab = ref<'pending' | 'processed'>('pending');
|
||||||
|
|
||||||
|
let status=ref('nomore')
|
||||||
|
|
||||||
|
onLoad(() => {
|
||||||
|
setTimeout(()=>{
|
||||||
|
loading.value=false
|
||||||
|
},1000)
|
||||||
|
})
|
||||||
|
|
||||||
|
// 切换选项卡
|
||||||
|
const switchTab = (tab : 'pending' | 'processed') => {
|
||||||
|
activeTab.value = tab;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
// 重新上报
|
||||||
|
const reportAgain = (orderNo : string) => {
|
||||||
|
uni.showModal({
|
||||||
|
title: '重新上报',
|
||||||
|
content: '确定要重新上报此订单异常吗?',
|
||||||
|
success: (res) => {
|
||||||
|
if (res.confirm) {
|
||||||
|
// 模拟重新上报
|
||||||
|
uni.showToast({
|
||||||
|
title: '已提交重新上报申请',
|
||||||
|
icon: 'success'
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
};
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style scoped lang="scss">
|
||||||
|
/* 页面基础样式 */
|
||||||
|
.abnormal-orders-page {
|
||||||
|
min-height: 100vh;
|
||||||
|
background-color: #f5f5f5;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 顶部导航栏 */
|
||||||
|
.nav-bar {
|
||||||
|
height: 100rpx;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: space-between;
|
||||||
|
background-color: #fff;
|
||||||
|
padding: 0 30rpx;
|
||||||
|
box-shadow: 0 2rpx 10rpx rgba(0, 0, 0, 0.05);
|
||||||
|
position: sticky;
|
||||||
|
top: 0;
|
||||||
|
z-index: 100;
|
||||||
|
}
|
||||||
|
|
||||||
|
.nav-left,
|
||||||
|
.nav-right {
|
||||||
|
width: 60rpx;
|
||||||
|
display: flex;
|
||||||
|
justify-content: center;
|
||||||
|
align-items: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.nav-center {
|
||||||
|
flex: 1;
|
||||||
|
display: flex;
|
||||||
|
justify-content: center;
|
||||||
|
align-items: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.nav-title {
|
||||||
|
font-size: 34rpx;
|
||||||
|
color: #333;
|
||||||
|
font-weight: 500;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 选项卡 */
|
||||||
|
.tab-bar {
|
||||||
|
height: 88rpx;
|
||||||
|
display: flex;
|
||||||
|
background-color: #fff;
|
||||||
|
margin-bottom: 20rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
.tab-item {
|
||||||
|
flex: 1;
|
||||||
|
display: flex;
|
||||||
|
justify-content: center;
|
||||||
|
align-items: center;
|
||||||
|
position: relative;
|
||||||
|
}
|
||||||
|
|
||||||
|
.tab-item.active::after {
|
||||||
|
content: '';
|
||||||
|
position: absolute;
|
||||||
|
bottom: 0;
|
||||||
|
left: 50%;
|
||||||
|
transform: translateX(-50%);
|
||||||
|
width: 50rpx;
|
||||||
|
height: 6rpx;
|
||||||
|
background-color: #1890ff;
|
||||||
|
border-radius: 3rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
.tab-text {
|
||||||
|
font-size: 28rpx;
|
||||||
|
color: #666;
|
||||||
|
}
|
||||||
|
|
||||||
|
.tab-text.active {
|
||||||
|
color: #1890ff;
|
||||||
|
font-weight: 500;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 订单列表 */
|
||||||
|
.order-list {
|
||||||
|
padding: 0 20rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
.order-item {
|
||||||
|
background-color: #fff;
|
||||||
|
border-radius: 16rpx;
|
||||||
|
padding: 30rpx;
|
||||||
|
margin-bottom: 20rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 订单头部 */
|
||||||
|
.order-header {
|
||||||
|
display: flex;
|
||||||
|
justify-content: space-between;
|
||||||
|
align-items: center;
|
||||||
|
margin-bottom: 20rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
.order-number {
|
||||||
|
font-size: 28rpx;
|
||||||
|
color: #333;
|
||||||
|
font-weight: 500;
|
||||||
|
}
|
||||||
|
|
||||||
|
.order-status {
|
||||||
|
padding: 4rpx 16rpx;
|
||||||
|
border-radius: 20rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
.order-status.pending {
|
||||||
|
background-color: #fff2e8;
|
||||||
|
}
|
||||||
|
|
||||||
|
.order-status.processed {
|
||||||
|
background-color: #f6ffed;
|
||||||
|
}
|
||||||
|
|
||||||
|
.status-text {
|
||||||
|
font-size: 24rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
.order-status.pending .status-text {
|
||||||
|
color: #fa5151;
|
||||||
|
}
|
||||||
|
|
||||||
|
.order-status.processed .status-text {
|
||||||
|
color: #52c41a;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
.abnormal-type {
|
||||||
|
font-size: 28rpx;
|
||||||
|
color: #333;
|
||||||
|
font-weight: 500;
|
||||||
|
display: block;
|
||||||
|
margin-bottom: 12rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
.abnormal-description {
|
||||||
|
font-size: 26rpx;
|
||||||
|
color: #666;
|
||||||
|
display: block;
|
||||||
|
margin-bottom: 12rpx;
|
||||||
|
line-height: 1.5;
|
||||||
|
}
|
||||||
|
|
||||||
|
.order-time {
|
||||||
|
font-size: 24rpx;
|
||||||
|
color: #999;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 操作按钮 */
|
||||||
|
.order-actions {
|
||||||
|
display: flex;
|
||||||
|
justify-content: flex-end;
|
||||||
|
gap: 20rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
.action-btn {
|
||||||
|
font-size: 26rpx;
|
||||||
|
padding: 8rpx 20rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
.detail-btn {
|
||||||
|
color: #1890ff;
|
||||||
|
}
|
||||||
|
|
||||||
|
.report-btn {
|
||||||
|
color: #52c41a;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 空状态 */
|
||||||
|
.empty-state {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
padding: 100rpx 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.empty-icon {
|
||||||
|
margin-bottom: 30rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
.empty-text {
|
||||||
|
font-size: 28rpx;
|
||||||
|
color: #999;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 骨架屏样式 - 纯CSS实现 */
|
||||||
|
/* 选项卡骨架屏 */
|
||||||
|
.tab-bar-skeleton {
|
||||||
|
height: 88rpx;
|
||||||
|
display: flex;
|
||||||
|
background-color: #fff;
|
||||||
|
margin-bottom: 20rpx;
|
||||||
|
padding: 0 40rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
.skeleton-tab-item {
|
||||||
|
flex: 1;
|
||||||
|
height: 36rpx;
|
||||||
|
align-self: center;
|
||||||
|
margin: 0 20rpx;
|
||||||
|
border-radius: 18rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 订单列表骨架屏 */
|
||||||
|
.skeleton-container {
|
||||||
|
padding: 0 20rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 订单项骨架 */
|
||||||
|
.skeleton-order-item {
|
||||||
|
background-color: #ffffff;
|
||||||
|
border-radius: 16rpx;
|
||||||
|
padding: 30rpx;
|
||||||
|
margin-bottom: 20rpx;
|
||||||
|
overflow: hidden;
|
||||||
|
box-shadow: 0 2rpx 8rpx rgba(0, 0, 0, 0.05);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 订单头部布局 */
|
||||||
|
.skeleton-header {
|
||||||
|
display: flex;
|
||||||
|
justify-content: space-between;
|
||||||
|
align-items: center;
|
||||||
|
margin-bottom: 20rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 底部布局 */
|
||||||
|
.skeleton-footer {
|
||||||
|
display: flex;
|
||||||
|
justify-content: space-between;
|
||||||
|
align-items: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 操作按钮区域 */
|
||||||
|
.skeleton-actions {
|
||||||
|
display: flex;
|
||||||
|
gap: 20rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 通用骨架占位元素 */
|
||||||
|
.skeleton-slot {
|
||||||
|
background: linear-gradient(90deg, #f0f0f0 25%, #e0e0e0 50%, #f0f0f0 75%);
|
||||||
|
background-size: 200% 100%;
|
||||||
|
animation: skeleton-loading 1.5s infinite ease-in-out;
|
||||||
|
border-radius: 8rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 特定元素尺寸 */
|
||||||
|
.skeleton-order-number {
|
||||||
|
width: 60%;
|
||||||
|
height: 36rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
.skeleton-status-badge {
|
||||||
|
width: 120rpx;
|
||||||
|
height: 40rpx;
|
||||||
|
border-radius: 20rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
.skeleton-type {
|
||||||
|
width: 30%;
|
||||||
|
height: 36rpx;
|
||||||
|
margin-bottom: 16rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
.skeleton-description {
|
||||||
|
width: 100%;
|
||||||
|
height: 32rpx;
|
||||||
|
margin-bottom: 16rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
.skeleton-time {
|
||||||
|
width: 25%;
|
||||||
|
height: 30rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
.skeleton-btn {
|
||||||
|
width: 100rpx;
|
||||||
|
height: 30rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 骨架屏动画 */
|
||||||
|
@keyframes skeleton-loading {
|
||||||
|
0% {
|
||||||
|
background-position: 200% 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
100% {
|
||||||
|
background-position: -200% 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</style>
|
||||||
@@ -0,0 +1,261 @@
|
|||||||
|
{
|
||||||
|
"easycom": {
|
||||||
|
// 注意一定要放在custom里,否则无效,https://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"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"pages": [ //pages数组中第一项表示应用启动页,参考:https://uniapp.dcloud.io/collocation/pages
|
||||||
|
|
||||||
|
{
|
||||||
|
|
||||||
|
"path": "pages/index/index",
|
||||||
|
"style": {
|
||||||
|
"navigationBarTitleText": "门店运营",
|
||||||
|
"navigationBarBackgroundColor": "#36394D",
|
||||||
|
"navigationStyle": "custom",
|
||||||
|
"backgroundColor": "#F8F8F8"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"path": "pages/index/task",
|
||||||
|
"style": {
|
||||||
|
"navigationBarTitleText": "任务",
|
||||||
|
"navigationBarBackgroundColor": "#36394D",
|
||||||
|
"navigationStyle": "custom",
|
||||||
|
"backgroundColor": "#F8F8F8"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"path": "pages/index/income",
|
||||||
|
"style": {
|
||||||
|
"navigationBarTitleText": "我的收入",
|
||||||
|
"navigationBarBackgroundColor": "#36394D",
|
||||||
|
"navigationStyle": "custom",
|
||||||
|
"backgroundColor": "#F8F8F8"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"path": "pages/index/user",
|
||||||
|
"style": {
|
||||||
|
"navigationBarTitleText": "我的",
|
||||||
|
"navigationBarBackgroundColor": "#36394D",
|
||||||
|
"navigationStyle": "custom",
|
||||||
|
"backgroundColor": "#F8F8F8"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"globalStyle": {
|
||||||
|
"navigationBarTextStyle": "black",
|
||||||
|
"navigationBarTitleText": "v派商家",
|
||||||
|
"navigationBarBackgroundColor": "#fff",
|
||||||
|
"backgroundColor": "#000"
|
||||||
|
},
|
||||||
|
"subPackages": [
|
||||||
|
{
|
||||||
|
"root": "pages/order",
|
||||||
|
"pages": [
|
||||||
|
{
|
||||||
|
"path": "orderDetail",
|
||||||
|
"style": {
|
||||||
|
"navigationBarTitleText": "项目中心",
|
||||||
|
"navigationStyle": "custom"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"path" : "navigation",
|
||||||
|
"style" :
|
||||||
|
{
|
||||||
|
"navigationBarTitleText" : "导航",
|
||||||
|
"navigationStyle": "custom"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"path" : "abnormal",
|
||||||
|
"style" :
|
||||||
|
{
|
||||||
|
"navigationBarTitleText" : "上报异常",
|
||||||
|
"navigationStyle": "custom"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"path" : "grabOrder",
|
||||||
|
"style" :
|
||||||
|
{
|
||||||
|
"navigationBarTitleText" : "订单详情"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"path" : "incomeDetail",
|
||||||
|
"style" :
|
||||||
|
{
|
||||||
|
"navigationBarTitleText" : "收入详情",
|
||||||
|
"navigationStyle": "custom"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"path" : "withdraw",
|
||||||
|
"style" :
|
||||||
|
{
|
||||||
|
"navigationBarTitleText" : "提现申请"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"path" : "finish",
|
||||||
|
"style" :
|
||||||
|
{
|
||||||
|
"navigationBarTitleText" : "订单完成"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"path" : "upAbnormal",
|
||||||
|
"style" :
|
||||||
|
{
|
||||||
|
"navigationBarTitleText" : "异常上报"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"path": "orderMap",
|
||||||
|
"style": {
|
||||||
|
"navigationBarTitleText": "订单地图"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"root": "pages/my",
|
||||||
|
"pages": [{
|
||||||
|
"path" : "edit",
|
||||||
|
"style" :
|
||||||
|
{
|
||||||
|
"navigationBarTitleText" : "编辑资料"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"path" : "statusContro",
|
||||||
|
"style" :
|
||||||
|
{
|
||||||
|
"navigationBarTitleText" : "上线管理"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"path" : "myKF",
|
||||||
|
"style" :
|
||||||
|
{
|
||||||
|
"navigationBarTitleText" : "联系客服",
|
||||||
|
"navigationStyle": "custom"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"path" : "AbnormalList",
|
||||||
|
"style" :
|
||||||
|
{
|
||||||
|
"navigationBarTitleText" : "异常订单"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"path" : "check",
|
||||||
|
"style" :
|
||||||
|
{
|
||||||
|
"navigationBarTitleText" : "签到奖励"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"path" : "abnormalDetail",
|
||||||
|
"style" :
|
||||||
|
{
|
||||||
|
"navigationBarTitleText" : "异常详情"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"path" : "security",
|
||||||
|
"style" :
|
||||||
|
{
|
||||||
|
"navigationBarTitleText" : "账号与安全"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"path" : "authentication",
|
||||||
|
"style" :
|
||||||
|
{
|
||||||
|
"navigationBarTitleText" : "实名认证"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"path" : "login",
|
||||||
|
"style" :
|
||||||
|
{
|
||||||
|
"navigationBarTitleText" : "登录",
|
||||||
|
"navigationStyle": "custom"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"path" : "noticeList",
|
||||||
|
"style" :
|
||||||
|
{
|
||||||
|
"navigationBarTitleText" : "消息通知",
|
||||||
|
"navigationStyle": "custom"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"path" : "setConnect",
|
||||||
|
"style" :
|
||||||
|
{
|
||||||
|
"navigationBarTitleText" : "紧急联系人"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"path" : "evaluate",
|
||||||
|
"style" :
|
||||||
|
{
|
||||||
|
"navigationBarTitleText" : "评价中心"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"path" : "completeData",
|
||||||
|
"style" :
|
||||||
|
{
|
||||||
|
"navigationBarTitleText" : "完善信息"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"path" : "withDrowList",
|
||||||
|
"style" :
|
||||||
|
{
|
||||||
|
"navigationBarTitleText" : "提现列表"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
]
|
||||||
|
}
|
||||||
|
],
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
"tabBar": {
|
||||||
|
"color": "#000",
|
||||||
|
"selectedColor": "#000",
|
||||||
|
"backgroundColor": "#FFFFFF",
|
||||||
|
"list": [{
|
||||||
|
"pagePath": "pages/index/index",
|
||||||
|
"iconPath": "static/tab/home.png",
|
||||||
|
"selectedIconPath": "/static/tab/homed.png",
|
||||||
|
"text": "主页"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"pagePath": "pages/index/income",
|
||||||
|
"iconPath": "static/tab/income.png",
|
||||||
|
"selectedIconPath": "static/tab/incomed.png",
|
||||||
|
"text": "收入"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"pagePath": "pages/index/user",
|
||||||
|
"iconPath": "static/tab/user.png",
|
||||||
|
"selectedIconPath": "static/tab/usered.png",
|
||||||
|
"text": "我的"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,19 @@
|
|||||||
|
export class UploadAssist {
|
||||||
|
static Upload(url: string, path: string, fromData: any) {
|
||||||
|
return new Promise(function(resolve, reject) {
|
||||||
|
uni.uploadFile({
|
||||||
|
url: url, //仅为示例,非真实的接口地址
|
||||||
|
filePath: path,
|
||||||
|
name: 'file',
|
||||||
|
formData: fromData,
|
||||||
|
success: (uploadFileRes) => {
|
||||||
|
resolve(uploadFileRes);
|
||||||
|
},
|
||||||
|
fail: (err) => {
|
||||||
|
reject(err);
|
||||||
|
|
||||||
|
},
|
||||||
|
});
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,22 @@
|
|||||||
|
import { Service } from '@/Service/Service';
|
||||||
|
/*****腾讯云存储*****/
|
||||||
|
class NvpTencentCosService {
|
||||||
|
private static GetAuthorizationPath: string = '/TencentCos/GetAuthorization';
|
||||||
|
/*****获取云存储配置*****/
|
||||||
|
static GetAuthorization() {
|
||||||
|
var result = Service.Request(this.GetAuthorizationPath, "GET", "");
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static GetUpLoadInfoPath: string = '/TencentCos/GetUpLoadInfo';
|
||||||
|
/*****获取上传地址*****/
|
||||||
|
static GetUpLoadInfo(code: string, fileName: string, desire: string) {
|
||||||
|
var result = Service.Request(this.GetUpLoadInfoPath, "GET", { code, fileName, desire });
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
export {
|
||||||
|
Service,
|
||||||
|
NvpTencentCosService
|
||||||
|
}
|
||||||
@@ -0,0 +1,63 @@
|
|||||||
|
import {Service} from "@/Service/Service"
|
||||||
|
export class EventHandler {
|
||||||
|
//处理事件
|
||||||
|
static Events(data: any) {
|
||||||
|
var result = JSON.parse(data.data);
|
||||||
|
if (result.code == 'msg') {
|
||||||
|
this.ChatEnent(result);
|
||||||
|
} else if (result.code == 'order') {
|
||||||
|
uni.$emit('newOrder', data);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static ChatEnent(data: any) {
|
||||||
|
console.log(data,'xxx')
|
||||||
|
var eventName = `chat_${data.chanId}`;
|
||||||
|
uni.$emit(eventName, data);
|
||||||
|
}
|
||||||
|
|
||||||
|
static ChatUserEnent(data: any) {
|
||||||
|
var eventUserName = `chatUser_${data.sendId}`;
|
||||||
|
uni.$emit('UpdatePrivateMsg', data);
|
||||||
|
uni.$emit(eventUserName, data);
|
||||||
|
this.plusPush();
|
||||||
|
}
|
||||||
|
|
||||||
|
static plusPush() {
|
||||||
|
//#ifdef APP-PLUS
|
||||||
|
if(!Service.getIsHede()){
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
let content = '您有一条新的消息~';
|
||||||
|
let options = {
|
||||||
|
cover: false,
|
||||||
|
when: new Date(),
|
||||||
|
title: '通知消息'
|
||||||
|
};
|
||||||
|
let body = {
|
||||||
|
id: 'id',
|
||||||
|
key: 'key'
|
||||||
|
};
|
||||||
|
let payload = JSON.stringify(body);
|
||||||
|
plus.push.createMessage(content, payload, options);
|
||||||
|
//#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
static SystemEnent(data: any) {
|
||||||
|
let obj = JSON.parse(data.data);
|
||||||
|
if (obj.code == 'Like' || obj.code == 'Aite' || obj.code == 'Comment' || obj.code == 'Notice') {
|
||||||
|
uni.$emit('MegEvent', obj);
|
||||||
|
} else if (obj.code == 'Off') {
|
||||||
|
uni.$emit('ImComOff', 'user');
|
||||||
|
} else if (obj.code == 'UpdateUserInfo') {
|
||||||
|
uni.$emit('UpdateUserInfo');
|
||||||
|
} else if (obj.code == 'Friend') {
|
||||||
|
uni.$emit('Friend');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static ConnectBus() {
|
||||||
|
uni.$emit('UpdateChat');
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,75 @@
|
|||||||
|
<script setup lang="ts">
|
||||||
|
import { onLaunch, onShow, onHide, onError } from '@dcloudio/uni-app'
|
||||||
|
import { ref, onUnmounted } from 'vue'
|
||||||
|
|
||||||
|
// 全局定时器引用
|
||||||
|
let globalTimer = null
|
||||||
|
|
||||||
|
// 每分钟要执行的方法
|
||||||
|
const minuteTask = () => {
|
||||||
|
console.log('每分钟执行一次的任务', new Date().toLocaleTimeString())
|
||||||
|
}
|
||||||
|
|
||||||
|
// 启动全局定时器
|
||||||
|
const startGlobalTimer = () => {
|
||||||
|
if (globalTimer) {
|
||||||
|
clearInterval(globalTimer)
|
||||||
|
}
|
||||||
|
|
||||||
|
// 立即执行一次
|
||||||
|
minuteTask()
|
||||||
|
|
||||||
|
// 设置每分钟执行一次(60000毫秒 = 1分钟)
|
||||||
|
globalTimer = setInterval(() => {
|
||||||
|
minuteTask()
|
||||||
|
}, 60000)
|
||||||
|
}
|
||||||
|
|
||||||
|
// 停止全局定时器
|
||||||
|
const stopGlobalTimer = () => {
|
||||||
|
if (globalTimer) {
|
||||||
|
clearInterval(globalTimer)
|
||||||
|
globalTimer = null
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
onLaunch(() => {
|
||||||
|
console.log('App Launch')
|
||||||
|
// 应用启动时开始定时器
|
||||||
|
startGlobalTimer()
|
||||||
|
})
|
||||||
|
|
||||||
|
onShow(() => {
|
||||||
|
console.log('App Show')
|
||||||
|
// 应用回到前台时重新开始定时器
|
||||||
|
startGlobalTimer()
|
||||||
|
})
|
||||||
|
|
||||||
|
onHide(() => {
|
||||||
|
console.log('App Hide')
|
||||||
|
// 应用进入后台时停止定时器,节省资源
|
||||||
|
stopGlobalTimer()
|
||||||
|
})
|
||||||
|
|
||||||
|
// Vue组件卸载时清理定时器
|
||||||
|
onUnmounted(() => {
|
||||||
|
stopGlobalTimer()
|
||||||
|
})
|
||||||
|
|
||||||
|
// 全局错误处理
|
||||||
|
onError((err) => {
|
||||||
|
console.error('App Error:', err)
|
||||||
|
})
|
||||||
|
</script>
|
||||||
|
<style lang="scss">
|
||||||
|
@import "uview-plus/index.scss";
|
||||||
|
@import "colorui/main.css";
|
||||||
|
@import "colorui/icon.css";
|
||||||
|
|
||||||
|
page {
|
||||||
|
--nav-mian: #1890FF; //全局颜色
|
||||||
|
--nav-vice: #52C41A; //副颜色
|
||||||
|
--nav-diluted: #FF4D4F; //次颜色
|
||||||
|
|
||||||
|
}
|
||||||
|
</style>
|
||||||
@@ -0,0 +1,511 @@
|
|||||||
|
<template>
|
||||||
|
<!-- 骨架屏 -->
|
||||||
|
<view v-if="loading" class="skeleton-container">
|
||||||
|
<!-- 余额区域骨架屏 -->
|
||||||
|
<view class="skeleton-balance-section">
|
||||||
|
<div class="skeleton-balance-label"></div>
|
||||||
|
<div class="skeleton-balance-amount"></div>
|
||||||
|
<div class="skeleton-balance-current"></div>
|
||||||
|
</view>
|
||||||
|
|
||||||
|
<!-- 账户选择区域骨架屏 -->
|
||||||
|
<view class="skeleton-account-section">
|
||||||
|
<div class="skeleton-section-title"></div>
|
||||||
|
<div class="skeleton-account-item">
|
||||||
|
<div class="skeleton-account-icon"></div>
|
||||||
|
<div class="skeleton-account-name"></div>
|
||||||
|
<div class="skeleton-account-radio"></div>
|
||||||
|
</div>
|
||||||
|
<div class="skeleton-account-item">
|
||||||
|
<div class="skeleton-account-icon"></div>
|
||||||
|
<div class="skeleton-account-name"></div>
|
||||||
|
<div class="skeleton-account-radio"></div>
|
||||||
|
</div>
|
||||||
|
</view>
|
||||||
|
|
||||||
|
<!-- 提示信息骨架屏 -->
|
||||||
|
<view class="skeleton-tip-section">
|
||||||
|
<div class="skeleton-tip-icon"></div>
|
||||||
|
<div class="skeleton-tip-content">
|
||||||
|
<div class="skeleton-tip-line"></div>
|
||||||
|
<div class="skeleton-tip-line-small"></div>
|
||||||
|
</div>
|
||||||
|
</view>
|
||||||
|
|
||||||
|
<!-- 确认按钮骨架屏 -->
|
||||||
|
<view class="skeleton-confirm-section">
|
||||||
|
<div class="skeleton-confirm-button"></div>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
<!-- 真实内容 -->
|
||||||
|
<view v-else class="withdraw-container">
|
||||||
|
<!-- 可提现金额 -->
|
||||||
|
<view class="balance-section">
|
||||||
|
<text class="balance-label">可提现金额</text>
|
||||||
|
<text class="balance-amount">¥86.50</text>
|
||||||
|
<text class="current-balance">当前钱包余额</text>
|
||||||
|
</view>
|
||||||
|
|
||||||
|
<!-- 提现账户选择 -->
|
||||||
|
<view class="account-section">
|
||||||
|
<text class="section-title">提现账户</text>
|
||||||
|
<view class=""
|
||||||
|
style="display: flex;align-items: center; border-bottom: 4rpx solid #e2e2e2;padding-bottom: 10px; margin-bottom: 10px;">
|
||||||
|
<up-icon name="zhifubao-circle-fill" size="30" color="#1890ff"></up-icon>
|
||||||
|
<view style="flex: 1; margin-left: 30rpx; " class="">
|
||||||
|
支付宝
|
||||||
|
</view>
|
||||||
|
<view @click="changePay(0)" class="">
|
||||||
|
<view v-if="current==0" class="radio-circle">
|
||||||
|
<view class="radio-inner"></view>
|
||||||
|
</view>
|
||||||
|
<view v-else class="radio-no-circle">
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
<view class="" style="display: flex;align-items: center;">
|
||||||
|
<up-icon name="weixin-circle-fill" size="30" color="#28C445"></up-icon>
|
||||||
|
<view style="flex: 1; margin-left: 30rpx; " class="">
|
||||||
|
微信
|
||||||
|
</view>
|
||||||
|
<view @click="changePay(1)" class="">
|
||||||
|
<view v-if="current==1" class="radio-circle">
|
||||||
|
<view class="radio-inner"></view>
|
||||||
|
</view>
|
||||||
|
<view v-else class="radio-no-circle">
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
|
||||||
|
<!-- 提示信息 -->
|
||||||
|
<view class="tip-section">
|
||||||
|
<up-icon name="clock" size="18" color="#1890ff"></up-icon>
|
||||||
|
<view class="" style="margin-left: 10rpx;">
|
||||||
|
<view class="tip-text">预计 T+1 工作日到账</view>
|
||||||
|
<view class="tip-text" style="color: #666666; font-size: 24rpx; margin-top: 10rpx; ">无手续费</view>
|
||||||
|
</view>
|
||||||
|
|
||||||
|
</view>
|
||||||
|
|
||||||
|
<!-- 确认按钮 -->
|
||||||
|
<view class="confirm-section">
|
||||||
|
<button class="confirm-button" @click="confirmWithdraw">确认提现 ¥86.50</button>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script setup lang="ts">
|
||||||
|
import { onLoad } from '@dcloudio/uni-app';
|
||||||
|
import { ref } from 'vue';
|
||||||
|
|
||||||
|
let current = ref(null)
|
||||||
|
let loading=ref(true)
|
||||||
|
|
||||||
|
onLoad(() => {
|
||||||
|
setTimeout(()=>{
|
||||||
|
loading.value=false
|
||||||
|
},1000)
|
||||||
|
})
|
||||||
|
|
||||||
|
const changePay = (item : any) => {
|
||||||
|
current.value = item
|
||||||
|
}
|
||||||
|
|
||||||
|
// 确认提现
|
||||||
|
const confirmWithdraw = () => {
|
||||||
|
// 这里可以添加提现逻辑
|
||||||
|
uni.showToast({
|
||||||
|
title: '提现申请已提交',
|
||||||
|
icon: 'success'
|
||||||
|
});
|
||||||
|
};
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style scoped>
|
||||||
|
.withdraw-container {
|
||||||
|
min-height: 100vh;
|
||||||
|
background-color: #fff;
|
||||||
|
padding-bottom: 40rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 选择 */
|
||||||
|
|
||||||
|
.radio-circle {
|
||||||
|
width: 36rpx;
|
||||||
|
height: 36rpx;
|
||||||
|
border: 2rpx solid var(--nav-mian);
|
||||||
|
border-radius: 50%;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
margin-right: 20rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
.radio-inner {
|
||||||
|
width: 20rpx;
|
||||||
|
height: 20rpx;
|
||||||
|
background-color: var(--nav-mian);
|
||||||
|
border-radius: 50%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.radio-no-circle {
|
||||||
|
width: 36rpx;
|
||||||
|
height: 36rpx;
|
||||||
|
border: 2rpx solid #dadada;
|
||||||
|
border-radius: 50%;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
margin-right: 20rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/* 顶部导航栏 */
|
||||||
|
.nav-bar {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: space-between;
|
||||||
|
padding: 30rpx 20rpx;
|
||||||
|
background-color: #fff;
|
||||||
|
position: sticky;
|
||||||
|
top: 0;
|
||||||
|
z-index: 100;
|
||||||
|
box-shadow: 0 2rpx 10rpx rgba(0, 0, 0, 0.05);
|
||||||
|
}
|
||||||
|
|
||||||
|
.nav-title {
|
||||||
|
font-size: 36rpx;
|
||||||
|
font-weight: 600;
|
||||||
|
color: #000;
|
||||||
|
}
|
||||||
|
|
||||||
|
.back-icon {
|
||||||
|
width: 40rpx;
|
||||||
|
height: 40rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
.help-icon {
|
||||||
|
width: 40rpx;
|
||||||
|
height: 40rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 余额显示区域 */
|
||||||
|
.balance-section {
|
||||||
|
background-color: #fff;
|
||||||
|
padding: 40rpx 30rpx;
|
||||||
|
margin-bottom: 20rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
.balance-label {
|
||||||
|
font-size: 32rpx;
|
||||||
|
color: #333;
|
||||||
|
display: block;
|
||||||
|
margin-bottom: 10rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
.balance-amount {
|
||||||
|
font-size: 60rpx;
|
||||||
|
font-weight: bold;
|
||||||
|
color: #ff4757;
|
||||||
|
display: block;
|
||||||
|
margin-bottom: 10rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
.current-balance {
|
||||||
|
font-size: 28rpx;
|
||||||
|
color: #999;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 账户选择区域 */
|
||||||
|
.account-section {
|
||||||
|
background-color: #fff;
|
||||||
|
padding: 30rpx;
|
||||||
|
margin-bottom: 20rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
.section-title {
|
||||||
|
font-size: 32rpx;
|
||||||
|
font-weight: 600;
|
||||||
|
color: #333;
|
||||||
|
display: block;
|
||||||
|
margin-bottom: 20rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
.account-item {
|
||||||
|
display: flex;
|
||||||
|
justify-content: space-between;
|
||||||
|
align-items: center;
|
||||||
|
padding: 25rpx 0;
|
||||||
|
border-bottom: 1rpx solid #f0f0f0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.account-item:last-child {
|
||||||
|
border-bottom: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
.account-info {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.account-icon {
|
||||||
|
width: 60rpx;
|
||||||
|
height: 60rpx;
|
||||||
|
border-radius: 12rpx;
|
||||||
|
background-color: #1677ff;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
margin-right: 20rpx;
|
||||||
|
border: 2rpx solid #000;
|
||||||
|
}
|
||||||
|
|
||||||
|
.account-icon.wechat {
|
||||||
|
background-color: #07c160;
|
||||||
|
}
|
||||||
|
|
||||||
|
.icon-text {
|
||||||
|
color: #fff;
|
||||||
|
font-size: 32rpx;
|
||||||
|
font-weight: bold;
|
||||||
|
}
|
||||||
|
|
||||||
|
.account-name {
|
||||||
|
font-size: 32rpx;
|
||||||
|
color: #333;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 提示信息区域 */
|
||||||
|
.tip-section {
|
||||||
|
display: flex;
|
||||||
|
align-items: flex-start;
|
||||||
|
background-color: #e6f7ff;
|
||||||
|
padding: 20rpx 30rpx;
|
||||||
|
margin: 0 30rpx 20rpx;
|
||||||
|
border-radius: 10rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
.tip-text {
|
||||||
|
font-size: 28rpx;
|
||||||
|
margin-left: 10rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 确认按钮区域 */
|
||||||
|
.confirm-section {
|
||||||
|
background-color: #fff;
|
||||||
|
position: fixed;
|
||||||
|
width: 100vw;
|
||||||
|
left: 0;
|
||||||
|
bottom: 0;
|
||||||
|
padding: 30rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
.confirm-button {
|
||||||
|
width: 100%;
|
||||||
|
height: 90rpx;
|
||||||
|
background-color: #1677ff;
|
||||||
|
color: #fff;
|
||||||
|
font-size: 36rpx;
|
||||||
|
font-weight: 600;
|
||||||
|
border-radius: 45rpx;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
border: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
.confirm-button:active {
|
||||||
|
background-color: #0958d9;
|
||||||
|
}
|
||||||
|
/* 骨架屏样式 */
|
||||||
|
.skeleton-container {
|
||||||
|
min-height: 100vh;
|
||||||
|
background-color: #fff;
|
||||||
|
padding-bottom: 40rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 骨架屏动画 */
|
||||||
|
@keyframes shimmer {
|
||||||
|
0% {
|
||||||
|
background-position: -1000px 0;
|
||||||
|
}
|
||||||
|
100% {
|
||||||
|
background-position: 1000px 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 骨架屏通用样式 */
|
||||||
|
.skeleton-balance-section,
|
||||||
|
.skeleton-account-section,
|
||||||
|
.skeleton-tip-section {
|
||||||
|
padding: 40rpx 30rpx;
|
||||||
|
margin-bottom: 20rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 余额区域骨架屏 */
|
||||||
|
.skeleton-balance-section {
|
||||||
|
background-color: #fff;
|
||||||
|
}
|
||||||
|
|
||||||
|
.skeleton-balance-label {
|
||||||
|
width: 30%;
|
||||||
|
height: 32rpx;
|
||||||
|
background-color: #e6e6e6;
|
||||||
|
margin-bottom: 20rpx;
|
||||||
|
border-radius: 4rpx;
|
||||||
|
animation: shimmer 1.5s infinite;
|
||||||
|
background-image: linear-gradient(90deg, #f0f0f0 25%, #e0e0e0 50%, #f0f0f0 75%);
|
||||||
|
background-size: 1000px 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.skeleton-balance-amount {
|
||||||
|
width: 40%;
|
||||||
|
height: 60rpx;
|
||||||
|
background-color: #e6e6e6;
|
||||||
|
margin-bottom: 20rpx;
|
||||||
|
border-radius: 4rpx;
|
||||||
|
animation: shimmer 1.5s infinite;
|
||||||
|
background-image: linear-gradient(90deg, #f0f0f0 25%, #e0e0e0 50%, #f0f0f0 75%);
|
||||||
|
background-size: 1000px 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.skeleton-balance-current {
|
||||||
|
width: 25%;
|
||||||
|
height: 28rpx;
|
||||||
|
background-color: #e6e6e6;
|
||||||
|
border-radius: 4rpx;
|
||||||
|
animation: shimmer 1.5s infinite;
|
||||||
|
background-image: linear-gradient(90deg, #f0f0f0 25%, #e0e0e0 50%, #f0f0f0 75%);
|
||||||
|
background-size: 1000px 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 账户选择区域骨架屏 */
|
||||||
|
.skeleton-account-section {
|
||||||
|
background-color: #fff;
|
||||||
|
}
|
||||||
|
|
||||||
|
.skeleton-section-title {
|
||||||
|
width: 25%;
|
||||||
|
height: 32rpx;
|
||||||
|
background-color: #e6e6e6;
|
||||||
|
margin-bottom: 30rpx;
|
||||||
|
border-radius: 4rpx;
|
||||||
|
animation: shimmer 1.5s infinite;
|
||||||
|
background-image: linear-gradient(90deg, #f0f0f0 25%, #e0e0e0 50%, #f0f0f0 75%);
|
||||||
|
background-size: 1000px 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.skeleton-account-item {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
margin-bottom: 30rpx;
|
||||||
|
padding-bottom: 30rpx;
|
||||||
|
border-bottom: 4rpx solid #e2e2e2;
|
||||||
|
}
|
||||||
|
|
||||||
|
.skeleton-account-item:last-child {
|
||||||
|
border-bottom: none;
|
||||||
|
padding-bottom: 0;
|
||||||
|
margin-bottom: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.skeleton-account-icon {
|
||||||
|
width: 60rpx;
|
||||||
|
height: 60rpx;
|
||||||
|
background-color: #e6e6e6;
|
||||||
|
border-radius: 12rpx;
|
||||||
|
margin-right: 20rpx;
|
||||||
|
animation: shimmer 1.5s infinite;
|
||||||
|
background-image: linear-gradient(90deg, #f0f0f0 25%, #e0e0e0 50%, #f0f0f0 75%);
|
||||||
|
background-size: 1000px 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.skeleton-account-name {
|
||||||
|
flex: 1;
|
||||||
|
height: 32rpx;
|
||||||
|
background-color: #e6e6e6;
|
||||||
|
border-radius: 4rpx;
|
||||||
|
margin-right: 20rpx;
|
||||||
|
animation: shimmer 1.5s infinite;
|
||||||
|
background-image: linear-gradient(90deg, #f0f0f0 25%, #e0e0e0 50%, #f0f0f0 75%);
|
||||||
|
background-size: 1000px 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.skeleton-account-radio {
|
||||||
|
width: 36rpx;
|
||||||
|
height: 36rpx;
|
||||||
|
background-color: #e6e6e6;
|
||||||
|
border-radius: 50%;
|
||||||
|
animation: shimmer 1.5s infinite;
|
||||||
|
background-image: linear-gradient(90deg, #f0f0f0 25%, #e0e0e0 50%, #f0f0f0 75%);
|
||||||
|
background-size: 1000px 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 提示信息骨架屏 */
|
||||||
|
.skeleton-tip-section {
|
||||||
|
display: flex;
|
||||||
|
align-items: flex-start;
|
||||||
|
background-color: #e6f7ff;
|
||||||
|
padding: 20rpx 30rpx;
|
||||||
|
margin: 0 30rpx 20rpx;
|
||||||
|
border-radius: 10rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
.skeleton-tip-icon {
|
||||||
|
width: 40rpx;
|
||||||
|
height: 40rpx;
|
||||||
|
background-color: #e6e6e6;
|
||||||
|
border-radius: 50%;
|
||||||
|
margin-right: 15rpx;
|
||||||
|
animation: shimmer 1.5s infinite;
|
||||||
|
background-image: linear-gradient(90deg, #f0f0f0 25%, #e0e0e0 50%, #f0f0f0 75%);
|
||||||
|
background-size: 1000px 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.skeleton-tip-content {
|
||||||
|
flex: 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
.skeleton-tip-line {
|
||||||
|
width: 70%;
|
||||||
|
height: 28rpx;
|
||||||
|
background-color: #e6e6e6;
|
||||||
|
margin-bottom: 15rpx;
|
||||||
|
border-radius: 4rpx;
|
||||||
|
animation: shimmer 1.5s infinite;
|
||||||
|
background-image: linear-gradient(90deg, #f0f0f0 25%, #e0e0e0 50%, #f0f0f0 75%);
|
||||||
|
background-size: 1000px 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.skeleton-tip-line-small {
|
||||||
|
width: 50%;
|
||||||
|
height: 24rpx;
|
||||||
|
background-color: #e6e6e6;
|
||||||
|
border-radius: 4rpx;
|
||||||
|
animation: shimmer 1.5s infinite;
|
||||||
|
background-image: linear-gradient(90deg, #f0f0f0 25%, #e0e0e0 50%, #f0f0f0 75%);
|
||||||
|
background-size: 1000px 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 确认按钮骨架屏 */
|
||||||
|
.skeleton-confirm-section {
|
||||||
|
position: fixed;
|
||||||
|
bottom: 0;
|
||||||
|
left: 0;
|
||||||
|
width: 100%;
|
||||||
|
background-color: #fff;
|
||||||
|
padding: 30rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
.skeleton-confirm-button {
|
||||||
|
width: 100%;
|
||||||
|
height: 90rpx;
|
||||||
|
background-color: #e6e6e6;
|
||||||
|
border-radius: 45rpx;
|
||||||
|
animation: shimmer 1.5s infinite;
|
||||||
|
background-image: linear-gradient(90deg, #f0f0f0 25%, #e0e0e0 50%, #f0f0f0 75%);
|
||||||
|
background-size: 1000px 100%;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
@@ -0,0 +1,335 @@
|
|||||||
|
<template>
|
||||||
|
<view class="review-management-page">
|
||||||
|
<!-- 全新方案:纯 CSS 手动构建的骨架屏 -->
|
||||||
|
<view v-if="loading" class="skeleton-wrapper">
|
||||||
|
<view class="skeleton-card" style="height: 150rpx;"></view>
|
||||||
|
<view class="skeleton-tabs">
|
||||||
|
<view class="skeleton-item skeleton-text" style="width: 100%; height: 44rpx;"></view>
|
||||||
|
</view>
|
||||||
|
<view v-for="i in 3" :key="i" class="skeleton-card">
|
||||||
|
<view class="skeleton-item skeleton-text" style="width: 100%; height: 300rpx;"></view>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
|
||||||
|
<!-- 页面实际内容 -->
|
||||||
|
<view v-else class="page-content" >
|
||||||
|
|
||||||
|
<!-- 1. 数据看板 -->
|
||||||
|
<view class="summary-card">
|
||||||
|
<view class="data-item">
|
||||||
|
<view class="value"><text class="score">{{ satisfaction }}%</text><up-icon name="star-fill"
|
||||||
|
color="#ff9900" size="20"></up-icon></view>
|
||||||
|
<text class="label">满意度</text>
|
||||||
|
</view>
|
||||||
|
<view class="data-item">
|
||||||
|
<text class="value">{{total}}</text>
|
||||||
|
<text class="label">总评价数</text>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
|
||||||
|
<!-- 2. Tabs 切换 -->
|
||||||
|
<view class="sticky-tabs-wrapper">
|
||||||
|
<up-tabs :list="reviewTabs" :current="currentTab" @change="onTabChange" lineColor="#fa6400"
|
||||||
|
:activeStyle="{ color: '#fa6400', fontWeight: 'bold' }" :inactiveStyle="{ color: '#666' }">
|
||||||
|
</up-tabs>
|
||||||
|
</view>
|
||||||
|
|
||||||
|
<view class="review-list">
|
||||||
|
<view class="review-card" v-for="review in reviewList" :key="review">
|
||||||
|
<view class="reviewer-info">
|
||||||
|
<text class="name" style="font-weight: bold;" >{{ review.nick }}</text>
|
||||||
|
<up-rate v-model="review.source" readonly activeColor="#ff9900" size="16"></up-rate>
|
||||||
|
<text class="time">{{ Service.formatDate(review.addTime,1) }}</text>
|
||||||
|
</view>
|
||||||
|
<text class="review-text">{{ review.sign }}</text>
|
||||||
|
</view>
|
||||||
|
|
||||||
|
<up-loadmore status="nomore" nomoreText="没有更多评价了"></up-loadmore>
|
||||||
|
<view class="" style="width: 100%; height: 20rpx;" >
|
||||||
|
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
|
||||||
|
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script setup lang="ts">
|
||||||
|
import { ref, reactive } from 'vue';
|
||||||
|
import { onLoad, onReachBottom, onShow } from '@dcloudio/uni-app';
|
||||||
|
import { Service } from "@/Service/Service";
|
||||||
|
import { CNRiderDataService } from '@/Service/CN/CNRiderDataService'
|
||||||
|
|
||||||
|
|
||||||
|
const loading = ref<boolean>(true);
|
||||||
|
const currentTab = ref<number>(0);
|
||||||
|
|
||||||
|
|
||||||
|
let satisfaction = ref(0)
|
||||||
|
let status = ref('nomore')
|
||||||
|
let page = ref(1)
|
||||||
|
|
||||||
|
|
||||||
|
let review = ref('')
|
||||||
|
|
||||||
|
let storeInfo = ref<any>()
|
||||||
|
let total = ref(0)
|
||||||
|
|
||||||
|
const reviewTabs = ref([
|
||||||
|
{ name: '全部' }, { name: '好评' }, { name: '差评' }
|
||||||
|
]);
|
||||||
|
|
||||||
|
const reviewList = ref<Array<any>>([]);
|
||||||
|
|
||||||
|
let currentId = ref('')
|
||||||
|
|
||||||
|
onLoad(() => {
|
||||||
|
getData()
|
||||||
|
});
|
||||||
|
onShow(() => { });
|
||||||
|
|
||||||
|
onReachBottom(()=>{
|
||||||
|
getList()
|
||||||
|
})
|
||||||
|
|
||||||
|
// 获取数据
|
||||||
|
const getData = () => {
|
||||||
|
status.value = 'loadmore'
|
||||||
|
page.value = 1
|
||||||
|
reviewList.value = []
|
||||||
|
getList()
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
const getList = () => {
|
||||||
|
if (status.value == 'loading' || status.value == 'nomore') {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
status.value = 'loading'
|
||||||
|
CNRiderDataService.GetRiderEvaluate(currentTab.value, page.value).then(res => {
|
||||||
|
loading.value = false
|
||||||
|
if (res.data) {
|
||||||
|
satisfaction.value = res.data.satisfaction
|
||||||
|
total.value=res.data.total
|
||||||
|
reviewList.value = [...reviewList.value, ...res.data.evaluateList]
|
||||||
|
page.value++
|
||||||
|
status.value = res.data.evaluateList == 10 ? 'loadmore' : 'nomore'
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
const onTabChange = (e : { index : number }) => {
|
||||||
|
currentTab.value = e.index;
|
||||||
|
getData()
|
||||||
|
};
|
||||||
|
|
||||||
|
const replyTo = () => {
|
||||||
|
|
||||||
|
if (review.value == '') {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
};
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style lang="scss" scoped>
|
||||||
|
|
||||||
|
page{
|
||||||
|
background-color: #f6f6f6;
|
||||||
|
}
|
||||||
|
|
||||||
|
@keyframes skeleton-blink {
|
||||||
|
0% {
|
||||||
|
background-position: 100% 50%;
|
||||||
|
}
|
||||||
|
|
||||||
|
100% {
|
||||||
|
background-position: 0 50%;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.skeleton-item {
|
||||||
|
background: linear-gradient(90deg, #f0f0f0 25%, #e0e0e0 50%, #f0f0f0 75%);
|
||||||
|
background-size: 200% 100%;
|
||||||
|
animation: skeleton-blink 1.5s infinite linear;
|
||||||
|
}
|
||||||
|
|
||||||
|
.skeleton-rect {
|
||||||
|
border-radius: 12rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
.skeleton-text {
|
||||||
|
border-radius: 4rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
.skeleton-wrapper {
|
||||||
|
padding: 24rpx;
|
||||||
|
background-color: #f7f7f7;
|
||||||
|
|
||||||
|
.skeleton-tabs {
|
||||||
|
padding: 20rpx 0;
|
||||||
|
background-color: #fff;
|
||||||
|
}
|
||||||
|
|
||||||
|
.skeleton-card {
|
||||||
|
background-color: #fff;
|
||||||
|
padding: 30rpx;
|
||||||
|
border-radius: 16rpx;
|
||||||
|
margin-bottom: 24rpx;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.review-management-page {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
.summary-card {
|
||||||
|
display: flex;
|
||||||
|
justify-content: space-around;
|
||||||
|
text-align: center;
|
||||||
|
background-color: #fff8f5;
|
||||||
|
border-radius: 16rpx;
|
||||||
|
padding: 30rpx;
|
||||||
|
margin: 24rpx;
|
||||||
|
|
||||||
|
.data-item {
|
||||||
|
.value {
|
||||||
|
font-size: 40rpx;
|
||||||
|
font-weight: bold;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
gap: 4rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
.label {
|
||||||
|
font-size: 24rpx;
|
||||||
|
color: #999;
|
||||||
|
margin-top: 8rpx;
|
||||||
|
display: block;
|
||||||
|
}
|
||||||
|
|
||||||
|
.text-red {
|
||||||
|
color: #fa5151;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.sticky-tabs-wrapper {
|
||||||
|
position: sticky;
|
||||||
|
top: 0;
|
||||||
|
z-index: 10;
|
||||||
|
background-color: #fff;
|
||||||
|
|
||||||
|
:deep(.up-tabs__wrapper__nav__item) {
|
||||||
|
flex: 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
:deep(.up-tabs__wrapper__nav) {
|
||||||
|
position: relative;
|
||||||
|
|
||||||
|
.unread-badge {
|
||||||
|
position: absolute;
|
||||||
|
top: 16rpx;
|
||||||
|
right: 20rpx;
|
||||||
|
background-color: #fa5151;
|
||||||
|
color: #fff;
|
||||||
|
font-size: 20rpx;
|
||||||
|
min-width: 32rpx;
|
||||||
|
height: 32rpx;
|
||||||
|
line-height: 32rpx;
|
||||||
|
border-radius: 16rpx;
|
||||||
|
text-align: center;
|
||||||
|
padding: 0 8rpx;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.review-list {
|
||||||
|
padding: 24rpx;
|
||||||
|
|
||||||
|
.review-card {
|
||||||
|
background-color: #fff;
|
||||||
|
border-radius: 16rpx;
|
||||||
|
padding: 30rpx;
|
||||||
|
margin-bottom: 24rpx;
|
||||||
|
|
||||||
|
&.bad-review {
|
||||||
|
border: 1rpx solid #fef0f0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.reviewer-info {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
gap: 16rpx;
|
||||||
|
|
||||||
|
.name {
|
||||||
|
font-size: 30rpx;
|
||||||
|
font-weight: 500;
|
||||||
|
}
|
||||||
|
|
||||||
|
.time {
|
||||||
|
font-size: 24rpx;
|
||||||
|
color: #999;
|
||||||
|
margin-left: auto;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.review-text {
|
||||||
|
font-size: 28rpx;
|
||||||
|
color: #333;
|
||||||
|
margin: 20rpx 0;
|
||||||
|
display: block;
|
||||||
|
line-height: 1.6;
|
||||||
|
}
|
||||||
|
|
||||||
|
.review-images {
|
||||||
|
display: flex;
|
||||||
|
gap: 16rpx;
|
||||||
|
|
||||||
|
.image-placeholder {
|
||||||
|
width: 160rpx;
|
||||||
|
height: 160rpx;
|
||||||
|
overflow: hidden;
|
||||||
|
border-radius: 8rpx;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.merchant-reply {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
gap: 12rpx;
|
||||||
|
background-color: #f5f5f5;
|
||||||
|
border-radius: 12rpx;
|
||||||
|
padding: 20rpx;
|
||||||
|
margin-top: 20rpx;
|
||||||
|
font-size: 26rpx;
|
||||||
|
|
||||||
|
.reply-label {
|
||||||
|
color: #fa6400;
|
||||||
|
font-weight: 500;
|
||||||
|
}
|
||||||
|
|
||||||
|
.reply-text {
|
||||||
|
color: #666;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.reply-action {
|
||||||
|
text-align: right;
|
||||||
|
margin-top: 20rpx;
|
||||||
|
|
||||||
|
text {
|
||||||
|
display: inline-block;
|
||||||
|
border: 1rpx solid #fa6400;
|
||||||
|
color: #fa6400;
|
||||||
|
font-size: 26rpx;
|
||||||
|
padding: 8rpx 24rpx;
|
||||||
|
border-radius: 30rpx;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</style>
|
||||||
@@ -0,0 +1,81 @@
|
|||||||
|
{
|
||||||
|
"id": "qf-image-cropper",
|
||||||
|
"displayName": "图片裁剪插件",
|
||||||
|
"version": "2.2.5",
|
||||||
|
"description": "图片裁剪插件,支持自定义尺寸、定点等比例缩放、拖动、图片翻转、剪切圆形/圆角图片、定制样式,功能多性能高体验好注释全。",
|
||||||
|
"keywords": [
|
||||||
|
"qf-image-cropper",
|
||||||
|
"图片裁剪",
|
||||||
|
"图片编辑",
|
||||||
|
"头像裁剪",
|
||||||
|
"小程序"
|
||||||
|
],
|
||||||
|
"repository": "",
|
||||||
|
"engines": {
|
||||||
|
"HBuilderX": "^3.1.0"
|
||||||
|
},
|
||||||
|
"dcloudext": {
|
||||||
|
"type": "component-vue",
|
||||||
|
"sale": {
|
||||||
|
"regular": {
|
||||||
|
"price": "0.00"
|
||||||
|
},
|
||||||
|
"sourcecode": {
|
||||||
|
"price": "0.00"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"contact": {
|
||||||
|
"qq": ""
|
||||||
|
},
|
||||||
|
"declaration": {
|
||||||
|
"ads": "无",
|
||||||
|
"data": "插件不采集任何数据",
|
||||||
|
"permissions": "无"
|
||||||
|
},
|
||||||
|
"npmurl": ""
|
||||||
|
},
|
||||||
|
"uni_modules": {
|
||||||
|
"dependencies": [],
|
||||||
|
"encrypt": [],
|
||||||
|
"platforms": {
|
||||||
|
"client": {
|
||||||
|
"Vue": {
|
||||||
|
"vue2": "y",
|
||||||
|
"vue3": "y"
|
||||||
|
},
|
||||||
|
"App": {
|
||||||
|
"app-vue": "y",
|
||||||
|
"app-nvue": "n"
|
||||||
|
},
|
||||||
|
"H5-mobile": {
|
||||||
|
"Safari": "y",
|
||||||
|
"Android Browser": "y",
|
||||||
|
"微信浏览器(Android)": "y",
|
||||||
|
"QQ浏览器(Android)": "u"
|
||||||
|
},
|
||||||
|
"H5-pc": {
|
||||||
|
"Chrome": "u",
|
||||||
|
"IE": "u",
|
||||||
|
"Edge": "u",
|
||||||
|
"Firefox": "u",
|
||||||
|
"Safari": "u"
|
||||||
|
},
|
||||||
|
"小程序": {
|
||||||
|
"微信": "y",
|
||||||
|
"阿里": "n",
|
||||||
|
"百度": "n",
|
||||||
|
"字节跳动": "n",
|
||||||
|
"QQ": "u",
|
||||||
|
"钉钉": "n",
|
||||||
|
"快手": "n",
|
||||||
|
"飞书": "n",
|
||||||
|
"京东": "n"
|
||||||
|
},
|
||||||
|
"快应用": {
|
||||||
|
"华为": "n",
|
||||||
|
"联盟": "n"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,544 @@
|
|||||||
|
<template>
|
||||||
|
<view v-if="loading" class="skeleton-container">
|
||||||
|
<!-- 收入概览区域骨架 -->
|
||||||
|
<view class="income-container" style="padding-top: 80rpx">
|
||||||
|
<view class="income-overview">
|
||||||
|
<view class="" style="display: flex; align-items: center; justify-content: space-between">
|
||||||
|
<view class="">
|
||||||
|
<view class="skeleton-income-title"></view>
|
||||||
|
<view class="" style="display: flex; align-items: center">
|
||||||
|
<view class="skeleton-income-amount"></view>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
<view class="skeleton-withdraw-button"></view>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
|
||||||
|
<!-- 收入明细区域骨架 -->
|
||||||
|
<view class="detail-header">
|
||||||
|
<view class="skeleton-detail-title"></view>
|
||||||
|
</view>
|
||||||
|
<!-- 时间选择标签骨架 -->
|
||||||
|
<view class="time-tabs">
|
||||||
|
<view class="skeleton-tab-item" v-for="(item, index) in 4" :key="index"></view>
|
||||||
|
</view>
|
||||||
|
<!-- 明细列表骨架 -->
|
||||||
|
<view class="detail-list" v-for="(item, index) in 3" :key="index">
|
||||||
|
<view class="detail-content">
|
||||||
|
<view class="skeleton-icon-placeholder"></view>
|
||||||
|
<view class="detail-info">
|
||||||
|
<view class="skeleton-order-id"></view>
|
||||||
|
<view class="skeleton-order-time"></view>
|
||||||
|
</view>
|
||||||
|
<view class="">
|
||||||
|
<view class="skeleton-order-amount"></view>
|
||||||
|
<view class="skeleton-order-balance"></view>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
<!-- 加载更多骨架 -->
|
||||||
|
<view class="skeleton-load-more"></view>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
|
||||||
|
<!-- 收入概览区域 -->
|
||||||
|
<view v-else class="income-container" style="padding-top: 80rpx">
|
||||||
|
<view v-if="!istrought" class="">
|
||||||
|
<view class="income-overview">
|
||||||
|
<view class="" style="display: flex; align-items: center; justify-content: space-between">
|
||||||
|
<view class="">
|
||||||
|
<text class="income-title">账户余额</text>
|
||||||
|
<view class="" style="display: flex; align-items: center">
|
||||||
|
<text class="income-amount">¥{{ riderAcc.account }}</text>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
<u-button class="withdraw-button" @click="Service.GoPage('/pages/order/withdraw')"
|
||||||
|
type="primary">立即提现</u-button>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
|
||||||
|
<!-- 收入明细区域 -->
|
||||||
|
<view class="detail-header">
|
||||||
|
<text class="detail-title">收支明细</text>
|
||||||
|
</view>
|
||||||
|
<!-- 时间选择标签 -->
|
||||||
|
<view class="time-tabs">
|
||||||
|
<text v-for="(item, index) in timeList" :key="index" @click="changeTab(index)"
|
||||||
|
:class="{ active: currentTime == index }" class="tab-item">{{
|
||||||
|
item
|
||||||
|
}}</text>
|
||||||
|
</view>
|
||||||
|
<view class="detail-list" v-for="(item, index) in accList" :key="index">
|
||||||
|
<view class="detail-content">
|
||||||
|
<view class="icon-placeholder">
|
||||||
|
<image :src="Service.GetIconImg('/static/index/income/order.png')"
|
||||||
|
style="width: 55rpx; height: 55rpx" mode=""></image>
|
||||||
|
</view>
|
||||||
|
<view class="detail-info">
|
||||||
|
<text class="order-id">{{ item.name }}</text>
|
||||||
|
<text class="order-time">{{ Service.formatDate(item.addTime, 1) }}</text>
|
||||||
|
</view>
|
||||||
|
<view class="" style="">
|
||||||
|
<view class="order-amount" style="text-align: right">
|
||||||
|
{{ item.code == '收入' ? '+' : '-' }}{{ item.amount }}
|
||||||
|
</view>
|
||||||
|
<view class="order-time"> 账户余额 {{ item.balance }} </view>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
<up-loadmore :status="status" />
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
<view v-if="istrought" style=" margin-top: 20rpx; text-align: center; font-weight: bold; font-size: 34rpx;"
|
||||||
|
class="">
|
||||||
|
信息审核中·请等待审核
|
||||||
|
</view>
|
||||||
|
|
||||||
|
<calender ref="calendar" :range="true" :insert="false" @confirm="dataConfirm" />
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script setup lang="ts">
|
||||||
|
import { onLoad, onShow } from '@dcloudio/uni-app'
|
||||||
|
import { ref, onMounted } from 'vue'
|
||||||
|
import * as echarts from 'echarts'
|
||||||
|
import { Service } from '@/Service/Service'
|
||||||
|
import { CNRiderDataService } from '@/Service/CN/CNRiderDataService'
|
||||||
|
import { CNRiderOrderService } from '@/Service/CN/CNRiderOrderService'
|
||||||
|
import calender from '@/uni_modules/uni-calendar/components/uni-calendar/uni-calendar'
|
||||||
|
|
||||||
|
let loading = ref(true)
|
||||||
|
let calendar = ref(null)
|
||||||
|
let timeList = ref(['今日', '本周', '本月', '自定义'])
|
||||||
|
|
||||||
|
let currentTime = ref(0)
|
||||||
|
|
||||||
|
let status = ref('nomore')
|
||||||
|
let page = ref(1)
|
||||||
|
let riderAcc = ref<any>({})
|
||||||
|
|
||||||
|
let accList = ref<Array<any>>([])
|
||||||
|
|
||||||
|
let timeString = ref('')
|
||||||
|
|
||||||
|
let istrought = ref(false)
|
||||||
|
|
||||||
|
onLoad(() => { })
|
||||||
|
|
||||||
|
onShow(() => {
|
||||||
|
getData()
|
||||||
|
getIncome()
|
||||||
|
})
|
||||||
|
|
||||||
|
onMounted(() => { })
|
||||||
|
|
||||||
|
const getData = () => {
|
||||||
|
CNRiderDataService.GetRiderAccInfo().then((res) => {
|
||||||
|
loading.value = false
|
||||||
|
if (res.code == 0) {
|
||||||
|
riderAcc.value = res.data.riderAcc
|
||||||
|
istrought.value = false
|
||||||
|
}
|
||||||
|
else if (res.code == 1008) {
|
||||||
|
istrought.value = true
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
Service.Msg(res.msg)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
// 收入列表
|
||||||
|
const getIncome = () => {
|
||||||
|
status.value = 'loadmore'
|
||||||
|
page.value = 1
|
||||||
|
accList.value = []
|
||||||
|
getIncomeList()
|
||||||
|
}
|
||||||
|
|
||||||
|
const getIncomeList = () => {
|
||||||
|
if (status.value == 'nomore' || status.value == 'loading') {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
status.value == 'loadmore'
|
||||||
|
CNRiderOrderService.GetRiderAccLog(
|
||||||
|
currentTime.value == 0 ? '' : currentTime.value == 3 ? timeString.value : String(currentTime.value),
|
||||||
|
page.value
|
||||||
|
).then((res) => {
|
||||||
|
accList.value = [...accList.value, ...res.data.accLog]
|
||||||
|
status.value = res.data.accLog == 10 ? 'loadmore' : 'nomore'
|
||||||
|
page.value++
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
const changeTab = (index : number) => {
|
||||||
|
currentTime.value = index
|
||||||
|
if (index == 3) {
|
||||||
|
calendar.value.open()
|
||||||
|
return
|
||||||
|
}
|
||||||
|
getIncome()
|
||||||
|
}
|
||||||
|
|
||||||
|
const dataConfirm = (e) => {
|
||||||
|
timeString.value = e.range.data[0] + '_' + e.range.data.slice(-1)
|
||||||
|
if (e.range.data.length == 0) {
|
||||||
|
timeString.value = e.fulldate
|
||||||
|
getIncome()
|
||||||
|
return
|
||||||
|
}
|
||||||
|
getIncome()
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style scoped>
|
||||||
|
.income-container {
|
||||||
|
padding: 20rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 收入概览区域 */
|
||||||
|
.income-overview {
|
||||||
|
background-color: #fff;
|
||||||
|
border-radius: 20rpx;
|
||||||
|
padding: 30rpx;
|
||||||
|
margin-bottom: 20rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
.income-title {
|
||||||
|
font-size: 28rpx;
|
||||||
|
color: #666;
|
||||||
|
display: block;
|
||||||
|
margin-bottom: 10rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
.income-amount {
|
||||||
|
font-size: 48rpx;
|
||||||
|
font-weight: bold;
|
||||||
|
color: #ff4d4f;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 时间标签 */
|
||||||
|
.time-tabs {
|
||||||
|
display: flex;
|
||||||
|
margin-bottom: 10rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
.tab-item {
|
||||||
|
font-size: 28rpx;
|
||||||
|
color: #666;
|
||||||
|
margin-right: 40rpx;
|
||||||
|
padding-bottom: 10rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
.tab-item.active {
|
||||||
|
color: #1890ff;
|
||||||
|
border-bottom: 3rpx solid #1890ff;
|
||||||
|
}
|
||||||
|
|
||||||
|
.month-total {
|
||||||
|
font-size: 30rpx;
|
||||||
|
color: #666;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 收入构成区域 */
|
||||||
|
.income-composition {
|
||||||
|
background-color: #fff;
|
||||||
|
border-radius: 20rpx;
|
||||||
|
padding: 30rpx;
|
||||||
|
margin-bottom: 20rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 饼图占位 */
|
||||||
|
.pie-chart-placeholder {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.pie-chart {
|
||||||
|
width: 200rpx;
|
||||||
|
height: 200rpx;
|
||||||
|
margin-right: 30rpx;
|
||||||
|
position: relative;
|
||||||
|
overflow: hidden;
|
||||||
|
}
|
||||||
|
|
||||||
|
.chart-legend {
|
||||||
|
flex: 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
.legend-item {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
margin-bottom: 15rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
.legend-dot {
|
||||||
|
width: 16rpx;
|
||||||
|
height: 16rpx;
|
||||||
|
border-radius: 50%;
|
||||||
|
margin-right: 10rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
.legend-dot.blue {
|
||||||
|
background-color: var(--nav-mian);
|
||||||
|
}
|
||||||
|
|
||||||
|
.legend-dot.orange {
|
||||||
|
background-color: var(--nav-vice);
|
||||||
|
}
|
||||||
|
|
||||||
|
.legend-dot.green {
|
||||||
|
background-color: var(--nav-diluted);
|
||||||
|
}
|
||||||
|
|
||||||
|
.legend-text {
|
||||||
|
font-size: 26rpx;
|
||||||
|
color: #666;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 钱包区域 */
|
||||||
|
.wallet-section {
|
||||||
|
background-color: #fff;
|
||||||
|
border-radius: 20rpx;
|
||||||
|
padding: 30rpx;
|
||||||
|
margin-bottom: 20rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
.wallet-header {
|
||||||
|
display: flex;
|
||||||
|
justify-content: space-between;
|
||||||
|
align-items: center;
|
||||||
|
margin-bottom: 20rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
.wallet-title {
|
||||||
|
font-size: 28rpx;
|
||||||
|
color: #333;
|
||||||
|
}
|
||||||
|
|
||||||
|
.wallet-amount {
|
||||||
|
font-size: 36rpx;
|
||||||
|
font-weight: bold;
|
||||||
|
color: #ff4d4f;
|
||||||
|
}
|
||||||
|
|
||||||
|
.withdraw-button {
|
||||||
|
margin: 0;
|
||||||
|
width: fit-content;
|
||||||
|
height: 60rpx;
|
||||||
|
line-height: 60rpx;
|
||||||
|
font-size: 24rpx;
|
||||||
|
border-radius: 40rpx;
|
||||||
|
background-color: #1890ff;
|
||||||
|
color: #fff;
|
||||||
|
}
|
||||||
|
|
||||||
|
.withdraw-tip {
|
||||||
|
display: block;
|
||||||
|
font-size: 22rpx;
|
||||||
|
color: #999;
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 收入明细区域 */
|
||||||
|
.income-detail {
|
||||||
|
background-color: #fff;
|
||||||
|
border-radius: 20rpx;
|
||||||
|
padding: 30rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
.detail-header {
|
||||||
|
margin-bottom: 20rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
.detail-title {
|
||||||
|
font-size: 34rpx;
|
||||||
|
font-weight: bold;
|
||||||
|
color: #333;
|
||||||
|
}
|
||||||
|
|
||||||
|
.detail-content {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.detail-list {
|
||||||
|
margin: 15rpx 0 0;
|
||||||
|
background-color: #fff;
|
||||||
|
padding: 20rpx 30rpx;
|
||||||
|
border-radius: 20rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 图标占位符 - 黑边白底 */
|
||||||
|
.icon-placeholder {
|
||||||
|
width: 70rpx;
|
||||||
|
height: 70rpx;
|
||||||
|
background-color: #e6f7ff;
|
||||||
|
border-radius: 8rpx;
|
||||||
|
margin-right: 20rpx;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.detail-info {
|
||||||
|
flex: 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
.order-id {
|
||||||
|
display: block;
|
||||||
|
font-size: 26rpx;
|
||||||
|
color: #333;
|
||||||
|
margin-bottom: 5rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
.order-time {
|
||||||
|
font-size: 24rpx;
|
||||||
|
color: #999;
|
||||||
|
}
|
||||||
|
|
||||||
|
.order-amount {
|
||||||
|
font-size: 32rpx;
|
||||||
|
font-weight: bold;
|
||||||
|
color: #ff4d4f;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 没有更多记录 */
|
||||||
|
.no-more {
|
||||||
|
text-align: center;
|
||||||
|
padding: 40rpx 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.no-more-text {
|
||||||
|
font-size: 24rpx;
|
||||||
|
color: #999;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 骨架屏样式 */
|
||||||
|
.skeleton-container {
|
||||||
|
width: 100%;
|
||||||
|
min-height: 100vh;
|
||||||
|
background-color: #f5f5f5;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 收入概览骨架 */
|
||||||
|
.skeleton-income-title {
|
||||||
|
width: 120rpx;
|
||||||
|
height: 28rpx;
|
||||||
|
background: linear-gradient(90deg, #f0f0f0 25%, #e6e6e6 50%, #f0f0f0 75%);
|
||||||
|
background-size: 200% 100%;
|
||||||
|
border-radius: 4rpx;
|
||||||
|
animation: skeleton-loading 1.5s infinite ease-in-out;
|
||||||
|
margin-bottom: 10rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
.skeleton-income-amount {
|
||||||
|
width: 240rpx;
|
||||||
|
height: 48rpx;
|
||||||
|
background: linear-gradient(90deg, #f0f0f0 25%, #e6e6e6 50%, #f0f0f0 75%);
|
||||||
|
background-size: 200% 100%;
|
||||||
|
border-radius: 8rpx;
|
||||||
|
animation: skeleton-loading 1.5s infinite ease-in-out;
|
||||||
|
}
|
||||||
|
|
||||||
|
.skeleton-withdraw-button {
|
||||||
|
width: 160rpx;
|
||||||
|
height: 60rpx;
|
||||||
|
background: linear-gradient(90deg, #f0f0f0 25%, #e6e6e6 50%, #f0f0f0 75%);
|
||||||
|
background-size: 200% 100%;
|
||||||
|
border-radius: 30rpx;
|
||||||
|
animation: skeleton-loading 1.5s infinite ease-in-out;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 明细标题骨架 */
|
||||||
|
.skeleton-detail-title {
|
||||||
|
width: 150rpx;
|
||||||
|
height: 34rpx;
|
||||||
|
background: linear-gradient(90deg, #f0f0f0 25%, #e6e6e6 50%, #f0f0f0 75%);
|
||||||
|
background-size: 200% 100%;
|
||||||
|
border-radius: 8rpx;
|
||||||
|
animation: skeleton-loading 1.5s infinite ease-in-out;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 时间标签骨架 */
|
||||||
|
.skeleton-tab-item {
|
||||||
|
width: 80rpx;
|
||||||
|
height: 28rpx;
|
||||||
|
background: linear-gradient(90deg, #f0f0f0 25%, #e6e6e6 50%, #f0f0f0 75%);
|
||||||
|
background-size: 200% 100%;
|
||||||
|
border-radius: 4rpx;
|
||||||
|
animation: skeleton-loading 1.5s infinite ease-in-out;
|
||||||
|
margin-right: 40rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 明细列表骨架 */
|
||||||
|
.skeleton-icon-placeholder {
|
||||||
|
width: 70rpx;
|
||||||
|
height: 70rpx;
|
||||||
|
background: linear-gradient(90deg, #f0f0f0 25%, #e6e6e6 50%, #f0f0f0 75%);
|
||||||
|
background-size: 200% 100%;
|
||||||
|
border-radius: 8rpx;
|
||||||
|
animation: skeleton-loading 1.5s infinite ease-in-out;
|
||||||
|
margin-right: 20rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
.skeleton-order-id {
|
||||||
|
width: 200rpx;
|
||||||
|
height: 26rpx;
|
||||||
|
background: linear-gradient(90deg, #f0f0f0 25%, #e6e6e6 50%, #f0f0f0 75%);
|
||||||
|
background-size: 200% 100%;
|
||||||
|
border-radius: 4rpx;
|
||||||
|
animation: skeleton-loading 1.5s infinite ease-in-out;
|
||||||
|
margin-bottom: 5rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
.skeleton-order-time {
|
||||||
|
width: 150rpx;
|
||||||
|
height: 24rpx;
|
||||||
|
background: linear-gradient(90deg, #f0f0f0 25%, #e6e6e6 50%, #f0f0f0 75%);
|
||||||
|
background-size: 200% 100%;
|
||||||
|
border-radius: 4rpx;
|
||||||
|
animation: skeleton-loading 1.5s infinite ease-in-out;
|
||||||
|
}
|
||||||
|
|
||||||
|
.skeleton-order-amount {
|
||||||
|
width: 120rpx;
|
||||||
|
height: 32rpx;
|
||||||
|
background: linear-gradient(90deg, #f0f0f0 25%, #e6e6e6 50%, #f0f0f0 75%);
|
||||||
|
background-size: 200% 100%;
|
||||||
|
border-radius: 4rpx;
|
||||||
|
animation: skeleton-loading 1.5s infinite ease-in-out;
|
||||||
|
text-align: right;
|
||||||
|
}
|
||||||
|
|
||||||
|
.skeleton-order-balance {
|
||||||
|
width: 180rpx;
|
||||||
|
height: 24rpx;
|
||||||
|
background: linear-gradient(90deg, #f0f0f0 25%, #e6e6e6 50%, #f0f0f0 75%);
|
||||||
|
background-size: 200% 100%;
|
||||||
|
border-radius: 4rpx;
|
||||||
|
animation: skeleton-loading 1.5s infinite ease-in-out;
|
||||||
|
text-align: right;
|
||||||
|
margin-top: 5rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 加载更多骨架 */
|
||||||
|
.skeleton-load-more {
|
||||||
|
height: 80rpx;
|
||||||
|
background: linear-gradient(90deg, #f0f0f0 25%, #e6e6e6 50%, #f0f0f0 75%);
|
||||||
|
background-size: 200% 100%;
|
||||||
|
border-radius: 40rpx;
|
||||||
|
animation: skeleton-loading 1.5s infinite ease-in-out;
|
||||||
|
margin: 20rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 骨架屏动画 */
|
||||||
|
@keyframes skeleton-loading {
|
||||||
|
0% {
|
||||||
|
background-position: -100% 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
100% {
|
||||||
|
background-position: 100% 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</style>
|
||||||
@@ -0,0 +1,355 @@
|
|||||||
|
import { HttpRequest, StoreAssist, UploadAssist, ResultData } from '@/common/Common';
|
||||||
|
import { BaseConfig } from './BaseConfig';
|
||||||
|
export class Service extends BaseConfig {
|
||||||
|
|
||||||
|
|
||||||
|
// 获取是否后台
|
||||||
|
static getIsHede () {
|
||||||
|
let isHede = this.GetStorageCache('isHede')
|
||||||
|
if (isHede == null || isHede == '') {
|
||||||
|
return false;
|
||||||
|
} else {
|
||||||
|
return isHede;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//获取API地址
|
||||||
|
static ApiUrl(path : string) {
|
||||||
|
return `${this.servesUrl}${path}`;
|
||||||
|
}
|
||||||
|
|
||||||
|
//获取图片地址
|
||||||
|
static GetpayImg(path : string) {
|
||||||
|
if (path.startsWith('http') || path.startsWith('https')) {
|
||||||
|
return path;
|
||||||
|
} else {
|
||||||
|
return `${this.payuploadUrl}${path}`;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//获取图标地址
|
||||||
|
static GetIconImg(path : string) {
|
||||||
|
return path
|
||||||
|
if (path.startsWith('http') || path.startsWith('https')) {
|
||||||
|
return path;
|
||||||
|
} else {
|
||||||
|
return `${this.imgUrl}${path}`;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//获取图片地址
|
||||||
|
static GetMateUrlByImg(path : string) {
|
||||||
|
return path
|
||||||
|
if (path.startsWith('http') || path.startsWith('https')) {
|
||||||
|
return path;
|
||||||
|
} else {
|
||||||
|
return `${this.imgUrl}${path}`;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
//获取音视频地址
|
||||||
|
static GetMateUrlByMedia(path : string) {
|
||||||
|
if (path.startsWith('http') || path.startsWith('https')) {
|
||||||
|
return path;
|
||||||
|
} else {
|
||||||
|
return `${this.mediaUrl}${path}`;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
//获取登录账号token
|
||||||
|
static GetUserToken() {
|
||||||
|
return Service.GetStorageCache('token');
|
||||||
|
}
|
||||||
|
// 获取登录状态
|
||||||
|
static GetUserIsLogin() {
|
||||||
|
var token = this.GetUserToken();
|
||||||
|
if (token == null || token == '') {
|
||||||
|
return false;
|
||||||
|
} else {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
//设置登录账户Token
|
||||||
|
static SetUserToken(token : string) {
|
||||||
|
this.SetStorageCache('token', token);
|
||||||
|
}
|
||||||
|
//清理登录账户Token
|
||||||
|
static OffUserToken() {
|
||||||
|
Service.DelStorageCache('token');
|
||||||
|
uni.$emit('ImComOff', 'user');
|
||||||
|
this.ClearUserStateData();
|
||||||
|
}
|
||||||
|
//获取登录账号状态信息
|
||||||
|
static GetUserStateData() {
|
||||||
|
return Service.GetStorageCache('StateDomain');
|
||||||
|
}
|
||||||
|
//设置当前登录账号状态信息
|
||||||
|
static SetUserStateData() {
|
||||||
|
return Service.GetStorageCache('StateDomain');
|
||||||
|
}
|
||||||
|
//清理当前登录账号状态信息
|
||||||
|
static ClearUserStateData() {
|
||||||
|
Service.DelStorageCache('StateDomain');
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//获取当前客户端ID
|
||||||
|
static GetUserClientId() {
|
||||||
|
return this.GetStorageCache('ClientId');
|
||||||
|
}
|
||||||
|
//保存当前客户端ID
|
||||||
|
static SetUserClientId(clientId: string) {
|
||||||
|
this.SetStorageCache('ClientId', clientId);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//获取缓存
|
||||||
|
static GetStorageCache(key : string) {
|
||||||
|
return StoreAssist.Get(key);
|
||||||
|
}
|
||||||
|
//删除缓存
|
||||||
|
static DelStorageCache(key : string) {
|
||||||
|
StoreAssist.Delete(key);
|
||||||
|
}
|
||||||
|
//设置缓存
|
||||||
|
static SetStorageCache(key : string, data : any) {
|
||||||
|
StoreAssist.Set(key, data);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*****以下是基础方法调用与拦截器*****/
|
||||||
|
|
||||||
|
static Request(url : string, method : 'GET' | 'POST' | 'PUT' | undefined, data : object | any) {
|
||||||
|
const token = Service.GetUserToken();
|
||||||
|
|
||||||
|
const _url = Service.ApiUrl(url);
|
||||||
|
var result = HttpRequest.RequestWithToken(_url, method, token, data).then((retResult : any) => {
|
||||||
|
if (retResult.statusCode == '200') {
|
||||||
|
var obj = retResult.data;
|
||||||
|
if (obj.code == 401) {
|
||||||
|
//过期
|
||||||
|
this.OffUserToken();
|
||||||
|
this.Msg('登录过期,请重新登录')
|
||||||
|
this.GoPage('/pages/my/login')
|
||||||
|
return Promise.reject();
|
||||||
|
} else if (obj.code == 40101) {
|
||||||
|
//失效
|
||||||
|
this.OffUserToken();
|
||||||
|
this.GoPageDelse('/pages/mine/login/login');
|
||||||
|
return Promise.reject();
|
||||||
|
} else if (obj.code == 1004) {
|
||||||
|
//资源不存在
|
||||||
|
this.GoPageDelse('/pages/AppSet/404/404');
|
||||||
|
return Promise.reject();
|
||||||
|
// return new ResultData(-1, '', '');
|
||||||
|
} else if (obj.code == 40188) {
|
||||||
|
//无权限
|
||||||
|
|
||||||
|
this.GoPageDelse('/pages/AppSet/40188/40188');
|
||||||
|
return Promise.reject();
|
||||||
|
// return new ResultData(-1, '', '');
|
||||||
|
} else if (obj.code == 1008) {
|
||||||
|
//业务提示
|
||||||
|
return new ResultData(obj.code, obj.msg, obj.data);
|
||||||
|
} else {
|
||||||
|
return new ResultData(obj.code, obj.msg, obj.data);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
return new ResultData(-1, '', '');
|
||||||
|
}
|
||||||
|
});
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
/*****以下是腾讯云oss上传*****/
|
||||||
|
static UpLoadMedia(code : string, fileName : string, desire : string, path : string) {
|
||||||
|
var result = this.Request(this.uploadUrl, 'GET', { code, fileName, desire }).then((retResult) => {
|
||||||
|
if (retResult.code == 0) {
|
||||||
|
var upOk = UploadAssist.Upload(retResult.data.url, path, retResult.data.cosData).then((upRet : any) => {
|
||||||
|
if (upRet.statusCode == 200) {
|
||||||
|
const retData : any = { code: retResult.data.code, file: retResult.data.file, cache: retResult.data.cache };
|
||||||
|
return new ResultData(0, '上传成功!', retData);
|
||||||
|
} else {
|
||||||
|
this.Msg('上传失败!');
|
||||||
|
return new ResultData(-1, '', '');
|
||||||
|
}
|
||||||
|
});
|
||||||
|
return upOk;
|
||||||
|
} else {
|
||||||
|
this.Msg('上传失败!');
|
||||||
|
return new ResultData(-1, retResult.msg,retResult.data);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
/***********消息操作**************/
|
||||||
|
static Msg(message : any, icon ?: any) : void {
|
||||||
|
if (icon != null) {
|
||||||
|
uni.showToast({
|
||||||
|
title: message,
|
||||||
|
icon: icon
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
uni.showToast({
|
||||||
|
title: message,
|
||||||
|
icon: 'none'
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static Alert(msg : string, cb ?: any) {
|
||||||
|
uni.showModal({
|
||||||
|
title: '提示',
|
||||||
|
content: msg,
|
||||||
|
showCancel: false,
|
||||||
|
cancelText: '取消',
|
||||||
|
confirmText: '确定',
|
||||||
|
success: res => {
|
||||||
|
if (res.confirm) {
|
||||||
|
cb && cb();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
static LoadIng(text : any) : void {
|
||||||
|
uni.showLoading({
|
||||||
|
title: text,
|
||||||
|
icon: 'none'
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
static LoadClose() : void {
|
||||||
|
uni.hideLoading();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**********跳转操作*********/
|
||||||
|
|
||||||
|
|
||||||
|
static GoPageTab(path : string) : void {
|
||||||
|
uni.switchTab({
|
||||||
|
url: path
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/**********跳转操作*********/
|
||||||
|
static GoPage(path : string) : void {
|
||||||
|
uni.navigateTo({
|
||||||
|
url: path, //跳转的页面
|
||||||
|
success: function (res) {
|
||||||
|
// 通过eventChannel向被打开页面传送数据
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
/**********跳转并删除当前页面操作*********/
|
||||||
|
static GoPageDelse(path : string) : void {
|
||||||
|
uni.redirectTo({
|
||||||
|
url: path //跳转的页面
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/**********返回上一页*********/
|
||||||
|
static GoPageBack() : void {
|
||||||
|
uni.navigateBack({ delta: 1 });
|
||||||
|
}
|
||||||
|
|
||||||
|
/*****获取图片base64*****/
|
||||||
|
static UpLoadMediaBase64(path : string) {
|
||||||
|
return new Promise(function (resolve, reject) {
|
||||||
|
uni.uploadFile({
|
||||||
|
url: 'http://cloud.pccsh.com/DefUp/UploadFileImgBase64', //仅为示例,非真实的接口地址
|
||||||
|
filePath: path,
|
||||||
|
name: 'file',
|
||||||
|
success: (uploadFileRes) => {
|
||||||
|
resolve(uploadFileRes);
|
||||||
|
},
|
||||||
|
fail: (err) => {
|
||||||
|
reject(err);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
/*****获取图片位置信息*****/
|
||||||
|
//获取时间戳
|
||||||
|
static GetTimeSpan(milliSecond : number) {
|
||||||
|
return Date.now() + milliSecond;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 时间戳处理
|
||||||
|
static formatDate(time : any, type : number) : string {
|
||||||
|
const date = new Date(time);
|
||||||
|
const year = date.getFullYear();
|
||||||
|
const month = String(date.getMonth() + 1).padStart(2, '0'); // 月份从0开始,所以加1,并用0填充
|
||||||
|
const day = String(date.getDate()).padStart(2, '0'); // 用0填充
|
||||||
|
const hours = String(date.getHours()).padStart(2, '0'); // 用0填充
|
||||||
|
const minutes = String(date.getMinutes()).padStart(2, '0'); // 用0填充
|
||||||
|
const seconds = String(date.getSeconds()).padStart(2, '0'); // 用0填充
|
||||||
|
if (type == 0) {
|
||||||
|
return `${year}-${month}-${day} ${hours}:${minutes}:${seconds}`;
|
||||||
|
}
|
||||||
|
else if (type == 1) {
|
||||||
|
return `${year}-${month}-${day} ${hours}:${minutes}`;
|
||||||
|
} else if (type == 2) {
|
||||||
|
return `${year}-${month}-${day}`;
|
||||||
|
} else if (type == 3) {
|
||||||
|
return `${hours}:${minutes}`;
|
||||||
|
} else if (type == 4) {
|
||||||
|
return `${year}${month}${day}`;
|
||||||
|
}
|
||||||
|
|
||||||
|
else {
|
||||||
|
return `${hours}:${minutes}`;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*****节流*****/
|
||||||
|
static throttle(fn: () => void, time: number) {
|
||||||
|
let canRun: boolean = true;
|
||||||
|
return function () {
|
||||||
|
if (!canRun) return;
|
||||||
|
canRun = false;
|
||||||
|
setTimeout(() => {
|
||||||
|
fn(); //可以不执行
|
||||||
|
canRun = true;
|
||||||
|
}, time);
|
||||||
|
};
|
||||||
|
}
|
||||||
|
/*****防抖*****/
|
||||||
|
static debounce<T extends (...args: any[]) => void>(fn: T, time: number): (...args: Parameters<T>) => void {
|
||||||
|
let timerId: NodeJS.Timeout | null = null;
|
||||||
|
|
||||||
|
return (...args: Parameters<T>) => {
|
||||||
|
if (timerId) {
|
||||||
|
clearTimeout(timerId);
|
||||||
|
}
|
||||||
|
|
||||||
|
timerId = setTimeout(() => {
|
||||||
|
fn(...args); // 执行传入的函数
|
||||||
|
timerId = null; // 清除定时器ID
|
||||||
|
}, time);
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// 普通图片上传
|
||||||
|
static uploadH5(path, dic, callback) {
|
||||||
|
console.log(this.payuploadUrl,'xxx')
|
||||||
|
uni.uploadFile({
|
||||||
|
url: this.payuploadUrl+'/Upload/Upload',
|
||||||
|
method: "POST",
|
||||||
|
header: {
|
||||||
|
'Authorization': 'Bearer ' + Service.GetUserToken(),
|
||||||
|
},
|
||||||
|
formData: {
|
||||||
|
"path": dic,
|
||||||
|
},
|
||||||
|
filePath: path,
|
||||||
|
name: 'file',
|
||||||
|
success: (data) => {
|
||||||
|
let info = data.data
|
||||||
|
callback(info)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,242 @@
|
|||||||
|
<template>
|
||||||
|
<!-- <UpApp :show="upShow" :url="url" /> -->
|
||||||
|
<view class="borybac" v-if="upShow">
|
||||||
|
<view class="up_box">
|
||||||
|
|
||||||
|
<view class="mt50">
|
||||||
|
<view class="" style="margin: 0 60rpx;" >
|
||||||
|
1.优化布局细节,优化购物体验,优化产品体验
|
||||||
|
</view>
|
||||||
|
<view class="" style="margin: 0 60rpx;" >
|
||||||
|
2.修复已知问题,修复一些BUG
|
||||||
|
</view>
|
||||||
|
|
||||||
|
</view>
|
||||||
|
|
||||||
|
<view class="jdBox">
|
||||||
|
<view class="jd">
|
||||||
|
<view class="jdbfb">
|
||||||
|
{{sum}}%
|
||||||
|
</view>
|
||||||
|
<view class="jdt">
|
||||||
|
<view class="jdn" :style="'width:'+sum+'%'">
|
||||||
|
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
<view v-if="buttonContro" class="jddx">
|
||||||
|
{{datacl(beg)}}/{{datacl(downlog)}}
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
|
||||||
|
<view class="" v-if="force==0"
|
||||||
|
style="width: 100%; padding: 0 20rpx; height: 60rpx; margin: 40rpx auto; display: flex; justify-content: space-between;">
|
||||||
|
<view class="" style="width: 70rpx;">
|
||||||
|
|
||||||
|
</view>
|
||||||
|
<view class=""
|
||||||
|
style="width: 240rpx; height: 60rpx; line-height: 60rpx; border-radius: 30rpx; text-align: center; color: #fff; font-size: 24rpx; background-color: #FFD700;"
|
||||||
|
@click="delUpApp">
|
||||||
|
开始更新
|
||||||
|
</view>
|
||||||
|
<view class="" style="font-size: 22rpx; line-height: 80rpx; color: #999;" @click="goindex">
|
||||||
|
暂不更新
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script setup lang="ts">
|
||||||
|
import { onLoad } from '@dcloudio/uni-app';
|
||||||
|
import { ref } from 'vue';
|
||||||
|
|
||||||
|
let buttonContro = ref(false)
|
||||||
|
|
||||||
|
let url = ref('')
|
||||||
|
let force = ref('0')
|
||||||
|
|
||||||
|
// 控制热更新
|
||||||
|
let upShow = ref(true)
|
||||||
|
let sum = ref(0)
|
||||||
|
let downlog = ref(0)
|
||||||
|
let beg = ref(0)
|
||||||
|
let remark = ref('')
|
||||||
|
let type = ref('')
|
||||||
|
|
||||||
|
//模拟请求
|
||||||
|
onLoad((data : any) => {
|
||||||
|
// getdata()
|
||||||
|
url.value = data.url
|
||||||
|
});
|
||||||
|
|
||||||
|
const goindex = function () {
|
||||||
|
uni.navigateBack({
|
||||||
|
delta: 1
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
const getdata = function () {
|
||||||
|
// RegisterService.GetNewVersion().then((res:any)=>{
|
||||||
|
// url.value = res.data.path
|
||||||
|
// downlog.value = res.data.size
|
||||||
|
// force.value = res.data.force
|
||||||
|
// remark.value = res.data.remark
|
||||||
|
// type.value = res.data.type
|
||||||
|
// if(res.data.force=='1'){
|
||||||
|
// delUpApp()
|
||||||
|
// }
|
||||||
|
// })
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
const datacl = function (e : any) {
|
||||||
|
if (e > 1024) {
|
||||||
|
let sl = ((e / 1024) / 1024).toFixed(1)
|
||||||
|
return sl + 'MB'
|
||||||
|
} else {
|
||||||
|
return (e / 1024).toFixed(1) + 'KB'
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
const delUpApp = function () {
|
||||||
|
|
||||||
|
if (buttonContro.value) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
buttonContro.value = true
|
||||||
|
// 1.开始请求下载
|
||||||
|
const downloadTask = uni.downloadFile({
|
||||||
|
url: url.value,
|
||||||
|
success: (downloadResult) => {
|
||||||
|
if (downloadResult.statusCode === 200) {
|
||||||
|
plus.runtime.install(downloadResult.tempFilePath, {
|
||||||
|
force: false
|
||||||
|
}, function () {
|
||||||
|
uni.hideLoading()
|
||||||
|
uni.showToast({
|
||||||
|
title: "下载成功",
|
||||||
|
complete() {
|
||||||
|
if (type.value == 'Bulking') {
|
||||||
|
setTimeout(function () {
|
||||||
|
plus.runtime.restart();
|
||||||
|
}, 2000)
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
})
|
||||||
|
console.log('install success...');
|
||||||
|
}, function (e) {
|
||||||
|
uni.hideLoading()
|
||||||
|
console.log(e, '失败')
|
||||||
|
// uni.$u.toast('下载失败!')
|
||||||
|
// console.error('install fail...');
|
||||||
|
});
|
||||||
|
}
|
||||||
|
},
|
||||||
|
fail(downloadResult) {
|
||||||
|
console.log(downloadResult, '失败')
|
||||||
|
// console.log('下载失败');
|
||||||
|
// uni.$u.toast('下载失败')
|
||||||
|
}
|
||||||
|
});
|
||||||
|
downloadTask.onProgressUpdate((res) => {
|
||||||
|
downlog.value = res.totalBytesExpectedToWrite
|
||||||
|
beg.value = res.totalBytesWritten
|
||||||
|
sum.value = res.progress
|
||||||
|
});
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style lang="scss" setup>
|
||||||
|
.borybac {
|
||||||
|
width: 100vw;
|
||||||
|
height: 100vh;
|
||||||
|
position: fixed;
|
||||||
|
top: 0;
|
||||||
|
left: 0;
|
||||||
|
background-color: #f6f6f6;
|
||||||
|
display: flex;
|
||||||
|
overflow: hidden;
|
||||||
|
|
||||||
|
.up_box {
|
||||||
|
width: 650rpx;
|
||||||
|
height: 1000rpx;
|
||||||
|
margin: 200rpx auto;
|
||||||
|
border-radius: 20rpx;
|
||||||
|
overflow: hidden;
|
||||||
|
position: relative;
|
||||||
|
background-image: url(@/static/index/system/updata.png);
|
||||||
|
background-repeat: no-repeat;
|
||||||
|
background-size: cover;
|
||||||
|
|
||||||
|
.mt50 {
|
||||||
|
display: block;
|
||||||
|
margin-top: 570rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
.jdBox {
|
||||||
|
overflow: hidden;
|
||||||
|
margin-top: 70rpx;
|
||||||
|
display: block;
|
||||||
|
width: 100%;
|
||||||
|
padding: 0 20rpx;
|
||||||
|
|
||||||
|
.jd {
|
||||||
|
display: block;
|
||||||
|
width: 90%;
|
||||||
|
height: 100%;
|
||||||
|
margin: 0 auto;
|
||||||
|
|
||||||
|
.jdbfb {
|
||||||
|
display: block;
|
||||||
|
width: 100%;
|
||||||
|
height: 40rpx;
|
||||||
|
line-height: 40rpx;
|
||||||
|
font-size: 30rpx;
|
||||||
|
color: #FFD700;
|
||||||
|
font-weight: 600;
|
||||||
|
}
|
||||||
|
|
||||||
|
.jdt {
|
||||||
|
margin-top: 10rpx;
|
||||||
|
display: block;
|
||||||
|
width: 100%;
|
||||||
|
height: 23rpx;
|
||||||
|
border-radius: 15rpx;
|
||||||
|
background-color: #E5E5E5;
|
||||||
|
|
||||||
|
.jdn {
|
||||||
|
display: block;
|
||||||
|
height: 23rpx;
|
||||||
|
border-radius: 15rpx;
|
||||||
|
background: radial-gradient(#8370F8 0%, #455FF8 100%);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.jddx {
|
||||||
|
width: 100%;
|
||||||
|
font-size: 24rpx;
|
||||||
|
margin-top: 20rpx;
|
||||||
|
font-weight: 600;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.text {
|
||||||
|
display: block;
|
||||||
|
text-align: center;
|
||||||
|
margin-top: 30rpx;
|
||||||
|
width: 100%;
|
||||||
|
height: 40rpx;
|
||||||
|
font-size: 32rpx;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
@@ -0,0 +1,22 @@
|
|||||||
|
## 1.1.7(2024-10-29)
|
||||||
|
修复底部露出部分组件bug
|
||||||
|
## 1.1.6(2024-08-20)
|
||||||
|
更新本地数据源为最新数据源
|
||||||
|
## 1.1.5(2024-06-12)
|
||||||
|
使用说明文档优化
|
||||||
|
## 1.1.4(2024-06-12)
|
||||||
|
增加问题反馈描述
|
||||||
|
## 1.1.3(2024-02-29)
|
||||||
|
更新使用文档
|
||||||
|
## 1.1.2(2024-01-16)
|
||||||
|
解决Vue3项目导入导出报错问题
|
||||||
|
## 1.1.1(2023-12-06)
|
||||||
|
defaultValue可以传入defaultValue:['河北省','唐山市','丰南区']数组类型以及defaultValue: '420103'地区编码字符串类型
|
||||||
|
## 1.1.0(2023-12-05)
|
||||||
|
即默认值传入地区编码,也支持传入中文省市区数组
|
||||||
|
## 1.0.9(2023-12-04)
|
||||||
|
优化
|
||||||
|
## 1.0.8(2023-10-24)
|
||||||
|
修复东菀市和中山市下各镇的行政编码错误问题
|
||||||
|
## 1.0.4(2023-09-15)
|
||||||
|
改为uni_modules规范
|
||||||
|
After Width: | Height: | Size: 594 B |
@@ -0,0 +1,125 @@
|
|||||||
|
<template>
|
||||||
|
<view class="">
|
||||||
|
<web-view ref="webviewRef" v-if="isshow" :src="url" @message="handleMessage" @logData = "logData"></web-view>
|
||||||
|
|
||||||
|
<!-- ✅ 新增:一个绝对定位的遮罩层,用于在刷新时覆盖 web-view -->
|
||||||
|
<view v-else class="reloading-mask">
|
||||||
|
<up-loading-icon text="正在获取订单状态..." v-if="orderOver" textSize="16"></up-loading-icon>
|
||||||
|
|
||||||
|
<up-loading-icon text="订单已完成" v-else textSize="16"></up-loading-icon>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script setup lang="ts">
|
||||||
|
import { onLoad } from '@dcloudio/uni-app';
|
||||||
|
import { Service } from "@/Service/Service";
|
||||||
|
import { ref, onMounted } from 'vue';
|
||||||
|
import { CNRiderOrderService } from '@/Service/CN/CNRiderOrderService'
|
||||||
|
|
||||||
|
let orderId = ref<string>('')
|
||||||
|
let url = ref<string>('')
|
||||||
|
let isshow = ref<false>(false)
|
||||||
|
|
||||||
|
let orderInfo = ref<any>({
|
||||||
|
isFood: 0
|
||||||
|
})
|
||||||
|
|
||||||
|
let riderOrder = ref<any>({
|
||||||
|
status:0
|
||||||
|
})
|
||||||
|
|
||||||
|
let orderOver = ref<true>(false)
|
||||||
|
|
||||||
|
onLoad((data) => {
|
||||||
|
if (data.orderId) {
|
||||||
|
orderId.value = data.orderId
|
||||||
|
getData()
|
||||||
|
} else {
|
||||||
|
Service.Msg('为获取到订单ID')
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
// 初始化url
|
||||||
|
const getUrl = () => {
|
||||||
|
isshow.value = false
|
||||||
|
url.value = 'https://hmjz.327gzs.top?orderId=' + orderId.value + '&isFood=' + riderOrder.value.status
|
||||||
|
isshow.value = true
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
const getData = () => {
|
||||||
|
CNRiderOrderService.GetUnitOrderInfo(orderId.value).then(res => {
|
||||||
|
if (res.code==0) {
|
||||||
|
orderInfo.value = res.data.orderInfo
|
||||||
|
riderOrder.value = res.data.riderOrder
|
||||||
|
getUrl()
|
||||||
|
|
||||||
|
}else{
|
||||||
|
Service.Msg(res.mgs)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
// 点击完成送餐取餐调用
|
||||||
|
const handleMessage = (data) => {
|
||||||
|
|
||||||
|
let preat = data.detail.data[0]
|
||||||
|
if(preat.action =='message'){
|
||||||
|
if (riderOrder.value.status == 0) {
|
||||||
|
// 去商家、取餐
|
||||||
|
pickFood(1)
|
||||||
|
} else {
|
||||||
|
// 去用户,送餐
|
||||||
|
pickFood(2)
|
||||||
|
}
|
||||||
|
}else if(preat.action =='logData'){
|
||||||
|
CNRiderOrderService.UpdateRiderLocation(preat.data[0],preat.data[1]).then(res=>{
|
||||||
|
if(res.code==0){
|
||||||
|
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
return
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
// 骑手定位
|
||||||
|
const logData = (data) =>{
|
||||||
|
console.log(data,'骑手定位')
|
||||||
|
}
|
||||||
|
|
||||||
|
// 取餐
|
||||||
|
const pickFood = ( type:number) => {
|
||||||
|
CNRiderOrderService.UpdateRiderOrderTake(orderId.value, type).then(res => {
|
||||||
|
if (res.data) {
|
||||||
|
Service.Msg(type==1?'取餐成功':'订单完成')
|
||||||
|
if(type==2){
|
||||||
|
setTimeout(()=>{Service.GoPageTab('/pages/index/index')},500)
|
||||||
|
}
|
||||||
|
getData()
|
||||||
|
} else {
|
||||||
|
Service.Msg(res.msg)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
};
|
||||||
|
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style lang="scss" scoped>
|
||||||
|
.reloading-mask {
|
||||||
|
position: absolute;
|
||||||
|
top: 0;
|
||||||
|
left: 0;
|
||||||
|
right: 0;
|
||||||
|
bottom: 0;
|
||||||
|
background-color: #f7f7f7; // 使用页面底色
|
||||||
|
display: flex;
|
||||||
|
justify-content: center;
|
||||||
|
align-items: center;
|
||||||
|
z-index: 10;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
@@ -0,0 +1,68 @@
|
|||||||
|
import { Service } from '@/Service/Service';
|
||||||
|
/*****订单接口*****/
|
||||||
|
class CNRiderOrderService {
|
||||||
|
private static GetRiderOrderListPath : string = '/Rider/GetRiderOrderList';
|
||||||
|
/*****首页新订单*****/
|
||||||
|
static GetRiderOrderList(page : number) {
|
||||||
|
var result = Service.Request(this.GetRiderOrderListPath, "GET", {page});
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static RiderTakeOrderPath : string = '/Rider/RiderTakeOrder';
|
||||||
|
/*****骑手接单*****/
|
||||||
|
static RiderTakeOrder(orderId : string) {
|
||||||
|
var result = Service.Request(this.RiderTakeOrderPath, "POST", {orderId});
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static GetRiderTakeOrderListPath : string = '/Rider/GetRiderTakeOrderList';
|
||||||
|
/*****首页 待取餐/配送中*****/
|
||||||
|
static GetRiderTakeOrderList(status: number,page : number) {
|
||||||
|
var result = Service.Request(this.GetRiderTakeOrderListPath, "GET", {status,page});
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
private static GetUnitOrderInfoPath : string = '/Order/GetUnitOrderInfo';
|
||||||
|
/*****获取订单详情*****/
|
||||||
|
static GetUnitOrderInfo(orderId: string) {
|
||||||
|
var result = Service.Request(this.GetUnitOrderInfoPath, "GET", {orderId});
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static UpdateRiderOrderTakePath : string = '/Rider/UpdateRiderOrderTake';
|
||||||
|
/*****取餐*****/
|
||||||
|
static UpdateRiderOrderTake(orderId: string,status:number) {
|
||||||
|
var result = Service.Request(this.UpdateRiderOrderTakePath, "POST", {orderId,status});
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static GetRiderAccLogPath : string = '/Rider/GetRiderAccLog';
|
||||||
|
/*****收入列表*****/
|
||||||
|
static GetRiderAccLog(time: string,page:number) {
|
||||||
|
var result = Service.Request(this.GetRiderAccLogPath, "GET", {time,page});
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static AddRiderWithPath : string = '/Rider/AddRiderWith';
|
||||||
|
/*****骑手提现*****/
|
||||||
|
static AddRiderWith(amount: number,payway:string,name:string,account:string) {
|
||||||
|
var result = Service.Request(this.AddRiderWithPath, "POST", {amount,payway,name,account});
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
private static GetRiderWithListPath : string = '/Rider/GetRiderWithList';
|
||||||
|
/*****骑手提现列表*****/
|
||||||
|
static GetRiderWithList(page:number) {
|
||||||
|
var result = Service.Request(this.GetRiderWithListPath, "GET", {page});
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
export {
|
||||||
|
Service,
|
||||||
|
CNRiderOrderService
|
||||||
|
}
|
||||||
|
After Width: | Height: | Size: 632 B |
@@ -0,0 +1,332 @@
|
|||||||
|
<template>
|
||||||
|
<view class="review-management-page">
|
||||||
|
<!-- 全新方案:纯 CSS 手动构建的骨架屏 -->
|
||||||
|
<view v-if="loading" class="skeleton-wrapper">
|
||||||
|
<view class="skeleton-card" style="height: 150rpx;"></view>
|
||||||
|
<view class="skeleton-tabs">
|
||||||
|
<view class="skeleton-item skeleton-text" style="width: 100%; height: 44rpx;"></view>
|
||||||
|
</view>
|
||||||
|
<view v-for="i in 3" :key="i" class="skeleton-card">
|
||||||
|
<view class="skeleton-item skeleton-text" style="width: 100%; height: 300rpx;"></view>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
|
||||||
|
<!-- 页面实际内容 -->
|
||||||
|
<view v-else class="page-content" :class="{'height-pre':showReview}">
|
||||||
|
|
||||||
|
<!-- 1. 数据看板 -->
|
||||||
|
<view class="summary-card">
|
||||||
|
<view class="data-item">
|
||||||
|
<view class="value"><text class="score">{{ satisfaction }}</text><up-icon name="star-fill"
|
||||||
|
color="#ff9900" size="20"></up-icon></view>
|
||||||
|
<text class="label">满意度</text>
|
||||||
|
</view>
|
||||||
|
<view class="data-item">
|
||||||
|
<text class="value">{{total}}</text>
|
||||||
|
<text class="label">总评价数</text>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
|
||||||
|
<!-- 2. Tabs 切换 -->
|
||||||
|
<view class="sticky-tabs-wrapper">
|
||||||
|
<up-tabs :list="reviewTabs" :current="currentTab" @change="onTabChange" lineColor="#fa6400"
|
||||||
|
:activeStyle="{ color: '#fa6400', fontWeight: 'bold' }" :inactiveStyle="{ color: '#666' }">
|
||||||
|
</up-tabs>
|
||||||
|
</view>
|
||||||
|
|
||||||
|
<view class="review-list">
|
||||||
|
<view class="review-card" v-for="review in reviewList" :key="review">
|
||||||
|
<view class="reviewer-info">
|
||||||
|
<text class="name" style="font-weight: bold;" >{{ review.nick }}</text>
|
||||||
|
<up-rate v-model="review.source" readonly activeColor="#ff9900" size="16"></up-rate>
|
||||||
|
<text class="time">{{ Service.formatDate(review.addTime,1) }}</text>
|
||||||
|
</view>
|
||||||
|
<text class="review-text">{{ review.sign }}</text>
|
||||||
|
</view>
|
||||||
|
|
||||||
|
<up-loadmore status="nomore" nomoreText="没有更多评价了"></up-loadmore>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
|
||||||
|
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script setup lang="ts">
|
||||||
|
import { ref, reactive } from 'vue';
|
||||||
|
import { onLoad, onShow } from '@dcloudio/uni-app';
|
||||||
|
import { Service } from "@/Service/Service";
|
||||||
|
import { CNRiderDataService } from '@/Service/CN/CNRiderDataService'
|
||||||
|
|
||||||
|
|
||||||
|
const loading = ref<boolean>(true);
|
||||||
|
const currentTab = ref<number>(0);
|
||||||
|
|
||||||
|
|
||||||
|
let satisfaction = ref(0)
|
||||||
|
let status = ref('nomore')
|
||||||
|
let page = ref(1)
|
||||||
|
|
||||||
|
let showReview = ref(false)
|
||||||
|
let review = ref('')
|
||||||
|
|
||||||
|
let storeInfo = ref<any>()
|
||||||
|
let total = ref(0)
|
||||||
|
|
||||||
|
const reviewTabs = ref([
|
||||||
|
{ name: '全部' }, { name: '好评' }, { name: '差评' }
|
||||||
|
]);
|
||||||
|
|
||||||
|
const reviewList = ref<Array<any>>([]);
|
||||||
|
|
||||||
|
let currentId = ref('')
|
||||||
|
|
||||||
|
onLoad(() => {
|
||||||
|
getData()
|
||||||
|
});
|
||||||
|
onShow(() => { });
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// 获取数据
|
||||||
|
const getData = () => {
|
||||||
|
status.value = 'loadmore'
|
||||||
|
page.value = 1
|
||||||
|
reviewList.value = []
|
||||||
|
getList()
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
const getList = () => {
|
||||||
|
if (status.value == 'loading' || status.value == 'nomore') {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
status.value = 'loading'
|
||||||
|
CNRiderDataService.GetRiderEvaluate(currentTab.value, page.value).then(res => {
|
||||||
|
loading.value = false
|
||||||
|
if (res.data) {
|
||||||
|
satisfaction.value = res.data.satisfaction
|
||||||
|
total.value=res.data.total.value
|
||||||
|
reviewList.value = [...reviewList.value, ...res.data.evaluateList]
|
||||||
|
page.value++
|
||||||
|
status.value = res.data.evaluateList == 10 ? 'loadmore' : 'nomore'
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
const onTabChange = (e : { index : number }) => {
|
||||||
|
currentTab.value = e.index;
|
||||||
|
getData()
|
||||||
|
};
|
||||||
|
|
||||||
|
const replyTo = () => {
|
||||||
|
|
||||||
|
if (review.value == '') {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
};
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style lang="scss" scoped>
|
||||||
|
.height-pre {
|
||||||
|
height: 100vh;
|
||||||
|
overflow: hidden;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@keyframes skeleton-blink {
|
||||||
|
0% {
|
||||||
|
background-position: 100% 50%;
|
||||||
|
}
|
||||||
|
|
||||||
|
100% {
|
||||||
|
background-position: 0 50%;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.skeleton-item {
|
||||||
|
background: linear-gradient(90deg, #f0f0f0 25%, #e0e0e0 50%, #f0f0f0 75%);
|
||||||
|
background-size: 200% 100%;
|
||||||
|
animation: skeleton-blink 1.5s infinite linear;
|
||||||
|
}
|
||||||
|
|
||||||
|
.skeleton-rect {
|
||||||
|
border-radius: 12rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
.skeleton-text {
|
||||||
|
border-radius: 4rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
.skeleton-wrapper {
|
||||||
|
padding: 24rpx;
|
||||||
|
background-color: #f7f7f7;
|
||||||
|
|
||||||
|
.skeleton-tabs {
|
||||||
|
padding: 20rpx 0;
|
||||||
|
background-color: #fff;
|
||||||
|
}
|
||||||
|
|
||||||
|
.skeleton-card {
|
||||||
|
background-color: #fff;
|
||||||
|
padding: 30rpx;
|
||||||
|
border-radius: 16rpx;
|
||||||
|
margin-bottom: 24rpx;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.review-management-page {
|
||||||
|
background-color: #f7f7f7;
|
||||||
|
min-height: 100vh;
|
||||||
|
}
|
||||||
|
|
||||||
|
.summary-card {
|
||||||
|
display: flex;
|
||||||
|
justify-content: space-around;
|
||||||
|
text-align: center;
|
||||||
|
background-color: #fff8f5;
|
||||||
|
border-radius: 16rpx;
|
||||||
|
padding: 30rpx;
|
||||||
|
margin: 24rpx;
|
||||||
|
|
||||||
|
.data-item {
|
||||||
|
.value {
|
||||||
|
font-size: 40rpx;
|
||||||
|
font-weight: bold;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
gap: 4rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
.label {
|
||||||
|
font-size: 24rpx;
|
||||||
|
color: #999;
|
||||||
|
margin-top: 8rpx;
|
||||||
|
display: block;
|
||||||
|
}
|
||||||
|
|
||||||
|
.text-red {
|
||||||
|
color: #fa5151;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.sticky-tabs-wrapper {
|
||||||
|
position: sticky;
|
||||||
|
top: 0;
|
||||||
|
z-index: 10;
|
||||||
|
background-color: #fff;
|
||||||
|
|
||||||
|
:deep(.up-tabs__wrapper__nav__item) {
|
||||||
|
flex: 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
:deep(.up-tabs__wrapper__nav) {
|
||||||
|
position: relative;
|
||||||
|
|
||||||
|
.unread-badge {
|
||||||
|
position: absolute;
|
||||||
|
top: 16rpx;
|
||||||
|
right: 20rpx;
|
||||||
|
background-color: #fa5151;
|
||||||
|
color: #fff;
|
||||||
|
font-size: 20rpx;
|
||||||
|
min-width: 32rpx;
|
||||||
|
height: 32rpx;
|
||||||
|
line-height: 32rpx;
|
||||||
|
border-radius: 16rpx;
|
||||||
|
text-align: center;
|
||||||
|
padding: 0 8rpx;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.review-list {
|
||||||
|
padding: 24rpx;
|
||||||
|
|
||||||
|
.review-card {
|
||||||
|
background-color: #fff;
|
||||||
|
border-radius: 16rpx;
|
||||||
|
padding: 30rpx;
|
||||||
|
margin-bottom: 24rpx;
|
||||||
|
|
||||||
|
&.bad-review {
|
||||||
|
border: 1rpx solid #fef0f0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.reviewer-info {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
gap: 16rpx;
|
||||||
|
|
||||||
|
.name {
|
||||||
|
font-size: 30rpx;
|
||||||
|
font-weight: 500;
|
||||||
|
}
|
||||||
|
|
||||||
|
.time {
|
||||||
|
font-size: 24rpx;
|
||||||
|
color: #999;
|
||||||
|
margin-left: auto;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.review-text {
|
||||||
|
font-size: 28rpx;
|
||||||
|
color: #333;
|
||||||
|
margin: 20rpx 0;
|
||||||
|
display: block;
|
||||||
|
line-height: 1.6;
|
||||||
|
}
|
||||||
|
|
||||||
|
.review-images {
|
||||||
|
display: flex;
|
||||||
|
gap: 16rpx;
|
||||||
|
|
||||||
|
.image-placeholder {
|
||||||
|
width: 160rpx;
|
||||||
|
height: 160rpx;
|
||||||
|
overflow: hidden;
|
||||||
|
border-radius: 8rpx;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.merchant-reply {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
gap: 12rpx;
|
||||||
|
background-color: #f5f5f5;
|
||||||
|
border-radius: 12rpx;
|
||||||
|
padding: 20rpx;
|
||||||
|
margin-top: 20rpx;
|
||||||
|
font-size: 26rpx;
|
||||||
|
|
||||||
|
.reply-label {
|
||||||
|
color: #fa6400;
|
||||||
|
font-weight: 500;
|
||||||
|
}
|
||||||
|
|
||||||
|
.reply-text {
|
||||||
|
color: #666;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.reply-action {
|
||||||
|
text-align: right;
|
||||||
|
margin-top: 20rpx;
|
||||||
|
|
||||||
|
text {
|
||||||
|
display: inline-block;
|
||||||
|
border: 1rpx solid #fa6400;
|
||||||
|
color: #fa6400;
|
||||||
|
font-size: 26rpx;
|
||||||
|
padding: 8rpx 24rpx;
|
||||||
|
border-radius: 30rpx;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</style>
|
||||||
@@ -0,0 +1,423 @@
|
|||||||
|
<template>
|
||||||
|
<!-- 骨架屏 -->
|
||||||
|
<view v-if="loading" class="order-detail skeleton-loading">
|
||||||
|
<!-- 订单基本信息骨架屏 -->
|
||||||
|
<view class="order-basic-info skeleton-section">
|
||||||
|
<view class="" style="display: flex; justify-content: space-between;align-items: center; " >
|
||||||
|
<view class="skeleton-block skeleton-short"></view>
|
||||||
|
<view class="skeleton-block skeleton-short"></view>
|
||||||
|
</view>
|
||||||
|
<view class="skeleton-block skeleton-long"></view>
|
||||||
|
<view class="" style="display: flex; align-items: center; justify-content: space-between;" >
|
||||||
|
<view class="skeleton-block skeleton-medium"></view>
|
||||||
|
<view class="skeleton-block skeleton-medium"></view>
|
||||||
|
</view>
|
||||||
|
<view class="skeleton-block skeleton-medium"></view>
|
||||||
|
<view class="skeleton-block skeleton-long"></view>
|
||||||
|
</view>
|
||||||
|
|
||||||
|
<!-- 物品清单骨架屏 -->
|
||||||
|
<view class="order-basic-info skeleton-section">
|
||||||
|
<view v-for="item in 4" class="skeleton-block" style="width: 100%; height: 40rpx; " ></view>
|
||||||
|
|
||||||
|
<view class="" style="display: flex; justify-content: center;" >
|
||||||
|
<view class="skeleton-block skeleton-short"></view>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
|
||||||
|
<!-- 地图区域骨架屏 -->
|
||||||
|
<view class="map-section skeleton-section">
|
||||||
|
<view class="map-placeholder skeleton-map"></view>
|
||||||
|
</view>
|
||||||
|
|
||||||
|
<!-- 地址区域骨架屏 -->
|
||||||
|
<view class="address-section skeleton-section">
|
||||||
|
<view class="skeleton-block skeleton-medium"></view>
|
||||||
|
<view class="skeleton-block skeleton-long"></view>
|
||||||
|
<view class="skeleton-block skeleton-long"></view>
|
||||||
|
<view class="skeleton-block skeleton-medium"></view>
|
||||||
|
<view class="skeleton-block skeleton-long"></view>
|
||||||
|
<view class="skeleton-block skeleton-long"></view>
|
||||||
|
<view class="skeleton-block skeleton-long"></view>
|
||||||
|
</view>
|
||||||
|
|
||||||
|
<view class="bottom-padding"></view>
|
||||||
|
|
||||||
|
<!-- 底部按钮骨架屏 -->
|
||||||
|
<view class="bottom-action">
|
||||||
|
<view class="skeleton-button"></view>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
<!-- 实际内容 -->
|
||||||
|
<view v-else class="order-detail">
|
||||||
|
<!-- 订单基本信息 -->
|
||||||
|
<view class="order-basic-info">
|
||||||
|
<view class="" style="display: flex; align-items: baseline; justify-content: space-between;">
|
||||||
|
<view class="info-item">
|
||||||
|
<view class="label" style="font-weight: 700; font-size: 30rpx;">30分钟内送达</view>
|
||||||
|
</view>
|
||||||
|
<view class="info-item">
|
||||||
|
<text class="label" style="font-weight: 700;">配送费</text>
|
||||||
|
<text class="value price">¥5.50</text>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
<view class="info-item">
|
||||||
|
<text class="label">订单编号 : </text>
|
||||||
|
<text class="value">20251021123456</text>
|
||||||
|
</view>
|
||||||
|
<view class="info-item" style=" justify-content: space-between;">
|
||||||
|
<view class="">
|
||||||
|
<text class="label">物品明细 : </text>
|
||||||
|
<text class="value">食物</text>
|
||||||
|
</view>
|
||||||
|
<view class="label">共3件商品</view>
|
||||||
|
</view>
|
||||||
|
<view class="info-item">
|
||||||
|
<text class="label">物品重量 : </text>
|
||||||
|
<text class="value">0.5kg</text>
|
||||||
|
</view>
|
||||||
|
<view class="info-item">
|
||||||
|
<view class="label" style="display: flex; align-items: baseline;">
|
||||||
|
<u-icon name="clock" size="24rpx" class="clock-icon"></u-icon>
|
||||||
|
2025-10-17 18:30下单
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
|
||||||
|
</view>
|
||||||
|
|
||||||
|
<!-- 物品清单 -->
|
||||||
|
<view class="order-basic-info">
|
||||||
|
<view class="" style="display: flex; align-items: center; ">
|
||||||
|
<view class="" style="flex: 1; font-size: 34rpx; font-weight: 600; ">
|
||||||
|
物品清单
|
||||||
|
</view>
|
||||||
|
<view class="" style="width: 100rpx; text-align: right; font-size: 30rpx; ">
|
||||||
|
5件
|
||||||
|
</view>
|
||||||
|
<view class="" style="width: 120rpx; text-align: right; font-size: 30rpx; ">
|
||||||
|
¥16
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
<!-- 商品列表 -->
|
||||||
|
<view class="" :style="{'height':isShow?'190rpx':'fit-content' }" style="overflow: hidden;">
|
||||||
|
<view class="" v-for="(goodsItem,goodsIndex) in 5 " :key="goodsIndex"
|
||||||
|
style="display: flex; align-items: center; margin-top: 15rpx; ">
|
||||||
|
<view class="" style="flex: 1; ">
|
||||||
|
康师傅 大食桶红烧牛肉143g/桶 经典红烧酱香免洗桶装速食泡面
|
||||||
|
</view>
|
||||||
|
<view class="" style="width: 100rpx; text-align: right; ">
|
||||||
|
×4
|
||||||
|
</view>
|
||||||
|
<view class="" style="width: 120rpx; text-align: right; ">
|
||||||
|
¥16
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
<view class="" @click="isShow=!isShow"
|
||||||
|
style=" margin-top: 20rpx; display: flex; align-items: center; justify-content: center; color: #666; ">
|
||||||
|
<up-icon :name="isShow?'arrow-down':'arrow-up'" color="#666" size="18"></up-icon>
|
||||||
|
{{isShow?'展开':'收入'}}
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
|
||||||
|
<!-- 地图区域 -->
|
||||||
|
<view class="map-section">
|
||||||
|
<view class="map-placeholder">
|
||||||
|
<text @click="Service.GoPage('/pages/order/navigation')" class="map-hint">点击查看完整导航</text>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
|
||||||
|
<!-- 取餐地址 -->
|
||||||
|
<view class="address-section">
|
||||||
|
<view class="" style=" border-bottom: 4rpx solid #e2e2e2; ">
|
||||||
|
<text class="section-title">取餐地址 : </text>
|
||||||
|
<view class="address-content">
|
||||||
|
<text class="store-name">张亮麻辣烫(五道口店)</text>
|
||||||
|
<text class="address">北京市海淀区成府路28号</text>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
<view style="margin-top: 20rpx; font-size: 30rpx;font-weight: 800;color: #333;">送餐地址 : </view>
|
||||||
|
<view class="address-content">
|
||||||
|
<text class="user-name">张*</text>
|
||||||
|
<text class="address">XX小区3栋502室</text>
|
||||||
|
<view class="remark">
|
||||||
|
<text class="remark-label">备注:</text>
|
||||||
|
<text class="remark-content">请放门口,勿按门铃</text>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
<view class="" style="width: 100vw; height: 140rpx; ">
|
||||||
|
|
||||||
|
</view>
|
||||||
|
|
||||||
|
<!-- 底部按钮 -->
|
||||||
|
<view class="bottom-action">
|
||||||
|
<up-button color="var(--nav-mian)" class="confirm-btn">立即接单</up-button>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script setup lang="ts">
|
||||||
|
import { onLoad } from '@dcloudio/uni-app';
|
||||||
|
import { ref, onMounted } from 'vue';
|
||||||
|
import { Service } from '@/Service/Service';
|
||||||
|
|
||||||
|
// 加载状态
|
||||||
|
const loading = ref(true);
|
||||||
|
|
||||||
|
let orderStatus = ref(0)
|
||||||
|
|
||||||
|
let isShow = ref(true)
|
||||||
|
|
||||||
|
onLoad(() => {
|
||||||
|
setTimeout(() => {
|
||||||
|
loading.value = false
|
||||||
|
}, 1000)
|
||||||
|
})
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style scoped>
|
||||||
|
.order-detail {
|
||||||
|
min-height: 100vh;
|
||||||
|
background-color: #f5f5f5;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 订单状态样式 */
|
||||||
|
.order-status {
|
||||||
|
background-color: #fff;
|
||||||
|
padding: 30rpx;
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* 订单基本信息样式 */
|
||||||
|
.order-basic-info {
|
||||||
|
background-color: #fff;
|
||||||
|
margin: 20rpx 20rpx;
|
||||||
|
padding: 30rpx;
|
||||||
|
border-radius: 20rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
.info-item {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
margin-bottom: 20rpx;
|
||||||
|
font-size: 28rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
.info-item:last-child {
|
||||||
|
margin-bottom: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.label {
|
||||||
|
color: #666;
|
||||||
|
margin-right: 10rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
.value {
|
||||||
|
color: #333;
|
||||||
|
}
|
||||||
|
|
||||||
|
.value.highlight {
|
||||||
|
color: var(--nav-diluted);
|
||||||
|
font-weight: 500;
|
||||||
|
}
|
||||||
|
|
||||||
|
.value.price {
|
||||||
|
color: var(--nav-diluted);
|
||||||
|
font-weight: 700;
|
||||||
|
}
|
||||||
|
|
||||||
|
.clock-icon {
|
||||||
|
color: #666;
|
||||||
|
margin-right: 8rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 地图区域样式 */
|
||||||
|
.map-section {
|
||||||
|
margin: 20rpx;
|
||||||
|
border-radius: 20rpx;
|
||||||
|
overflow: hidden;
|
||||||
|
}
|
||||||
|
|
||||||
|
.map-placeholder {
|
||||||
|
width: 100%;
|
||||||
|
height: 400rpx;
|
||||||
|
background-color: #f0f0f0;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
position: relative;
|
||||||
|
border: 1rpx solid #e8e8e8;
|
||||||
|
}
|
||||||
|
|
||||||
|
.map-placeholder::before {
|
||||||
|
content: '';
|
||||||
|
position: absolute;
|
||||||
|
top: 0;
|
||||||
|
left: 0;
|
||||||
|
right: 0;
|
||||||
|
bottom: 0;
|
||||||
|
background: linear-gradient(135deg, #f5f5f5 25%, #e6e6e6 25%, #e6e6e6 50%, #f5f5f5 50%, #f5f5f5 75%, #e6e6e6 75%, #e6e6e6 100%);
|
||||||
|
background-size: 20rpx 20rpx;
|
||||||
|
opacity: 0.3;
|
||||||
|
}
|
||||||
|
|
||||||
|
.map-hint {
|
||||||
|
font-size: 28rpx;
|
||||||
|
color: #666;
|
||||||
|
position: relative;
|
||||||
|
z-index: 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 地址区域样式 */
|
||||||
|
.address-section {
|
||||||
|
background-color: #fff;
|
||||||
|
margin: 20rpx;
|
||||||
|
padding: 30rpx;
|
||||||
|
border-radius: 20rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
.section-title {
|
||||||
|
font-size: 30rpx;
|
||||||
|
font-weight: 800;
|
||||||
|
color: #333;
|
||||||
|
margin-bottom: 25rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
.address-content {
|
||||||
|
position: relative;
|
||||||
|
}
|
||||||
|
|
||||||
|
.store-name,
|
||||||
|
.user-name {
|
||||||
|
font-size: 34rpx;
|
||||||
|
font-weight: 600;
|
||||||
|
margin-bottom: 15rpx;
|
||||||
|
display: block;
|
||||||
|
}
|
||||||
|
|
||||||
|
.address {
|
||||||
|
font-size: 26rpx;
|
||||||
|
color: #666;
|
||||||
|
line-height: 1.5;
|
||||||
|
margin-bottom: 25rpx;
|
||||||
|
display: block;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
.pickup-code,
|
||||||
|
.remark {
|
||||||
|
font-size: 26rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
.code-label,
|
||||||
|
.code-value {
|
||||||
|
color: var(--nav-mian);
|
||||||
|
font-weight: 600;
|
||||||
|
}
|
||||||
|
|
||||||
|
.remark-label,
|
||||||
|
.remark-content {
|
||||||
|
color: #FAAD14;
|
||||||
|
font-weight: 600;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 底部按钮样式 */
|
||||||
|
.bottom-action {
|
||||||
|
background-color: #fff;
|
||||||
|
width: 100vw;
|
||||||
|
position: fixed;
|
||||||
|
bottom: 0;
|
||||||
|
left: 0;
|
||||||
|
padding: 20rpx 30rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
.confirm-btn {
|
||||||
|
width: 100%;
|
||||||
|
height: 90rpx;
|
||||||
|
font-size: 32rpx;
|
||||||
|
line-height: 90rpx;
|
||||||
|
border-radius: 45rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 骨架屏样式 */
|
||||||
|
.skeleton-loading .skeleton-section {
|
||||||
|
margin: 20rpx 20rpx;
|
||||||
|
padding: 30rpx;
|
||||||
|
border-radius: 20rpx;
|
||||||
|
background-color: #fff;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
.skeleton-block {
|
||||||
|
background-color: #f0f0f0;
|
||||||
|
margin-bottom: 20rpx;
|
||||||
|
border-radius: 4rpx;
|
||||||
|
position: relative;
|
||||||
|
overflow: hidden;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
.skeleton-short {
|
||||||
|
height: 40rpx;
|
||||||
|
width: 30%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.skeleton-medium {
|
||||||
|
height: 30rpx;
|
||||||
|
width: 30%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.skeleton-long {
|
||||||
|
height: 30rpx;
|
||||||
|
width: 90%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.skeleton-map {
|
||||||
|
height: 400rpx;
|
||||||
|
background-color: #f0f0f0;
|
||||||
|
border-radius: 20rpx;
|
||||||
|
margin: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.skeleton-button {
|
||||||
|
height: 90rpx;
|
||||||
|
background-color: #f0f0f0;
|
||||||
|
border-radius: 45rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
.bottom-padding {
|
||||||
|
height: 140rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 骨架屏动画 */
|
||||||
|
.skeleton-block::after,
|
||||||
|
.skeleton-map::after,
|
||||||
|
.skeleton-button::after {
|
||||||
|
content: '';
|
||||||
|
position: absolute;
|
||||||
|
top: 0;
|
||||||
|
left: 0;
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
background: linear-gradient(90deg, transparent, rgba(255, 255, 255, 0.2), transparent);
|
||||||
|
animation: shimmer 1.5s infinite;
|
||||||
|
}
|
||||||
|
|
||||||
|
@keyframes shimmer {
|
||||||
|
0% {
|
||||||
|
transform: translateX(-100%);
|
||||||
|
}
|
||||||
|
|
||||||
|
100% {
|
||||||
|
transform: translateX(100%);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</style>
|
||||||
@@ -0,0 +1,494 @@
|
|||||||
|
<template>
|
||||||
|
<!-- 骨架屏 -->
|
||||||
|
<view v-if="loading" class="task-list-container skeleton-loading">
|
||||||
|
<!-- 顶部标签栏 -->
|
||||||
|
<view class="tab-bar">
|
||||||
|
<view v-for="(tab, index) in tabs" :key="index" class="tab-item">
|
||||||
|
<view class="skeleton-tab-text"></view>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
<view class="" style="width: 100vw; height: 120rpx"> </view>
|
||||||
|
|
||||||
|
<!-- 骨架屏订单列表 -->
|
||||||
|
<view class="order-list">
|
||||||
|
<!-- 骨架屏任务卡片 1 -->
|
||||||
|
<view v-for="item in 3" class="task-section skeleton-card">
|
||||||
|
<view class="" style="display: flex; align-items: center; justify-content: space-between;" >
|
||||||
|
<view class="skeleton-tag"></view>
|
||||||
|
<view class="skeleton-time-group">
|
||||||
|
<view class="icon-placeholder"></view>
|
||||||
|
<view class="skeleton-time-text"></view>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
<view class="skeleton-merchant-info">
|
||||||
|
<view class="skeleton-merchant-name"></view>
|
||||||
|
<view class="skeleton-distance"></view>
|
||||||
|
</view>
|
||||||
|
<view class="skeleton-address-info">
|
||||||
|
<view class="icon-placeholder"></view>
|
||||||
|
<view class="skeleton-address-text"></view>
|
||||||
|
</view>
|
||||||
|
<view class="skeleton-price-time-row">
|
||||||
|
<view class="skeleton-price"></view>
|
||||||
|
<view class="skeleton-time-group">
|
||||||
|
<view class="icon-placeholder"></view>
|
||||||
|
<view class="skeleton-time-text"></view>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
<view class="skeleton-button"></view>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
<view class="" style="width: 100vw; display: flex; justify-content: center; margin-top: 20rpx; " >
|
||||||
|
<view class="" style="width: 200rpx; height: 40rpx; background-color: #fff; border-radius: 4rpx; " >
|
||||||
|
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
|
||||||
|
|
||||||
|
</view>
|
||||||
|
|
||||||
|
|
||||||
|
<view v-else class="task-list-container">
|
||||||
|
<!-- 顶部标签栏 -->
|
||||||
|
<view class="tab-bar">
|
||||||
|
<view v-for="(tab, index) in tabs" :key="index" class="tab-item" :class="{ active: activeTab === index }"
|
||||||
|
@click="switchTab(index)">
|
||||||
|
<text class="tab-text">{{ tab }}</text>
|
||||||
|
<view v-if="activeTab === index" class="active-line"></view>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
<view class="" style="width: 100vw; height: 120rpx; ">
|
||||||
|
|
||||||
|
</view>
|
||||||
|
<!-- 订单列表 -->
|
||||||
|
<view class="order-list">
|
||||||
|
<view @click="gopage()" v-for="(orderItem,orderIndex) in 3 " :key="orderIndex" class="task-section">
|
||||||
|
<!-- 高价单标签 -->
|
||||||
|
<view class="" style="display: flex; align-items: center; justify-content: space-between;">
|
||||||
|
<view v-if="activeTab==0" class="high-price-tag" style="border-radius: 8rpx;" >
|
||||||
|
<image :src="Service.GetIconImg('/static/index/task/fire.png')" style="width: 24rpx; height: 24rpx;" mode=""></image>
|
||||||
|
<text class="high-price-text" style="margin-left: 4rpx;" >高价单</text>
|
||||||
|
</view>
|
||||||
|
<view v-else class="high-price-tag" :style="{'border':activeTab==1?'1rpx solid #52C41A':'1rpx solid #FAAD14','color':activeTab==1?'#52C41A':'#FAAD14' }" style="background-color: #fff;" >
|
||||||
|
<text class="high-price-text">{{activeTab==1?'待取单':'配送中'}}</text>
|
||||||
|
</view>
|
||||||
|
<view class="" v-if="activeTab!==0" style="display: flex; align-items: baseline;">
|
||||||
|
<up-icon name="phone" color="var(--nav-mian)" size="20"></up-icon>
|
||||||
|
<text style="margin-left: 10rpx; color: var(--nav-mian); ">拨打商家</text>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
|
||||||
|
<!-- 商家信息 -->
|
||||||
|
<view class="merchant-info">
|
||||||
|
<text class="merchant-name">老北京炸酱面</text>
|
||||||
|
<text class="distance">500m</text>
|
||||||
|
</view>
|
||||||
|
|
||||||
|
<!-- 地址信息 -->
|
||||||
|
<view class="address-info">
|
||||||
|
<up-icon name="map" color="#999" size="24rpx" />
|
||||||
|
<text class="address-text">北京市朝阳区三里屯SOHO</text>
|
||||||
|
<text v-if="activeTab!==0" class="address-text">共3件商品</text>
|
||||||
|
</view>
|
||||||
|
<!-- 商品次数-->
|
||||||
|
<view v-if="activeTab==1" class="address-info">
|
||||||
|
<text class="address-text">共3件商品</text>
|
||||||
|
</view>
|
||||||
|
|
||||||
|
<!-- 价格和取餐时间 -->
|
||||||
|
<view class="price-time-row">
|
||||||
|
<view v-if="activeTab==0" class="">
|
||||||
|
<text class="price">¥5.50</text>
|
||||||
|
<text style="color: var(--nav-mian); font-weight: 600; margin-left: 10rpx; ">/单</text>
|
||||||
|
</view>
|
||||||
|
<view v-if="activeTab==1" class="">
|
||||||
|
<text style="font-size: 30rpx; font-weight: 600; color: #1890FF; ">取件码: </text>
|
||||||
|
<text style="color: var(--nav-mian); font-weight: 600; margin-left: 10rpx; ">A121</text>
|
||||||
|
</view>
|
||||||
|
<view v-if="activeTab==2" class="">
|
||||||
|
<text class="address-text">据您1.2km</text>
|
||||||
|
</view>
|
||||||
|
<view class="pickup-time">
|
||||||
|
<up-icon name="clock" color="#FF9500" size="24rpx" />
|
||||||
|
<text class="time-text" :style="{'color':activeTab==0?'#FAAD14':'#FF0000'}" >{{activeTab==0?'12:30 前取餐':'12:30 前送达'}}</text>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
|
||||||
|
<!-- 立即抢单按钮 -->
|
||||||
|
<up-button type="primary" @click="buttonClick()" :color="activeTab==0?'#1890FF':(activeTab==1?'#52C41A':'#52C41A')" size="large" class="grab-btn">{{ activeTab==0?'立即抢单':(activeTab==1?'我已取餐':'确认送达') }}</up-button>
|
||||||
|
</view>
|
||||||
|
|
||||||
|
<!-- 没有更多任务提示 -->
|
||||||
|
<up-loadmore :status="status" />
|
||||||
|
<view class="" style="width: 100vw; height: 60rpx; " ></view>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script setup lang="ts">
|
||||||
|
import { onLoad } from '@dcloudio/uni-app'
|
||||||
|
import { ref } from 'vue'
|
||||||
|
import { Service } from '@/Service/Service'
|
||||||
|
|
||||||
|
let loading = ref(true)
|
||||||
|
// 标签数据
|
||||||
|
const tabs = ['新任务', '待取货', '配送中']
|
||||||
|
const activeTab = ref(0)
|
||||||
|
let status = ref('nomore')
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
onLoad(() => {
|
||||||
|
setTimeout(() => {
|
||||||
|
loading.value = false
|
||||||
|
}, 1000)
|
||||||
|
})
|
||||||
|
|
||||||
|
// 页面跳转
|
||||||
|
const gopage = () => {
|
||||||
|
if (activeTab.value == 0) {
|
||||||
|
Service.GoPage('/pages/order/grabOrder')
|
||||||
|
} else {
|
||||||
|
Service.GoPage('/pages/order/orderDetail')
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
const buttonClick=()=>{
|
||||||
|
|
||||||
|
if(activeTab.value==2){
|
||||||
|
Service.GoPage('/pages/order/finish')
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 切换标签
|
||||||
|
const switchTab = (index : number) => {
|
||||||
|
activeTab.value = index
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style scoped>
|
||||||
|
page {
|
||||||
|
background-color: #F5F5F5;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 顶部标签栏 */
|
||||||
|
.tab-bar {
|
||||||
|
display: flex;
|
||||||
|
background-color: #FFFFFF;
|
||||||
|
padding: 20rpx 0 0;
|
||||||
|
border-bottom: 1rpx solid #E5E5E5;
|
||||||
|
position: fixed;
|
||||||
|
top: 0;
|
||||||
|
left: 0;
|
||||||
|
width: 100vw;
|
||||||
|
background-color: #fff;
|
||||||
|
}
|
||||||
|
|
||||||
|
.tab-item {
|
||||||
|
flex: 1;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
align-items: center;
|
||||||
|
padding: 20rpx 0;
|
||||||
|
position: relative;
|
||||||
|
}
|
||||||
|
|
||||||
|
.tab-text {
|
||||||
|
font-size: 28rpx;
|
||||||
|
color: #666666;
|
||||||
|
}
|
||||||
|
|
||||||
|
.tab-item.active .tab-text {
|
||||||
|
color: var(--nav-mian);
|
||||||
|
font-weight: 600;
|
||||||
|
}
|
||||||
|
|
||||||
|
.active-line {
|
||||||
|
position: absolute;
|
||||||
|
bottom: 0;
|
||||||
|
width: 110rpx;
|
||||||
|
height: 6rpx;
|
||||||
|
background-color: var(--nav-mian);
|
||||||
|
border-radius: 3rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 订单列表 */
|
||||||
|
.order-list {
|
||||||
|
padding: 0rpx 30rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
.task-section {
|
||||||
|
margin-top: 20rpx;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
background-color: #fff;
|
||||||
|
border-radius: 20rpx;
|
||||||
|
padding: 20rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* 标签样式 */
|
||||||
|
.high-price-tag {
|
||||||
|
width: fit-content;
|
||||||
|
background-color: #FF7875;
|
||||||
|
color: #FFFFFF;
|
||||||
|
padding: 5rpx 20rpx;
|
||||||
|
border-radius: 20rpx;
|
||||||
|
font-size: 24rpx;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.status-tag {
|
||||||
|
position: absolute;
|
||||||
|
top: 20rpx;
|
||||||
|
left: 20rpx;
|
||||||
|
padding: 5rpx 20rpx;
|
||||||
|
border-radius: 20rpx;
|
||||||
|
font-size: 24rpx;
|
||||||
|
z-index: 10;
|
||||||
|
}
|
||||||
|
|
||||||
|
.status-tag.pending {
|
||||||
|
background-color: #4CD964;
|
||||||
|
color: #FFFFFF;
|
||||||
|
}
|
||||||
|
|
||||||
|
.status-tag.delivering {
|
||||||
|
background-color: #FF9500;
|
||||||
|
color: #FFFFFF;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 右侧操作按钮 */
|
||||||
|
.right-action {
|
||||||
|
position: absolute;
|
||||||
|
top: 20rpx;
|
||||||
|
right: 20rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
.call-btn {
|
||||||
|
padding: 5rpx 15rpx;
|
||||||
|
font-size: 24rpx;
|
||||||
|
line-height: 36rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 信息展示 */
|
||||||
|
.merchant-info {
|
||||||
|
margin-top: 20rpx;
|
||||||
|
display: flex;
|
||||||
|
justify-content: space-between;
|
||||||
|
align-items: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.merchant-name {
|
||||||
|
font-size: 34rpx;
|
||||||
|
font-weight: 600;
|
||||||
|
color: #333333;
|
||||||
|
}
|
||||||
|
|
||||||
|
.distance {
|
||||||
|
font-size: 28rpx;
|
||||||
|
color: #666666;
|
||||||
|
}
|
||||||
|
|
||||||
|
.address-info {
|
||||||
|
display: flex;
|
||||||
|
align-items: baseline;
|
||||||
|
margin-top: 15rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
.address-text {
|
||||||
|
margin-left: 10rpx;
|
||||||
|
font-size: 28rpx;
|
||||||
|
color: #666666;
|
||||||
|
flex: 1;
|
||||||
|
overflow: hidden;
|
||||||
|
text-overflow: ellipsis;
|
||||||
|
white-space: nowrap;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 价格和时间 */
|
||||||
|
.price-time-row {
|
||||||
|
margin-top: 20rpx;
|
||||||
|
display: flex;
|
||||||
|
justify-content: space-between;
|
||||||
|
align-items: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.price {
|
||||||
|
font-size: 36rpx;
|
||||||
|
font-weight: 600;
|
||||||
|
color: #FF3B30;
|
||||||
|
}
|
||||||
|
|
||||||
|
.pickup-code {
|
||||||
|
font-size: 28rpx;
|
||||||
|
color: #333333;
|
||||||
|
font-weight: 500;
|
||||||
|
}
|
||||||
|
|
||||||
|
.pickup-time {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.time-text {
|
||||||
|
margin-left: 8rpx;
|
||||||
|
font-size: 26rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 按钮样式 */
|
||||||
|
.grab-btn {
|
||||||
|
margin-top: 25rpx;
|
||||||
|
height: 80rpx;
|
||||||
|
line-height: 80rpx;
|
||||||
|
border-radius: 40rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
.grab-btn {
|
||||||
|
background-color: #007AFF;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 没有更多任务 */
|
||||||
|
.no-more-tasks {
|
||||||
|
margin-top: 40rpx;
|
||||||
|
text-align: center;
|
||||||
|
padding: 20rpx 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.no-more-text {
|
||||||
|
font-size: 28rpx;
|
||||||
|
color: #999999;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 骨架屏样式 */
|
||||||
|
.skeleton-loading .skeleton-card {
|
||||||
|
background-color: #fff;
|
||||||
|
border-radius: 20rpx;
|
||||||
|
padding: 20rpx;
|
||||||
|
position: relative;
|
||||||
|
overflow: hidden;
|
||||||
|
}
|
||||||
|
|
||||||
|
.skeleton-tab-text {
|
||||||
|
width: 80rpx;
|
||||||
|
height: 30rpx;
|
||||||
|
background-color: #f0f0f0;
|
||||||
|
border-radius: 4rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
.skeleton-tag {
|
||||||
|
width: 100rpx;
|
||||||
|
height: 30rpx;
|
||||||
|
background-color: #f0f0f0;
|
||||||
|
border-radius: 15rpx;
|
||||||
|
margin-bottom: 20rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
.skeleton-merchant-info {
|
||||||
|
display: flex;
|
||||||
|
justify-content: space-between;
|
||||||
|
align-items: center;
|
||||||
|
margin-bottom: 15rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
.skeleton-merchant-name {
|
||||||
|
width: 200rpx;
|
||||||
|
height: 34rpx;
|
||||||
|
background-color: #f0f0f0;
|
||||||
|
border-radius: 4rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
.skeleton-distance {
|
||||||
|
width: 60rpx;
|
||||||
|
height: 28rpx;
|
||||||
|
background-color: #f0f0f0;
|
||||||
|
border-radius: 4rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
.skeleton-address-info {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
margin-bottom: 20rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
.icon-placeholder {
|
||||||
|
width: 24rpx;
|
||||||
|
height: 24rpx;
|
||||||
|
background-color: #f0f0f0;
|
||||||
|
border-radius: 4rpx;
|
||||||
|
margin-right: 10rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
.skeleton-address-text {
|
||||||
|
width: 400rpx;
|
||||||
|
height: 28rpx;
|
||||||
|
background-color: #f0f0f0;
|
||||||
|
border-radius: 4rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
.skeleton-price-time-row {
|
||||||
|
display: flex;
|
||||||
|
justify-content: space-between;
|
||||||
|
align-items: center;
|
||||||
|
margin-bottom: 25rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
.skeleton-price {
|
||||||
|
width: 80rpx;
|
||||||
|
height: 36rpx;
|
||||||
|
background-color: #f0f0f0;
|
||||||
|
border-radius: 4rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
.skeleton-time-group {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.skeleton-time-text {
|
||||||
|
width: 150rpx;
|
||||||
|
height: 26rpx;
|
||||||
|
background-color: #f0f0f0;
|
||||||
|
border-radius: 4rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
.skeleton-button {
|
||||||
|
width: 100%;
|
||||||
|
height: 80rpx;
|
||||||
|
background-color: #f0f0f0;
|
||||||
|
border-radius: 40rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 骨架屏动画 */
|
||||||
|
.skeleton-card .skeleton-tag::after,
|
||||||
|
.skeleton-card .skeleton-merchant-name::after,
|
||||||
|
.skeleton-card .skeleton-distance::after,
|
||||||
|
.skeleton-card .skeleton-address-text::after,
|
||||||
|
.skeleton-card .icon-placeholder::after,
|
||||||
|
.skeleton-card .skeleton-price::after,
|
||||||
|
.skeleton-card .skeleton-time-text::after,
|
||||||
|
.skeleton-card .skeleton-button::after,
|
||||||
|
.skeleton-loading .skeleton-tab-text::after {
|
||||||
|
content: '';
|
||||||
|
position: absolute;
|
||||||
|
top: 0;
|
||||||
|
left: 0;
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
background: linear-gradient(90deg, transparent, rgba(255, 255, 255, 0.2), transparent);
|
||||||
|
animation: shimmer 1.5s infinite;
|
||||||
|
}
|
||||||
|
|
||||||
|
@keyframes shimmer {
|
||||||
|
0% {
|
||||||
|
transform: translateX(-100%);
|
||||||
|
}
|
||||||
|
|
||||||
|
100% {
|
||||||
|
transform: translateX(100%);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</style>
|
||||||
@@ -0,0 +1,476 @@
|
|||||||
|
<template>
|
||||||
|
|
||||||
|
<view class="skeleton-container" v-if="isLoading">
|
||||||
|
<!-- 顶部提示栏骨架 -->
|
||||||
|
<view class="skeleton-top-tip"></view>
|
||||||
|
|
||||||
|
<!-- 身份信息区域骨架 -->
|
||||||
|
<view class="skeleton-section">
|
||||||
|
<view class="skeleton-title"></view>
|
||||||
|
<view class="skeleton-form-item">
|
||||||
|
<view class="skeleton-label"></view>
|
||||||
|
<view class="skeleton-input"></view>
|
||||||
|
</view>
|
||||||
|
<view class="skeleton-form-item">
|
||||||
|
<view class="skeleton-label"></view>
|
||||||
|
<view class="skeleton-input"></view>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
|
||||||
|
<!-- 身份证照片区域骨架 -->
|
||||||
|
<view class="skeleton-section">
|
||||||
|
<view class="skeleton-title"></view>
|
||||||
|
<view class="skeleton-upload-item"></view>
|
||||||
|
<view class="skeleton-upload-item"></view>
|
||||||
|
</view>
|
||||||
|
|
||||||
|
<!-- 人脸识别区域骨架 -->
|
||||||
|
<view class="skeleton-section">
|
||||||
|
<view class="skeleton-title"></view>
|
||||||
|
<view class="skeleton-face-area">
|
||||||
|
<view class="skeleton-face-icon"></view>
|
||||||
|
<view class="skeleton-face-text"></view>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
|
||||||
|
<!-- 协议勾选骨架 -->
|
||||||
|
<view class="skeleton-agreement"></view>
|
||||||
|
|
||||||
|
<!-- 提交按钮骨架 -->
|
||||||
|
<view class="skeleton-submit"></view>
|
||||||
|
</view>
|
||||||
|
|
||||||
|
|
||||||
|
<view v-else class="real-name-auth-container">
|
||||||
|
<!-- 顶部提示栏 -->
|
||||||
|
<view class="top-tip">
|
||||||
|
<text class="tip-text">请完成实名认证,保障您的接单权益</text>
|
||||||
|
</view>
|
||||||
|
|
||||||
|
<!-- 表单内容 -->
|
||||||
|
<view class="form-content">
|
||||||
|
<!-- 身份信息区域 -->
|
||||||
|
<view class="section">
|
||||||
|
<view class="section-title">身份信息</view>
|
||||||
|
|
||||||
|
<!-- 姓名输入 -->
|
||||||
|
<view class="form-item">
|
||||||
|
<view class="label">姓名</view>
|
||||||
|
<u-input v-model="formData.name" placeholder="请输入身份证姓名" placeholder-color="#999" border="none"
|
||||||
|
class="input" input-align="right" />
|
||||||
|
</view>
|
||||||
|
|
||||||
|
<!-- 身份证号输入 -->
|
||||||
|
<view class="form-item">
|
||||||
|
<view class="label">身份证号</view>
|
||||||
|
<u-input v-model="formData.idCard" placeholder="请输入18位身份证号" placeholder-color="#999" border="none"
|
||||||
|
class="input" input-align="right" maxlength="18" />
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
|
||||||
|
<!-- 身份证照片区域 -->
|
||||||
|
<view class="section">
|
||||||
|
<view class="section-title">身份证照片</view>
|
||||||
|
|
||||||
|
<!-- 上传身份证正面 -->
|
||||||
|
<view class="upload-item">
|
||||||
|
<view class="upload-area bordered-area">
|
||||||
|
<view class="upload-content">
|
||||||
|
<view class="upload-icon">+</view>
|
||||||
|
<view class="upload-text">上传身份证正面</view>
|
||||||
|
</view>
|
||||||
|
<!-- 显示上传后的占位图 -->
|
||||||
|
<view v-if="formData.frontImage" class="uploaded-placeholder">
|
||||||
|
<text>身份证正面</text>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
|
||||||
|
<!-- 上传身份证反面 -->
|
||||||
|
<view class="upload-item">
|
||||||
|
<view class="upload-area bordered-area">
|
||||||
|
<view class="upload-content">
|
||||||
|
<view class="upload-icon">+</view>
|
||||||
|
<view class="upload-text">上传身份证反面</view>
|
||||||
|
</view>
|
||||||
|
<!-- 显示上传后的占位图 -->
|
||||||
|
<view v-if="formData.backImage" class="uploaded-placeholder">
|
||||||
|
<text>身份证反面</text>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
|
||||||
|
<!-- 人脸识别区域 -->
|
||||||
|
<view class="section">
|
||||||
|
<view class="section-title">人脸验证</view>
|
||||||
|
|
||||||
|
<view class="face-verify-area" @click="handleFaceVerify">
|
||||||
|
<view class="face-icon">
|
||||||
|
<up-icon name="account" size="60" color="#1890ff"></up-icon>
|
||||||
|
</view>
|
||||||
|
<view class="face-text">点击进行人脸识别</view>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
|
||||||
|
<!-- 协议勾选 -->
|
||||||
|
<view class="agreement-section">
|
||||||
|
<u-checkbox v-model="formData.agreed" shape="circle" class="checkbox" />
|
||||||
|
<text class="agreement-text">我已阅读并同意</text>
|
||||||
|
<text class="agreement-link" @click="handleAgreementClick">《骑手实名认证协议》</text>
|
||||||
|
</view>
|
||||||
|
|
||||||
|
<!-- 提交按钮 -->
|
||||||
|
<view class="submit-section">
|
||||||
|
<u-button type="primary" class="submit-btn" size="large">
|
||||||
|
提交认证
|
||||||
|
</u-button>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script setup lang="ts">
|
||||||
|
import { onLoad } from '@dcloudio/uni-app';
|
||||||
|
import { ref, computed } from 'vue';
|
||||||
|
|
||||||
|
let isLoading = ref(true)
|
||||||
|
|
||||||
|
// 表单数据
|
||||||
|
const formData = ref({
|
||||||
|
name: '',
|
||||||
|
idCard: '',
|
||||||
|
frontImage: '',
|
||||||
|
backImage: '',
|
||||||
|
agreed: false
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
|
onLoad(() => {
|
||||||
|
setTimeout(() => {
|
||||||
|
isLoading.value = false
|
||||||
|
}, 1000)
|
||||||
|
})
|
||||||
|
|
||||||
|
// 处理人脸识别
|
||||||
|
const handleFaceVerify = () => {
|
||||||
|
// 在实际应用中,这里会调用人脸识别相关API
|
||||||
|
console.log('开始人脸识别');
|
||||||
|
};
|
||||||
|
|
||||||
|
// 处理协议点击
|
||||||
|
const handleAgreementClick = () => {
|
||||||
|
// 打开协议详情
|
||||||
|
console.log('打开协议详情');
|
||||||
|
};
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style scoped lang="scss">
|
||||||
|
page {
|
||||||
|
background-color: #f5f5f5;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 骨架屏样式 */
|
||||||
|
.skeleton-container {
|
||||||
|
padding: 0 30rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
.skeleton-top-tip {
|
||||||
|
height: 70rpx;
|
||||||
|
width: 100%;
|
||||||
|
background-color: #e6f7ff;
|
||||||
|
margin: 20rpx 0;
|
||||||
|
border-radius: 10rpx;
|
||||||
|
animation: skeleton-loading 1.5s infinite ease-in-out;
|
||||||
|
}
|
||||||
|
|
||||||
|
.skeleton-section {
|
||||||
|
margin-bottom: 40rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
.skeleton-title {
|
||||||
|
height: 32rpx;
|
||||||
|
width: 160rpx;
|
||||||
|
background-color: #e6e6e6;
|
||||||
|
border-radius: 16rpx;
|
||||||
|
margin-bottom: 20rpx;
|
||||||
|
animation: skeleton-loading 1.5s infinite ease-in-out;
|
||||||
|
}
|
||||||
|
|
||||||
|
.skeleton-form-item {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
background-color: #fff;
|
||||||
|
padding: 30rpx;
|
||||||
|
border-bottom: 1rpx solid #f0f0f0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.skeleton-form-item:last-child {
|
||||||
|
border-bottom: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
.skeleton-label {
|
||||||
|
height: 28rpx;
|
||||||
|
width: 120rpx;
|
||||||
|
background-color: #e6e6e6;
|
||||||
|
border-radius: 14rpx;
|
||||||
|
animation: skeleton-loading 1.5s infinite ease-in-out;
|
||||||
|
}
|
||||||
|
|
||||||
|
.skeleton-input {
|
||||||
|
height: 28rpx;
|
||||||
|
width: calc(100% - 140rpx);
|
||||||
|
background-color: #e6e6e6;
|
||||||
|
margin-left: 20rpx;
|
||||||
|
border-radius: 14rpx;
|
||||||
|
animation: skeleton-loading 1.5s infinite ease-in-out;
|
||||||
|
}
|
||||||
|
|
||||||
|
.skeleton-upload-item {
|
||||||
|
height: 200rpx;
|
||||||
|
width: 100%;
|
||||||
|
background-color: #fff;
|
||||||
|
border: 2rpx solid #000;
|
||||||
|
border-radius: 20rpx;
|
||||||
|
margin-bottom: 20rpx;
|
||||||
|
animation: skeleton-loading 1.5s infinite ease-in-out;
|
||||||
|
}
|
||||||
|
|
||||||
|
.skeleton-face-area {
|
||||||
|
height: 240rpx;
|
||||||
|
background-color: #fff;
|
||||||
|
border-radius: 8rpx;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.skeleton-face-icon {
|
||||||
|
width: 120rpx;
|
||||||
|
height: 120rpx;
|
||||||
|
border-radius: 50%;
|
||||||
|
background-color: #e6e6e6;
|
||||||
|
margin-bottom: 20rpx;
|
||||||
|
animation: skeleton-loading 1.5s infinite ease-in-out;
|
||||||
|
}
|
||||||
|
|
||||||
|
.skeleton-face-text {
|
||||||
|
height: 28rpx;
|
||||||
|
width: 200rpx;
|
||||||
|
background-color: #e6e6e6;
|
||||||
|
border-radius: 14rpx;
|
||||||
|
animation: skeleton-loading 1.5s infinite ease-in-out;
|
||||||
|
}
|
||||||
|
|
||||||
|
.skeleton-agreement {
|
||||||
|
height: 30rpx;
|
||||||
|
width: 60%;
|
||||||
|
background-color: #e6e6e6;
|
||||||
|
border-radius: 15rpx;
|
||||||
|
margin-bottom: 40rpx;
|
||||||
|
animation: skeleton-loading 1.5s infinite ease-in-out;
|
||||||
|
}
|
||||||
|
|
||||||
|
.skeleton-submit {
|
||||||
|
height: 92rpx;
|
||||||
|
width: 100%;
|
||||||
|
background-color: #e6e6e6;
|
||||||
|
border-radius: 46rpx;
|
||||||
|
animation: skeleton-loading 1.5s infinite ease-in-out;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 骨架屏动画 */
|
||||||
|
@keyframes skeleton-loading {
|
||||||
|
0% {
|
||||||
|
opacity: 0.6;
|
||||||
|
}
|
||||||
|
|
||||||
|
50% {
|
||||||
|
opacity: 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
100% {
|
||||||
|
opacity: 0.6;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.top-tip {
|
||||||
|
background-color: #E6F7FF;
|
||||||
|
padding: 20rpx 30rpx;
|
||||||
|
margin: 20rpx;
|
||||||
|
border-radius: 20rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
.tip-text {
|
||||||
|
color: #1890ff;
|
||||||
|
font-size: 28rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
.form-content {
|
||||||
|
padding: 0 30rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
.section {
|
||||||
|
margin-bottom: 40rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
.section-title {
|
||||||
|
font-size: 32rpx;
|
||||||
|
font-weight: bold;
|
||||||
|
color: #333;
|
||||||
|
margin-bottom: 20rpx;
|
||||||
|
padding-left: 10rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
.form-item {
|
||||||
|
background-color: #fff;
|
||||||
|
padding: 30rpx;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
border-bottom: 1rpx solid #f0f0f0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.form-item:last-child {
|
||||||
|
border-bottom: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
.label {
|
||||||
|
width: 120rpx;
|
||||||
|
font-size: 28rpx;
|
||||||
|
color: #333;
|
||||||
|
}
|
||||||
|
|
||||||
|
.input {
|
||||||
|
flex: 1;
|
||||||
|
font-size: 28rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
.upload-item {
|
||||||
|
margin-bottom: 20rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
.upload-area {
|
||||||
|
height: 200rpx;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
justify-content: center;
|
||||||
|
align-items: center;
|
||||||
|
cursor: pointer;
|
||||||
|
position: relative;
|
||||||
|
}
|
||||||
|
|
||||||
|
.bordered-area {
|
||||||
|
background-color: #fff;
|
||||||
|
border-radius: 20rpx;
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.upload-content {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
justify-content: center;
|
||||||
|
align-items: center;
|
||||||
|
height: 100%;
|
||||||
|
z-index: 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
.upload-icon {
|
||||||
|
font-size: 60rpx;
|
||||||
|
color: #1890ff;
|
||||||
|
margin-bottom: 10rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
.upload-text {
|
||||||
|
font-size: 28rpx;
|
||||||
|
color: #1890ff;
|
||||||
|
}
|
||||||
|
|
||||||
|
.uploaded-placeholder {
|
||||||
|
position: absolute;
|
||||||
|
top: 0;
|
||||||
|
left: 0;
|
||||||
|
right: 0;
|
||||||
|
bottom: 0;
|
||||||
|
background-color: #fff;
|
||||||
|
display: flex;
|
||||||
|
justify-content: center;
|
||||||
|
align-items: center;
|
||||||
|
border: 2rpx solid #000;
|
||||||
|
color: #333;
|
||||||
|
font-size: 28rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
.face-verify-area {
|
||||||
|
background-color: #fff;
|
||||||
|
height: 240rpx;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
justify-content: center;
|
||||||
|
align-items: center;
|
||||||
|
cursor: pointer;
|
||||||
|
border-radius: 8rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
.face-icon {
|
||||||
|
width: 120rpx;
|
||||||
|
height: 120rpx;
|
||||||
|
border-radius: 50%;
|
||||||
|
background-color: #e6f7ff;
|
||||||
|
display: flex;
|
||||||
|
justify-content: center;
|
||||||
|
align-items: center;
|
||||||
|
margin-bottom: 20rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
.face-text {
|
||||||
|
font-size: 28rpx;
|
||||||
|
color: #1890ff;
|
||||||
|
font-weight: 500;
|
||||||
|
}
|
||||||
|
|
||||||
|
.agreement-section {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
margin-bottom: 40rpx;
|
||||||
|
padding: 0 10rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
.checkbox {
|
||||||
|
margin-right: 10rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
.agreement-text {
|
||||||
|
font-size: 26rpx;
|
||||||
|
color: #666;
|
||||||
|
}
|
||||||
|
|
||||||
|
.agreement-link {
|
||||||
|
font-size: 26rpx;
|
||||||
|
color: #1890ff;
|
||||||
|
margin-left: 4rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
.input {
|
||||||
|
flex: 1;
|
||||||
|
font-size: 28rpx;
|
||||||
|
color: #333;
|
||||||
|
}
|
||||||
|
|
||||||
|
.submit-section {
|
||||||
|
margin-top: 60rpx;
|
||||||
|
padding: 0 20rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
.submit-btn {
|
||||||
|
height: 92rpx;
|
||||||
|
font-size: 32rpx;
|
||||||
|
border-radius: 46rpx;
|
||||||
|
background-color: #1890ff;
|
||||||
|
}
|
||||||
|
|
||||||
|
.submit-btn[disabled] {
|
||||||
|
background-color: #a0cfff;
|
||||||
|
color: #ffffff;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
13938
.svn/pristine/1f/1ffed74b02329a3cddec4cb05b3f8203ebe54f3b.svn-base
Normal file
@@ -0,0 +1,808 @@
|
|||||||
|
<template>
|
||||||
|
|
||||||
|
<view v-if="isLoading" class="skeleton-container" style="padding-top: 80rpx;" >
|
||||||
|
<!-- 统计数据区域骨架 -->
|
||||||
|
<view class="skeleton-stats-section">
|
||||||
|
<view class="skeleton-stat-item">
|
||||||
|
<view class="skeleton-stat-label"></view>
|
||||||
|
<view class="skeleton-stat-value"></view>
|
||||||
|
</view>
|
||||||
|
<view class="skeleton-stat-item">
|
||||||
|
<view class="skeleton-stat-label"></view>
|
||||||
|
<view class="skeleton-stat-value"></view>
|
||||||
|
</view>
|
||||||
|
<view class="skeleton-stat-item">
|
||||||
|
<view class="skeleton-stat-label"></view>
|
||||||
|
<view class="skeleton-stat-value"></view>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
|
||||||
|
<!-- 接单按钮骨架 -->
|
||||||
|
<view class="skeleton-action-section">
|
||||||
|
<view class="skeleton-accept-btn"></view>
|
||||||
|
</view>
|
||||||
|
|
||||||
|
<!-- 标签栏骨架 -->
|
||||||
|
<view class="skeleton-tab-bar">
|
||||||
|
<view class="skeleton-tab-item">
|
||||||
|
<view class="skeleton-tab-text"></view>
|
||||||
|
</view>
|
||||||
|
<view class="skeleton-tab-item">
|
||||||
|
<view class="skeleton-tab-text"></view>
|
||||||
|
</view>
|
||||||
|
<view class="skeleton-tab-item">
|
||||||
|
<view class="skeleton-tab-text"></view>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
|
||||||
|
<!-- 任务列表骨架 -->
|
||||||
|
<view class="skeleton-task-list">
|
||||||
|
<!-- 任务卡片骨架 -->
|
||||||
|
<view class="skeleton-task-section" v-for="i in 3" :key="i">
|
||||||
|
<!-- 高价单标签骨架 -->
|
||||||
|
<view class="skeleton-tag-row">
|
||||||
|
<view class="skeleton-high-price-tag"></view>
|
||||||
|
<view class="skeleton-phone-btn"></view>
|
||||||
|
</view>
|
||||||
|
|
||||||
|
<!-- 商家信息骨架 -->
|
||||||
|
<view class="skeleton-merchant-info">
|
||||||
|
<view class="skeleton-merchant-name"></view>
|
||||||
|
<view class="skeleton-distance"></view>
|
||||||
|
</view>
|
||||||
|
|
||||||
|
<!-- 地址信息骨架 -->
|
||||||
|
<view class="skeleton-address-info">
|
||||||
|
<view class="skeleton-address-text"></view>
|
||||||
|
</view>
|
||||||
|
|
||||||
|
<!-- 价格和取餐时间骨架 -->
|
||||||
|
<view class="skeleton-price-time-row">
|
||||||
|
<view class="skeleton-pickup-code"></view>
|
||||||
|
<view class="skeleton-pickup-time"></view>
|
||||||
|
</view>
|
||||||
|
|
||||||
|
<!-- 立即抢单按钮骨架 -->
|
||||||
|
<view class="skeleton-grab-btn"></view>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
|
||||||
|
<!-- 实际内容 -->
|
||||||
|
<view v-else class="rider-home" style="padding-top: 60rpx;" >
|
||||||
|
<!-- 统计数据区域 -->
|
||||||
|
<view class="stats-section">
|
||||||
|
<view class="stat-item">
|
||||||
|
<text class="stat-label">今日收入</text>
|
||||||
|
<text class="stat-value income">¥{{userData.dayAmount.toFixed(2)}}</text>
|
||||||
|
</view>
|
||||||
|
<view class="stat-item">
|
||||||
|
<text class="stat-label">已完成</text>
|
||||||
|
<text class="stat-value completed">{{userData.dayOrderCount}}单</text>
|
||||||
|
</view>
|
||||||
|
<view class="stat-item">
|
||||||
|
<text class="stat-label">配送中</text>
|
||||||
|
<text class="stat-value ongoing">{{ userData.takeOrderCount }}单</text>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
|
||||||
|
<!-- 接单按钮 -->
|
||||||
|
<view class="action-section">
|
||||||
|
<up-button :disabled='riderInfo.status===0' type="primary" shape="circle" size="default"
|
||||||
|
class="accept-orders-btn"
|
||||||
|
@click="toggleAcceptOrders">{{ riderInfo.status==0?'审核中':(riderInfo.isOnline == 0 ? '已下线' : '已上线') }}</up-button>
|
||||||
|
</view>
|
||||||
|
|
||||||
|
<view class="tab-bar">
|
||||||
|
<view v-for="(tab, index) in tabs" :key="index" class="tab-item" :class="{ active: activeTab === index }"
|
||||||
|
@click="switchTab(index)">
|
||||||
|
<text class="tab-text">{{ tab }}</text>
|
||||||
|
<view v-if="activeTab === index" class="active-line"></view>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
|
||||||
|
<view v-if="riderInfo.status==1" class="" style="padding: 0 30rpx;">
|
||||||
|
<!-- -->
|
||||||
|
<view v-for="(orderItem,orderIndex) in orderList " @click="gopage(orderItem.orderId)" :key="orderIndex"
|
||||||
|
class="task-section">
|
||||||
|
<!-- 高价单标签 -->
|
||||||
|
<view class="" style="display: flex; align-items: center; justify-content: space-between;">
|
||||||
|
|
||||||
|
<view class="high-price-tag"
|
||||||
|
:style="{'border':activeTab==0?'1rpx solid #FF7875':(activeTab==1?'1rpx solid #52C41A':'1rpx solid #FAAD14'),'color':activeTab==0?'#FF7875':(activeTab==1?'#52C41A':'#FAAD14') }"
|
||||||
|
style="background-color: #fff;">
|
||||||
|
<text class="high-price-text">{{activeTab==0? '新订单':(activeTab==1? '待取单':'配送中')}}</text>
|
||||||
|
</view>
|
||||||
|
<view class="" @click.stop="call(orderItem.phone)" style="display: flex; align-items: baseline;">
|
||||||
|
<up-icon name="phone" color="var(--nav-mian)" size="20"></up-icon>
|
||||||
|
<text style="margin-left: 10rpx; color: var(--nav-mian); ">拨打商家</text>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
|
||||||
|
<!-- 商家信息 -->
|
||||||
|
<view class="merchant-info">
|
||||||
|
<text class="merchant-name">{{ orderItem.storeName }}</text>
|
||||||
|
<text v-if="activeTab==1" class="distance">{{ distance(orderItem.distance) }}</text>
|
||||||
|
</view>
|
||||||
|
|
||||||
|
<!-- 地址信息 -->
|
||||||
|
<view class="address-info">
|
||||||
|
<up-icon name="map" color="#999" size="24rpx" />
|
||||||
|
<text class="address-text"> {{orderItem.address }}</text>
|
||||||
|
<!-- <text v-if="activeTab!==0" class="address-text">共3件商品</text> -->
|
||||||
|
</view>
|
||||||
|
<!-- 商品次数-->
|
||||||
|
<!-- <view class="address-info">
|
||||||
|
<text class="address-text">共3件商品</text>
|
||||||
|
<view class="">
|
||||||
|
<text class="price">¥5.50</text>
|
||||||
|
<text style="color: var(--nav-mian); font-weight: 600; margin-left: 10rpx; ">/单</text>
|
||||||
|
</view>
|
||||||
|
</view> -->
|
||||||
|
|
||||||
|
<!-- 价格和取餐时间 -->
|
||||||
|
<view class="price-time-row">
|
||||||
|
<view v-if="activeTab==1" class="">
|
||||||
|
<text style="font-size: 30rpx; font-weight: 600; color: #1890FF; ">取件码: </text>
|
||||||
|
<text style="color: var(--nav-mian); font-weight: 600; margin-left: 10rpx; ">{{orderItem.pickCode }}</text>
|
||||||
|
</view>
|
||||||
|
<view v-if="activeTab!==1" class="">
|
||||||
|
<text class="address-text">据您{{ distance(orderItem.distance) }}</text>
|
||||||
|
</view>
|
||||||
|
<view class="pickup-time">
|
||||||
|
<up-icon name="clock" :color="activeTab==0?'#FAAD14':'#FF0000'" size="16" />
|
||||||
|
<text class="time-text"
|
||||||
|
:style="{'color':activeTab==0?'#FAAD14':'#FF0000'}">{{ orderItem.makeTime.split(' ').length==2?'预计'+orderItem.makeTime.split(' ')[1]+'送达':orderItem.makeTime }}</text>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
|
||||||
|
<!-- 立即抢单按钮 -->
|
||||||
|
|
||||||
|
<view class="" style="display: flex; ">
|
||||||
|
<view class="" style="width: 100%;"
|
||||||
|
@click.stop="activeTab==0?takeOrder(orderItem.orderId):pickFood(orderItem.orderId)">
|
||||||
|
<button type="primary" :color="activeTab==0?'#1890FF':'#52C41A'" size="large"
|
||||||
|
class="grab-btn">{{ activeTab==0?'立即接单':(activeTab==1?'我已取餐':'确认送达')}}</button>
|
||||||
|
</view>
|
||||||
|
<view class="" style="width: 20rpx;" v-if="activeTab!=0">
|
||||||
|
|
||||||
|
</view>
|
||||||
|
<view style="width: 100%;" v-if="activeTab!=0" @click.stop="Service.GoPage('/pages/order/orderMap?orderId='+orderItem.orderId)" class="">
|
||||||
|
<button type="primary" color="#1890FF"
|
||||||
|
class="grab-btn">{{activeTab==1?'导航取餐':'导航送餐'}}</button>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
<up-loadmore :status="status" />
|
||||||
|
</view>
|
||||||
|
|
||||||
|
<view v-if="riderInfo.status==0" style=" margin-top: 20rpx; text-align: center; font-weight: bold; font-size: 34rpx;" class="">
|
||||||
|
信息审核中·请等待审核
|
||||||
|
</view>
|
||||||
|
|
||||||
|
|
||||||
|
<view class="" style="width: 100%; height: 60rpx; ">
|
||||||
|
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script setup lang="ts">
|
||||||
|
import { onLoad, onShow } from '@dcloudio/uni-app';
|
||||||
|
import { ref, onMounted } from 'vue';
|
||||||
|
import { Service } from '@/Service/Service';
|
||||||
|
import { CNRiderDataService } from '@/Service/CN/CNRiderDataService'
|
||||||
|
import { CNRiderOrderService } from '@/Service/CN/CNRiderOrderService'
|
||||||
|
|
||||||
|
// 加载状态
|
||||||
|
const isLoading = ref(true);
|
||||||
|
let status = ref('nomore')
|
||||||
|
let page = ref(1)
|
||||||
|
|
||||||
|
let userData = ref({
|
||||||
|
dayAmount: 0,
|
||||||
|
dayOrderCount: 0,
|
||||||
|
takeOrderCount: 0
|
||||||
|
})
|
||||||
|
|
||||||
|
const tabs = ['新订单', '待取货', '配送中']
|
||||||
|
const activeTab = ref(0)
|
||||||
|
let riderInfo = ref<any>({})
|
||||||
|
|
||||||
|
let orderList = ref<Array<any>>([])
|
||||||
|
|
||||||
|
|
||||||
|
onLoad(() => {
|
||||||
|
uni.$on(`newOrder`, (data) => {
|
||||||
|
newOrder()
|
||||||
|
});
|
||||||
|
})
|
||||||
|
|
||||||
|
|
||||||
|
onShow(() => {
|
||||||
|
getData()
|
||||||
|
getOrderData()
|
||||||
|
})
|
||||||
|
|
||||||
|
// 有新订单
|
||||||
|
const newOrder = () =>{
|
||||||
|
if(activeTab.value==0){
|
||||||
|
getOrderData()
|
||||||
|
}
|
||||||
|
|
||||||
|
audioPlay()
|
||||||
|
}
|
||||||
|
|
||||||
|
const getData = () => {
|
||||||
|
CNRiderDataService.GetRiderHomeInfo().then(res => {
|
||||||
|
isLoading.value = false
|
||||||
|
riderInfo.value = res.data.riderInfo
|
||||||
|
userData.value = res.data
|
||||||
|
if (res.data.riderInfo.status === -1) {
|
||||||
|
Service.GoPage('/pages/my/completeData')
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
const getOrderData = () => {
|
||||||
|
status.value = 'loadmore'
|
||||||
|
page.value = 1
|
||||||
|
orderList.value = []
|
||||||
|
getOrderList()
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//获取订单
|
||||||
|
const getOrderList = () => {
|
||||||
|
if (status.value == 'nomore' || status.value == 'loading') {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
status.value == 'loadmore'
|
||||||
|
|
||||||
|
if (activeTab.value == 0) {
|
||||||
|
CNRiderOrderService.GetRiderOrderList(page.value).then(res => {
|
||||||
|
orderList.value = [...orderList.value, ...res.data.list]
|
||||||
|
status.value = res.data.list == 10 ? 'loadmore' : 'nomore'
|
||||||
|
page.value++
|
||||||
|
})
|
||||||
|
} else {
|
||||||
|
CNRiderOrderService.GetRiderTakeOrderList(activeTab.value == 1 ? 0 : 1, page.value).then(res => {
|
||||||
|
orderList.value = [...orderList.value, ...res.data.list]
|
||||||
|
status.value = res.data.list == 10 ? 'loadmore' : 'nomore'
|
||||||
|
page.value++
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 接单
|
||||||
|
const takeOrder = (orderId : string) => {
|
||||||
|
CNRiderOrderService.RiderTakeOrder(orderId).then(res => {
|
||||||
|
if (res.data) {
|
||||||
|
activeTab.value=1
|
||||||
|
getOrderData()
|
||||||
|
getData()
|
||||||
|
} else {
|
||||||
|
Service.Msg(res.msg)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
// 取餐
|
||||||
|
const pickFood = (orderId : string) => {
|
||||||
|
CNRiderOrderService.UpdateRiderOrderTake(orderId, activeTab.value).then(res => {
|
||||||
|
if (res.data) {
|
||||||
|
getOrderData()
|
||||||
|
getData()
|
||||||
|
} else {
|
||||||
|
Service.Msg(res.msg)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// 切换标签
|
||||||
|
const switchTab = (index : number) => {
|
||||||
|
activeTab.value = index
|
||||||
|
getOrderData()
|
||||||
|
}
|
||||||
|
|
||||||
|
// 切换接单状态
|
||||||
|
const toggleAcceptOrders = () => {
|
||||||
|
CNRiderDataService.UpdateRiderOnline().then(res => {
|
||||||
|
if (res.data) {
|
||||||
|
getData()
|
||||||
|
} else {
|
||||||
|
Service.Msg(res.msg)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
// 距离计算
|
||||||
|
const distance = (item : any) => {
|
||||||
|
if (item < 0) {
|
||||||
|
return Number(item * 100).toFixed(2) + 'm'
|
||||||
|
} else {
|
||||||
|
return Number(item).toFixed(2) + 'km'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 拨打电话
|
||||||
|
const call = (e : string) => {
|
||||||
|
uni.makePhoneCall({
|
||||||
|
phoneNumber: e
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// 页面跳转
|
||||||
|
const gopage = (id) => {
|
||||||
|
if (activeTab.value == 0) {
|
||||||
|
Service.GoPage('/pages/order/grabOrder?orderId=' + id)
|
||||||
|
} else {
|
||||||
|
Service.GoPage('/pages/order/orderDetail?orderId=' + id+'&type='+activeTab.value)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const audioPlay = () => {
|
||||||
|
const innerAudioContext = uni.createInnerAudioContext();
|
||||||
|
innerAudioContext.autoplay = true;
|
||||||
|
innerAudioContext.src = '/static/order.mp3';
|
||||||
|
innerAudioContext.onPlay(() => {
|
||||||
|
console.log('开始播放');
|
||||||
|
});
|
||||||
|
innerAudioContext.onError((res) => {
|
||||||
|
console.log(res.errMsg);
|
||||||
|
console.log(res.errCode);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style scoped lang="scss">
|
||||||
|
page {
|
||||||
|
background-color: #F6f6f6;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* 统计数据区域 */
|
||||||
|
.stats-section {
|
||||||
|
background-color: #ffffff;
|
||||||
|
margin: 20rpx;
|
||||||
|
border-radius: 16rpx;
|
||||||
|
display: flex;
|
||||||
|
justify-content: space-around;
|
||||||
|
padding: 30rpx 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.stat-item {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
align-items: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.stat-label {
|
||||||
|
font-size: 28rpx;
|
||||||
|
color: #666666;
|
||||||
|
margin-bottom: 10rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
.stat-value {
|
||||||
|
font-size: 36rpx;
|
||||||
|
font-weight: 600;
|
||||||
|
}
|
||||||
|
|
||||||
|
.income {
|
||||||
|
color: var(--nav-diluted);
|
||||||
|
}
|
||||||
|
|
||||||
|
.completed {
|
||||||
|
color: var(--nav-vice);
|
||||||
|
}
|
||||||
|
|
||||||
|
.ongoing {
|
||||||
|
color: #FF9500;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 接单按钮 */
|
||||||
|
.action-section {
|
||||||
|
margin: 0 20rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
.accept-orders-btn {
|
||||||
|
width: 100%;
|
||||||
|
height: 90rpx;
|
||||||
|
font-size: 32rpx;
|
||||||
|
background-color: #52C41A;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* 顶部标签栏 */
|
||||||
|
.tab-bar {
|
||||||
|
margin-top: 20rpx;
|
||||||
|
display: flex;
|
||||||
|
background-color: #FFFFFF;
|
||||||
|
padding: 20rpx 0 0;
|
||||||
|
border-bottom: 1rpx solid #E5E5E5;
|
||||||
|
width: 100vw;
|
||||||
|
background-color: #fff;
|
||||||
|
}
|
||||||
|
|
||||||
|
.tab-item {
|
||||||
|
flex: 1;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
align-items: center;
|
||||||
|
padding: 20rpx 0;
|
||||||
|
position: relative;
|
||||||
|
}
|
||||||
|
|
||||||
|
.tab-text {
|
||||||
|
font-size: 28rpx;
|
||||||
|
color: #666666;
|
||||||
|
}
|
||||||
|
|
||||||
|
.tab-item.active .tab-text {
|
||||||
|
color: var(--nav-mian);
|
||||||
|
font-weight: 600;
|
||||||
|
}
|
||||||
|
|
||||||
|
.active-line {
|
||||||
|
position: absolute;
|
||||||
|
bottom: 0;
|
||||||
|
width: 110rpx;
|
||||||
|
height: 6rpx;
|
||||||
|
background-color: var(--nav-mian);
|
||||||
|
border-radius: 3rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
.task-section {
|
||||||
|
margin-top: 20rpx;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
background-color: #fff;
|
||||||
|
border-radius: 20rpx;
|
||||||
|
padding: 20rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* 标签样式 */
|
||||||
|
.high-price-tag {
|
||||||
|
width: fit-content;
|
||||||
|
background-color: #FF7875;
|
||||||
|
color: #FFFFFF;
|
||||||
|
padding: 5rpx 20rpx;
|
||||||
|
border-radius: 20rpx;
|
||||||
|
font-size: 24rpx;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.status-tag {
|
||||||
|
position: absolute;
|
||||||
|
top: 20rpx;
|
||||||
|
left: 20rpx;
|
||||||
|
padding: 5rpx 20rpx;
|
||||||
|
border-radius: 20rpx;
|
||||||
|
font-size: 24rpx;
|
||||||
|
z-index: 10;
|
||||||
|
}
|
||||||
|
|
||||||
|
.status-tag.pending {
|
||||||
|
background-color: #4CD964;
|
||||||
|
color: #FFFFFF;
|
||||||
|
}
|
||||||
|
|
||||||
|
.status-tag.delivering {
|
||||||
|
background-color: #FF9500;
|
||||||
|
color: #FFFFFF;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 右侧操作按钮 */
|
||||||
|
.right-action {
|
||||||
|
position: absolute;
|
||||||
|
top: 20rpx;
|
||||||
|
right: 20rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
.call-btn {
|
||||||
|
padding: 5rpx 15rpx;
|
||||||
|
font-size: 24rpx;
|
||||||
|
line-height: 36rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 信息展示 */
|
||||||
|
.merchant-info {
|
||||||
|
margin-top: 20rpx;
|
||||||
|
display: flex;
|
||||||
|
justify-content: space-between;
|
||||||
|
align-items: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.merchant-name {
|
||||||
|
font-size: 34rpx;
|
||||||
|
font-weight: 600;
|
||||||
|
color: #333333;
|
||||||
|
}
|
||||||
|
|
||||||
|
.distance {
|
||||||
|
font-size: 28rpx;
|
||||||
|
color: #666666;
|
||||||
|
}
|
||||||
|
|
||||||
|
.address-info {
|
||||||
|
display: flex;
|
||||||
|
align-items: baseline;
|
||||||
|
margin-top: 15rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
.address-text {
|
||||||
|
margin-left: 10rpx;
|
||||||
|
font-size: 28rpx;
|
||||||
|
color: #666666;
|
||||||
|
flex: 1;
|
||||||
|
overflow: hidden;
|
||||||
|
text-overflow: ellipsis;
|
||||||
|
white-space: nowrap;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 价格和时间 */
|
||||||
|
.price-time-row {
|
||||||
|
margin-top: 20rpx;
|
||||||
|
display: flex;
|
||||||
|
justify-content: space-between;
|
||||||
|
align-items: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.price {
|
||||||
|
font-size: 36rpx;
|
||||||
|
font-weight: 600;
|
||||||
|
color: #FF3B30;
|
||||||
|
}
|
||||||
|
|
||||||
|
.pickup-code {
|
||||||
|
font-size: 28rpx;
|
||||||
|
color: #333333;
|
||||||
|
font-weight: 500;
|
||||||
|
}
|
||||||
|
|
||||||
|
.pickup-time {
|
||||||
|
display: flex;
|
||||||
|
align-items: baseline;
|
||||||
|
}
|
||||||
|
|
||||||
|
.time-text {
|
||||||
|
margin-left: 8rpx;
|
||||||
|
font-size: 26rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 按钮样式 */
|
||||||
|
.grab-btn {
|
||||||
|
margin-top: 25rpx;
|
||||||
|
height: 80rpx;
|
||||||
|
line-height: 80rpx;
|
||||||
|
border-radius: 40rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
.grab-btn {
|
||||||
|
background-color: #007AFF;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/* uview组件样式覆盖 */
|
||||||
|
::v-deep .u-button--primary {
|
||||||
|
background-color: var(--nav-vice);
|
||||||
|
border-color: var(--nav-vice);
|
||||||
|
}
|
||||||
|
|
||||||
|
::v-deep .u-button--mini {
|
||||||
|
background-color: var(--nav-mian);
|
||||||
|
border-color: var(--nav-mian);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* 骨架屏样式 */
|
||||||
|
.skeleton-container {
|
||||||
|
padding: 20rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 统计数据区域骨架 */
|
||||||
|
.skeleton-stats-section {
|
||||||
|
background-color: #ffffff;
|
||||||
|
margin: 0 20rpx;
|
||||||
|
border-radius: 16rpx;
|
||||||
|
display: flex;
|
||||||
|
justify-content: space-around;
|
||||||
|
padding: 30rpx 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.skeleton-stat-item {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
align-items: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.skeleton-stat-label {
|
||||||
|
width: 120rpx;
|
||||||
|
height: 28rpx;
|
||||||
|
background-color: #e6e6e6;
|
||||||
|
border-radius: 8rpx;
|
||||||
|
margin-bottom: 10rpx;
|
||||||
|
animation: skeleton-loading 1.5s infinite;
|
||||||
|
}
|
||||||
|
|
||||||
|
.skeleton-stat-value {
|
||||||
|
width: 150rpx;
|
||||||
|
height: 36rpx;
|
||||||
|
background-color: #e6e6e6;
|
||||||
|
border-radius: 8rpx;
|
||||||
|
animation: skeleton-loading 1.5s infinite;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 接单按钮骨架 */
|
||||||
|
.skeleton-action-section {
|
||||||
|
margin: 20rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
.skeleton-accept-btn {
|
||||||
|
width: 100%;
|
||||||
|
height: 90rpx;
|
||||||
|
background-color: #e6e6e6;
|
||||||
|
border-radius: 8rpx;
|
||||||
|
animation: skeleton-loading 1.5s infinite;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 标签栏骨架 */
|
||||||
|
.skeleton-tab-bar {
|
||||||
|
display: flex;
|
||||||
|
background-color: #ffffff;
|
||||||
|
padding: 20rpx 0 0;
|
||||||
|
border-bottom: 1rpx solid #e5e5e5;
|
||||||
|
}
|
||||||
|
|
||||||
|
.skeleton-tab-item {
|
||||||
|
flex: 1;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
align-items: center;
|
||||||
|
padding: 20rpx 0;
|
||||||
|
position: relative;
|
||||||
|
}
|
||||||
|
|
||||||
|
.skeleton-tab-text {
|
||||||
|
width: 100rpx;
|
||||||
|
height: 28rpx;
|
||||||
|
background-color: #e6e6e6;
|
||||||
|
border-radius: 8rpx;
|
||||||
|
animation: skeleton-loading 1.5s infinite;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 任务列表骨架 */
|
||||||
|
.skeleton-task-list {
|
||||||
|
padding: 0 20rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
.skeleton-task-section {
|
||||||
|
margin-top: 20rpx;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
background-color: #fff;
|
||||||
|
border-radius: 20rpx;
|
||||||
|
padding: 20rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 标签骨架 */
|
||||||
|
.skeleton-tag-row {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: space-between;
|
||||||
|
}
|
||||||
|
|
||||||
|
.skeleton-high-price-tag {
|
||||||
|
width: 120rpx;
|
||||||
|
height: 30rpx;
|
||||||
|
background-color: #e6e6e6;
|
||||||
|
border-radius: 20rpx;
|
||||||
|
animation: skeleton-loading 1.5s infinite;
|
||||||
|
}
|
||||||
|
|
||||||
|
.skeleton-phone-btn {
|
||||||
|
width: 150rpx;
|
||||||
|
height: 30rpx;
|
||||||
|
background-color: #e6e6e6;
|
||||||
|
border-radius: 8rpx;
|
||||||
|
animation: skeleton-loading 1.5s infinite;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 商家信息骨架 */
|
||||||
|
.skeleton-merchant-info {
|
||||||
|
margin-top: 20rpx;
|
||||||
|
display: flex;
|
||||||
|
justify-content: space-between;
|
||||||
|
align-items: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.skeleton-merchant-name {
|
||||||
|
width: 200rpx;
|
||||||
|
height: 34rpx;
|
||||||
|
background-color: #e6e6e6;
|
||||||
|
border-radius: 8rpx;
|
||||||
|
animation: skeleton-loading 1.5s infinite;
|
||||||
|
}
|
||||||
|
|
||||||
|
.skeleton-distance {
|
||||||
|
width: 80rpx;
|
||||||
|
height: 28rpx;
|
||||||
|
background-color: #e6e6e6;
|
||||||
|
border-radius: 8rpx;
|
||||||
|
animation: skeleton-loading 1.5s infinite;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 地址信息骨架 */
|
||||||
|
.skeleton-address-info {
|
||||||
|
display: flex;
|
||||||
|
align-items: baseline;
|
||||||
|
margin-top: 15rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
.skeleton-address-text {
|
||||||
|
width: 100%;
|
||||||
|
height: 28rpx;
|
||||||
|
background-color: #e6e6e6;
|
||||||
|
border-radius: 8rpx;
|
||||||
|
animation: skeleton-loading 1.5s infinite;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 价格和时间骨架 */
|
||||||
|
.skeleton-price-time-row {
|
||||||
|
margin-top: 20rpx;
|
||||||
|
display: flex;
|
||||||
|
justify-content: space-between;
|
||||||
|
align-items: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.skeleton-pickup-code {
|
||||||
|
width: 150rpx;
|
||||||
|
height: 30rpx;
|
||||||
|
background-color: #e6e6e6;
|
||||||
|
border-radius: 8rpx;
|
||||||
|
animation: skeleton-loading 1.5s infinite;
|
||||||
|
}
|
||||||
|
|
||||||
|
.skeleton-pickup-time {
|
||||||
|
width: 200rpx;
|
||||||
|
height: 30rpx;
|
||||||
|
background-color: #e6e6e6;
|
||||||
|
border-radius: 8rpx;
|
||||||
|
animation: skeleton-loading 1.5s infinite;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 按钮骨架 */
|
||||||
|
.skeleton-grab-btn {
|
||||||
|
margin-top: 25rpx;
|
||||||
|
height: 80rpx;
|
||||||
|
background-color: #e6e6e6;
|
||||||
|
border-radius: 40rpx;
|
||||||
|
animation: skeleton-loading 1.5s infinite;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 骨架屏动画 */
|
||||||
|
@keyframes skeleton-loading {
|
||||||
|
0% {
|
||||||
|
background-color: #e6e6e6;
|
||||||
|
}
|
||||||
|
|
||||||
|
50% {
|
||||||
|
background-color: #f0f0f0;
|
||||||
|
}
|
||||||
|
|
||||||
|
100% {
|
||||||
|
background-color: #e6e6e6;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</style>
|
||||||
@@ -0,0 +1,799 @@
|
|||||||
|
<template>
|
||||||
|
|
||||||
|
<view v-if="isLoading" class="skeleton-container" style="padding-top: 80rpx;">
|
||||||
|
<!-- 统计数据区域骨架 -->
|
||||||
|
<view class="skeleton-stats-section">
|
||||||
|
<view class="skeleton-stat-item">
|
||||||
|
<view class="skeleton-stat-label"></view>
|
||||||
|
<view class="skeleton-stat-value"></view>
|
||||||
|
</view>
|
||||||
|
<view class="skeleton-stat-item">
|
||||||
|
<view class="skeleton-stat-label"></view>
|
||||||
|
<view class="skeleton-stat-value"></view>
|
||||||
|
</view>
|
||||||
|
<view class="skeleton-stat-item">
|
||||||
|
<view class="skeleton-stat-label"></view>
|
||||||
|
<view class="skeleton-stat-value"></view>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
|
||||||
|
<!-- 接单按钮骨架 -->
|
||||||
|
<view class="skeleton-action-section">
|
||||||
|
<view class="skeleton-accept-btn"></view>
|
||||||
|
</view>
|
||||||
|
|
||||||
|
<!-- 标签栏骨架 -->
|
||||||
|
<view class="skeleton-tab-bar">
|
||||||
|
<view class="skeleton-tab-item">
|
||||||
|
<view class="skeleton-tab-text"></view>
|
||||||
|
</view>
|
||||||
|
<view class="skeleton-tab-item">
|
||||||
|
<view class="skeleton-tab-text"></view>
|
||||||
|
</view>
|
||||||
|
<view class="skeleton-tab-item">
|
||||||
|
<view class="skeleton-tab-text"></view>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
|
||||||
|
<!-- 任务列表骨架 -->
|
||||||
|
<view class="skeleton-task-list">
|
||||||
|
<!-- 任务卡片骨架 -->
|
||||||
|
<view class="skeleton-task-section" v-for="i in 3" :key="i">
|
||||||
|
<!-- 高价单标签骨架 -->
|
||||||
|
<view class="skeleton-tag-row">
|
||||||
|
<view class="skeleton-high-price-tag"></view>
|
||||||
|
<view class="skeleton-phone-btn"></view>
|
||||||
|
</view>
|
||||||
|
|
||||||
|
<!-- 商家信息骨架 -->
|
||||||
|
<view class="skeleton-merchant-info">
|
||||||
|
<view class="skeleton-merchant-name"></view>
|
||||||
|
<view class="skeleton-distance"></view>
|
||||||
|
</view>
|
||||||
|
|
||||||
|
<!-- 地址信息骨架 -->
|
||||||
|
<view class="skeleton-address-info">
|
||||||
|
<view class="skeleton-address-text"></view>
|
||||||
|
</view>
|
||||||
|
|
||||||
|
<!-- 价格和取餐时间骨架 -->
|
||||||
|
<view class="skeleton-price-time-row">
|
||||||
|
<view class="skeleton-pickup-code"></view>
|
||||||
|
<view class="skeleton-pickup-time"></view>
|
||||||
|
</view>
|
||||||
|
|
||||||
|
<!-- 立即抢单按钮骨架 -->
|
||||||
|
<view class="skeleton-grab-btn"></view>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
|
||||||
|
<!-- 实际内容 -->
|
||||||
|
<view v-else class="rider-home" style="padding-top: 60rpx;">
|
||||||
|
<!-- 统计数据区域 -->
|
||||||
|
<view class="stats-section">
|
||||||
|
<view class="stat-item">
|
||||||
|
<text class="stat-label">今日收入</text>
|
||||||
|
<text class="stat-value income">¥{{userData.dayAmount.toFixed(2)}}</text>
|
||||||
|
</view>
|
||||||
|
<view class="stat-item">
|
||||||
|
<text class="stat-label">已完成</text>
|
||||||
|
<text class="stat-value completed">{{userData.dayOrderCount}}单</text>
|
||||||
|
</view>
|
||||||
|
<view class="stat-item">
|
||||||
|
<text class="stat-label">配送中</text>
|
||||||
|
<text class="stat-value ongoing">{{ userData.takeOrderCount }}单</text>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
|
||||||
|
<!-- 接单按钮 -->
|
||||||
|
<view class="action-section">
|
||||||
|
<up-button :disabled='riderInfo.status===0' type="primary" shape="circle" size="default"
|
||||||
|
class="accept-orders-btn"
|
||||||
|
@click="toggleAcceptOrders">{{ riderInfo.status==0?'审核中':(riderInfo.isOnline == 0 ? '已下线' : '已上线') }}</up-button>
|
||||||
|
</view>
|
||||||
|
|
||||||
|
<view class="tab-bar">
|
||||||
|
<view v-for="(tab, index) in tabs" :key="index" class="tab-item" :class="{ active: activeTab === index }"
|
||||||
|
@click="switchTab(index)">
|
||||||
|
<text class="tab-text">{{ tab }}</text>
|
||||||
|
<view v-if="activeTab === index" class="active-line"></view>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
|
||||||
|
<view v-if="riderInfo.status==1" class="" style="padding: 0 30rpx;">
|
||||||
|
<!-- -->
|
||||||
|
<view v-for="(orderItem,orderIndex) in orderList " @click="gopage(orderItem.orderId)" :key="orderIndex"
|
||||||
|
class="task-section">
|
||||||
|
<!-- 高价单标签 -->
|
||||||
|
<view class="" style="display: flex; align-items: center; justify-content: space-between;">
|
||||||
|
|
||||||
|
<view class="high-price-tag"
|
||||||
|
:style="{'border':activeTab==0?'1rpx solid #FF7875':(activeTab==1?'1rpx solid #52C41A':'1rpx solid #FAAD14'),'color':activeTab==0?'#FF7875':(activeTab==1?'#52C41A':'#FAAD14') }"
|
||||||
|
style="background-color: #fff;">
|
||||||
|
<text class="high-price-text">{{activeTab==0? '新订单':(activeTab==1? '待取单':'配送中')}}</text>
|
||||||
|
</view>
|
||||||
|
<view class="" @click.stop="call(orderItem.phone)" style="display: flex; align-items: baseline;">
|
||||||
|
<up-icon name="phone" color="var(--nav-mian)" size="20"></up-icon>
|
||||||
|
<text style="margin-left: 10rpx; color: var(--nav-mian); ">拨打商家</text>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
|
||||||
|
<!-- 商家信息 -->
|
||||||
|
<view class="merchant-info">
|
||||||
|
<text class="merchant-name">{{ orderItem.storeName }}</text>
|
||||||
|
<text v-if="activeTab==1" class="distance">{{ distance(orderItem.distance) }}</text>
|
||||||
|
</view>
|
||||||
|
|
||||||
|
<!-- 地址信息 -->
|
||||||
|
<view class="address-info">
|
||||||
|
<up-icon name="map" color="#999" size="24rpx" />
|
||||||
|
<text class="address-text"> {{orderItem.address }}</text>
|
||||||
|
<!-- <text v-if="activeTab!==0" class="address-text">共3件商品</text> -->
|
||||||
|
</view>
|
||||||
|
<!-- 商品次数-->
|
||||||
|
<!-- <view class="address-info">
|
||||||
|
<text class="address-text">共3件商品</text>
|
||||||
|
<view class="">
|
||||||
|
<text class="price">¥5.50</text>
|
||||||
|
<text style="color: var(--nav-mian); font-weight: 600; margin-left: 10rpx; ">/单</text>
|
||||||
|
</view>
|
||||||
|
</view> -->
|
||||||
|
|
||||||
|
<!-- 价格和取餐时间 -->
|
||||||
|
<view class="price-time-row">
|
||||||
|
<view v-if="activeTab==1" class="">
|
||||||
|
<text style="font-size: 30rpx; font-weight: 600; color: #1890FF; ">取件码: </text>
|
||||||
|
<text
|
||||||
|
style="color: var(--nav-mian); font-weight: 600; margin-left: 10rpx; ">{{orderItem.pickCode }}</text>
|
||||||
|
</view>
|
||||||
|
<view v-if="activeTab!==1" class="">
|
||||||
|
<text class="address-text">据您{{ distance(orderItem.distance) }}</text>
|
||||||
|
</view>
|
||||||
|
<view class="pickup-time">
|
||||||
|
<up-icon name="clock" :color="activeTab==0?'#FAAD14':'#FF0000'" size="16" />
|
||||||
|
<text class="time-text"
|
||||||
|
:style="{'color':activeTab==0?'#FAAD14':'#FF0000'}">{{ orderItem.makeTime.split(' ').length==2?'预计'+orderItem.makeTime.split(' ')[1]+'送达':orderItem.makeTime }}</text>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
|
||||||
|
<!-- 立即抢单按钮 -->
|
||||||
|
|
||||||
|
<view class="" style="display: flex; ">
|
||||||
|
<view class="" style="width: 100%;"
|
||||||
|
@click.stop="activeTab==0?takeOrder(orderItem.orderId):pickFood(orderItem.orderId)">
|
||||||
|
<button type="primary" :color="activeTab==0?'#1890FF':'#52C41A'" size="large"
|
||||||
|
class="grab-btn">{{ activeTab==0?'立即接单':(activeTab==1?'我已取餐':'确认送达')}}</button>
|
||||||
|
</view>
|
||||||
|
<view class="" style="width: 20rpx;" v-if="activeTab!=0">
|
||||||
|
|
||||||
|
</view>
|
||||||
|
<view style="width: 100%;" v-if="activeTab!=0"
|
||||||
|
@click.stop="Service.GoPage('/pages/order/orderMap?orderId='+orderItem.orderId)" class="">
|
||||||
|
<button type="primary" color="#1890FF" class="grab-btn">{{activeTab==1?'导航取餐':'导航送餐'}}</button>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
<up-loadmore :status="status" />
|
||||||
|
</view>
|
||||||
|
|
||||||
|
<view v-if="riderInfo.status==0"
|
||||||
|
style=" margin-top: 20rpx; text-align: center; font-weight: bold; font-size: 34rpx;" class="">
|
||||||
|
信息审核中·请等待审核
|
||||||
|
</view>
|
||||||
|
|
||||||
|
|
||||||
|
<view class="" style="width: 100%; height: 60rpx; ">
|
||||||
|
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script setup lang="ts">
|
||||||
|
import { onLoad, onShow } from '@dcloudio/uni-app';
|
||||||
|
import { ref, onMounted } from 'vue';
|
||||||
|
import { Service } from '@/Service/Service';
|
||||||
|
import { CNRiderDataService } from '@/Service/CN/CNRiderDataService'
|
||||||
|
import { CNRiderOrderService } from '@/Service/CN/CNRiderOrderService'
|
||||||
|
|
||||||
|
// 加载状态
|
||||||
|
const isLoading = ref(true);
|
||||||
|
let status = ref('nomore')
|
||||||
|
let page = ref(1)
|
||||||
|
|
||||||
|
let userData = ref({
|
||||||
|
dayAmount: 0,
|
||||||
|
dayOrderCount: 0,
|
||||||
|
takeOrderCount: 0
|
||||||
|
})
|
||||||
|
|
||||||
|
const tabs = ['新订单', '待取货', '配送中']
|
||||||
|
const activeTab = ref(0)
|
||||||
|
let riderInfo = ref<any>({})
|
||||||
|
|
||||||
|
let orderList = ref<Array<any>>([])
|
||||||
|
|
||||||
|
let a = ref(1)
|
||||||
|
|
||||||
|
onLoad(() => {
|
||||||
|
uni.$on(`newOrder`, (data) => {
|
||||||
|
a.value++
|
||||||
|
console.log('消息推送1', a.value);
|
||||||
|
newOrder()
|
||||||
|
});
|
||||||
|
})
|
||||||
|
|
||||||
|
|
||||||
|
onShow(() => {
|
||||||
|
getData()
|
||||||
|
getOrderData()
|
||||||
|
})
|
||||||
|
|
||||||
|
// 有新订单
|
||||||
|
const newOrder = () => {
|
||||||
|
if (activeTab.value == 0) {
|
||||||
|
getOrderData()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const getData = () => {
|
||||||
|
CNRiderDataService.GetRiderHomeInfo().then(res => {
|
||||||
|
isLoading.value = false
|
||||||
|
riderInfo.value = res.data.riderInfo
|
||||||
|
userData.value = res.data
|
||||||
|
if (res.data.riderInfo.status === -1) {
|
||||||
|
Service.GoPage('/pages/my/completeData')
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
const getOrderData = () => {
|
||||||
|
status.value = 'loadmore'
|
||||||
|
page.value = 1
|
||||||
|
orderList.value = []
|
||||||
|
getOrderList()
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//获取订单
|
||||||
|
const getOrderList = () => {
|
||||||
|
if (status.value == 'nomore' || status.value == 'loading') {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
status.value == 'loadmore'
|
||||||
|
|
||||||
|
if (activeTab.value == 0) {
|
||||||
|
CNRiderOrderService.GetRiderOrderList(page.value).then(res => {
|
||||||
|
orderList.value = [...orderList.value, ...res.data.list]
|
||||||
|
status.value = res.data.list == 10 ? 'loadmore' : 'nomore'
|
||||||
|
page.value++
|
||||||
|
})
|
||||||
|
} else {
|
||||||
|
CNRiderOrderService.GetRiderTakeOrderList(activeTab.value == 1 ? 0 : 1, page.value).then(res => {
|
||||||
|
orderList.value = [...orderList.value, ...res.data.list]
|
||||||
|
status.value = res.data.list == 10 ? 'loadmore' : 'nomore'
|
||||||
|
page.value++
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 接单
|
||||||
|
const takeOrder = (orderId : string) => {
|
||||||
|
CNRiderOrderService.RiderTakeOrder(orderId).then(res => {
|
||||||
|
if (res.data) {
|
||||||
|
activeTab.value = 1
|
||||||
|
getOrderData()
|
||||||
|
getData()
|
||||||
|
} else {
|
||||||
|
Service.Msg(res.msg)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
// 取餐
|
||||||
|
const pickFood = (orderId : string) => {
|
||||||
|
CNRiderOrderService.UpdateRiderOrderTake(orderId, activeTab.value).then(res => {
|
||||||
|
if (res.data) {
|
||||||
|
getOrderData()
|
||||||
|
getData()
|
||||||
|
} else {
|
||||||
|
Service.Msg(res.msg)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// 切换标签
|
||||||
|
const switchTab = (index : number) => {
|
||||||
|
activeTab.value = index
|
||||||
|
getOrderData()
|
||||||
|
}
|
||||||
|
|
||||||
|
// 切换接单状态
|
||||||
|
const toggleAcceptOrders = () => {
|
||||||
|
CNRiderDataService.UpdateRiderOnline().then(res => {
|
||||||
|
if (res.data) {
|
||||||
|
getData()
|
||||||
|
} else {
|
||||||
|
Service.Msg(res.msg)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
// 距离计算
|
||||||
|
const distance = (item : any) => {
|
||||||
|
if (item < 0) {
|
||||||
|
return Number(item * 100).toFixed(2) + 'm'
|
||||||
|
} else {
|
||||||
|
return Number(item).toFixed(2) + 'km'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 拨打电话
|
||||||
|
const call = (e : string) => {
|
||||||
|
uni.makePhoneCall({
|
||||||
|
phoneNumber: e
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// 页面跳转
|
||||||
|
const gopage = (id) => {
|
||||||
|
if (activeTab.value == 0) {
|
||||||
|
Service.GoPage('/pages/order/grabOrder?orderId=' + id)
|
||||||
|
} else {
|
||||||
|
Service.GoPage('/pages/order/orderDetail?orderId=' + id + '&type=' + activeTab.value)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style scoped lang="scss">
|
||||||
|
page {
|
||||||
|
background-color: #F6f6f6;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* 统计数据区域 */
|
||||||
|
.stats-section {
|
||||||
|
background-color: #ffffff;
|
||||||
|
margin: 20rpx;
|
||||||
|
border-radius: 16rpx;
|
||||||
|
display: flex;
|
||||||
|
justify-content: space-around;
|
||||||
|
padding: 30rpx 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.stat-item {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
align-items: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.stat-label {
|
||||||
|
font-size: 28rpx;
|
||||||
|
color: #666666;
|
||||||
|
margin-bottom: 10rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
.stat-value {
|
||||||
|
font-size: 36rpx;
|
||||||
|
font-weight: 600;
|
||||||
|
}
|
||||||
|
|
||||||
|
.income {
|
||||||
|
color: var(--nav-diluted);
|
||||||
|
}
|
||||||
|
|
||||||
|
.completed {
|
||||||
|
color: var(--nav-vice);
|
||||||
|
}
|
||||||
|
|
||||||
|
.ongoing {
|
||||||
|
color: #FF9500;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 接单按钮 */
|
||||||
|
.action-section {
|
||||||
|
margin: 0 20rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
.accept-orders-btn {
|
||||||
|
width: 100%;
|
||||||
|
height: 90rpx;
|
||||||
|
font-size: 32rpx;
|
||||||
|
background-color: #52C41A;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* 顶部标签栏 */
|
||||||
|
.tab-bar {
|
||||||
|
margin-top: 20rpx;
|
||||||
|
display: flex;
|
||||||
|
background-color: #FFFFFF;
|
||||||
|
padding: 20rpx 0 0;
|
||||||
|
border-bottom: 1rpx solid #E5E5E5;
|
||||||
|
width: 100vw;
|
||||||
|
background-color: #fff;
|
||||||
|
}
|
||||||
|
|
||||||
|
.tab-item {
|
||||||
|
flex: 1;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
align-items: center;
|
||||||
|
padding: 20rpx 0;
|
||||||
|
position: relative;
|
||||||
|
}
|
||||||
|
|
||||||
|
.tab-text {
|
||||||
|
font-size: 28rpx;
|
||||||
|
color: #666666;
|
||||||
|
}
|
||||||
|
|
||||||
|
.tab-item.active .tab-text {
|
||||||
|
color: var(--nav-mian);
|
||||||
|
font-weight: 600;
|
||||||
|
}
|
||||||
|
|
||||||
|
.active-line {
|
||||||
|
position: absolute;
|
||||||
|
bottom: 0;
|
||||||
|
width: 110rpx;
|
||||||
|
height: 6rpx;
|
||||||
|
background-color: var(--nav-mian);
|
||||||
|
border-radius: 3rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
.task-section {
|
||||||
|
margin-top: 20rpx;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
background-color: #fff;
|
||||||
|
border-radius: 20rpx;
|
||||||
|
padding: 20rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* 标签样式 */
|
||||||
|
.high-price-tag {
|
||||||
|
width: fit-content;
|
||||||
|
background-color: #FF7875;
|
||||||
|
color: #FFFFFF;
|
||||||
|
padding: 5rpx 20rpx;
|
||||||
|
border-radius: 20rpx;
|
||||||
|
font-size: 24rpx;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.status-tag {
|
||||||
|
position: absolute;
|
||||||
|
top: 20rpx;
|
||||||
|
left: 20rpx;
|
||||||
|
padding: 5rpx 20rpx;
|
||||||
|
border-radius: 20rpx;
|
||||||
|
font-size: 24rpx;
|
||||||
|
z-index: 10;
|
||||||
|
}
|
||||||
|
|
||||||
|
.status-tag.pending {
|
||||||
|
background-color: #4CD964;
|
||||||
|
color: #FFFFFF;
|
||||||
|
}
|
||||||
|
|
||||||
|
.status-tag.delivering {
|
||||||
|
background-color: #FF9500;
|
||||||
|
color: #FFFFFF;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 右侧操作按钮 */
|
||||||
|
.right-action {
|
||||||
|
position: absolute;
|
||||||
|
top: 20rpx;
|
||||||
|
right: 20rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
.call-btn {
|
||||||
|
padding: 5rpx 15rpx;
|
||||||
|
font-size: 24rpx;
|
||||||
|
line-height: 36rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 信息展示 */
|
||||||
|
.merchant-info {
|
||||||
|
margin-top: 20rpx;
|
||||||
|
display: flex;
|
||||||
|
justify-content: space-between;
|
||||||
|
align-items: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.merchant-name {
|
||||||
|
font-size: 34rpx;
|
||||||
|
font-weight: 600;
|
||||||
|
color: #333333;
|
||||||
|
}
|
||||||
|
|
||||||
|
.distance {
|
||||||
|
font-size: 28rpx;
|
||||||
|
color: #666666;
|
||||||
|
}
|
||||||
|
|
||||||
|
.address-info {
|
||||||
|
display: flex;
|
||||||
|
align-items: baseline;
|
||||||
|
margin-top: 15rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
.address-text {
|
||||||
|
margin-left: 10rpx;
|
||||||
|
font-size: 28rpx;
|
||||||
|
color: #666666;
|
||||||
|
flex: 1;
|
||||||
|
overflow: hidden;
|
||||||
|
text-overflow: ellipsis;
|
||||||
|
white-space: nowrap;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 价格和时间 */
|
||||||
|
.price-time-row {
|
||||||
|
margin-top: 20rpx;
|
||||||
|
display: flex;
|
||||||
|
justify-content: space-between;
|
||||||
|
align-items: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.price {
|
||||||
|
font-size: 36rpx;
|
||||||
|
font-weight: 600;
|
||||||
|
color: #FF3B30;
|
||||||
|
}
|
||||||
|
|
||||||
|
.pickup-code {
|
||||||
|
font-size: 28rpx;
|
||||||
|
color: #333333;
|
||||||
|
font-weight: 500;
|
||||||
|
}
|
||||||
|
|
||||||
|
.pickup-time {
|
||||||
|
display: flex;
|
||||||
|
align-items: baseline;
|
||||||
|
}
|
||||||
|
|
||||||
|
.time-text {
|
||||||
|
margin-left: 8rpx;
|
||||||
|
font-size: 26rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 按钮样式 */
|
||||||
|
.grab-btn {
|
||||||
|
margin-top: 25rpx;
|
||||||
|
height: 80rpx;
|
||||||
|
line-height: 80rpx;
|
||||||
|
border-radius: 40rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
.grab-btn {
|
||||||
|
background-color: #007AFF;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/* uview组件样式覆盖 */
|
||||||
|
::v-deep .u-button--primary {
|
||||||
|
background-color: var(--nav-vice);
|
||||||
|
border-color: var(--nav-vice);
|
||||||
|
}
|
||||||
|
|
||||||
|
::v-deep .u-button--mini {
|
||||||
|
background-color: var(--nav-mian);
|
||||||
|
border-color: var(--nav-mian);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* 骨架屏样式 */
|
||||||
|
.skeleton-container {
|
||||||
|
padding: 20rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 统计数据区域骨架 */
|
||||||
|
.skeleton-stats-section {
|
||||||
|
background-color: #ffffff;
|
||||||
|
margin: 0 20rpx;
|
||||||
|
border-radius: 16rpx;
|
||||||
|
display: flex;
|
||||||
|
justify-content: space-around;
|
||||||
|
padding: 30rpx 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.skeleton-stat-item {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
align-items: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.skeleton-stat-label {
|
||||||
|
width: 120rpx;
|
||||||
|
height: 28rpx;
|
||||||
|
background-color: #e6e6e6;
|
||||||
|
border-radius: 8rpx;
|
||||||
|
margin-bottom: 10rpx;
|
||||||
|
animation: skeleton-loading 1.5s infinite;
|
||||||
|
}
|
||||||
|
|
||||||
|
.skeleton-stat-value {
|
||||||
|
width: 150rpx;
|
||||||
|
height: 36rpx;
|
||||||
|
background-color: #e6e6e6;
|
||||||
|
border-radius: 8rpx;
|
||||||
|
animation: skeleton-loading 1.5s infinite;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 接单按钮骨架 */
|
||||||
|
.skeleton-action-section {
|
||||||
|
margin: 20rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
.skeleton-accept-btn {
|
||||||
|
width: 100%;
|
||||||
|
height: 90rpx;
|
||||||
|
background-color: #e6e6e6;
|
||||||
|
border-radius: 8rpx;
|
||||||
|
animation: skeleton-loading 1.5s infinite;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 标签栏骨架 */
|
||||||
|
.skeleton-tab-bar {
|
||||||
|
display: flex;
|
||||||
|
background-color: #ffffff;
|
||||||
|
padding: 20rpx 0 0;
|
||||||
|
border-bottom: 1rpx solid #e5e5e5;
|
||||||
|
}
|
||||||
|
|
||||||
|
.skeleton-tab-item {
|
||||||
|
flex: 1;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
align-items: center;
|
||||||
|
padding: 20rpx 0;
|
||||||
|
position: relative;
|
||||||
|
}
|
||||||
|
|
||||||
|
.skeleton-tab-text {
|
||||||
|
width: 100rpx;
|
||||||
|
height: 28rpx;
|
||||||
|
background-color: #e6e6e6;
|
||||||
|
border-radius: 8rpx;
|
||||||
|
animation: skeleton-loading 1.5s infinite;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 任务列表骨架 */
|
||||||
|
.skeleton-task-list {
|
||||||
|
padding: 0 20rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
.skeleton-task-section {
|
||||||
|
margin-top: 20rpx;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
background-color: #fff;
|
||||||
|
border-radius: 20rpx;
|
||||||
|
padding: 20rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 标签骨架 */
|
||||||
|
.skeleton-tag-row {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: space-between;
|
||||||
|
}
|
||||||
|
|
||||||
|
.skeleton-high-price-tag {
|
||||||
|
width: 120rpx;
|
||||||
|
height: 30rpx;
|
||||||
|
background-color: #e6e6e6;
|
||||||
|
border-radius: 20rpx;
|
||||||
|
animation: skeleton-loading 1.5s infinite;
|
||||||
|
}
|
||||||
|
|
||||||
|
.skeleton-phone-btn {
|
||||||
|
width: 150rpx;
|
||||||
|
height: 30rpx;
|
||||||
|
background-color: #e6e6e6;
|
||||||
|
border-radius: 8rpx;
|
||||||
|
animation: skeleton-loading 1.5s infinite;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 商家信息骨架 */
|
||||||
|
.skeleton-merchant-info {
|
||||||
|
margin-top: 20rpx;
|
||||||
|
display: flex;
|
||||||
|
justify-content: space-between;
|
||||||
|
align-items: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.skeleton-merchant-name {
|
||||||
|
width: 200rpx;
|
||||||
|
height: 34rpx;
|
||||||
|
background-color: #e6e6e6;
|
||||||
|
border-radius: 8rpx;
|
||||||
|
animation: skeleton-loading 1.5s infinite;
|
||||||
|
}
|
||||||
|
|
||||||
|
.skeleton-distance {
|
||||||
|
width: 80rpx;
|
||||||
|
height: 28rpx;
|
||||||
|
background-color: #e6e6e6;
|
||||||
|
border-radius: 8rpx;
|
||||||
|
animation: skeleton-loading 1.5s infinite;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 地址信息骨架 */
|
||||||
|
.skeleton-address-info {
|
||||||
|
display: flex;
|
||||||
|
align-items: baseline;
|
||||||
|
margin-top: 15rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
.skeleton-address-text {
|
||||||
|
width: 100%;
|
||||||
|
height: 28rpx;
|
||||||
|
background-color: #e6e6e6;
|
||||||
|
border-radius: 8rpx;
|
||||||
|
animation: skeleton-loading 1.5s infinite;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 价格和时间骨架 */
|
||||||
|
.skeleton-price-time-row {
|
||||||
|
margin-top: 20rpx;
|
||||||
|
display: flex;
|
||||||
|
justify-content: space-between;
|
||||||
|
align-items: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.skeleton-pickup-code {
|
||||||
|
width: 150rpx;
|
||||||
|
height: 30rpx;
|
||||||
|
background-color: #e6e6e6;
|
||||||
|
border-radius: 8rpx;
|
||||||
|
animation: skeleton-loading 1.5s infinite;
|
||||||
|
}
|
||||||
|
|
||||||
|
.skeleton-pickup-time {
|
||||||
|
width: 200rpx;
|
||||||
|
height: 30rpx;
|
||||||
|
background-color: #e6e6e6;
|
||||||
|
border-radius: 8rpx;
|
||||||
|
animation: skeleton-loading 1.5s infinite;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 按钮骨架 */
|
||||||
|
.skeleton-grab-btn {
|
||||||
|
margin-top: 25rpx;
|
||||||
|
height: 80rpx;
|
||||||
|
background-color: #e6e6e6;
|
||||||
|
border-radius: 40rpx;
|
||||||
|
animation: skeleton-loading 1.5s infinite;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 骨架屏动画 */
|
||||||
|
@keyframes skeleton-loading {
|
||||||
|
0% {
|
||||||
|
background-color: #e6e6e6;
|
||||||
|
}
|
||||||
|
|
||||||
|
50% {
|
||||||
|
background-color: #f0f0f0;
|
||||||
|
}
|
||||||
|
|
||||||
|
100% {
|
||||||
|
background-color: #e6e6e6;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</style>
|
||||||
@@ -0,0 +1,78 @@
|
|||||||
|
/**
|
||||||
|
* 这里是uni-app内置的常用样式变量
|
||||||
|
*
|
||||||
|
* uni-app 官方扩展插件及插件市场(https://ext.dcloud.net.cn)上很多三方插件均使用了这些样式变量
|
||||||
|
* 如果你是插件开发者,建议你使用scss预处理,并在插件代码中直接使用这些变量(无需 import 这个文件),方便用户通过搭积木的方式开发整体风格一致的App
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
@import 'uview-plus/theme.scss';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 如果你是App开发者(插件使用者),你可以通过修改这些变量来定制自己的插件主题,实现自定义主题功能
|
||||||
|
*
|
||||||
|
* 如果你的项目同样使用了scss预处理,你也可以直接在你的 scss 代码中使用如下变量,同时无需 import 这个文件
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* 颜色变量 */
|
||||||
|
|
||||||
|
/* 行为相关颜色 */
|
||||||
|
$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;
|
||||||
@@ -0,0 +1,119 @@
|
|||||||
|
<script setup lang="ts">
|
||||||
|
import { onLaunch, onShow, onHide } from "@dcloudio/uni-app";
|
||||||
|
import { onMounted, ref } from "vue";
|
||||||
|
import { WebSocket } from '@/Service/Comm/TwWebSocket';
|
||||||
|
import { Service } from "@/Service/Service"
|
||||||
|
import { CNRiderOrderService } from '@/Service/CN/CNRiderOrderService'
|
||||||
|
|
||||||
|
let isios = ref(false)
|
||||||
|
|
||||||
|
const currentLatitude = ref(0);
|
||||||
|
const currentLongitude = ref(0);
|
||||||
|
|
||||||
|
let locationTimer: ReturnType<typeof setInterval> | null = null;
|
||||||
|
|
||||||
|
|
||||||
|
onLaunch(() => {
|
||||||
|
isios.value = uni.getSystemInfoSync().platform != 'ios'//是否为ios
|
||||||
|
//#ifdef APP-PLUS//app
|
||||||
|
if (isios.value) {
|
||||||
|
// getVersion()//更新
|
||||||
|
}
|
||||||
|
//#endif
|
||||||
|
// 在 App 启动时,立即初始化并建立 WebSocket 连接
|
||||||
|
WebSocket.ConnectSocketInit();
|
||||||
|
// 打开调用
|
||||||
|
uni.$on("ImCom", () => {
|
||||||
|
WebSocket.ConnectSocketInit();
|
||||||
|
})
|
||||||
|
// 关闭调用
|
||||||
|
uni.$on("ImComOff", () => {
|
||||||
|
WebSocket.CloseSocket();
|
||||||
|
})
|
||||||
|
|
||||||
|
});
|
||||||
|
onShow(() => {
|
||||||
|
WebSocket.ConnectSocketInit();
|
||||||
|
|
||||||
|
});
|
||||||
|
onHide(() => {
|
||||||
|
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
|
const startFetchingLocation = () => {
|
||||||
|
// 安全检查:如果定时器已存在,先清除,防止重复启动
|
||||||
|
if (locationTimer) {
|
||||||
|
clearInterval(locationTimer);
|
||||||
|
}
|
||||||
|
|
||||||
|
console.log("开始定时获取位置,间隔1分钟...");
|
||||||
|
|
||||||
|
// 1. 立即执行第一次获取
|
||||||
|
getLocationNow();
|
||||||
|
|
||||||
|
// 2. 设置定时器,每 60000 毫秒 (1分钟) 执行一次
|
||||||
|
locationTimer = setInterval(() => {
|
||||||
|
getLocationNow();
|
||||||
|
}, 60000);
|
||||||
|
};
|
||||||
|
|
||||||
|
const getLocationNow = () => {
|
||||||
|
uni.getLocation({
|
||||||
|
type: 'wgs84',
|
||||||
|
isHighAccuracy: true,
|
||||||
|
success: (res) => {
|
||||||
|
|
||||||
|
if(Service.GetUserIsLogin()){
|
||||||
|
CNRiderOrderService.UpdateRiderLocation(res.longitude,res.latitude).then(res=>{})
|
||||||
|
}
|
||||||
|
|
||||||
|
},
|
||||||
|
fail: (err) => {
|
||||||
|
// console.error('获取经纬度失败:', err);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 停止定时获取位置
|
||||||
|
*/
|
||||||
|
const stopFetchingLocation = () => {
|
||||||
|
if (locationTimer) {
|
||||||
|
clearInterval(locationTimer);
|
||||||
|
locationTimer = null; // 清理 ID
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
const getUpData = () => {
|
||||||
|
// #ifdef APP
|
||||||
|
// plus.runtime.getProperty(plus.runtime.appid, (wgtinfo) => {
|
||||||
|
// NvpMerchService.GetAppVersion().then(res=>{
|
||||||
|
// console.log('wgtinfo.versionCode',wgtinfo.versionCode);
|
||||||
|
// if (res.data.version > wgtinfo.versionCode) {
|
||||||
|
// setTimeout(function() {
|
||||||
|
// uni.navigateTo({
|
||||||
|
// url: "/pages/upData/upData?info=" +
|
||||||
|
// encodeURIComponent(
|
||||||
|
// JSON.stringify(res.data))
|
||||||
|
// })
|
||||||
|
// }, 1000)
|
||||||
|
// }
|
||||||
|
// })
|
||||||
|
// })
|
||||||
|
// #endif
|
||||||
|
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
<style lang="scss">
|
||||||
|
@import "uview-plus/index.scss";
|
||||||
|
@import "colorui/main.css";
|
||||||
|
@import "colorui/icon.css";
|
||||||
|
|
||||||
|
page {
|
||||||
|
--nav-mian: #1890FF; //全局颜色
|
||||||
|
--nav-vice: #52C41A; //副颜色
|
||||||
|
--nav-diluted: #FF4D4F; //次颜色
|
||||||
|
|
||||||
|
}
|
||||||
|
</style>
|
||||||
@@ -0,0 +1,22 @@
|
|||||||
|
import { Service } from '@/Service/Service';
|
||||||
|
/*****登录接口*****/
|
||||||
|
class CNRiderLoginService {
|
||||||
|
private static RiderLoginPath : string = '/Login/RiderLogin';
|
||||||
|
/*****登录注册*****/
|
||||||
|
static RiderLogin(login : any) {
|
||||||
|
var result = Service.Request(this.RiderLoginPath, "POST", login);
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static GetKefuInfoPath: string = '/Home/GetKefuInfo';
|
||||||
|
/*****获取客服电话*****/
|
||||||
|
static GetKefuInfo() {
|
||||||
|
var result = Service.Request(this.GetKefuInfoPath, "GET", {});
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
export {
|
||||||
|
Service,
|
||||||
|
CNRiderLoginService
|
||||||
|
}
|
||||||
@@ -0,0 +1,36 @@
|
|||||||
|
<template>
|
||||||
|
<!-- 导航栏 -->
|
||||||
|
<view class=""
|
||||||
|
style="padding:50rpx 20rpx 18rpx; box-sizing: border-box; position: fixed;top: 0; left: 0; width: 100vw; background-color: rgba(0,0,0,0.6); display: flex; align-items: center; justify-content: space-between; ">
|
||||||
|
<view class="" @click="Service.GoPageBack()">
|
||||||
|
<up-icon name="arrow-left" color="#fff" size="32rpx"></up-icon>
|
||||||
|
</view>
|
||||||
|
<view class="" style="color: #fff; ">
|
||||||
|
配送中 · 2单
|
||||||
|
</view>
|
||||||
|
<image :src="Service.GetIconImg('/static/index/order/voice.png')"
|
||||||
|
style="width: 32rpx; height: 32rpx; " mode=""></image>
|
||||||
|
</view>
|
||||||
|
<view class="" style="width: 100%; height: 88rpx; ">
|
||||||
|
|
||||||
|
</view>
|
||||||
|
<view>
|
||||||
|
1111
|
||||||
|
</view>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script setup lang="ts">
|
||||||
|
import { onShow, onLoad } from "@dcloudio/uni-app";
|
||||||
|
import { Service } from "@/Service/Service"
|
||||||
|
|
||||||
|
onLoad(() => {
|
||||||
|
|
||||||
|
});
|
||||||
|
|
||||||
|
onShow(() => {
|
||||||
|
|
||||||
|
});
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style lang="scss">
|
||||||
|
</style>
|
||||||
@@ -0,0 +1,494 @@
|
|||||||
|
<template>
|
||||||
|
<!-- 骨架屏 -->
|
||||||
|
<view v-if="loading" class="task-list-container skeleton-loading">
|
||||||
|
<!-- 顶部标签栏 -->
|
||||||
|
<view class="tab-bar">
|
||||||
|
<view v-for="(tab, index) in tabs" :key="index" class="tab-item">
|
||||||
|
<view class="skeleton-tab-text"></view>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
<view class="" style="width: 100vw; height: 120rpx"> </view>
|
||||||
|
|
||||||
|
<!-- 骨架屏订单列表 -->
|
||||||
|
<view class="order-list">
|
||||||
|
<!-- 骨架屏任务卡片 1 -->
|
||||||
|
<view v-for="item in 3" class="task-section skeleton-card">
|
||||||
|
<view class="" style="display: flex; align-items: center; justify-content: space-between;" >
|
||||||
|
<view class="skeleton-tag"></view>
|
||||||
|
<view class="skeleton-time-group">
|
||||||
|
<view class="icon-placeholder"></view>
|
||||||
|
<view class="skeleton-time-text"></view>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
<view class="skeleton-merchant-info">
|
||||||
|
<view class="skeleton-merchant-name"></view>
|
||||||
|
<view class="skeleton-distance"></view>
|
||||||
|
</view>
|
||||||
|
<view class="skeleton-address-info">
|
||||||
|
<view class="icon-placeholder"></view>
|
||||||
|
<view class="skeleton-address-text"></view>
|
||||||
|
</view>
|
||||||
|
<view class="skeleton-price-time-row">
|
||||||
|
<view class="skeleton-price"></view>
|
||||||
|
<view class="skeleton-time-group">
|
||||||
|
<view class="icon-placeholder"></view>
|
||||||
|
<view class="skeleton-time-text"></view>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
<view class="skeleton-button"></view>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
<view class="" style="width: 100vw; display: flex; justify-content: center; margin-top: 20rpx; " >
|
||||||
|
<view class="" style="width: 200rpx; height: 40rpx; background-color: #fff; border-radius: 4rpx; " >
|
||||||
|
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
|
||||||
|
|
||||||
|
</view>
|
||||||
|
|
||||||
|
|
||||||
|
<view v-else class="task-list-container" style="padding-top: 60rpx;" >
|
||||||
|
<!-- 顶部标签栏 -->
|
||||||
|
<view class="tab-bar">
|
||||||
|
<view v-for="(tab, index) in tabs" :key="index" class="tab-item" :class="{ active: activeTab === index }"
|
||||||
|
@click="switchTab(index)">
|
||||||
|
<text class="tab-text">{{ tab }}</text>
|
||||||
|
<view v-if="activeTab === index" class="active-line"></view>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
<view class="" style="width: 100vw; height: 120rpx; ">
|
||||||
|
|
||||||
|
</view>
|
||||||
|
<!-- 订单列表 -->
|
||||||
|
<view class="order-list">
|
||||||
|
<view @click="gopage()" v-for="(orderItem,orderIndex) in 3 " :key="orderIndex" class="task-section">
|
||||||
|
<!-- 高价单标签 -->
|
||||||
|
<view class="" style="display: flex; align-items: center; justify-content: space-between;">
|
||||||
|
<view v-if="activeTab==0" class="high-price-tag" style="border-radius: 8rpx;" >
|
||||||
|
<image :src="Service.GetIconImg('/static/index/task/fire.png')" style="width: 24rpx; height: 24rpx;" mode=""></image>
|
||||||
|
<text class="high-price-text" style="margin-left: 4rpx;" >高价单</text>
|
||||||
|
</view>
|
||||||
|
<view v-else class="high-price-tag" :style="{'border':activeTab==1?'1rpx solid #52C41A':'1rpx solid #FAAD14','color':activeTab==1?'#52C41A':'#FAAD14' }" style="background-color: #fff;" >
|
||||||
|
<text class="high-price-text">{{activeTab==1?'待取单':'配送中'}}</text>
|
||||||
|
</view>
|
||||||
|
<view class="" v-if="activeTab!==0" style="display: flex; align-items: baseline;">
|
||||||
|
<up-icon name="phone" color="var(--nav-mian)" size="20"></up-icon>
|
||||||
|
<text style="margin-left: 10rpx; color: var(--nav-mian); ">拨打商家</text>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
|
||||||
|
<!-- 商家信息 -->
|
||||||
|
<view class="merchant-info">
|
||||||
|
<text class="merchant-name">老北京炸酱面</text>
|
||||||
|
<text class="distance">500m</text>
|
||||||
|
</view>
|
||||||
|
|
||||||
|
<!-- 地址信息 -->
|
||||||
|
<view class="address-info">
|
||||||
|
<up-icon name="map" color="#999" size="24rpx" />
|
||||||
|
<text class="address-text">北京市朝阳区三里屯SOHO</text>
|
||||||
|
<text v-if="activeTab!==0" class="address-text">共3件商品</text>
|
||||||
|
</view>
|
||||||
|
<!-- 商品次数-->
|
||||||
|
<view v-if="activeTab==1" class="address-info">
|
||||||
|
<text class="address-text">共3件商品</text>
|
||||||
|
</view>
|
||||||
|
|
||||||
|
<!-- 价格和取餐时间 -->
|
||||||
|
<view class="price-time-row">
|
||||||
|
<view v-if="activeTab==0" class="">
|
||||||
|
<text class="price">¥5.50</text>
|
||||||
|
<text style="color: var(--nav-mian); font-weight: 600; margin-left: 10rpx; ">/单</text>
|
||||||
|
</view>
|
||||||
|
<view v-if="activeTab==1" class="">
|
||||||
|
<text style="font-size: 30rpx; font-weight: 600; color: #1890FF; ">取件码: </text>
|
||||||
|
<text style="color: var(--nav-mian); font-weight: 600; margin-left: 10rpx; ">A121</text>
|
||||||
|
</view>
|
||||||
|
<view v-if="activeTab==2" class="">
|
||||||
|
<text class="address-text">据您1.2km</text>
|
||||||
|
</view>
|
||||||
|
<view class="pickup-time">
|
||||||
|
<up-icon name="clock" color="#FF9500" size="24rpx" />
|
||||||
|
<text class="time-text" :style="{'color':activeTab==0?'#FAAD14':'#FF0000'}" >{{activeTab==0?'12:30 前取餐':'12:30 前送达'}}</text>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
|
||||||
|
<!-- 立即抢单按钮 -->
|
||||||
|
<up-button type="primary" @click="buttonClick()" :color="activeTab==0?'#1890FF':(activeTab==1?'#52C41A':'#52C41A')" size="large" class="grab-btn">{{ activeTab==0?'立即抢单':(activeTab==1?'我已取餐':'确认送达') }}</up-button>
|
||||||
|
</view>
|
||||||
|
|
||||||
|
<!-- 没有更多任务提示 -->
|
||||||
|
<up-loadmore :status="status" />
|
||||||
|
<view class="" style="width: 100vw; height: 60rpx; " ></view>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script setup lang="ts">
|
||||||
|
import { onLoad } from '@dcloudio/uni-app'
|
||||||
|
import { ref } from 'vue'
|
||||||
|
import { Service } from '@/Service/Service'
|
||||||
|
|
||||||
|
let loading = ref(true)
|
||||||
|
// 标签数据
|
||||||
|
const tabs = ['新任务', '待取货', '配送中']
|
||||||
|
const activeTab = ref(0)
|
||||||
|
let status = ref('nomore')
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
onLoad(() => {
|
||||||
|
setTimeout(() => {
|
||||||
|
loading.value = false
|
||||||
|
}, 1000)
|
||||||
|
})
|
||||||
|
|
||||||
|
// 页面跳转
|
||||||
|
const gopage = () => {
|
||||||
|
if (activeTab.value == 0) {
|
||||||
|
Service.GoPage('/pages/order/grabOrder')
|
||||||
|
} else {
|
||||||
|
Service.GoPage('/pages/order/orderDetail')
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
const buttonClick=()=>{
|
||||||
|
|
||||||
|
if(activeTab.value==2){
|
||||||
|
Service.GoPage('/pages/order/finish')
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 切换标签
|
||||||
|
const switchTab = (index : number) => {
|
||||||
|
activeTab.value = index
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style scoped>
|
||||||
|
page {
|
||||||
|
background-color: #F5F5F5;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 顶部标签栏 */
|
||||||
|
.tab-bar {
|
||||||
|
display: flex;
|
||||||
|
background-color: #FFFFFF;
|
||||||
|
padding: 20rpx 0 0;
|
||||||
|
border-bottom: 1rpx solid #E5E5E5;
|
||||||
|
position: fixed;
|
||||||
|
top: 0;
|
||||||
|
left: 0;
|
||||||
|
width: 100vw;
|
||||||
|
background-color: #fff;
|
||||||
|
}
|
||||||
|
|
||||||
|
.tab-item {
|
||||||
|
flex: 1;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
align-items: center;
|
||||||
|
padding: 20rpx 0;
|
||||||
|
position: relative;
|
||||||
|
}
|
||||||
|
|
||||||
|
.tab-text {
|
||||||
|
font-size: 28rpx;
|
||||||
|
color: #666666;
|
||||||
|
}
|
||||||
|
|
||||||
|
.tab-item.active .tab-text {
|
||||||
|
color: var(--nav-mian);
|
||||||
|
font-weight: 600;
|
||||||
|
}
|
||||||
|
|
||||||
|
.active-line {
|
||||||
|
position: absolute;
|
||||||
|
bottom: 0;
|
||||||
|
width: 110rpx;
|
||||||
|
height: 6rpx;
|
||||||
|
background-color: var(--nav-mian);
|
||||||
|
border-radius: 3rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 订单列表 */
|
||||||
|
.order-list {
|
||||||
|
padding: 0rpx 30rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
.task-section {
|
||||||
|
margin-top: 20rpx;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
background-color: #fff;
|
||||||
|
border-radius: 20rpx;
|
||||||
|
padding: 20rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* 标签样式 */
|
||||||
|
.high-price-tag {
|
||||||
|
width: fit-content;
|
||||||
|
background-color: #FF7875;
|
||||||
|
color: #FFFFFF;
|
||||||
|
padding: 5rpx 20rpx;
|
||||||
|
border-radius: 20rpx;
|
||||||
|
font-size: 24rpx;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.status-tag {
|
||||||
|
position: absolute;
|
||||||
|
top: 20rpx;
|
||||||
|
left: 20rpx;
|
||||||
|
padding: 5rpx 20rpx;
|
||||||
|
border-radius: 20rpx;
|
||||||
|
font-size: 24rpx;
|
||||||
|
z-index: 10;
|
||||||
|
}
|
||||||
|
|
||||||
|
.status-tag.pending {
|
||||||
|
background-color: #4CD964;
|
||||||
|
color: #FFFFFF;
|
||||||
|
}
|
||||||
|
|
||||||
|
.status-tag.delivering {
|
||||||
|
background-color: #FF9500;
|
||||||
|
color: #FFFFFF;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 右侧操作按钮 */
|
||||||
|
.right-action {
|
||||||
|
position: absolute;
|
||||||
|
top: 20rpx;
|
||||||
|
right: 20rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
.call-btn {
|
||||||
|
padding: 5rpx 15rpx;
|
||||||
|
font-size: 24rpx;
|
||||||
|
line-height: 36rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 信息展示 */
|
||||||
|
.merchant-info {
|
||||||
|
margin-top: 20rpx;
|
||||||
|
display: flex;
|
||||||
|
justify-content: space-between;
|
||||||
|
align-items: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.merchant-name {
|
||||||
|
font-size: 34rpx;
|
||||||
|
font-weight: 600;
|
||||||
|
color: #333333;
|
||||||
|
}
|
||||||
|
|
||||||
|
.distance {
|
||||||
|
font-size: 28rpx;
|
||||||
|
color: #666666;
|
||||||
|
}
|
||||||
|
|
||||||
|
.address-info {
|
||||||
|
display: flex;
|
||||||
|
align-items: baseline;
|
||||||
|
margin-top: 15rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
.address-text {
|
||||||
|
margin-left: 10rpx;
|
||||||
|
font-size: 28rpx;
|
||||||
|
color: #666666;
|
||||||
|
flex: 1;
|
||||||
|
overflow: hidden;
|
||||||
|
text-overflow: ellipsis;
|
||||||
|
white-space: nowrap;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 价格和时间 */
|
||||||
|
.price-time-row {
|
||||||
|
margin-top: 20rpx;
|
||||||
|
display: flex;
|
||||||
|
justify-content: space-between;
|
||||||
|
align-items: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.price {
|
||||||
|
font-size: 36rpx;
|
||||||
|
font-weight: 600;
|
||||||
|
color: #FF3B30;
|
||||||
|
}
|
||||||
|
|
||||||
|
.pickup-code {
|
||||||
|
font-size: 28rpx;
|
||||||
|
color: #333333;
|
||||||
|
font-weight: 500;
|
||||||
|
}
|
||||||
|
|
||||||
|
.pickup-time {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.time-text {
|
||||||
|
margin-left: 8rpx;
|
||||||
|
font-size: 26rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 按钮样式 */
|
||||||
|
.grab-btn {
|
||||||
|
margin-top: 25rpx;
|
||||||
|
height: 80rpx;
|
||||||
|
line-height: 80rpx;
|
||||||
|
border-radius: 40rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
.grab-btn {
|
||||||
|
background-color: #007AFF;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 没有更多任务 */
|
||||||
|
.no-more-tasks {
|
||||||
|
margin-top: 40rpx;
|
||||||
|
text-align: center;
|
||||||
|
padding: 20rpx 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.no-more-text {
|
||||||
|
font-size: 28rpx;
|
||||||
|
color: #999999;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 骨架屏样式 */
|
||||||
|
.skeleton-loading .skeleton-card {
|
||||||
|
background-color: #fff;
|
||||||
|
border-radius: 20rpx;
|
||||||
|
padding: 20rpx;
|
||||||
|
position: relative;
|
||||||
|
overflow: hidden;
|
||||||
|
}
|
||||||
|
|
||||||
|
.skeleton-tab-text {
|
||||||
|
width: 80rpx;
|
||||||
|
height: 30rpx;
|
||||||
|
background-color: #f0f0f0;
|
||||||
|
border-radius: 4rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
.skeleton-tag {
|
||||||
|
width: 100rpx;
|
||||||
|
height: 30rpx;
|
||||||
|
background-color: #f0f0f0;
|
||||||
|
border-radius: 15rpx;
|
||||||
|
margin-bottom: 20rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
.skeleton-merchant-info {
|
||||||
|
display: flex;
|
||||||
|
justify-content: space-between;
|
||||||
|
align-items: center;
|
||||||
|
margin-bottom: 15rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
.skeleton-merchant-name {
|
||||||
|
width: 200rpx;
|
||||||
|
height: 34rpx;
|
||||||
|
background-color: #f0f0f0;
|
||||||
|
border-radius: 4rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
.skeleton-distance {
|
||||||
|
width: 60rpx;
|
||||||
|
height: 28rpx;
|
||||||
|
background-color: #f0f0f0;
|
||||||
|
border-radius: 4rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
.skeleton-address-info {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
margin-bottom: 20rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
.icon-placeholder {
|
||||||
|
width: 24rpx;
|
||||||
|
height: 24rpx;
|
||||||
|
background-color: #f0f0f0;
|
||||||
|
border-radius: 4rpx;
|
||||||
|
margin-right: 10rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
.skeleton-address-text {
|
||||||
|
width: 400rpx;
|
||||||
|
height: 28rpx;
|
||||||
|
background-color: #f0f0f0;
|
||||||
|
border-radius: 4rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
.skeleton-price-time-row {
|
||||||
|
display: flex;
|
||||||
|
justify-content: space-between;
|
||||||
|
align-items: center;
|
||||||
|
margin-bottom: 25rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
.skeleton-price {
|
||||||
|
width: 80rpx;
|
||||||
|
height: 36rpx;
|
||||||
|
background-color: #f0f0f0;
|
||||||
|
border-radius: 4rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
.skeleton-time-group {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.skeleton-time-text {
|
||||||
|
width: 150rpx;
|
||||||
|
height: 26rpx;
|
||||||
|
background-color: #f0f0f0;
|
||||||
|
border-radius: 4rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
.skeleton-button {
|
||||||
|
width: 100%;
|
||||||
|
height: 80rpx;
|
||||||
|
background-color: #f0f0f0;
|
||||||
|
border-radius: 40rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 骨架屏动画 */
|
||||||
|
.skeleton-card .skeleton-tag::after,
|
||||||
|
.skeleton-card .skeleton-merchant-name::after,
|
||||||
|
.skeleton-card .skeleton-distance::after,
|
||||||
|
.skeleton-card .skeleton-address-text::after,
|
||||||
|
.skeleton-card .icon-placeholder::after,
|
||||||
|
.skeleton-card .skeleton-price::after,
|
||||||
|
.skeleton-card .skeleton-time-text::after,
|
||||||
|
.skeleton-card .skeleton-button::after,
|
||||||
|
.skeleton-loading .skeleton-tab-text::after {
|
||||||
|
content: '';
|
||||||
|
position: absolute;
|
||||||
|
top: 0;
|
||||||
|
left: 0;
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
background: linear-gradient(90deg, transparent, rgba(255, 255, 255, 0.2), transparent);
|
||||||
|
animation: shimmer 1.5s infinite;
|
||||||
|
}
|
||||||
|
|
||||||
|
@keyframes shimmer {
|
||||||
|
0% {
|
||||||
|
transform: translateX(-100%);
|
||||||
|
}
|
||||||
|
|
||||||
|
100% {
|
||||||
|
transform: translateX(100%);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</style>
|
||||||
@@ -0,0 +1,443 @@
|
|||||||
|
<template>
|
||||||
|
<!-- 骨架屏 -->
|
||||||
|
<view v-if="loading" class="order-detail skeleton-loading">
|
||||||
|
<!-- 订单基本信息骨架屏 -->
|
||||||
|
<view class="order-basic-info skeleton-section">
|
||||||
|
<view class="" style="display: flex; justify-content: space-between;align-items: center; ">
|
||||||
|
<view class="skeleton-block skeleton-short"></view>
|
||||||
|
<view class="skeleton-block skeleton-short"></view>
|
||||||
|
</view>
|
||||||
|
<view class="skeleton-block skeleton-long"></view>
|
||||||
|
<view class="" style="display: flex; align-items: center; justify-content: space-between;">
|
||||||
|
<view class="skeleton-block skeleton-medium"></view>
|
||||||
|
<view class="skeleton-block skeleton-medium"></view>
|
||||||
|
</view>
|
||||||
|
<view class="skeleton-block skeleton-medium"></view>
|
||||||
|
<view class="skeleton-block skeleton-long"></view>
|
||||||
|
</view>
|
||||||
|
|
||||||
|
<!-- 物品清单骨架屏 -->
|
||||||
|
<view class="order-basic-info skeleton-section">
|
||||||
|
<view v-for="item in 4" class="skeleton-block" style="width: 100%; height: 40rpx; "></view>
|
||||||
|
|
||||||
|
<view class="" style="display: flex; justify-content: center;">
|
||||||
|
<view class="skeleton-block skeleton-short"></view>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
|
||||||
|
<!-- 地图区域骨架屏 -->
|
||||||
|
<view class="map-section skeleton-section">
|
||||||
|
<view class="map-placeholder skeleton-map"></view>
|
||||||
|
</view>
|
||||||
|
|
||||||
|
<!-- 地址区域骨架屏 -->
|
||||||
|
<view class="address-section skeleton-section">
|
||||||
|
<view class="skeleton-block skeleton-medium"></view>
|
||||||
|
<view class="skeleton-block skeleton-long"></view>
|
||||||
|
<view class="skeleton-block skeleton-long"></view>
|
||||||
|
<view class="skeleton-block skeleton-medium"></view>
|
||||||
|
<view class="skeleton-block skeleton-long"></view>
|
||||||
|
<view class="skeleton-block skeleton-long"></view>
|
||||||
|
<view class="skeleton-block skeleton-long"></view>
|
||||||
|
</view>
|
||||||
|
|
||||||
|
<view class="bottom-padding"></view>
|
||||||
|
|
||||||
|
<!-- 底部按钮骨架屏 -->
|
||||||
|
<view class="bottom-action">
|
||||||
|
<view class="skeleton-button"></view>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
<!-- 实际内容 -->
|
||||||
|
<view v-else class="order-detail">
|
||||||
|
<!-- 订单基本信息 -->
|
||||||
|
<view class="order-basic-info">
|
||||||
|
<view class="info-item">
|
||||||
|
<view class="label" style="font-weight: 700; font-size: 30rpx;"> {{ orderInfo.distribution=='预约订单'?'预计'+orderInfo.makeTime.split(' ')[1]+'送达':orderInfo.makeTime }} </view>
|
||||||
|
</view>
|
||||||
|
<view class="info-item">
|
||||||
|
<text class="label">订单编号 : </text>
|
||||||
|
<text class="value">{{ orderId }}</text>
|
||||||
|
</view>
|
||||||
|
|
||||||
|
<view class="info-item">
|
||||||
|
<view class="label" style="display: flex; align-items: baseline;">
|
||||||
|
<u-icon name="clock" size="16" class="clock-icon"></u-icon>
|
||||||
|
{{ Service.formatDate(orderInfo.addTime,1) }} 下单
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
|
||||||
|
</view>
|
||||||
|
|
||||||
|
<!-- 物品清单 -->
|
||||||
|
<view class="order-basic-info">
|
||||||
|
<view class="" style="display: flex; align-items: center; ">
|
||||||
|
<view class="" style="flex: 1; font-size: 34rpx; font-weight: 600; ">
|
||||||
|
物品清单
|
||||||
|
</view>
|
||||||
|
<view class="" style="width: 100rpx; text-align: right; font-size: 30rpx; ">
|
||||||
|
数量
|
||||||
|
</view>
|
||||||
|
<view class="" style="width: 120rpx; text-align: right; font-size: 30rpx; ">
|
||||||
|
金额
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
<!-- 商品列表 -->
|
||||||
|
<view class="" :style="{'height':isShow?'110rpx':'fit-content' }" style="overflow: hidden;">
|
||||||
|
<view class="" v-for="(goodsItem,goodsIndex) in JSON.parse(orderInfo.detail) " :key="goodsIndex"
|
||||||
|
style="display: flex; align-items: center; margin-top: 15rpx; ">
|
||||||
|
<view class="" style="flex: 1; ">
|
||||||
|
{{goodsItem.goodsName}}
|
||||||
|
</view>
|
||||||
|
<view class="" style="width: 100rpx; text-align: right; ">
|
||||||
|
×{{ goodsItem.count }}
|
||||||
|
</view>
|
||||||
|
<view class="" style="width: 120rpx; text-align: right; ">
|
||||||
|
¥{{ goodsItem.count*goodsItem.price }}
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
<view class="" style="display: flex; align-items: center; justify-content: space-between;" >
|
||||||
|
<view class="">
|
||||||
|
|
||||||
|
</view>
|
||||||
|
<view class="info-item">
|
||||||
|
<text class="label" style="font-weight: 700;">配送费</text>
|
||||||
|
<text class="value price">¥{{ Number(orderInfo.postage).toFixed(2) }}</text>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
<view class="" v-if="JSON.parse(orderInfo.detail).length>2" @click="isShow=!isShow"
|
||||||
|
style=" margin-top: 20rpx; display: flex; align-items: center; justify-content: center; color: #666; ">
|
||||||
|
<up-icon :name="isShow?'arrow-down':'arrow-up'" color="#666" size="18"></up-icon>
|
||||||
|
{{isShow?'展开':'收入'}}
|
||||||
|
</view>
|
||||||
|
|
||||||
|
</view>
|
||||||
|
<!-- 取餐地址 -->
|
||||||
|
<view class="address-section">
|
||||||
|
<view class="" style=" border-bottom: 4rpx solid #e2e2e2; ">
|
||||||
|
<view class="section-title">取餐地址 : </view>
|
||||||
|
<view class="address-content">
|
||||||
|
<text class="store-name">{{ storeInfo.name }}</text>
|
||||||
|
<text class="address"> {{ storeInfo.city }}{{storeInfo.region }}{{ storeInfo.address }}</text>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
<view style="margin: 10rpx 0; font-size: 30rpx;font-weight: 800;color: #333;">送餐地址 : </view>
|
||||||
|
<view class="address-content">
|
||||||
|
<text class="user-name">{{ JSON.parse(orderInfo.address).realName }}</text>
|
||||||
|
<text class="address">{{ JSON.parse(orderInfo.address).address }}</text>
|
||||||
|
<view v-if="orderInfo.remark" class="remark">
|
||||||
|
<text class="remark-label">备注:</text>
|
||||||
|
<text class="remark-content">请放门口,勿按门铃</text>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
<view class="" style="width: 100vw; height: 140rpx; ">
|
||||||
|
|
||||||
|
</view>
|
||||||
|
|
||||||
|
<!-- 底部按钮 -->
|
||||||
|
<view class="bottom-action">
|
||||||
|
<up-button @click="placeOrder()" color="var(--nav-mian)" class="confirm-btn">立即接单</up-button>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script setup lang="ts">
|
||||||
|
import { onLoad } from '@dcloudio/uni-app';
|
||||||
|
import { ref, onMounted } from 'vue';
|
||||||
|
import { Service } from '@/Service/Service';
|
||||||
|
import { CNRiderOrderService } from '@/Service/CN/CNRiderOrderService'
|
||||||
|
|
||||||
|
// 加载状态
|
||||||
|
const loading = ref(true);
|
||||||
|
|
||||||
|
let orderStatus = ref(0)
|
||||||
|
|
||||||
|
let isShow = ref(true)
|
||||||
|
|
||||||
|
let deliveryTime = ref('')
|
||||||
|
|
||||||
|
let orderInfo = ref<any>({})
|
||||||
|
let storeInfo = ref<any>({})
|
||||||
|
let storeLocation = ref<any>({})
|
||||||
|
|
||||||
|
let orderId = ref('')
|
||||||
|
onLoad((data : any) => {
|
||||||
|
orderId.value = data.orderId
|
||||||
|
getData()
|
||||||
|
})
|
||||||
|
|
||||||
|
const getData = () => {
|
||||||
|
CNRiderOrderService.GetUnitOrderInfo(orderId.value).then(res => {
|
||||||
|
loading.value = false
|
||||||
|
|
||||||
|
if (res.data) {
|
||||||
|
deliveryTime.value = res.data.deliveryTime
|
||||||
|
orderInfo.value = res.data.orderInfo
|
||||||
|
storeInfo.value = res.data.storeInfo
|
||||||
|
storeLocation.value = res.data.storeLocation
|
||||||
|
}
|
||||||
|
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
const placeOrder = () => {
|
||||||
|
CNRiderOrderService.RiderTakeOrder(orderId.value).then(res => {
|
||||||
|
if (res.data) {
|
||||||
|
Service.Msg('接单成功!')
|
||||||
|
setTimeout(() => {
|
||||||
|
Service.GoPageBack()
|
||||||
|
},1000)
|
||||||
|
} else {
|
||||||
|
Service.Msg(res.msg)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style scoped>
|
||||||
|
.order-detail {
|
||||||
|
min-height: 100vh;
|
||||||
|
background-color: #f5f5f5;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 订单状态样式 */
|
||||||
|
.order-status {
|
||||||
|
background-color: #fff;
|
||||||
|
padding: 30rpx;
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* 订单基本信息样式 */
|
||||||
|
.order-basic-info {
|
||||||
|
background-color: #fff;
|
||||||
|
margin: 20rpx 20rpx;
|
||||||
|
padding: 30rpx;
|
||||||
|
border-radius: 20rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
.info-item {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
margin-bottom: 20rpx;
|
||||||
|
font-size: 28rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
.info-item:last-child {
|
||||||
|
margin-bottom: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.label {
|
||||||
|
color: #666;
|
||||||
|
margin-right: 10rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
.value {
|
||||||
|
color: #333;
|
||||||
|
}
|
||||||
|
|
||||||
|
.value.highlight {
|
||||||
|
color: var(--nav-diluted);
|
||||||
|
font-weight: 500;
|
||||||
|
}
|
||||||
|
|
||||||
|
.value.price {
|
||||||
|
color: var(--nav-diluted);
|
||||||
|
font-weight: 700;
|
||||||
|
}
|
||||||
|
|
||||||
|
.clock-icon {
|
||||||
|
color: #666;
|
||||||
|
margin-right: 8rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 地图区域样式 */
|
||||||
|
.map-section {
|
||||||
|
margin: 20rpx;
|
||||||
|
border-radius: 20rpx;
|
||||||
|
overflow: hidden;
|
||||||
|
}
|
||||||
|
|
||||||
|
.map-placeholder {
|
||||||
|
width: 100%;
|
||||||
|
height: 400rpx;
|
||||||
|
background-color: #f0f0f0;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
position: relative;
|
||||||
|
border: 1rpx solid #e8e8e8;
|
||||||
|
}
|
||||||
|
|
||||||
|
.map-placeholder::before {
|
||||||
|
content: '';
|
||||||
|
position: absolute;
|
||||||
|
top: 0;
|
||||||
|
left: 0;
|
||||||
|
right: 0;
|
||||||
|
bottom: 0;
|
||||||
|
background: linear-gradient(135deg, #f5f5f5 25%, #e6e6e6 25%, #e6e6e6 50%, #f5f5f5 50%, #f5f5f5 75%, #e6e6e6 75%, #e6e6e6 100%);
|
||||||
|
background-size: 20rpx 20rpx;
|
||||||
|
opacity: 0.3;
|
||||||
|
}
|
||||||
|
|
||||||
|
.map-hint {
|
||||||
|
font-size: 28rpx;
|
||||||
|
color: #666;
|
||||||
|
position: relative;
|
||||||
|
z-index: 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 地址区域样式 */
|
||||||
|
.address-section {
|
||||||
|
background-color: #fff;
|
||||||
|
margin: 20rpx;
|
||||||
|
padding: 30rpx;
|
||||||
|
border-radius: 20rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
.section-title {
|
||||||
|
font-size: 30rpx;
|
||||||
|
font-weight: 800;
|
||||||
|
color: #333;
|
||||||
|
margin: 10rpx 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.address-content {
|
||||||
|
position: relative;
|
||||||
|
}
|
||||||
|
|
||||||
|
.store-name,
|
||||||
|
.user-name {
|
||||||
|
font-size: 34rpx;
|
||||||
|
font-weight: 600;
|
||||||
|
margin-bottom: 15rpx;
|
||||||
|
display: block;
|
||||||
|
}
|
||||||
|
|
||||||
|
.address {
|
||||||
|
font-size: 26rpx;
|
||||||
|
color: #666;
|
||||||
|
line-height: 1.5;
|
||||||
|
margin-bottom: 25rpx;
|
||||||
|
display: block;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
.pickup-code,
|
||||||
|
.remark {
|
||||||
|
font-size: 26rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
.code-label,
|
||||||
|
.code-value {
|
||||||
|
color: var(--nav-mian);
|
||||||
|
font-weight: 600;
|
||||||
|
}
|
||||||
|
|
||||||
|
.remark-label,
|
||||||
|
.remark-content {
|
||||||
|
color: #FAAD14;
|
||||||
|
font-weight: 600;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 底部按钮样式 */
|
||||||
|
.bottom-action {
|
||||||
|
background-color: #fff;
|
||||||
|
width: 100vw;
|
||||||
|
position: fixed;
|
||||||
|
bottom: 0;
|
||||||
|
left: 0;
|
||||||
|
padding: 20rpx 30rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
.confirm-btn {
|
||||||
|
width: 100%;
|
||||||
|
height: 90rpx;
|
||||||
|
font-size: 32rpx;
|
||||||
|
line-height: 90rpx;
|
||||||
|
border-radius: 45rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 骨架屏样式 */
|
||||||
|
.skeleton-loading .skeleton-section {
|
||||||
|
margin: 20rpx 20rpx;
|
||||||
|
padding: 30rpx;
|
||||||
|
border-radius: 20rpx;
|
||||||
|
background-color: #fff;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
.skeleton-block {
|
||||||
|
background-color: #f0f0f0;
|
||||||
|
margin-bottom: 20rpx;
|
||||||
|
border-radius: 4rpx;
|
||||||
|
position: relative;
|
||||||
|
overflow: hidden;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
.skeleton-short {
|
||||||
|
height: 40rpx;
|
||||||
|
width: 30%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.skeleton-medium {
|
||||||
|
height: 30rpx;
|
||||||
|
width: 30%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.skeleton-long {
|
||||||
|
height: 30rpx;
|
||||||
|
width: 90%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.skeleton-map {
|
||||||
|
height: 400rpx;
|
||||||
|
background-color: #f0f0f0;
|
||||||
|
border-radius: 20rpx;
|
||||||
|
margin: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.skeleton-button {
|
||||||
|
height: 90rpx;
|
||||||
|
background-color: #f0f0f0;
|
||||||
|
border-radius: 45rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
.bottom-padding {
|
||||||
|
height: 140rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 骨架屏动画 */
|
||||||
|
.skeleton-block::after,
|
||||||
|
.skeleton-map::after,
|
||||||
|
.skeleton-button::after {
|
||||||
|
content: '';
|
||||||
|
position: absolute;
|
||||||
|
top: 0;
|
||||||
|
left: 0;
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
background: linear-gradient(90deg, transparent, rgba(255, 255, 255, 0.2), transparent);
|
||||||
|
animation: shimmer 1.5s infinite;
|
||||||
|
}
|
||||||
|
|
||||||
|
@keyframes shimmer {
|
||||||
|
0% {
|
||||||
|
transform: translateX(-100%);
|
||||||
|
}
|
||||||
|
|
||||||
|
100% {
|
||||||
|
transform: translateX(100%);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</style>
|
||||||
@@ -0,0 +1,146 @@
|
|||||||
|
{
|
||||||
|
"name" : "骑手端",
|
||||||
|
"appid" : "__UNI__06C2D6A",
|
||||||
|
"description" : "",
|
||||||
|
"versionName" : "1.0.2",
|
||||||
|
"versionCode" : 102,
|
||||||
|
"transformPx" : false,
|
||||||
|
/* 5+App特有相关 */
|
||||||
|
"app-plus" : {
|
||||||
|
"compatible" : {
|
||||||
|
"ignoreVersion" : true //true表示忽略版本检查提示框,HBuilderX1.9.0及以上版本支持
|
||||||
|
},
|
||||||
|
"usingComponents" : true,
|
||||||
|
"nvueStyleCompiler" : "uni-app",
|
||||||
|
"compilerVersion" : 3,
|
||||||
|
"splashscreen" : {
|
||||||
|
"alwaysShowBeforeRender" : false,
|
||||||
|
"waiting" : false,
|
||||||
|
"autoclose" : true,
|
||||||
|
"delay" : 0
|
||||||
|
},
|
||||||
|
/* 模块配置 */
|
||||||
|
"modules" : {
|
||||||
|
"Barcode" : {},
|
||||||
|
"Maps" : {},
|
||||||
|
"Geolocation" : {},
|
||||||
|
"Camera" : {},
|
||||||
|
"Contacts" : {}
|
||||||
|
},
|
||||||
|
/* 应用发布信息 */
|
||||||
|
"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\"/>",
|
||||||
|
"<uses-permission android:name=\"android.permission.CALL_PHONE\"/>"
|
||||||
|
],
|
||||||
|
"minSdkVersion" : 25,
|
||||||
|
"targetSdkVersion" : 25,
|
||||||
|
"abiFilters" : [ "armeabi-v7a", "arm64-v8a", "x86" ]
|
||||||
|
},
|
||||||
|
/* ios打包配置 */
|
||||||
|
"ios" : {
|
||||||
|
"idfa" : false,
|
||||||
|
"dSYMs" : false
|
||||||
|
},
|
||||||
|
/* SDK配置 */
|
||||||
|
"sdkConfigs" : {
|
||||||
|
"ad" : {},
|
||||||
|
"maps" : {
|
||||||
|
"amap" : {
|
||||||
|
"name" : "amapZAvZjTHj",
|
||||||
|
"appkey_ios" : "3caf9e6f01b0085be1e75e0d0e281fe7",
|
||||||
|
"appkey_android" : "3caf9e6f01b0085be1e75e0d0e281fe7"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"geolocation" : {
|
||||||
|
"amap" : {
|
||||||
|
"name" : "amapZAvZjTHj",
|
||||||
|
"__platform__" : [ "android" ],
|
||||||
|
"appkey_ios" : "",
|
||||||
|
"appkey_android" : "3caf9e6f01b0085be1e75e0d0e281fe7"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"icons" : {
|
||||||
|
"android" : {
|
||||||
|
"hdpi" : "unpackage/res/icons/72x72.png",
|
||||||
|
"xhdpi" : "unpackage/res/icons/96x96.png",
|
||||||
|
"xxhdpi" : "unpackage/res/icons/144x144.png",
|
||||||
|
"xxxhdpi" : "unpackage/res/icons/192x192.png"
|
||||||
|
},
|
||||||
|
"ios" : {
|
||||||
|
"appstore" : "unpackage/res/icons/1024x1024.png",
|
||||||
|
"ipad" : {
|
||||||
|
"app" : "unpackage/res/icons/76x76.png",
|
||||||
|
"app@2x" : "unpackage/res/icons/152x152.png",
|
||||||
|
"notification" : "unpackage/res/icons/20x20.png",
|
||||||
|
"notification@2x" : "unpackage/res/icons/40x40.png",
|
||||||
|
"proapp@2x" : "unpackage/res/icons/167x167.png",
|
||||||
|
"settings" : "unpackage/res/icons/29x29.png",
|
||||||
|
"settings@2x" : "unpackage/res/icons/58x58.png",
|
||||||
|
"spotlight" : "unpackage/res/icons/40x40.png",
|
||||||
|
"spotlight@2x" : "unpackage/res/icons/80x80.png"
|
||||||
|
},
|
||||||
|
"iphone" : {
|
||||||
|
"app@2x" : "unpackage/res/icons/120x120.png",
|
||||||
|
"app@3x" : "unpackage/res/icons/180x180.png",
|
||||||
|
"notification@2x" : "unpackage/res/icons/40x40.png",
|
||||||
|
"notification@3x" : "unpackage/res/icons/60x60.png",
|
||||||
|
"settings@2x" : "unpackage/res/icons/58x58.png",
|
||||||
|
"settings@3x" : "unpackage/res/icons/87x87.png",
|
||||||
|
"spotlight@2x" : "unpackage/res/icons/80x80.png",
|
||||||
|
"spotlight@3x" : "unpackage/res/icons/120x120.png"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
/* 快应用特有相关 */
|
||||||
|
"quickapp" : {},
|
||||||
|
/* 小程序特有相关 */
|
||||||
|
"mp-weixin" : {
|
||||||
|
"appid" : "wx6ef5a6a74620a3e8",
|
||||||
|
"setting" : {
|
||||||
|
"urlCheck" : false
|
||||||
|
},
|
||||||
|
"usingComponents" : true
|
||||||
|
},
|
||||||
|
"mp-alipay" : {
|
||||||
|
"usingComponents" : true
|
||||||
|
},
|
||||||
|
"mp-baidu" : {
|
||||||
|
"usingComponents" : true
|
||||||
|
},
|
||||||
|
"mp-toutiao" : {
|
||||||
|
"usingComponents" : true
|
||||||
|
},
|
||||||
|
"uniStatistics" : {
|
||||||
|
"enable" : false
|
||||||
|
},
|
||||||
|
"vueVersion" : "3",
|
||||||
|
"h5" : {
|
||||||
|
"sdkConfigs" : {
|
||||||
|
"maps" : {
|
||||||
|
"qqmap" : {
|
||||||
|
"key" : "7DIBZ-K4HCJ-ZR2FE-FOOOP-SALFT-RLFYW"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,146 @@
|
|||||||
|
{
|
||||||
|
"name" : "骑手端",
|
||||||
|
"appid" : "__UNI__06C2D6A",
|
||||||
|
"description" : "",
|
||||||
|
"versionName" : "1.0.6",
|
||||||
|
"versionCode" : 106,
|
||||||
|
"transformPx" : false,
|
||||||
|
/* 5+App特有相关 */
|
||||||
|
"app-plus" : {
|
||||||
|
"compatible" : {
|
||||||
|
"ignoreVersion" : true //true表示忽略版本检查提示框,HBuilderX1.9.0及以上版本支持
|
||||||
|
},
|
||||||
|
"usingComponents" : true,
|
||||||
|
"nvueStyleCompiler" : "uni-app",
|
||||||
|
"compilerVersion" : 3,
|
||||||
|
"splashscreen" : {
|
||||||
|
"alwaysShowBeforeRender" : false,
|
||||||
|
"waiting" : false,
|
||||||
|
"autoclose" : true,
|
||||||
|
"delay" : 0
|
||||||
|
},
|
||||||
|
/* 模块配置 */
|
||||||
|
"modules" : {
|
||||||
|
"Barcode" : {},
|
||||||
|
"Maps" : {},
|
||||||
|
"Geolocation" : {},
|
||||||
|
"Camera" : {},
|
||||||
|
"Contacts" : {}
|
||||||
|
},
|
||||||
|
/* 应用发布信息 */
|
||||||
|
"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\"/>",
|
||||||
|
"<uses-permission android:name=\"android.permission.CALL_PHONE\"/>"
|
||||||
|
],
|
||||||
|
"minSdkVersion" : 25,
|
||||||
|
"targetSdkVersion" : 25,
|
||||||
|
"abiFilters" : [ "armeabi-v7a", "arm64-v8a", "x86" ]
|
||||||
|
},
|
||||||
|
/* ios打包配置 */
|
||||||
|
"ios" : {
|
||||||
|
"idfa" : false,
|
||||||
|
"dSYMs" : false
|
||||||
|
},
|
||||||
|
/* SDK配置 */
|
||||||
|
"sdkConfigs" : {
|
||||||
|
"ad" : {},
|
||||||
|
"maps" : {
|
||||||
|
"amap" : {
|
||||||
|
"name" : "amapZAvZjTHj",
|
||||||
|
"appkey_ios" : "3caf9e6f01b0085be1e75e0d0e281fe7",
|
||||||
|
"appkey_android" : "3caf9e6f01b0085be1e75e0d0e281fe7"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"geolocation" : {
|
||||||
|
"amap" : {
|
||||||
|
"name" : "amapZAvZjTHj",
|
||||||
|
"__platform__" : [ "android" ],
|
||||||
|
"appkey_ios" : "",
|
||||||
|
"appkey_android" : "3caf9e6f01b0085be1e75e0d0e281fe7"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"icons" : {
|
||||||
|
"android" : {
|
||||||
|
"hdpi" : "unpackage/res/icons/72x72.png",
|
||||||
|
"xhdpi" : "unpackage/res/icons/96x96.png",
|
||||||
|
"xxhdpi" : "unpackage/res/icons/144x144.png",
|
||||||
|
"xxxhdpi" : "unpackage/res/icons/192x192.png"
|
||||||
|
},
|
||||||
|
"ios" : {
|
||||||
|
"appstore" : "unpackage/res/icons/1024x1024.png",
|
||||||
|
"ipad" : {
|
||||||
|
"app" : "unpackage/res/icons/76x76.png",
|
||||||
|
"app@2x" : "unpackage/res/icons/152x152.png",
|
||||||
|
"notification" : "unpackage/res/icons/20x20.png",
|
||||||
|
"notification@2x" : "unpackage/res/icons/40x40.png",
|
||||||
|
"proapp@2x" : "unpackage/res/icons/167x167.png",
|
||||||
|
"settings" : "unpackage/res/icons/29x29.png",
|
||||||
|
"settings@2x" : "unpackage/res/icons/58x58.png",
|
||||||
|
"spotlight" : "unpackage/res/icons/40x40.png",
|
||||||
|
"spotlight@2x" : "unpackage/res/icons/80x80.png"
|
||||||
|
},
|
||||||
|
"iphone" : {
|
||||||
|
"app@2x" : "unpackage/res/icons/120x120.png",
|
||||||
|
"app@3x" : "unpackage/res/icons/180x180.png",
|
||||||
|
"notification@2x" : "unpackage/res/icons/40x40.png",
|
||||||
|
"notification@3x" : "unpackage/res/icons/60x60.png",
|
||||||
|
"settings@2x" : "unpackage/res/icons/58x58.png",
|
||||||
|
"settings@3x" : "unpackage/res/icons/87x87.png",
|
||||||
|
"spotlight@2x" : "unpackage/res/icons/80x80.png",
|
||||||
|
"spotlight@3x" : "unpackage/res/icons/120x120.png"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
/* 快应用特有相关 */
|
||||||
|
"quickapp" : {},
|
||||||
|
/* 小程序特有相关 */
|
||||||
|
"mp-weixin" : {
|
||||||
|
"appid" : "wx6ef5a6a74620a3e8",
|
||||||
|
"setting" : {
|
||||||
|
"urlCheck" : false
|
||||||
|
},
|
||||||
|
"usingComponents" : true
|
||||||
|
},
|
||||||
|
"mp-alipay" : {
|
||||||
|
"usingComponents" : true
|
||||||
|
},
|
||||||
|
"mp-baidu" : {
|
||||||
|
"usingComponents" : true
|
||||||
|
},
|
||||||
|
"mp-toutiao" : {
|
||||||
|
"usingComponents" : true
|
||||||
|
},
|
||||||
|
"uniStatistics" : {
|
||||||
|
"enable" : false
|
||||||
|
},
|
||||||
|
"vueVersion" : "3",
|
||||||
|
"h5" : {
|
||||||
|
"sdkConfigs" : {
|
||||||
|
"maps" : {
|
||||||
|
"qqmap" : {
|
||||||
|
"key" : "7DIBZ-K4HCJ-ZR2FE-FOOOP-SALFT-RLFYW"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,196 @@
|
|||||||
|
<template>
|
||||||
|
<view class="contact-support-page">
|
||||||
|
<!-- 全新方案:纯 CSS 手动构建的骨架屏 -->
|
||||||
|
<view v-if="loading" class="skeleton-wrapper">
|
||||||
|
<view class="skeleton-card">
|
||||||
|
<view style="padding: 40rpx 0; ">
|
||||||
|
<view class="skeleton-item skeleton-text" style="width: 100%; height: 60rpx;"></view>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
|
||||||
|
</view>
|
||||||
|
|
||||||
|
<!-- 页面实际内容 -->
|
||||||
|
<view v-else class="page-content">
|
||||||
|
|
||||||
|
<view class="page-container">
|
||||||
|
<view class="card emergency-card" @click="callEmergency">
|
||||||
|
<view class="emergency-title">
|
||||||
|
<up-icon name="phone-fill" color="#fa6400" size="18"></up-icon>
|
||||||
|
<text>紧急问题?直接拨打人工客服</text>
|
||||||
|
</view>
|
||||||
|
<text class="phone-number">{{ phone }}</text>
|
||||||
|
<text class="service-time">9:00-22:00</text>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script setup lang="ts">
|
||||||
|
import { ref, reactive } from 'vue';
|
||||||
|
import { onLoad, onShow } from '@dcloudio/uni-app';
|
||||||
|
import { Service, CNRiderLoginService } from "@/Service/CN/CNRiderLoginService";
|
||||||
|
const loading = ref<boolean>(true);
|
||||||
|
|
||||||
|
let phone=ref('')
|
||||||
|
|
||||||
|
onLoad(() => {
|
||||||
|
getData()
|
||||||
|
});
|
||||||
|
onShow(() => { });
|
||||||
|
|
||||||
|
const getData=()=>{
|
||||||
|
|
||||||
|
CNRiderLoginService.GetKefuInfo().then(res=>{
|
||||||
|
loading.value = false;
|
||||||
|
|
||||||
|
if(res.code==0){
|
||||||
|
phone.value=res.data.phone
|
||||||
|
}
|
||||||
|
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
const callEmergency = () => {
|
||||||
|
uni.makePhoneCall({
|
||||||
|
phoneNumber: phone.value
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style lang="scss" scoped>
|
||||||
|
@keyframes skeleton-blink {
|
||||||
|
0% {
|
||||||
|
background-position: 100% 50%;
|
||||||
|
}
|
||||||
|
|
||||||
|
100% {
|
||||||
|
background-position: 0 50%;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.skeleton-item {
|
||||||
|
background: linear-gradient(90deg, #f0f0f0 25%, #e0e0e0 50%, #f0f0f0 75%);
|
||||||
|
background-size: 200% 100%;
|
||||||
|
animation: skeleton-blink 1.5s infinite linear;
|
||||||
|
}
|
||||||
|
|
||||||
|
.skeleton-rect {
|
||||||
|
border-radius: 12rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
.skeleton-text {
|
||||||
|
border-radius: 4rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
.skeleton-wrapper {
|
||||||
|
padding: 24rpx;
|
||||||
|
background-color: #f7f7f7;
|
||||||
|
|
||||||
|
.skeleton-card {
|
||||||
|
background-color: #fff;
|
||||||
|
padding: 30rpx;
|
||||||
|
border-radius: 16rpx;
|
||||||
|
margin-bottom: 24rpx;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.contact-support-page {
|
||||||
|
background-color: #f7f7f7;
|
||||||
|
min-height: 100vh;
|
||||||
|
}
|
||||||
|
|
||||||
|
.page-container {
|
||||||
|
padding: 24rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
.card {
|
||||||
|
background-color: #fff;
|
||||||
|
border-radius: 16rpx;
|
||||||
|
margin-bottom: 24rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
.section {
|
||||||
|
.section-title {
|
||||||
|
font-size: 28rpx;
|
||||||
|
color: #666;
|
||||||
|
margin-bottom: 20rpx;
|
||||||
|
display: block;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.notice-box {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
gap: 16rpx;
|
||||||
|
border-radius: 16rpx;
|
||||||
|
padding: 24rpx;
|
||||||
|
font-size: 26rpx;
|
||||||
|
|
||||||
|
&.info-box {
|
||||||
|
background-color: #ecf5ff;
|
||||||
|
color: #40a9ff;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.menu-list {
|
||||||
|
padding: 0 30rpx;
|
||||||
|
|
||||||
|
:deep(.up-cell-group) {
|
||||||
|
.up-cell {
|
||||||
|
.up-cell__body {
|
||||||
|
padding: 28rpx 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.cell-title {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
margin-left: 20rpx;
|
||||||
|
|
||||||
|
.title {
|
||||||
|
font-size: 30rpx;
|
||||||
|
color: #333;
|
||||||
|
}
|
||||||
|
|
||||||
|
.desc {
|
||||||
|
font-size: 24rpx;
|
||||||
|
color: #999;
|
||||||
|
margin-top: 4rpx;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.emergency-card {
|
||||||
|
background-color: #ffffff;
|
||||||
|
text-align: center;
|
||||||
|
padding: 30rpx;
|
||||||
|
|
||||||
|
.emergency-title {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
gap: 10rpx;
|
||||||
|
font-size: 28rpx;
|
||||||
|
color: #fa6400;
|
||||||
|
font-weight: 500;
|
||||||
|
}
|
||||||
|
|
||||||
|
.phone-number {
|
||||||
|
display: block;
|
||||||
|
font-size: 44rpx;
|
||||||
|
font-weight: bold;
|
||||||
|
color: #333;
|
||||||
|
margin: 16rpx 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.service-time {
|
||||||
|
font-size: 26rpx;
|
||||||
|
color: #999;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</style>
|
||||||
@@ -0,0 +1,743 @@
|
|||||||
|
<template>
|
||||||
|
<view class="image-cropper" :style="{ zIndex }" @wheel="cropper.mousewheel">
|
||||||
|
<canvas v-if="use2d" type="2d" id="imgCanvas" class="img-canvas" :style="{
|
||||||
|
width: `${canvansWidth}px`,
|
||||||
|
height: `${canvansHeight}px`
|
||||||
|
}"></canvas>
|
||||||
|
<canvas v-else id="imgCanvas" canvas-id="imgCanvas" class="img-canvas" :style="{
|
||||||
|
width: `${canvansWidth}px`,
|
||||||
|
height: `${canvansHeight}px`
|
||||||
|
}"></canvas>
|
||||||
|
<view id="pic-preview" class="pic-preview" :change:init="cropper.initObserver" :init="initData" @touchstart="cropper.touchstart" @touchmove="cropper.touchmove" @touchend="cropper.touchend">
|
||||||
|
<image v-if="imgSrc" id="crop-image" class="crop-image" :style="cropper.imageStyles" :src="imgSrc" webp></image>
|
||||||
|
<view v-for="(item, index) in maskList" :key="item.id" :id="item.id" class="crop-mask-block" :style="cropper.maskStylesList[index]"></view>
|
||||||
|
<view v-if="showBorder" id="crop-border" class="crop-border" :style="cropper.borderStyles"></view>
|
||||||
|
<view v-if="radius > 0" id="crop-circle-box" class="crop-circle-box" :style="cropper.circleBoxStyles">
|
||||||
|
<view class="crop-circle" id="crop-circle" :style="cropper.circleStyles"></view>
|
||||||
|
</view>
|
||||||
|
<block v-if="showGrid">
|
||||||
|
<view v-for="(item, index) in gridList" :key="item.id" :id="item.id" class="crop-grid" :style="cropper.gridStylesList[index]"></view>
|
||||||
|
</block>
|
||||||
|
<block v-if="showAngle">
|
||||||
|
<view v-for="(item, index) in angleList" :key="item.id" :id="item.id" class="crop-angle" :style="cropper.angleStylesList[index]">
|
||||||
|
<view :style="[{
|
||||||
|
width: `${angleSize}px`,
|
||||||
|
height: `${angleSize}px`
|
||||||
|
}]"></view>
|
||||||
|
</view>
|
||||||
|
</block>
|
||||||
|
</view>
|
||||||
|
<slot />
|
||||||
|
<view class="fixed-bottom safe-area-inset-bottom" :style="{ zIndex: initData.area.zIndex + 99 }">
|
||||||
|
<view v-if="(rotatable || reverseRotatable) && !!imgSrc" class="action-bar">
|
||||||
|
<view v-if="reverseRotatable" class="rotate-icon" @click="cropper.rotateImage270"></view>
|
||||||
|
<view v-if="rotatable" class="rotate-icon is-reverse" @click="cropper.rotateImage90"></view>
|
||||||
|
</view>
|
||||||
|
<view v-if="!choosable" class="choose-btn" @click="cropClick">确定</view>
|
||||||
|
<block v-else-if="!!imgSrc">
|
||||||
|
<view class="rechoose" @click="chooseImage">重选</view>
|
||||||
|
<button class="button" size="mini" @click="cropClick">确定</button>
|
||||||
|
</block>
|
||||||
|
<view v-else class="choose-btn" @click="chooseImage">选择图片</view>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<!-- #ifdef APP-VUE -->
|
||||||
|
<script module="cropper" lang="renderjs">
|
||||||
|
import cropper from './qf-image-cropper.render.js';
|
||||||
|
// vue3 app renderjs中条件编译无效
|
||||||
|
cropper.setPlatform('APP');
|
||||||
|
export default {
|
||||||
|
mixins: [ cropper ]
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
<!-- #endif -->
|
||||||
|
<!-- #ifdef H5 -->
|
||||||
|
<script module="cropper" lang="renderjs">
|
||||||
|
import cropper from './qf-image-cropper.render.js';
|
||||||
|
export default {
|
||||||
|
mixins: [ cropper ]
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
<!-- #endif -->
|
||||||
|
<!-- #ifdef MP-WEIXIN || MP-QQ -->
|
||||||
|
<script module="cropper" lang="wxs" src="./qf-image-cropper.wxs"></script>
|
||||||
|
<!-- #endif -->
|
||||||
|
<script>
|
||||||
|
/** 裁剪区域最大宽高所占屏幕宽度百分比 */
|
||||||
|
const AREA_SIZE = 75;
|
||||||
|
/** 图片默认宽高 */
|
||||||
|
const IMG_SIZE = 300;
|
||||||
|
|
||||||
|
export default {
|
||||||
|
name:"qf-image-cropper",
|
||||||
|
// #ifdef MP-WEIXIN
|
||||||
|
options: {
|
||||||
|
// 表示启用样式隔离,在自定义组件内外,使用 class 指定的样式将不会相互影响
|
||||||
|
styleIsolation: "isolated"
|
||||||
|
},
|
||||||
|
// #endif
|
||||||
|
props: {
|
||||||
|
/** 图片资源地址 */
|
||||||
|
src: {
|
||||||
|
type: String,
|
||||||
|
default: ''
|
||||||
|
},
|
||||||
|
/** 裁剪宽度,有些平台或设备对于canvas的尺寸有限制,过大可能会导致无法正常绘制 */
|
||||||
|
width: {
|
||||||
|
type: Number,
|
||||||
|
default: IMG_SIZE
|
||||||
|
},
|
||||||
|
/** 裁剪高度,有些平台或设备对于canvas的尺寸有限制,过大可能会导致无法正常绘制 */
|
||||||
|
height: {
|
||||||
|
type: Number,
|
||||||
|
default: IMG_SIZE
|
||||||
|
},
|
||||||
|
/** 是否绘制裁剪区域边框 */
|
||||||
|
showBorder: {
|
||||||
|
type: Boolean,
|
||||||
|
default: true
|
||||||
|
},
|
||||||
|
/** 是否绘制裁剪区域网格参考线 */
|
||||||
|
showGrid: {
|
||||||
|
type: Boolean,
|
||||||
|
default: true
|
||||||
|
},
|
||||||
|
/** 是否展示四个支持伸缩的角 */
|
||||||
|
showAngle: {
|
||||||
|
type: Boolean,
|
||||||
|
default: true
|
||||||
|
},
|
||||||
|
/** 裁剪区域最小缩放倍数 */
|
||||||
|
areaScale: {
|
||||||
|
type: Number,
|
||||||
|
default: 0.3
|
||||||
|
},
|
||||||
|
/** 图片最小缩放倍数 */
|
||||||
|
minScale: {
|
||||||
|
type: Number,
|
||||||
|
default: 1
|
||||||
|
},
|
||||||
|
/** 图片最大缩放倍数 */
|
||||||
|
maxScale: {
|
||||||
|
type: Number,
|
||||||
|
default: 5
|
||||||
|
},
|
||||||
|
/** 检查图片位置是否超出裁剪边界,如果超出则会矫正位置 */
|
||||||
|
checkRange: {
|
||||||
|
type: Boolean,
|
||||||
|
default: true
|
||||||
|
},
|
||||||
|
/** 生成图片背景色:如果裁剪区域没有完全包含在图片中时,不设置该属性生成图片存在一定的透明块 */
|
||||||
|
backgroundColor: {
|
||||||
|
type: String
|
||||||
|
},
|
||||||
|
/** 是否有回弹效果:当 checkRange 为 true 时有效,拖动时可以拖出边界,释放时会弹回边界 */
|
||||||
|
bounce: {
|
||||||
|
type: Boolean,
|
||||||
|
default: true
|
||||||
|
},
|
||||||
|
/** 是否支持翻转 */
|
||||||
|
rotatable: {
|
||||||
|
type: Boolean,
|
||||||
|
default: true
|
||||||
|
},
|
||||||
|
/** 是否支持逆向翻转 */
|
||||||
|
reverseRotatable: {
|
||||||
|
type: Boolean,
|
||||||
|
default: false
|
||||||
|
},
|
||||||
|
/** 是否支持从本地选择素材 */
|
||||||
|
choosable: {
|
||||||
|
type: Boolean,
|
||||||
|
default: true
|
||||||
|
},
|
||||||
|
/** 是否开启硬件加速,图片缩放过程中如果出现元素的“留影”或“重影”效果,可通过该方式解决或减轻这一问题 */
|
||||||
|
gpu: {
|
||||||
|
type: Boolean,
|
||||||
|
default: false
|
||||||
|
},
|
||||||
|
/** 四个角尺寸,单位px */
|
||||||
|
angleSize: {
|
||||||
|
type: Number,
|
||||||
|
default: 20
|
||||||
|
},
|
||||||
|
/** 四个角边框宽度,单位px */
|
||||||
|
angleBorderWidth: {
|
||||||
|
type: Number,
|
||||||
|
default: 2
|
||||||
|
},
|
||||||
|
zIndex: {
|
||||||
|
type: [Number, String]
|
||||||
|
},
|
||||||
|
/** 裁剪图片圆角半径,单位px */
|
||||||
|
radius: {
|
||||||
|
type: Number,
|
||||||
|
default: 0
|
||||||
|
},
|
||||||
|
/** 生成文件的类型,只支持 'jpg' 或 'png'。默认为 'png' */
|
||||||
|
fileType: {
|
||||||
|
type: String,
|
||||||
|
default: 'png'
|
||||||
|
},
|
||||||
|
/**
|
||||||
|
* 图片从绘制到生成所需时间,单位ms
|
||||||
|
* 微信小程序平台使用 `Canvas 2D` 绘制时有效
|
||||||
|
* 如绘制大图或出现裁剪图片空白等情况应适当调大该值,因 `Canvas 2d` 采用同步绘制,需自己把控绘制完成时间
|
||||||
|
*/
|
||||||
|
delay: {
|
||||||
|
type: Number,
|
||||||
|
default: 1000
|
||||||
|
},
|
||||||
|
// #ifdef H5
|
||||||
|
/**
|
||||||
|
* 页面是否是原生标题栏
|
||||||
|
* H5平台当 showAngle 为 true 时,使用插件的页面在 `page.json` 中配置了 "navigationStyle": "custom" 时,必须将此值设为 false ,否则四个可拉伸角的触发位置会有偏差。
|
||||||
|
* 注:因H5平台的窗口高度是包含标题栏的,而屏幕触摸点的坐标是不包含的
|
||||||
|
*/
|
||||||
|
navigation: {
|
||||||
|
type: Boolean,
|
||||||
|
default: true
|
||||||
|
}
|
||||||
|
// #endif
|
||||||
|
},
|
||||||
|
emits: ["crop"],
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
// 用不同 id 使 v-for key 不重复
|
||||||
|
maskList: [
|
||||||
|
{ id: 'crop-mask-block-1' },
|
||||||
|
{ id: 'crop-mask-block-2' },
|
||||||
|
{ id: 'crop-mask-block-3' },
|
||||||
|
{ id: 'crop-mask-block-4' },
|
||||||
|
],
|
||||||
|
gridList: [
|
||||||
|
{ id: 'crop-grid-1' },
|
||||||
|
{ id: 'crop-grid-2' },
|
||||||
|
{ id: 'crop-grid-3' },
|
||||||
|
{ id: 'crop-grid-4' },
|
||||||
|
],
|
||||||
|
angleList: [
|
||||||
|
{ id: 'crop-angle-1' },
|
||||||
|
{ id: 'crop-angle-2' },
|
||||||
|
{ id: 'crop-angle-3' },
|
||||||
|
{ id: 'crop-angle-4' },
|
||||||
|
],
|
||||||
|
/** 本地缓存的图片路径 */
|
||||||
|
imgSrc: '',
|
||||||
|
/** 图片的裁剪宽度 */
|
||||||
|
imgWidth: IMG_SIZE,
|
||||||
|
/** 图片的裁剪高度 */
|
||||||
|
imgHeight: IMG_SIZE,
|
||||||
|
/** 裁剪区域最大宽度所占屏幕宽度百分比 */
|
||||||
|
widthPercent: AREA_SIZE,
|
||||||
|
/** 裁剪区域最大高度所占屏幕宽度百分比 */
|
||||||
|
heightPercent: AREA_SIZE,
|
||||||
|
/** 裁剪区域布局信息 */
|
||||||
|
area: {},
|
||||||
|
/** 未被缩放过的图片宽 */
|
||||||
|
oldWidth: 0,
|
||||||
|
/** 未被缩放过的图片高 */
|
||||||
|
oldHeight: 0,
|
||||||
|
/** 系统信息 */
|
||||||
|
sys: uni.getSystemInfoSync(),
|
||||||
|
scaleWidth: 0,
|
||||||
|
scaleHeight: 0,
|
||||||
|
rotate: 0,
|
||||||
|
offsetX: 0,
|
||||||
|
offsetY: 0,
|
||||||
|
use2d: false,
|
||||||
|
canvansWidth: 0,
|
||||||
|
canvansHeight: 0,
|
||||||
|
// imageStyles: {},
|
||||||
|
// maskStylesList: [{}, {}, {}, {}],
|
||||||
|
// borderStyles: {},
|
||||||
|
// gridStylesList: [{}, {}, {}, {}],
|
||||||
|
// angleStylesList: [{}, {}, {}, {}],
|
||||||
|
// circleBoxStyles: {},
|
||||||
|
// circleStyles: {},
|
||||||
|
}
|
||||||
|
},
|
||||||
|
computed: {
|
||||||
|
initData() {
|
||||||
|
// console.log('initData')
|
||||||
|
return {
|
||||||
|
timestamp: new Date().getTime(),
|
||||||
|
area: {
|
||||||
|
...this.area,
|
||||||
|
bounce: this.bounce,
|
||||||
|
showBorder: this.showBorder,
|
||||||
|
showGrid: this.showGrid,
|
||||||
|
showAngle: this.showAngle,
|
||||||
|
angleSize: this.angleSize,
|
||||||
|
angleBorderWidth: this.angleBorderWidth,
|
||||||
|
minScale: this.areaScale,
|
||||||
|
widthPercent: this.widthPercent,
|
||||||
|
heightPercent: this.heightPercent,
|
||||||
|
radius: this.radius,
|
||||||
|
checkRange: this.checkRange,
|
||||||
|
zIndex: +this.zIndex || 0,
|
||||||
|
},
|
||||||
|
sys: this.sys,
|
||||||
|
img: {
|
||||||
|
minScale: this.minScale,
|
||||||
|
maxScale: this.maxScale,
|
||||||
|
src: this.imgSrc,
|
||||||
|
width: this.oldWidth,
|
||||||
|
height: this.oldHeight,
|
||||||
|
oldWidth: this.oldWidth,
|
||||||
|
oldHeight: this.oldHeight,
|
||||||
|
gpu: this.gpu,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
imgProps() {
|
||||||
|
return {
|
||||||
|
width: this.width,
|
||||||
|
height: this.height,
|
||||||
|
src: this.src,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
watch: {
|
||||||
|
imgProps: {
|
||||||
|
handler(val, oldVal) {
|
||||||
|
// 自定义裁剪尺,示例如下:
|
||||||
|
this.imgWidth = Number(val.width) || IMG_SIZE;
|
||||||
|
this.imgHeight = Number(val.height) || IMG_SIZE;
|
||||||
|
let use2d = true;
|
||||||
|
// #ifndef MP-WEIXIN
|
||||||
|
use2d = false;
|
||||||
|
// #endif
|
||||||
|
// if(use2d && (this.imgWidth > 1365 || this.imgHeight > 1365)) {
|
||||||
|
// use2d = false;
|
||||||
|
// }
|
||||||
|
let canvansWidth = this.imgWidth;
|
||||||
|
let canvansHeight = this.imgHeight;
|
||||||
|
let size = Math.max(canvansWidth, canvansHeight)
|
||||||
|
let scalc = 1;
|
||||||
|
if(size > 1365) {
|
||||||
|
scalc = 1365 / size;
|
||||||
|
}
|
||||||
|
this.canvansWidth = canvansWidth * scalc;
|
||||||
|
this.canvansHeight = canvansHeight * scalc;
|
||||||
|
this.use2d = use2d;
|
||||||
|
this.initArea();
|
||||||
|
const src = val.src || this.imgSrc;
|
||||||
|
src && this.initImage(src, oldVal === undefined);
|
||||||
|
},
|
||||||
|
immediate: true
|
||||||
|
},
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
/** 提供给wxs调用,用来接收图片变更数据 */
|
||||||
|
dataChange(e) {
|
||||||
|
// console.log('dataChange', e)
|
||||||
|
this.scaleWidth = e.width;
|
||||||
|
this.scaleHeight = e.height;
|
||||||
|
this.rotate = e.rotate;
|
||||||
|
this.offsetX = e.x;
|
||||||
|
this.offsetY = e.y;
|
||||||
|
},
|
||||||
|
/** 初始化裁剪区域布局信息 */
|
||||||
|
initArea() {
|
||||||
|
// 底部操作栏高度 = 底部底部操作栏内容高度 + 设备底部安全区域高度
|
||||||
|
this.sys.offsetBottom = uni.upx2px(100) + this.sys.safeAreaInsets.bottom;
|
||||||
|
// #ifndef H5
|
||||||
|
this.sys.windowTop = 0;
|
||||||
|
this.sys.navigation = true;
|
||||||
|
// #endif
|
||||||
|
// #ifdef H5
|
||||||
|
// h5平台的窗口高度是包含标题栏的
|
||||||
|
this.sys.windowTop = this.sys.windowTop || 44;
|
||||||
|
this.sys.navigation = this.navigation;
|
||||||
|
// #endif
|
||||||
|
let wp = this.widthPercent;
|
||||||
|
let hp = this.heightPercent;
|
||||||
|
if (this.imgWidth > this.imgHeight) {
|
||||||
|
hp = hp * this.imgHeight / this.imgWidth;
|
||||||
|
} else if (this.imgWidth < this.imgHeight) {
|
||||||
|
wp = wp * this.imgWidth / this.imgHeight;
|
||||||
|
}
|
||||||
|
const size = this.sys.windowWidth > this.sys.windowHeight ? this.sys.windowHeight : this.sys.windowWidth;
|
||||||
|
const width = size * wp / 100;
|
||||||
|
const height = size * hp / 100;
|
||||||
|
const left = (this.sys.windowWidth - width) / 2;
|
||||||
|
const right = left + width;
|
||||||
|
const top = (this.sys.windowHeight + this.sys.windowTop - this.sys.offsetBottom - height) / 2;
|
||||||
|
const bottom = this.sys.windowHeight + this.sys.windowTop - this.sys.offsetBottom - top;
|
||||||
|
this.area = { width, height, left, right, top, bottom };
|
||||||
|
this.scaleWidth = width;
|
||||||
|
this.scaleHeight = height;
|
||||||
|
},
|
||||||
|
/** 从本地选取图片 */
|
||||||
|
chooseImage(options) {
|
||||||
|
// #ifdef MP-WEIXIN || MP-JD
|
||||||
|
if(uni.chooseMedia) {
|
||||||
|
uni.chooseMedia({
|
||||||
|
...options,
|
||||||
|
count: 1,
|
||||||
|
mediaType: ['image'],
|
||||||
|
success: (res) => {
|
||||||
|
this.resetData();
|
||||||
|
this.initImage(res.tempFiles[0].tempFilePath);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
// #endif
|
||||||
|
uni.chooseImage({
|
||||||
|
...options,
|
||||||
|
count: 1,
|
||||||
|
success: (res) => {
|
||||||
|
this.resetData();
|
||||||
|
this.initImage(res.tempFiles[0].path);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
},
|
||||||
|
/** 重置数据 */
|
||||||
|
resetData() {
|
||||||
|
this.imgSrc = '';
|
||||||
|
this.rotate = 0;
|
||||||
|
this.offsetX = 0;
|
||||||
|
this.offsetY = 0;
|
||||||
|
this.initArea();
|
||||||
|
},
|
||||||
|
/**
|
||||||
|
* 初始化图片信息
|
||||||
|
* @param {String} url 图片链接
|
||||||
|
*/
|
||||||
|
initImage(url, isFirst) {
|
||||||
|
uni.getImageInfo({
|
||||||
|
src: url,
|
||||||
|
success: async (res) => {
|
||||||
|
if (isFirst && this.src === url) await (new Promise((resolve) => setTimeout(resolve, 50)));
|
||||||
|
this.imgSrc = res.path;
|
||||||
|
let scale = res.width / res.height;
|
||||||
|
let areaScale = this.area.width / this.area.height;
|
||||||
|
if (scale > 1) { // 横向图片
|
||||||
|
if (scale >= areaScale) { // 图片宽不小于目标宽,则高固定,宽自适应
|
||||||
|
this.scaleWidth = (this.scaleHeight / res.height) * this.scaleWidth * (res.width / this.scaleWidth);
|
||||||
|
} else { // 否则宽固定、高自适应
|
||||||
|
this.scaleHeight = res.height * this.scaleWidth / res.width;
|
||||||
|
}
|
||||||
|
} else { // 纵向图片
|
||||||
|
if (scale <= areaScale) { // 图片高不小于目标高,宽固定,高自适应
|
||||||
|
this.scaleHeight = (this.scaleWidth / res.width) * this.scaleHeight / (this.scaleHeight / res.height);
|
||||||
|
} else { // 否则高固定,宽自适应
|
||||||
|
this.scaleWidth = res.width * this.scaleHeight / res.height;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// 记录原始宽高,为缩放比列做限制
|
||||||
|
this.oldWidth = +this.scaleWidth.toFixed(2);
|
||||||
|
this.oldHeight = +this.scaleHeight.toFixed(2);
|
||||||
|
},
|
||||||
|
fail: (err) => {
|
||||||
|
console.error(err)
|
||||||
|
}
|
||||||
|
});
|
||||||
|
},
|
||||||
|
/**
|
||||||
|
* 剪切图片圆角
|
||||||
|
* @param {Object} ctx canvas 的绘图上下文对象
|
||||||
|
* @param {Number} radius 圆角半径
|
||||||
|
* @param {Number} scale 生成图片的实际尺寸与截取区域比
|
||||||
|
* @param {Function} drawImage 执行剪切时所调用的绘图方法,入参为是否执行了剪切
|
||||||
|
*/
|
||||||
|
drawClipImage(ctx, radius, scale, drawImage) {
|
||||||
|
if(radius > 0) {
|
||||||
|
ctx.save();
|
||||||
|
ctx.beginPath();
|
||||||
|
const w = this.canvansWidth;
|
||||||
|
const h = this.canvansHeight;
|
||||||
|
if(w === h && radius >= w / 2) { // 圆形
|
||||||
|
ctx.arc(w / 2, h / 2, w / 2, 0, 2 * Math.PI);
|
||||||
|
} else { // 圆角矩形
|
||||||
|
if(w !== h) { // 限制圆角半径不能超过短边的一半
|
||||||
|
radius = Math.min(w / 2, h / 2, radius);
|
||||||
|
// radius = Math.min(Math.max(w, h) / 2, radius);
|
||||||
|
}
|
||||||
|
ctx.moveTo(radius, 0);
|
||||||
|
ctx.arcTo(w, 0, w, h, radius);
|
||||||
|
ctx.arcTo(w, h, 0, h, radius);
|
||||||
|
ctx.arcTo(0, h, 0, 0, radius);
|
||||||
|
ctx.arcTo(0, 0, w, 0, radius);
|
||||||
|
ctx.closePath();
|
||||||
|
}
|
||||||
|
ctx.clip();
|
||||||
|
drawImage && drawImage(true);
|
||||||
|
ctx.restore();
|
||||||
|
} else {
|
||||||
|
drawImage && drawImage(false);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
/**
|
||||||
|
* 旋转图片
|
||||||
|
* @param {Object} ctx canvas 的绘图上下文对象
|
||||||
|
* @param {Number} rotate 旋转角度
|
||||||
|
* @param {Number} scale 生成图片的实际尺寸与截取区域比
|
||||||
|
*/
|
||||||
|
drawRotateImage(ctx, rotate, scale) {
|
||||||
|
if(rotate !== 0) {
|
||||||
|
// 1. 以图片中心点为旋转中心点
|
||||||
|
const x = this.scaleWidth * scale / 2;
|
||||||
|
const y = this.scaleHeight * scale / 2;
|
||||||
|
ctx.translate(x, y);
|
||||||
|
// 2. 旋转画布
|
||||||
|
ctx.rotate(rotate * Math.PI / 180);
|
||||||
|
// 3. 旋转完画布后恢复设置旋转中心时所做的偏移
|
||||||
|
ctx.translate(-x, -y);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
drawImage(ctx, image, callback) {
|
||||||
|
// 生成图片的实际尺寸与截取区域比
|
||||||
|
const scale = this.canvansWidth / this.area.width;
|
||||||
|
if(this.backgroundColor) {
|
||||||
|
if(ctx.setFillStyle) ctx.setFillStyle(this.backgroundColor);
|
||||||
|
else ctx.fillStyle = this.backgroundColor;
|
||||||
|
ctx.fillRect(0, 0, this.canvansWidth, this.canvansHeight);
|
||||||
|
}
|
||||||
|
this.drawClipImage(ctx, this.radius, scale, () => {
|
||||||
|
this.drawRotateImage(ctx, this.rotate, scale);
|
||||||
|
const r = this.rotate / 90;
|
||||||
|
ctx.drawImage(
|
||||||
|
image,
|
||||||
|
[
|
||||||
|
(this.offsetX - this.area.left),
|
||||||
|
(this.offsetY - this.area.top),
|
||||||
|
-(this.offsetX - this.area.left),
|
||||||
|
-(this.offsetY - this.area.top)
|
||||||
|
][r] * scale,
|
||||||
|
[
|
||||||
|
(this.offsetY - this.area.top),
|
||||||
|
-(this.offsetX - this.area.left),
|
||||||
|
-(this.offsetY - this.area.top),
|
||||||
|
(this.offsetX - this.area.left)
|
||||||
|
][r] * scale,
|
||||||
|
this.scaleWidth * scale,
|
||||||
|
this.scaleHeight * scale
|
||||||
|
);
|
||||||
|
});
|
||||||
|
},
|
||||||
|
/**
|
||||||
|
* 绘图
|
||||||
|
* @param {Object} canvas
|
||||||
|
* @param {Object} ctx canvas 的绘图上下文对象
|
||||||
|
* @param {String} src 图片路径
|
||||||
|
* @param {Function} callback 开始绘制时回调
|
||||||
|
*/
|
||||||
|
draw2DImage(canvas, ctx, src, callback) {
|
||||||
|
// console.log('draw2DImage', canvas, ctx, src, callback)
|
||||||
|
if(canvas) {
|
||||||
|
const image = canvas.createImage();
|
||||||
|
image.onload = () => {
|
||||||
|
this.drawImage(ctx, image);
|
||||||
|
// 如果觉得`生成时间过长`或`出现生成图片空白`可尝试调整延迟时间
|
||||||
|
callback && setTimeout(callback, this.delay);
|
||||||
|
};
|
||||||
|
image.onerror = (err) => {
|
||||||
|
console.error(err)
|
||||||
|
uni.hideLoading();
|
||||||
|
};
|
||||||
|
image.src = src;
|
||||||
|
} else {
|
||||||
|
this.drawImage(ctx, src);
|
||||||
|
setTimeout(() => {
|
||||||
|
ctx.draw(false, callback);
|
||||||
|
}, 200);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
/**
|
||||||
|
* 画布转图片到本地缓存
|
||||||
|
* @param {Object} canvas
|
||||||
|
* @param {String} canvasId
|
||||||
|
*/
|
||||||
|
canvasToTempFilePath(canvas, canvasId) {
|
||||||
|
// console.log('canvasToTempFilePath', canvas, canvasId)
|
||||||
|
uni.canvasToTempFilePath({
|
||||||
|
canvas,
|
||||||
|
canvasId,
|
||||||
|
x: 0,
|
||||||
|
y: 0,
|
||||||
|
width: this.canvansWidth,
|
||||||
|
height: this.canvansHeight,
|
||||||
|
destWidth: this.imgWidth, // 必要,保证生成图片宽度不受设备分辨率影响
|
||||||
|
destHeight: this.imgHeight, // 必要,保证生成图片高度不受设备分辨率影响
|
||||||
|
fileType: this.fileType, // 目标文件的类型,默认png
|
||||||
|
success: (res) => {
|
||||||
|
// 生成的图片临时文件路径
|
||||||
|
this.handleImage(res.tempFilePath);
|
||||||
|
},
|
||||||
|
fail: (err) => {
|
||||||
|
uni.hideLoading();
|
||||||
|
uni.showToast({ title: '裁剪失败,生成图片异常!', icon: 'none' });
|
||||||
|
}
|
||||||
|
}, this);
|
||||||
|
},
|
||||||
|
/** 确认裁剪 */
|
||||||
|
cropClick() {
|
||||||
|
uni.showLoading({ title: '裁剪中...', mask: true });
|
||||||
|
if(!this.use2d) {
|
||||||
|
const ctx = uni.createCanvasContext('imgCanvas', this);
|
||||||
|
ctx.clearRect(0, 0, this.canvansWidth, this.canvansHeight);
|
||||||
|
this.draw2DImage(null, ctx, this.imgSrc, () => {
|
||||||
|
this.canvasToTempFilePath(null, 'imgCanvas');
|
||||||
|
});
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
// #ifdef MP-WEIXIN
|
||||||
|
const query = uni.createSelectorQuery().in(this);
|
||||||
|
query.select('#imgCanvas')
|
||||||
|
.fields({ node: true, size: true })
|
||||||
|
.exec((res) => {
|
||||||
|
const canvas = res[0].node;
|
||||||
|
|
||||||
|
const dpr = uni.getSystemInfoSync().pixelRatio;
|
||||||
|
canvas.width = res[0].width * dpr;
|
||||||
|
canvas.height = res[0].height * dpr;
|
||||||
|
const ctx = canvas.getContext('2d');
|
||||||
|
ctx.scale(dpr, dpr);
|
||||||
|
ctx.clearRect(0, 0, this.canvansWidth, this.canvansHeight);
|
||||||
|
|
||||||
|
this.draw2DImage(canvas, ctx, this.imgSrc, () => {
|
||||||
|
this.canvasToTempFilePath(canvas);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
// #endif
|
||||||
|
},
|
||||||
|
handleImage(tempFilePath){
|
||||||
|
// 在H5平台下,tempFilePath 为 base64
|
||||||
|
// console.log(tempFilePath)
|
||||||
|
uni.hideLoading();
|
||||||
|
this.$emit('crop', { tempFilePath });
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style lang="scss" scoped>
|
||||||
|
.image-cropper {
|
||||||
|
position: fixed;
|
||||||
|
left: 0;
|
||||||
|
right: 0;
|
||||||
|
top: 0;
|
||||||
|
bottom: 0;
|
||||||
|
overflow: hidden;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
background-color: #000;
|
||||||
|
.img-canvas {
|
||||||
|
position: absolute !important;
|
||||||
|
transform: translateX(-100%);
|
||||||
|
}
|
||||||
|
.pic-preview {
|
||||||
|
width: 100%;
|
||||||
|
flex: 1;
|
||||||
|
position: relative;
|
||||||
|
|
||||||
|
.crop-mask-block {
|
||||||
|
background-color: rgba(51, 51, 51, 0.8);
|
||||||
|
z-index: 2;
|
||||||
|
position: fixed;
|
||||||
|
box-sizing: border-box;
|
||||||
|
pointer-events: none;
|
||||||
|
}
|
||||||
|
.crop-circle-box {
|
||||||
|
position: fixed;
|
||||||
|
box-sizing: border-box;
|
||||||
|
z-index: 2;
|
||||||
|
pointer-events: none;
|
||||||
|
overflow: hidden;
|
||||||
|
.crop-circle {
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.crop-image {
|
||||||
|
padding: 0 !important;
|
||||||
|
margin: 0 !important;
|
||||||
|
border-radius: 0 !important;
|
||||||
|
display: block !important;
|
||||||
|
backface-visibility: hidden;
|
||||||
|
}
|
||||||
|
.crop-border {
|
||||||
|
position: fixed;
|
||||||
|
border: 1px solid #fff;
|
||||||
|
box-sizing: border-box;
|
||||||
|
z-index: 3;
|
||||||
|
pointer-events: none;
|
||||||
|
}
|
||||||
|
.crop-grid {
|
||||||
|
position: fixed;
|
||||||
|
z-index: 3;
|
||||||
|
border-style: dashed;
|
||||||
|
border-color: #fff;
|
||||||
|
pointer-events: none;
|
||||||
|
opacity: 0.5;
|
||||||
|
}
|
||||||
|
.crop-angle {
|
||||||
|
position: fixed;
|
||||||
|
z-index: 3;
|
||||||
|
border-style: solid;
|
||||||
|
border-color: #fff;
|
||||||
|
pointer-events: none;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.fixed-bottom {
|
||||||
|
position: fixed;
|
||||||
|
left: 0;
|
||||||
|
right: 0;
|
||||||
|
bottom: 0;
|
||||||
|
z-index: 99;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: row;
|
||||||
|
background-color: $uni-bg-color-grey;
|
||||||
|
|
||||||
|
.action-bar {
|
||||||
|
position: absolute;
|
||||||
|
top: -90rpx;
|
||||||
|
left: 10rpx;
|
||||||
|
display: flex;
|
||||||
|
.rotate-icon {
|
||||||
|
background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAADAAAAAwCAYAAABXAvmHAAAAAXNSR0IArs4c6QAABCFJREFUaEPtml3IpVMUx3//ko/ChTIyiGFSMyhllI8bc4F85yuNC2FCqLmQC1+FZORiEkUMNW7UjKjJULgxV+NzSkxDhEkZgwsyigv119J63p7zvOc8z37OmXdOb51dz82711r7/99r7bXXXucVi3xokeNnRqCvB20fDmwAlgK/5bcD+FTSr33tHXQP2H4MeHQE0A+B5yRtLiUyDQJrgVc6AAaBpyV93kXkoBMIQLbfBS5NcK8BRwDXNcD+AdwnaVMbiWkRCPBBohpxHuK7M7865sclRdgNHVMhkF6IMIpwirFEUhzo8M7lwIvASTXEqyVtH8ZgagQSbOzsDknv18HZXpHn5IL8+94IOUm7miSmSqAttjPdbgGuTrnNktYsGgLpoYuAD2qg1zRTbG8P2D4SOC6/Q7vSHPALsE/S7wWy80RsPw/ckxMfSTq/LtRJwPbxwF3ASiCUTxwHCPAnEBfVF8AWSTtL7Ng+LfWOTfmlkn6udFsJ5K15R6a4kvX6yGyUFBvTOWzHXXFzCt4g6c1OArYj9iIGh43YgR+BvztXh1PSa4cMkd0jaVmXDduPAE+k3HpJD7cSGFKvfAc8FQUX8IOk/V2L1udtB/hTgdOBW4Aba/M7Ja1qs2f7euCNlHlZUlx4/495IWQ7Jl+qGbxX0gt9AHfJ2o6zFBVoNVrDKe+F3Sm8VdK1bQQ+A85JgXckXdkFaJx527cC9TpnVdvBtl3h2iapuhsGPdBw1b9xnUvaNw7AEh3bnwDnpuwGSfeP0rN9NvAMELXRXFkxEEK2nwQeSiOtRVQJwC4Z29cAW1Nuu6TVXTrN+SaBt4ErUug2Sa/2NdhH3vZy4NvU2S/p6D768w5xI3WOrAD7LtISFpGdIhVXKfaYvjd20wP13L9M0p4DBbaFRKToSLExVkr6qs+aIwlI6iwz+izUQqC+ab29PiMwqRcmPXczD8w8MFj1zg7xXEqbpdHCw7FgWSjafZL+KcQxtpjteCeflwYulFR/J3TabSslVkj6utPChAK2f6q9uZdLitKieLQRuExSvX9ZbLRUMFs09efpUZL+KtUfVo1GW/umNHC3pOhRLtiwfSbwZS6wV9IJfRdreuBBYH0a2STp9r4G+8jbXgc8mzoDT8VSO00ClwDv1ZR7XyylC4ec7ejaLUmdsV6Aw7oSbwFXpdFdks7qA6pU1na0aR6owgeIR/1cx63UzjAC0YXYVjMQHlkn6ZtSo21ytuPZGKFagQ/xsXZ/3iGuFrYdjafXG0DiQMeBi47c9/GV3BO247UV38n5o0UAP6xmu7jFOGxjRr66On5NPBDOCBsDTapxjHY1dyOcolNXnYlx1himE53p2PmNkxosevfavhg4Izt2k7TXPwZ2S6p6QZPin/2rwcQ7OKmBohCadJGF1P8PG6aaQBKVX/8AAAAASUVORK5CYII=');
|
||||||
|
background-size: 60% 60%;
|
||||||
|
background-repeat: no-repeat;
|
||||||
|
background-position: center;
|
||||||
|
width: 80rpx;
|
||||||
|
height: 80rpx;
|
||||||
|
&.is-reverse {
|
||||||
|
transform: rotateY(180deg);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.rechoose {
|
||||||
|
color: $uni-color-primary;
|
||||||
|
padding: 0 $uni-spacing-row-lg;
|
||||||
|
line-height: 100rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
.choose-btn {
|
||||||
|
color: $uni-color-primary;
|
||||||
|
text-align: center;
|
||||||
|
line-height: 100rpx;
|
||||||
|
flex: 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
.button {
|
||||||
|
margin: auto $uni-spacing-row-lg auto auto;
|
||||||
|
background-color: $uni-color-primary;
|
||||||
|
color: #fff;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.safe-area-inset-bottom {
|
||||||
|
padding-bottom: 0;
|
||||||
|
padding-bottom: constant(safe-area-inset-bottom); // 兼容 IOS<11.2
|
||||||
|
padding-bottom: env(safe-area-inset-bottom); // 兼容 IOS>=11.2
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
</style>
|
||||||
@@ -0,0 +1,180 @@
|
|||||||
|
<template>
|
||||||
|
<view class="abnormal-reported-page">
|
||||||
|
<!-- 成功提示区域 -->
|
||||||
|
<view class="success-section">
|
||||||
|
<view class="success-icon">
|
||||||
|
<up-icon name="checkmark-circle-fill" size="80" color="#4CD964"></up-icon>
|
||||||
|
</view>
|
||||||
|
<view class="success-title">异常已上报!</view>
|
||||||
|
<view class="success-desc">配送计时已暂停,不影响您的准时率</view>
|
||||||
|
</view>
|
||||||
|
|
||||||
|
<!-- 订单信息卡片 -->
|
||||||
|
<view class="order-card">
|
||||||
|
<view class="order-item">
|
||||||
|
<text class="order-label">订单号</text>
|
||||||
|
<text class="order-value" style="font-weight: 600;" >MT20251017123456</text>
|
||||||
|
</view>
|
||||||
|
<view class="order-item">
|
||||||
|
<text class="order-label">商品信息</text>
|
||||||
|
<text class="order-value">共3件商品</text>
|
||||||
|
</view>
|
||||||
|
<view class="order-item">
|
||||||
|
<text class="order-label">配送地址</text>
|
||||||
|
<text class="order-value">XX小区3栋502室</text>
|
||||||
|
</view>
|
||||||
|
<view class="order-item">
|
||||||
|
<text class="order-label">用户备注</text>
|
||||||
|
<text class="order-value remark-text">请放门口,勿按门铃</text>
|
||||||
|
</view>
|
||||||
|
|
||||||
|
<!-- 查看详情按钮 -->
|
||||||
|
<view class="view-detail-btn">
|
||||||
|
<text>查看详情</text>
|
||||||
|
<up-icon name="arrow-right" size="20" color="#999"></up-icon>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
|
||||||
|
<!-- 底部占位 -->
|
||||||
|
<view class="bottom-space"></view>
|
||||||
|
|
||||||
|
<!-- 底部按钮区域 -->
|
||||||
|
<view class="bottom-buttons">
|
||||||
|
<up-button type="primary" size="default" class="continue-btn">
|
||||||
|
继续接单
|
||||||
|
</up-button>
|
||||||
|
<up-button type="default" size="default" class="view-progress-btn">
|
||||||
|
查看异常进度
|
||||||
|
</up-button>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script setup lang="ts">
|
||||||
|
import { onLoad } from '@dcloudio/uni-app'
|
||||||
|
|
||||||
|
// 页面加载时的逻辑
|
||||||
|
onLoad(() => {
|
||||||
|
console.log('异常上报成功页面加载')
|
||||||
|
})
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style lang="scss">
|
||||||
|
page{
|
||||||
|
background-color: #fff;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// 成功提示区域样式
|
||||||
|
.success-section {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
padding: 60rpx 30rpx;
|
||||||
|
background-color: #F6FFFB;
|
||||||
|
margin: 20rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
.success-icon {
|
||||||
|
margin-bottom: 30rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
.success-title {
|
||||||
|
font-size: 36rpx;
|
||||||
|
font-weight: 600;
|
||||||
|
color: #333;
|
||||||
|
margin-bottom: 16rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
.success-desc {
|
||||||
|
font-size: 28rpx;
|
||||||
|
color: #999;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 订单卡片样式
|
||||||
|
.order-card {
|
||||||
|
background-color: #fff;
|
||||||
|
padding: 30rpx;
|
||||||
|
border-radius: 12rpx;
|
||||||
|
margin: 0 30rpx;
|
||||||
|
box-shadow: 0 0 10rpx 0 #e2e2e2;
|
||||||
|
}
|
||||||
|
|
||||||
|
.order-item {
|
||||||
|
display: flex;
|
||||||
|
justify-content: space-between;
|
||||||
|
align-items: center;
|
||||||
|
margin-bottom: 24rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
.order-item:last-child {
|
||||||
|
margin-bottom: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.order-label {
|
||||||
|
font-size: 28rpx;
|
||||||
|
color: #666;
|
||||||
|
}
|
||||||
|
|
||||||
|
.order-value {
|
||||||
|
font-size: 28rpx;
|
||||||
|
color: #333;
|
||||||
|
text-align: right;
|
||||||
|
flex: 1;
|
||||||
|
margin-left: 30rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
.remark-text {
|
||||||
|
color: #FF6F00;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 查看详情按钮样式
|
||||||
|
.view-detail-btn {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: space-between;
|
||||||
|
margin-top: 30rpx;
|
||||||
|
padding-top: 30rpx;
|
||||||
|
border-top: 1rpx solid #f0f0f0;
|
||||||
|
color: #999;
|
||||||
|
font-size: 28rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 底部占位
|
||||||
|
.bottom-space {
|
||||||
|
height: 280rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 底部按钮区域样式
|
||||||
|
.bottom-buttons {
|
||||||
|
position: fixed;
|
||||||
|
bottom: 0;
|
||||||
|
left: 0;
|
||||||
|
right: 0;
|
||||||
|
gap: 20rpx;
|
||||||
|
padding: 20rpx;
|
||||||
|
background-color: #fff;
|
||||||
|
box-shadow: 0 -2rpx 20rpx rgba(0, 0, 0, 0.05);
|
||||||
|
display: flex;
|
||||||
|
}
|
||||||
|
|
||||||
|
.continue-btn {
|
||||||
|
border-radius: 50rpx;
|
||||||
|
height: 100rpx;
|
||||||
|
line-height: 100rpx;
|
||||||
|
font-size: 32rpx;
|
||||||
|
background-color: #007AFF;
|
||||||
|
margin-bottom: 20rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
.view-progress-btn {
|
||||||
|
border-radius: 50rpx;
|
||||||
|
height: 100rpx;
|
||||||
|
line-height: 98rpx;
|
||||||
|
font-size: 32rpx;
|
||||||
|
color: #007AFF;
|
||||||
|
border: 1rpx solid #007AFF;
|
||||||
|
background-color: #fff;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
@@ -0,0 +1,103 @@
|
|||||||
|
|
||||||
|
|
||||||
|
## Calendar 日历
|
||||||
|
> **组件名:uni-calendar**
|
||||||
|
> 代码块: `uCalendar`
|
||||||
|
|
||||||
|
|
||||||
|
日历组件
|
||||||
|
|
||||||
|
> **注意事项**
|
||||||
|
> 为了避免错误使用,给大家带来不好的开发体验,请在使用组件前仔细阅读下面的注意事项,可以帮你避免一些错误。
|
||||||
|
> - 本组件农历转换使用的js是 [@1900-2100区间内的公历、农历互转](https://github.com/jjonline/calendar.js)
|
||||||
|
> - 仅支持自定义组件模式
|
||||||
|
> - `date`属性传入的应该是一个 String ,如: 2019-06-27 ,而不是 new Date()
|
||||||
|
> - 通过 `insert` 属性来确定当前的事件是 @change 还是 @confirm 。理应合并为一个事件,但是为了区分模式,现使用两个事件,这里需要注意
|
||||||
|
> - 弹窗模式下无法阻止后面的元素滚动,如有需要阻止,请在弹窗弹出后,手动设置滚动元素为不可滚动
|
||||||
|
|
||||||
|
|
||||||
|
### 安装方式
|
||||||
|
|
||||||
|
本组件符合[easycom](https://uniapp.dcloud.io/collocation/pages?id=easycom)规范,`HBuilderX 2.5.5`起,只需将本组件导入项目,在页面`template`中即可直接使用,无需在页面中`import`和注册`components`。
|
||||||
|
|
||||||
|
如需通过`npm`方式使用`uni-ui`组件,另见文档:[https://ext.dcloud.net.cn/plugin?id=55](https://ext.dcloud.net.cn/plugin?id=55)
|
||||||
|
|
||||||
|
### 基本用法
|
||||||
|
|
||||||
|
在 ``template`` 中使用组件
|
||||||
|
|
||||||
|
```html
|
||||||
|
<view>
|
||||||
|
<uni-calendar
|
||||||
|
:insert="true"
|
||||||
|
:lunar="true"
|
||||||
|
:start-date="'2019-3-2'"
|
||||||
|
:end-date="'2019-5-20'"
|
||||||
|
@change="change"
|
||||||
|
/>
|
||||||
|
</view>
|
||||||
|
```
|
||||||
|
|
||||||
|
### 通过方法打开日历
|
||||||
|
|
||||||
|
需要设置 `insert` 为 `false`
|
||||||
|
|
||||||
|
```html
|
||||||
|
<view>
|
||||||
|
<uni-calendar
|
||||||
|
ref="calendar"
|
||||||
|
:insert="false"
|
||||||
|
@confirm="confirm"
|
||||||
|
/>
|
||||||
|
<button @click="open">打开日历</button>
|
||||||
|
</view>
|
||||||
|
```
|
||||||
|
|
||||||
|
```javascript
|
||||||
|
|
||||||
|
export default {
|
||||||
|
data() {
|
||||||
|
return {};
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
open(){
|
||||||
|
this.$refs.calendar.open();
|
||||||
|
},
|
||||||
|
confirm(e) {
|
||||||
|
console.log(e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
|
|
||||||
|
## API
|
||||||
|
|
||||||
|
### Calendar Props
|
||||||
|
|
||||||
|
| 属性名 | 类型 | 默认值| 说明 |
|
||||||
|
| - | - | - | - |
|
||||||
|
| date | String |- | 自定义当前时间,默认为今天 |
|
||||||
|
| lunar | Boolean | false | 显示农历 |
|
||||||
|
| startDate | String |- | 日期选择范围-开始日期 |
|
||||||
|
| endDate | String |- | 日期选择范围-结束日期 |
|
||||||
|
| range | Boolean | false | 范围选择 |
|
||||||
|
| insert | Boolean | false | 插入模式,可选值,ture:插入模式;false:弹窗模式;默认为插入模式 |
|
||||||
|
|clearDate |Boolean |true |弹窗模式是否清空上次选择内容 |
|
||||||
|
| selected | Array |- | 打点,期待格式[{date: '2019-06-27', info: '签到', data: { custom: '自定义信息', name: '自定义消息头',xxx:xxx... }}] |
|
||||||
|
|showMonth | Boolean | true | 是否显示月份为背景 |
|
||||||
|
|
||||||
|
### Calendar Events
|
||||||
|
|
||||||
|
| 事件名 | 说明 |返回值|
|
||||||
|
| - | - | - |
|
||||||
|
| open | 弹出日历组件,`insert :false` 时生效|- |
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
## 组件示例
|
||||||
|
|
||||||
|
点击查看:[https://hellouniapp.dcloud.net.cn/pages/extUI/calendar/calendar](https://hellouniapp.dcloud.net.cn/pages/extUI/calendar/calendar)
|
||||||
@@ -0,0 +1,588 @@
|
|||||||
|
<template>
|
||||||
|
<!-- 骨架屏 -->
|
||||||
|
<view v-if="loading" class="skeleton-container">
|
||||||
|
<!-- 余额区域骨架屏 -->
|
||||||
|
<view class="skeleton-balance-section">
|
||||||
|
<view class="skeleton-balance-label"></view>
|
||||||
|
<view class="skeleton-balance-amount"></view>
|
||||||
|
<view class="skeleton-balance-current"></view>
|
||||||
|
</view>
|
||||||
|
|
||||||
|
<!-- 账户选择区域骨架屏 -->
|
||||||
|
<view class="skeleton-account-section">
|
||||||
|
<view class="skeleton-section-title"></view>
|
||||||
|
<view class="skeleton-account-item">
|
||||||
|
<view class="skeleton-account-icon"></view>
|
||||||
|
<view class="skeleton-account-name"></view>
|
||||||
|
<view class="skeleton-account-radio"></view>
|
||||||
|
</view>
|
||||||
|
<view class="skeleton-account-item">
|
||||||
|
<view class="skeleton-account-icon"></view>
|
||||||
|
<view class="skeleton-account-name"></view>
|
||||||
|
<view class="skeleton-account-radio"></view>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
|
||||||
|
<!-- 提示信息骨架屏 -->
|
||||||
|
<view class="skeleton-tip-section">
|
||||||
|
<view class="skeleton-tip-icon"></view>
|
||||||
|
<view class="skeleton-tip-content">
|
||||||
|
<view class="skeleton-tip-line"></view>
|
||||||
|
<view class="skeleton-tip-line-small"></view>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
|
||||||
|
<!-- 确认按钮骨架屏 -->
|
||||||
|
<view class="skeleton-confirm-section">
|
||||||
|
<view class="skeleton-confirm-button"></view>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
<!-- 真实内容 -->
|
||||||
|
<view v-else class="withdraw-container">
|
||||||
|
<!-- 可提现金额 -->
|
||||||
|
<view class="balance-section">
|
||||||
|
<text class="balance-label">可提现金额</text>
|
||||||
|
<text class="balance-amount">¥{{ riderAcc.account }}</text>
|
||||||
|
<text class="current-balance">当前钱包余额</text>
|
||||||
|
</view>
|
||||||
|
|
||||||
|
<!-- 提现账户选择 -->
|
||||||
|
<view class="account-section">
|
||||||
|
<text class="section-title">提现账户</text>
|
||||||
|
<view class=""
|
||||||
|
style="display: flex;align-items: center; border-bottom: 4rpx solid #e2e2e2;padding-bottom: 10px; margin-bottom: 10px;">
|
||||||
|
<up-icon name="zhifubao-circle-fill" size="30" color="#1890ff"></up-icon>
|
||||||
|
<view style="flex: 1; margin-left: 30rpx; " class="">
|
||||||
|
支付宝
|
||||||
|
</view>
|
||||||
|
<view @click="changePay(0)" class="">
|
||||||
|
<view v-if="current==0" class="radio-circle">
|
||||||
|
<view class="radio-inner"></view>
|
||||||
|
</view>
|
||||||
|
<view v-else class="radio-no-circle">
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
<view class="" style="display: flex;align-items: center;">
|
||||||
|
<up-icon name="weixin-circle-fill" size="30" color="#28C445"></up-icon>
|
||||||
|
<view style="flex: 1; margin-left: 30rpx; " class="">
|
||||||
|
微信
|
||||||
|
</view>
|
||||||
|
<view @click="changePay(1)" class="">
|
||||||
|
<view v-if="current==1" class="radio-circle">
|
||||||
|
<view class="radio-inner"></view>
|
||||||
|
</view>
|
||||||
|
<view v-else class="radio-no-circle">
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
|
||||||
|
<!-- 提现账号 -->
|
||||||
|
<view class="" v-if="current!=null" style="margin: 20rpx 30rpx; ">
|
||||||
|
<view class="" style="font-size: 34rpx; font-weight: 600; ">
|
||||||
|
账号信息
|
||||||
|
</view>
|
||||||
|
|
||||||
|
<up-form labelPosition="top" label-width="200" :model="account" ref="form1">
|
||||||
|
<up-form-item label="姓名" prop="userInfo.name" :borderBottom="true" ref="item1">
|
||||||
|
<up-input v-model="account.name" @change="changePrice" placeholder="请输入姓名" border="none"></up-input>
|
||||||
|
</up-form-item>
|
||||||
|
<up-form-item :label="current==0? '支付宝账号':'微信账号'" prop="userInfo.name" :borderBottom="true" ref="item1">
|
||||||
|
<up-input v-model="account.id" :placeholder="current==0? '请输入支付宝账号':'请输入微信账号'"
|
||||||
|
border="none"></up-input>
|
||||||
|
</up-form-item>
|
||||||
|
<up-form-item label="提现金额" prop="userInfo.name" :borderBottom="true" ref="item1">
|
||||||
|
<up-input v-model="account.price" type="digit" placeholder="请输入提现金额" border="none"></up-input>
|
||||||
|
</up-form-item>
|
||||||
|
</up-form>
|
||||||
|
</view>
|
||||||
|
|
||||||
|
|
||||||
|
<!-- 提示信息 -->
|
||||||
|
<view class="tip-section">
|
||||||
|
<up-icon name="clock" size="18" color="#1890ff"></up-icon>
|
||||||
|
<view class="" style="margin-left: 10rpx;">
|
||||||
|
<view class="tip-text">预计 T+1 工作日到账</view>
|
||||||
|
<view class="tip-text" style="color: #666666; font-size: 24rpx; margin-top: 10rpx; ">无手续费</view>
|
||||||
|
</view>
|
||||||
|
|
||||||
|
</view>
|
||||||
|
|
||||||
|
<!-- 确认按钮 -->
|
||||||
|
<view class="confirm-section">
|
||||||
|
<button class="confirm-button" @click="confirmWithdraw">确认提现</button>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script setup lang="ts">
|
||||||
|
import { onLoad } from '@dcloudio/uni-app';
|
||||||
|
import { ref } from 'vue';
|
||||||
|
import { Service } from '@/Service/Service';
|
||||||
|
import { CNRiderOrderService } from '@/Service/CN/CNRiderOrderService'
|
||||||
|
import { CNRiderDataService } from '@/Service/CN/CNRiderDataService'
|
||||||
|
|
||||||
|
let current = ref(null)
|
||||||
|
let loading = ref(true)
|
||||||
|
|
||||||
|
|
||||||
|
let account = ref({
|
||||||
|
id: '',
|
||||||
|
price: "",
|
||||||
|
name: ''
|
||||||
|
})
|
||||||
|
|
||||||
|
let riderAcc = ref<any>({})
|
||||||
|
|
||||||
|
onLoad(() => {
|
||||||
|
getData()
|
||||||
|
})
|
||||||
|
|
||||||
|
|
||||||
|
const getData = () => {
|
||||||
|
CNRiderDataService.GetRiderAccInfo().then(res => {
|
||||||
|
loading.value = false
|
||||||
|
if (res.data) {
|
||||||
|
riderAcc.value = res.data.riderAcc
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
const changePay = (item : any) => {
|
||||||
|
current.value = item
|
||||||
|
}
|
||||||
|
|
||||||
|
const changePrice = (e : string) => {
|
||||||
|
console.log(e);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// 确认提现
|
||||||
|
const confirmWithdraw = () => {
|
||||||
|
if (!account.value.name) {
|
||||||
|
Service.Msg('请输入姓名!')
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if (!account.value.price) {
|
||||||
|
Service.Msg('请输入提现金额!')
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if (!account.value.id) {
|
||||||
|
Service.Msg('请输入账户号!')
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
uni.showModal({
|
||||||
|
title: '提示',
|
||||||
|
content: '请仔细确认身份信息?',
|
||||||
|
success: function (res) {
|
||||||
|
if (res.confirm) {
|
||||||
|
CNRiderOrderService.AddRiderWith(Number(account.value.price), current.value == 0 ? '支付宝' : '微信', account.value.name, account.value.id).then(res => {
|
||||||
|
if (res.code == 0) {
|
||||||
|
Service.Msg('提现成功')
|
||||||
|
setTimeout(() => {
|
||||||
|
Service.GoPage('/pages/my/withDrowList')
|
||||||
|
}, 1000)
|
||||||
|
} else {
|
||||||
|
Service.Msg(res.msg)
|
||||||
|
}
|
||||||
|
|
||||||
|
})
|
||||||
|
} else {
|
||||||
|
// 用户点击取消后的操作
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
};
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style scoped>
|
||||||
|
.withdraw-container {
|
||||||
|
min-height: 100vh;
|
||||||
|
background-color: #fff;
|
||||||
|
padding-bottom: 40rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 选择 */
|
||||||
|
|
||||||
|
.radio-circle {
|
||||||
|
width: 36rpx;
|
||||||
|
height: 36rpx;
|
||||||
|
border: 2rpx solid var(--nav-mian);
|
||||||
|
border-radius: 50%;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
margin-right: 20rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
.radio-inner {
|
||||||
|
width: 20rpx;
|
||||||
|
height: 20rpx;
|
||||||
|
background-color: var(--nav-mian);
|
||||||
|
border-radius: 50%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.radio-no-circle {
|
||||||
|
width: 36rpx;
|
||||||
|
height: 36rpx;
|
||||||
|
border: 2rpx solid #dadada;
|
||||||
|
border-radius: 50%;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
margin-right: 20rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/* 顶部导航栏 */
|
||||||
|
.nav-bar {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: space-between;
|
||||||
|
padding: 30rpx 20rpx;
|
||||||
|
background-color: #fff;
|
||||||
|
position: sticky;
|
||||||
|
top: 0;
|
||||||
|
z-index: 100;
|
||||||
|
box-shadow: 0 2rpx 10rpx rgba(0, 0, 0, 0.05);
|
||||||
|
}
|
||||||
|
|
||||||
|
.nav-title {
|
||||||
|
font-size: 36rpx;
|
||||||
|
font-weight: 600;
|
||||||
|
color: #000;
|
||||||
|
}
|
||||||
|
|
||||||
|
.back-icon {
|
||||||
|
width: 40rpx;
|
||||||
|
height: 40rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
.help-icon {
|
||||||
|
width: 40rpx;
|
||||||
|
height: 40rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 余额显示区域 */
|
||||||
|
.balance-section {
|
||||||
|
background-color: #fff;
|
||||||
|
padding: 40rpx 30rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
.balance-label {
|
||||||
|
font-size: 32rpx;
|
||||||
|
color: #333;
|
||||||
|
display: block;
|
||||||
|
margin-bottom: 10rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
.balance-amount {
|
||||||
|
font-size: 60rpx;
|
||||||
|
font-weight: bold;
|
||||||
|
color: #ff4757;
|
||||||
|
display: block;
|
||||||
|
margin-bottom: 10rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
.current-balance {
|
||||||
|
font-size: 28rpx;
|
||||||
|
color: #999;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 账户选择区域 */
|
||||||
|
.account-section {
|
||||||
|
background-color: #fff;
|
||||||
|
padding: 30rpx;
|
||||||
|
margin-bottom: 20rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
.section-title {
|
||||||
|
font-size: 32rpx;
|
||||||
|
font-weight: 600;
|
||||||
|
color: #333;
|
||||||
|
display: block;
|
||||||
|
margin-bottom: 20rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
.account-item {
|
||||||
|
display: flex;
|
||||||
|
justify-content: space-between;
|
||||||
|
align-items: center;
|
||||||
|
padding: 25rpx 0;
|
||||||
|
border-bottom: 1rpx solid #f0f0f0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.account-item:last-child {
|
||||||
|
border-bottom: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
.account-info {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.account-icon {
|
||||||
|
width: 60rpx;
|
||||||
|
height: 60rpx;
|
||||||
|
border-radius: 12rpx;
|
||||||
|
background-color: #1677ff;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
margin-right: 20rpx;
|
||||||
|
border: 2rpx solid #000;
|
||||||
|
}
|
||||||
|
|
||||||
|
.account-icon.wechat {
|
||||||
|
background-color: #07c160;
|
||||||
|
}
|
||||||
|
|
||||||
|
.icon-text {
|
||||||
|
color: #fff;
|
||||||
|
font-size: 32rpx;
|
||||||
|
font-weight: bold;
|
||||||
|
}
|
||||||
|
|
||||||
|
.account-name {
|
||||||
|
font-size: 32rpx;
|
||||||
|
color: #333;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 提示信息区域 */
|
||||||
|
.tip-section {
|
||||||
|
display: flex;
|
||||||
|
align-items: flex-start;
|
||||||
|
background-color: #e6f7ff;
|
||||||
|
padding: 20rpx 30rpx;
|
||||||
|
margin: 0 30rpx 20rpx;
|
||||||
|
border-radius: 10rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
.tip-text {
|
||||||
|
font-size: 28rpx;
|
||||||
|
margin-left: 10rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 确认按钮区域 */
|
||||||
|
.confirm-section {
|
||||||
|
background-color: #fff;
|
||||||
|
position: fixed;
|
||||||
|
width: 100vw;
|
||||||
|
left: 0;
|
||||||
|
bottom: 0;
|
||||||
|
padding: 30rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
.confirm-button {
|
||||||
|
width: 100%;
|
||||||
|
height: 90rpx;
|
||||||
|
background-color: #1677ff;
|
||||||
|
color: #fff;
|
||||||
|
font-size: 36rpx;
|
||||||
|
font-weight: 600;
|
||||||
|
border-radius: 45rpx;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
border: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
.confirm-button:active {
|
||||||
|
background-color: #0958d9;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 骨架屏样式 */
|
||||||
|
.skeleton-container {
|
||||||
|
min-height: 100vh;
|
||||||
|
background-color: #fff;
|
||||||
|
padding-bottom: 40rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 骨架屏动画 */
|
||||||
|
@keyframes shimmer {
|
||||||
|
0% {
|
||||||
|
background-position: -1000px 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
100% {
|
||||||
|
background-position: 1000px 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 骨架屏通用样式 */
|
||||||
|
.skeleton-balance-section,
|
||||||
|
.skeleton-account-section,
|
||||||
|
.skeleton-tip-section {
|
||||||
|
padding: 40rpx 30rpx;
|
||||||
|
margin-bottom: 20rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 余额区域骨架屏 */
|
||||||
|
.skeleton-balance-section {
|
||||||
|
background-color: #fff;
|
||||||
|
}
|
||||||
|
|
||||||
|
.skeleton-balance-label {
|
||||||
|
width: 30%;
|
||||||
|
height: 32rpx;
|
||||||
|
background-color: #e6e6e6;
|
||||||
|
margin-bottom: 20rpx;
|
||||||
|
border-radius: 4rpx;
|
||||||
|
animation: shimmer 1.5s infinite;
|
||||||
|
background-image: linear-gradient(90deg, #f0f0f0 25%, #e0e0e0 50%, #f0f0f0 75%);
|
||||||
|
background-size: 1000px 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.skeleton-balance-amount {
|
||||||
|
width: 40%;
|
||||||
|
height: 60rpx;
|
||||||
|
background-color: #e6e6e6;
|
||||||
|
margin-bottom: 20rpx;
|
||||||
|
border-radius: 4rpx;
|
||||||
|
animation: shimmer 1.5s infinite;
|
||||||
|
background-image: linear-gradient(90deg, #f0f0f0 25%, #e0e0e0 50%, #f0f0f0 75%);
|
||||||
|
background-size: 1000px 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.skeleton-balance-current {
|
||||||
|
width: 25%;
|
||||||
|
height: 28rpx;
|
||||||
|
background-color: #e6e6e6;
|
||||||
|
border-radius: 4rpx;
|
||||||
|
animation: shimmer 1.5s infinite;
|
||||||
|
background-image: linear-gradient(90deg, #f0f0f0 25%, #e0e0e0 50%, #f0f0f0 75%);
|
||||||
|
background-size: 1000px 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 账户选择区域骨架屏 */
|
||||||
|
.skeleton-account-section {
|
||||||
|
background-color: #fff;
|
||||||
|
}
|
||||||
|
|
||||||
|
.skeleton-section-title {
|
||||||
|
width: 25%;
|
||||||
|
height: 32rpx;
|
||||||
|
background-color: #e6e6e6;
|
||||||
|
margin-bottom: 30rpx;
|
||||||
|
border-radius: 4rpx;
|
||||||
|
animation: shimmer 1.5s infinite;
|
||||||
|
background-image: linear-gradient(90deg, #f0f0f0 25%, #e0e0e0 50%, #f0f0f0 75%);
|
||||||
|
background-size: 1000px 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.skeleton-account-item {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
margin-bottom: 30rpx;
|
||||||
|
padding-bottom: 30rpx;
|
||||||
|
border-bottom: 4rpx solid #e2e2e2;
|
||||||
|
}
|
||||||
|
|
||||||
|
.skeleton-account-item:last-child {
|
||||||
|
border-bottom: none;
|
||||||
|
padding-bottom: 0;
|
||||||
|
margin-bottom: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.skeleton-account-icon {
|
||||||
|
width: 60rpx;
|
||||||
|
height: 60rpx;
|
||||||
|
background-color: #e6e6e6;
|
||||||
|
border-radius: 12rpx;
|
||||||
|
margin-right: 20rpx;
|
||||||
|
animation: shimmer 1.5s infinite;
|
||||||
|
background-image: linear-gradient(90deg, #f0f0f0 25%, #e0e0e0 50%, #f0f0f0 75%);
|
||||||
|
background-size: 1000px 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.skeleton-account-name {
|
||||||
|
flex: 1;
|
||||||
|
height: 32rpx;
|
||||||
|
background-color: #e6e6e6;
|
||||||
|
border-radius: 4rpx;
|
||||||
|
margin-right: 20rpx;
|
||||||
|
animation: shimmer 1.5s infinite;
|
||||||
|
background-image: linear-gradient(90deg, #f0f0f0 25%, #e0e0e0 50%, #f0f0f0 75%);
|
||||||
|
background-size: 1000px 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.skeleton-account-radio {
|
||||||
|
width: 36rpx;
|
||||||
|
height: 36rpx;
|
||||||
|
background-color: #e6e6e6;
|
||||||
|
border-radius: 50%;
|
||||||
|
animation: shimmer 1.5s infinite;
|
||||||
|
background-image: linear-gradient(90deg, #f0f0f0 25%, #e0e0e0 50%, #f0f0f0 75%);
|
||||||
|
background-size: 1000px 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 提示信息骨架屏 */
|
||||||
|
.skeleton-tip-section {
|
||||||
|
display: flex;
|
||||||
|
align-items: flex-start;
|
||||||
|
background-color: #e6f7ff;
|
||||||
|
padding: 20rpx 30rpx;
|
||||||
|
margin: 0 30rpx 20rpx;
|
||||||
|
border-radius: 10rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
.skeleton-tip-icon {
|
||||||
|
width: 40rpx;
|
||||||
|
height: 40rpx;
|
||||||
|
background-color: #e6e6e6;
|
||||||
|
border-radius: 50%;
|
||||||
|
margin-right: 15rpx;
|
||||||
|
animation: shimmer 1.5s infinite;
|
||||||
|
background-image: linear-gradient(90deg, #f0f0f0 25%, #e0e0e0 50%, #f0f0f0 75%);
|
||||||
|
background-size: 1000px 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.skeleton-tip-content {
|
||||||
|
flex: 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
.skeleton-tip-line {
|
||||||
|
width: 70%;
|
||||||
|
height: 28rpx;
|
||||||
|
background-color: #e6e6e6;
|
||||||
|
margin-bottom: 15rpx;
|
||||||
|
border-radius: 4rpx;
|
||||||
|
animation: shimmer 1.5s infinite;
|
||||||
|
background-image: linear-gradient(90deg, #f0f0f0 25%, #e0e0e0 50%, #f0f0f0 75%);
|
||||||
|
background-size: 1000px 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.skeleton-tip-line-small {
|
||||||
|
width: 50%;
|
||||||
|
height: 24rpx;
|
||||||
|
background-color: #e6e6e6;
|
||||||
|
border-radius: 4rpx;
|
||||||
|
animation: shimmer 1.5s infinite;
|
||||||
|
background-image: linear-gradient(90deg, #f0f0f0 25%, #e0e0e0 50%, #f0f0f0 75%);
|
||||||
|
background-size: 1000px 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 确认按钮骨架屏 */
|
||||||
|
.skeleton-confirm-section {
|
||||||
|
position: fixed;
|
||||||
|
bottom: 0;
|
||||||
|
left: 0;
|
||||||
|
width: 100%;
|
||||||
|
background-color: #fff;
|
||||||
|
padding: 30rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
.skeleton-confirm-button {
|
||||||
|
width: 100%;
|
||||||
|
height: 90rpx;
|
||||||
|
background-color: #e6e6e6;
|
||||||
|
border-radius: 45rpx;
|
||||||
|
animation: shimmer 1.5s infinite;
|
||||||
|
background-image: linear-gradient(90deg, #f0f0f0 25%, #e0e0e0 50%, #f0f0f0 75%);
|
||||||
|
background-size: 1000px 100%;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
@@ -0,0 +1,112 @@
|
|||||||
|
<template>
|
||||||
|
<view class="home">
|
||||||
|
<view class=""
|
||||||
|
style=" margin-top: 300rpx; display: flex; flex-direction: column; justify-content: center; align-items: center;">
|
||||||
|
<image :src="Service.GetIconImg('/static/dele/logo.png')" style="width: 150rpx; height: 150rpx; "
|
||||||
|
mode=""></image>
|
||||||
|
<view class="" style="font-size: 36rpx; font-weight: 600; ">
|
||||||
|
美味到家
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
<view class="" style="margin: 30rpx 30rpx;">
|
||||||
|
<view class="" style="font-size: 34rpx; font-weight: 600; ">
|
||||||
|
欢迎登陆
|
||||||
|
</view>
|
||||||
|
<view class="" style="font-size: 28rpx; margin-top: 20rpx; ">
|
||||||
|
手机号登录,安全又便捷
|
||||||
|
</view>
|
||||||
|
|
||||||
|
<view class="" style="margin-top: 30rpx;">
|
||||||
|
<up-input v-model="login.phone" type="number" shape='circle'
|
||||||
|
:customStyle="{'padding':'20rpx 30rpx','font-size':'32rpx'}" placeholder="请输入手机号" clearable='true'
|
||||||
|
border="surround"></up-input>
|
||||||
|
</view>
|
||||||
|
|
||||||
|
<view class=""
|
||||||
|
style=" display: flex; align-items: center; justify-content: space-between; margin-top: 30rpx; border: 1rpx solid #dadbde; box-sizing: border-box; padding: 20rpx 30rpx; border-radius: 200rpx; ">
|
||||||
|
<up-code-input v-model="login.code" mode="line" size='24'></up-code-input>
|
||||||
|
<view class="wrap">
|
||||||
|
<up-toast ref="uToastRef"></up-toast>
|
||||||
|
<up-code :seconds="seconds" @end="end" @start="start" ref="uCodeRef" @change="codeChange"></up-code>
|
||||||
|
<view @click="getCode">{{tips}}</view>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
|
||||||
|
<view class="" style="text-align: center; color: #888; margin-top: 30rpx; ">
|
||||||
|
登录即代表同意
|
||||||
|
<text style="color: var(--nav-banbacor);">《用户协议》</text>
|
||||||
|
和
|
||||||
|
<text style="color: var(--nav-banbacor);">《隐私政策》</text>
|
||||||
|
</view>
|
||||||
|
<view class="" style="text-align: center; margin-top: 20rpx;">
|
||||||
|
新用户?系统将自动为您注册
|
||||||
|
</view>
|
||||||
|
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script setup lang="ts">
|
||||||
|
import { onShow, onLoad } from "@dcloudio/uni-app";
|
||||||
|
import { Service } from "@/Service/Service"
|
||||||
|
import { ref } from "vue";
|
||||||
|
|
||||||
|
let login = ref({
|
||||||
|
phone: '',
|
||||||
|
code: ''
|
||||||
|
})
|
||||||
|
|
||||||
|
const tips = ref('');
|
||||||
|
const seconds = ref(60);
|
||||||
|
const uCodeRef = ref(null);
|
||||||
|
|
||||||
|
|
||||||
|
onLoad(() => {
|
||||||
|
|
||||||
|
});
|
||||||
|
|
||||||
|
onShow(() => {
|
||||||
|
|
||||||
|
});
|
||||||
|
|
||||||
|
const codeChange = (text) => {
|
||||||
|
tips.value = text;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
const getCode = () => {
|
||||||
|
if (uCodeRef.value.canGetCode) {
|
||||||
|
// 模拟向后端请求验证码
|
||||||
|
uni.showLoading({
|
||||||
|
title: '正在获取验证码',
|
||||||
|
});
|
||||||
|
setTimeout(() => {
|
||||||
|
uni.hideLoading();
|
||||||
|
// 这里此提示会被start()方法中的提示覆盖
|
||||||
|
Service.Msg('验证码已发送')
|
||||||
|
// 通知验证码组件内部开始倒计时
|
||||||
|
uCodeRef.value.start();
|
||||||
|
}, 2000);
|
||||||
|
} else {
|
||||||
|
Service.Msg('倒计时结束后再发送')
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
const end = () => {
|
||||||
|
console.log('倒计时结束');
|
||||||
|
};
|
||||||
|
|
||||||
|
const start = () => {
|
||||||
|
console.log('倒计时开始');
|
||||||
|
};
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style lang="scss">
|
||||||
|
.home {
|
||||||
|
width: 100vw;
|
||||||
|
height: 100vh;
|
||||||
|
background: linear-gradient(to bottom, var(--nav-mian), #fff 40%);
|
||||||
|
overflow: hidden;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
@@ -0,0 +1,807 @@
|
|||||||
|
<template>
|
||||||
|
|
||||||
|
<view v-if="isLoading" class="skeleton-container" style="padding-top: 80rpx;" >
|
||||||
|
<!-- 统计数据区域骨架 -->
|
||||||
|
<view class="skeleton-stats-section">
|
||||||
|
<view class="skeleton-stat-item">
|
||||||
|
<view class="skeleton-stat-label"></view>
|
||||||
|
<view class="skeleton-stat-value"></view>
|
||||||
|
</view>
|
||||||
|
<view class="skeleton-stat-item">
|
||||||
|
<view class="skeleton-stat-label"></view>
|
||||||
|
<view class="skeleton-stat-value"></view>
|
||||||
|
</view>
|
||||||
|
<view class="skeleton-stat-item">
|
||||||
|
<view class="skeleton-stat-label"></view>
|
||||||
|
<view class="skeleton-stat-value"></view>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
|
||||||
|
<!-- 接单按钮骨架 -->
|
||||||
|
<view class="skeleton-action-section">
|
||||||
|
<view class="skeleton-accept-btn"></view>
|
||||||
|
</view>
|
||||||
|
|
||||||
|
<!-- 标签栏骨架 -->
|
||||||
|
<view class="skeleton-tab-bar">
|
||||||
|
<view class="skeleton-tab-item">
|
||||||
|
<view class="skeleton-tab-text"></view>
|
||||||
|
</view>
|
||||||
|
<view class="skeleton-tab-item">
|
||||||
|
<view class="skeleton-tab-text"></view>
|
||||||
|
</view>
|
||||||
|
<view class="skeleton-tab-item">
|
||||||
|
<view class="skeleton-tab-text"></view>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
|
||||||
|
<!-- 任务列表骨架 -->
|
||||||
|
<view class="skeleton-task-list">
|
||||||
|
<!-- 任务卡片骨架 -->
|
||||||
|
<view class="skeleton-task-section" v-for="i in 3" :key="i">
|
||||||
|
<!-- 高价单标签骨架 -->
|
||||||
|
<view class="skeleton-tag-row">
|
||||||
|
<view class="skeleton-high-price-tag"></view>
|
||||||
|
<view class="skeleton-phone-btn"></view>
|
||||||
|
</view>
|
||||||
|
|
||||||
|
<!-- 商家信息骨架 -->
|
||||||
|
<view class="skeleton-merchant-info">
|
||||||
|
<view class="skeleton-merchant-name"></view>
|
||||||
|
<view class="skeleton-distance"></view>
|
||||||
|
</view>
|
||||||
|
|
||||||
|
<!-- 地址信息骨架 -->
|
||||||
|
<view class="skeleton-address-info">
|
||||||
|
<view class="skeleton-address-text"></view>
|
||||||
|
</view>
|
||||||
|
|
||||||
|
<!-- 价格和取餐时间骨架 -->
|
||||||
|
<view class="skeleton-price-time-row">
|
||||||
|
<view class="skeleton-pickup-code"></view>
|
||||||
|
<view class="skeleton-pickup-time"></view>
|
||||||
|
</view>
|
||||||
|
|
||||||
|
<!-- 立即抢单按钮骨架 -->
|
||||||
|
<view class="skeleton-grab-btn"></view>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
|
||||||
|
<!-- 实际内容 -->
|
||||||
|
<view v-else class="rider-home" style="padding-top: 60rpx;" >
|
||||||
|
<!-- 统计数据区域 -->
|
||||||
|
<view class="stats-section">
|
||||||
|
<view class="stat-item">
|
||||||
|
<text class="stat-label">今日收入</text>
|
||||||
|
<text class="stat-value income">¥{{userData.dayAmount.toFixed(2)}}</text>
|
||||||
|
</view>
|
||||||
|
<view class="stat-item">
|
||||||
|
<text class="stat-label">已完成</text>
|
||||||
|
<text class="stat-value completed">{{userData.dayOrderCount}}单</text>
|
||||||
|
</view>
|
||||||
|
<view class="stat-item">
|
||||||
|
<text class="stat-label">配送中</text>
|
||||||
|
<text class="stat-value ongoing">{{ userData.takeOrderCount }}单</text>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
|
||||||
|
<!-- 接单按钮 -->
|
||||||
|
<view class="action-section">
|
||||||
|
<up-button :disabled='riderInfo.status===0' type="primary" shape="circle" size="default"
|
||||||
|
class="accept-orders-btn"
|
||||||
|
@click="toggleAcceptOrders">{{ riderInfo.status==0?'审核中':(riderInfo.isOnline == 0 ? '已下线' : '已上线') }}</up-button>
|
||||||
|
</view>
|
||||||
|
|
||||||
|
<view class="tab-bar">
|
||||||
|
<view v-for="(tab, index) in tabs" :key="index" class="tab-item" :class="{ active: activeTab === index }"
|
||||||
|
@click="switchTab(index)">
|
||||||
|
<text class="tab-text">{{ tab }}</text>
|
||||||
|
<view v-if="activeTab === index" class="active-line"></view>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
|
||||||
|
<view v-if="riderInfo.status===1" class="" style="padding: 0 30rpx;">
|
||||||
|
<!-- -->
|
||||||
|
<view v-for="(orderItem,orderIndex) in orderList " @click="gopage(orderItem.orderId)" :key="orderIndex"
|
||||||
|
class="task-section">
|
||||||
|
<!-- 高价单标签 -->
|
||||||
|
<view class="" style="display: flex; align-items: center; justify-content: space-between;">
|
||||||
|
|
||||||
|
<view class="high-price-tag"
|
||||||
|
:style="{'border':activeTab==0?'1rpx solid #FF7875':(activeTab==1?'1rpx solid #52C41A':'1rpx solid #FAAD14'),'color':activeTab==0?'#FF7875':(activeTab==1?'#52C41A':'#FAAD14') }"
|
||||||
|
style="background-color: #fff;">
|
||||||
|
<text class="high-price-text">{{activeTab==0? '新订单':(activeTab==1? '待取单':'配送中')}}</text>
|
||||||
|
</view>
|
||||||
|
<view class="" @click.stop="call(orderItem.phone)" style="display: flex; align-items: baseline;">
|
||||||
|
<up-icon name="phone" color="var(--nav-mian)" size="20"></up-icon>
|
||||||
|
<text style="margin-left: 10rpx; color: var(--nav-mian); ">拨打商家</text>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
|
||||||
|
<!-- 商家信息 -->
|
||||||
|
<view class="merchant-info">
|
||||||
|
<text class="merchant-name">{{ orderItem.storeName }}</text>
|
||||||
|
<text v-if="activeTab==1" class="distance">{{ distance(orderItem.distance) }}</text>
|
||||||
|
</view>
|
||||||
|
|
||||||
|
<!-- 地址信息 -->
|
||||||
|
<view class="address-info">
|
||||||
|
<up-icon name="map" color="#999" size="24rpx" />
|
||||||
|
<text class="address-text"> {{orderItem.address }}</text>
|
||||||
|
<!-- <text v-if="activeTab!==0" class="address-text">共3件商品</text> -->
|
||||||
|
</view>
|
||||||
|
<!-- 商品次数-->
|
||||||
|
<!-- <view class="address-info">
|
||||||
|
<text class="address-text">共3件商品</text>
|
||||||
|
<view class="">
|
||||||
|
<text class="price">¥5.50</text>
|
||||||
|
<text style="color: var(--nav-mian); font-weight: 600; margin-left: 10rpx; ">/单</text>
|
||||||
|
</view>
|
||||||
|
</view> -->
|
||||||
|
|
||||||
|
<!-- 价格和取餐时间 -->
|
||||||
|
<view class="price-time-row">
|
||||||
|
<view v-if="activeTab==1" class="">
|
||||||
|
<text style="font-size: 30rpx; font-weight: 600; color: #1890FF; ">取件码: </text>
|
||||||
|
<text style="color: var(--nav-mian); font-weight: 600; margin-left: 10rpx; ">A121</text>
|
||||||
|
</view>
|
||||||
|
<view v-if="activeTab!==1" class="">
|
||||||
|
<text class="address-text">据您{{ distance(orderItem.distance) }}</text>
|
||||||
|
</view>
|
||||||
|
<view class="pickup-time">
|
||||||
|
<up-icon name="clock" :color="activeTab==0?'#FAAD14':'#FF0000'" size="16" />
|
||||||
|
<text class="time-text"
|
||||||
|
:style="{'color':activeTab==0?'#FAAD14':'#FF0000'}">{{ orderItem.makeTime.split(' ').length==2?'预计'+orderItem.makeTime.split(' ')[1]+'送达':orderItem.makeTime }}</text>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
|
||||||
|
<!-- 立即抢单按钮 -->
|
||||||
|
|
||||||
|
<view class="" style="display: flex; ">
|
||||||
|
<view class="" style="width: 100%;"
|
||||||
|
@click.stop="activeTab==0?takeOrder(orderItem.orderId):pickFood(orderItem.orderId)">
|
||||||
|
<button type="primary" :color="activeTab==0?'#1890FF':'#52C41A'" size="large"
|
||||||
|
class="grab-btn">{{ activeTab==0?'立即接单':(activeTab==1?'我已取餐':'确认送达')}}</button>
|
||||||
|
</view>
|
||||||
|
<view class="" style="width: 20rpx;" v-if="activeTab!=0">
|
||||||
|
|
||||||
|
</view>
|
||||||
|
<view style="width: 100%;" v-if="activeTab!=0" @click.stop="Service.GoPage('/pages/order/orderMap?orderId='+orderItem.orderId)" class="">
|
||||||
|
<button type="primary" color="#1890FF"
|
||||||
|
class="grab-btn">{{activeTab==1?'导航取餐':'导航送餐'}}</button>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
|
||||||
|
|
||||||
|
</view>
|
||||||
|
<up-loadmore :status="status" />
|
||||||
|
</view>
|
||||||
|
|
||||||
|
|
||||||
|
<view v-else class="" style="font-weight: bold; text-align: center; font-size: 32rpx; margin-top: 100rpx; ">
|
||||||
|
信息审核中·暂时无法接单
|
||||||
|
</view>
|
||||||
|
|
||||||
|
|
||||||
|
<view class="" style="width: 100%; height: 60rpx; ">
|
||||||
|
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script setup lang="ts">
|
||||||
|
import { onLoad, onShow } from '@dcloudio/uni-app';
|
||||||
|
import { ref, onMounted } from 'vue';
|
||||||
|
import { Service } from '@/Service/Service';
|
||||||
|
import { CNRiderDataService } from '@/Service/CN/CNRiderDataService'
|
||||||
|
import { CNRiderOrderService } from '@/Service/CN/CNRiderOrderService'
|
||||||
|
|
||||||
|
// 加载状态
|
||||||
|
const isLoading = ref(true);
|
||||||
|
let status = ref('nomore')
|
||||||
|
let page = ref(1)
|
||||||
|
|
||||||
|
let userData = ref({
|
||||||
|
dayAmount: 0,
|
||||||
|
dayOrderCount: 0,
|
||||||
|
takeOrderCount: 0
|
||||||
|
})
|
||||||
|
|
||||||
|
const tabs = ['新订单', '待取货', '配送中']
|
||||||
|
const activeTab = ref(0)
|
||||||
|
let riderInfo = ref<any>({})
|
||||||
|
|
||||||
|
let orderList = ref<Array<any>>([])
|
||||||
|
|
||||||
|
|
||||||
|
onLoad(() => {
|
||||||
|
uni.$on(`newOrder`, (data) => {
|
||||||
|
newOrder()
|
||||||
|
});
|
||||||
|
})
|
||||||
|
|
||||||
|
|
||||||
|
onShow(() => {
|
||||||
|
getData()
|
||||||
|
getOrderData()
|
||||||
|
})
|
||||||
|
|
||||||
|
// 有新订单
|
||||||
|
const newOrder = () =>{
|
||||||
|
audioPlay()
|
||||||
|
}
|
||||||
|
|
||||||
|
const getData = () => {
|
||||||
|
CNRiderDataService.GetRiderHomeInfo().then(res => {
|
||||||
|
isLoading.value = false
|
||||||
|
riderInfo.value = res.data.riderInfo
|
||||||
|
userData.value = res.data
|
||||||
|
if (res.data.riderInfo.status === -1) {
|
||||||
|
Service.GoPage('/pages/my/completeData')
|
||||||
|
}
|
||||||
|
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
const getOrderData = () => {
|
||||||
|
status.value = 'loadmore'
|
||||||
|
page.value = 1
|
||||||
|
orderList.value = []
|
||||||
|
getOrderList()
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//获取订单
|
||||||
|
const getOrderList = () => {
|
||||||
|
if (status.value == 'nomore' || status.value == 'loading') {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
status.value == 'loadmore'
|
||||||
|
|
||||||
|
if (activeTab.value == 0) {
|
||||||
|
CNRiderOrderService.GetRiderOrderList(page.value).then(res => {
|
||||||
|
orderList.value = [...orderList.value, ...res.data.list]
|
||||||
|
status.value = res.data.list == 10 ? 'loadmore' : 'nomore'
|
||||||
|
page.value++
|
||||||
|
})
|
||||||
|
} else {
|
||||||
|
CNRiderOrderService.GetRiderTakeOrderList(activeTab.value == 1 ? 0 : 1, page.value).then(res => {
|
||||||
|
orderList.value = [...orderList.value, ...res.data.list]
|
||||||
|
status.value = res.data.list == 10 ? 'loadmore' : 'nomore'
|
||||||
|
page.value++
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 接单
|
||||||
|
const takeOrder = (orderId : string) => {
|
||||||
|
CNRiderOrderService.RiderTakeOrder(orderId).then(res => {
|
||||||
|
if (res.data) {
|
||||||
|
getOrderData()
|
||||||
|
getData()
|
||||||
|
} else {
|
||||||
|
Service.Msg(res.msg)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
// 取餐
|
||||||
|
const pickFood = (orderId : string) => {
|
||||||
|
CNRiderOrderService.UpdateRiderOrderTake(orderId, activeTab.value).then(res => {
|
||||||
|
if (res.data) {
|
||||||
|
getOrderData()
|
||||||
|
getData()
|
||||||
|
} else {
|
||||||
|
Service.Msg(res.msg)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// 切换标签
|
||||||
|
const switchTab = (index : number) => {
|
||||||
|
activeTab.value = index
|
||||||
|
getOrderData()
|
||||||
|
}
|
||||||
|
|
||||||
|
// 切换接单状态
|
||||||
|
const toggleAcceptOrders = () => {
|
||||||
|
CNRiderDataService.UpdateRiderOnline().then(res => {
|
||||||
|
if (res.data) {
|
||||||
|
getData()
|
||||||
|
} else {
|
||||||
|
Service.Msg(res.msg)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
// 距离计算
|
||||||
|
const distance = (item : any) => {
|
||||||
|
if (item < 0) {
|
||||||
|
return Number(item * 100).toFixed(2) + 'm'
|
||||||
|
} else {
|
||||||
|
return Number(item).toFixed(2) + 'km'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 拨打电话
|
||||||
|
const call = (e : string) => {
|
||||||
|
uni.makePhoneCall({
|
||||||
|
phoneNumber: e
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// 页面跳转
|
||||||
|
const gopage = (id) => {
|
||||||
|
if (activeTab.value == 0) {
|
||||||
|
Service.GoPage('/pages/order/grabOrder?orderId=' + id)
|
||||||
|
} else {
|
||||||
|
Service.GoPage('/pages/order/orderDetail?orderId=' + id+'&type='+activeTab.value)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const audioPlay = () => {
|
||||||
|
const innerAudioContext = uni.createInnerAudioContext();
|
||||||
|
innerAudioContext.autoplay = true;
|
||||||
|
innerAudioContext.src = '/static/order.mp3';
|
||||||
|
innerAudioContext.onPlay(() => {
|
||||||
|
console.log('开始播放');
|
||||||
|
});
|
||||||
|
innerAudioContext.onError((res) => {
|
||||||
|
console.log(res.errMsg);
|
||||||
|
console.log(res.errCode);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style scoped lang="scss">
|
||||||
|
page {
|
||||||
|
background-color: #F6f6f6;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* 统计数据区域 */
|
||||||
|
.stats-section {
|
||||||
|
background-color: #ffffff;
|
||||||
|
margin: 20rpx;
|
||||||
|
border-radius: 16rpx;
|
||||||
|
display: flex;
|
||||||
|
justify-content: space-around;
|
||||||
|
padding: 30rpx 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.stat-item {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
align-items: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.stat-label {
|
||||||
|
font-size: 28rpx;
|
||||||
|
color: #666666;
|
||||||
|
margin-bottom: 10rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
.stat-value {
|
||||||
|
font-size: 36rpx;
|
||||||
|
font-weight: 600;
|
||||||
|
}
|
||||||
|
|
||||||
|
.income {
|
||||||
|
color: var(--nav-diluted);
|
||||||
|
}
|
||||||
|
|
||||||
|
.completed {
|
||||||
|
color: var(--nav-vice);
|
||||||
|
}
|
||||||
|
|
||||||
|
.ongoing {
|
||||||
|
color: #FF9500;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 接单按钮 */
|
||||||
|
.action-section {
|
||||||
|
margin: 0 20rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
.accept-orders-btn {
|
||||||
|
width: 100%;
|
||||||
|
height: 90rpx;
|
||||||
|
font-size: 32rpx;
|
||||||
|
background-color: #52C41A;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* 顶部标签栏 */
|
||||||
|
.tab-bar {
|
||||||
|
margin-top: 20rpx;
|
||||||
|
display: flex;
|
||||||
|
background-color: #FFFFFF;
|
||||||
|
padding: 20rpx 0 0;
|
||||||
|
border-bottom: 1rpx solid #E5E5E5;
|
||||||
|
width: 100vw;
|
||||||
|
background-color: #fff;
|
||||||
|
}
|
||||||
|
|
||||||
|
.tab-item {
|
||||||
|
flex: 1;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
align-items: center;
|
||||||
|
padding: 20rpx 0;
|
||||||
|
position: relative;
|
||||||
|
}
|
||||||
|
|
||||||
|
.tab-text {
|
||||||
|
font-size: 28rpx;
|
||||||
|
color: #666666;
|
||||||
|
}
|
||||||
|
|
||||||
|
.tab-item.active .tab-text {
|
||||||
|
color: var(--nav-mian);
|
||||||
|
font-weight: 600;
|
||||||
|
}
|
||||||
|
|
||||||
|
.active-line {
|
||||||
|
position: absolute;
|
||||||
|
bottom: 0;
|
||||||
|
width: 110rpx;
|
||||||
|
height: 6rpx;
|
||||||
|
background-color: var(--nav-mian);
|
||||||
|
border-radius: 3rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
.task-section {
|
||||||
|
margin-top: 20rpx;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
background-color: #fff;
|
||||||
|
border-radius: 20rpx;
|
||||||
|
padding: 20rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* 标签样式 */
|
||||||
|
.high-price-tag {
|
||||||
|
width: fit-content;
|
||||||
|
background-color: #FF7875;
|
||||||
|
color: #FFFFFF;
|
||||||
|
padding: 5rpx 20rpx;
|
||||||
|
border-radius: 20rpx;
|
||||||
|
font-size: 24rpx;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.status-tag {
|
||||||
|
position: absolute;
|
||||||
|
top: 20rpx;
|
||||||
|
left: 20rpx;
|
||||||
|
padding: 5rpx 20rpx;
|
||||||
|
border-radius: 20rpx;
|
||||||
|
font-size: 24rpx;
|
||||||
|
z-index: 10;
|
||||||
|
}
|
||||||
|
|
||||||
|
.status-tag.pending {
|
||||||
|
background-color: #4CD964;
|
||||||
|
color: #FFFFFF;
|
||||||
|
}
|
||||||
|
|
||||||
|
.status-tag.delivering {
|
||||||
|
background-color: #FF9500;
|
||||||
|
color: #FFFFFF;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 右侧操作按钮 */
|
||||||
|
.right-action {
|
||||||
|
position: absolute;
|
||||||
|
top: 20rpx;
|
||||||
|
right: 20rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
.call-btn {
|
||||||
|
padding: 5rpx 15rpx;
|
||||||
|
font-size: 24rpx;
|
||||||
|
line-height: 36rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 信息展示 */
|
||||||
|
.merchant-info {
|
||||||
|
margin-top: 20rpx;
|
||||||
|
display: flex;
|
||||||
|
justify-content: space-between;
|
||||||
|
align-items: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.merchant-name {
|
||||||
|
font-size: 34rpx;
|
||||||
|
font-weight: 600;
|
||||||
|
color: #333333;
|
||||||
|
}
|
||||||
|
|
||||||
|
.distance {
|
||||||
|
font-size: 28rpx;
|
||||||
|
color: #666666;
|
||||||
|
}
|
||||||
|
|
||||||
|
.address-info {
|
||||||
|
display: flex;
|
||||||
|
align-items: baseline;
|
||||||
|
margin-top: 15rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
.address-text {
|
||||||
|
margin-left: 10rpx;
|
||||||
|
font-size: 28rpx;
|
||||||
|
color: #666666;
|
||||||
|
flex: 1;
|
||||||
|
overflow: hidden;
|
||||||
|
text-overflow: ellipsis;
|
||||||
|
white-space: nowrap;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 价格和时间 */
|
||||||
|
.price-time-row {
|
||||||
|
margin-top: 20rpx;
|
||||||
|
display: flex;
|
||||||
|
justify-content: space-between;
|
||||||
|
align-items: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.price {
|
||||||
|
font-size: 36rpx;
|
||||||
|
font-weight: 600;
|
||||||
|
color: #FF3B30;
|
||||||
|
}
|
||||||
|
|
||||||
|
.pickup-code {
|
||||||
|
font-size: 28rpx;
|
||||||
|
color: #333333;
|
||||||
|
font-weight: 500;
|
||||||
|
}
|
||||||
|
|
||||||
|
.pickup-time {
|
||||||
|
display: flex;
|
||||||
|
align-items: baseline;
|
||||||
|
}
|
||||||
|
|
||||||
|
.time-text {
|
||||||
|
margin-left: 8rpx;
|
||||||
|
font-size: 26rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 按钮样式 */
|
||||||
|
.grab-btn {
|
||||||
|
margin-top: 25rpx;
|
||||||
|
height: 80rpx;
|
||||||
|
line-height: 80rpx;
|
||||||
|
border-radius: 40rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
.grab-btn {
|
||||||
|
background-color: #007AFF;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/* uview组件样式覆盖 */
|
||||||
|
::v-deep .u-button--primary {
|
||||||
|
background-color: var(--nav-vice);
|
||||||
|
border-color: var(--nav-vice);
|
||||||
|
}
|
||||||
|
|
||||||
|
::v-deep .u-button--mini {
|
||||||
|
background-color: var(--nav-mian);
|
||||||
|
border-color: var(--nav-mian);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* 骨架屏样式 */
|
||||||
|
.skeleton-container {
|
||||||
|
padding: 20rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 统计数据区域骨架 */
|
||||||
|
.skeleton-stats-section {
|
||||||
|
background-color: #ffffff;
|
||||||
|
margin: 0 20rpx;
|
||||||
|
border-radius: 16rpx;
|
||||||
|
display: flex;
|
||||||
|
justify-content: space-around;
|
||||||
|
padding: 30rpx 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.skeleton-stat-item {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
align-items: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.skeleton-stat-label {
|
||||||
|
width: 120rpx;
|
||||||
|
height: 28rpx;
|
||||||
|
background-color: #e6e6e6;
|
||||||
|
border-radius: 8rpx;
|
||||||
|
margin-bottom: 10rpx;
|
||||||
|
animation: skeleton-loading 1.5s infinite;
|
||||||
|
}
|
||||||
|
|
||||||
|
.skeleton-stat-value {
|
||||||
|
width: 150rpx;
|
||||||
|
height: 36rpx;
|
||||||
|
background-color: #e6e6e6;
|
||||||
|
border-radius: 8rpx;
|
||||||
|
animation: skeleton-loading 1.5s infinite;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 接单按钮骨架 */
|
||||||
|
.skeleton-action-section {
|
||||||
|
margin: 20rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
.skeleton-accept-btn {
|
||||||
|
width: 100%;
|
||||||
|
height: 90rpx;
|
||||||
|
background-color: #e6e6e6;
|
||||||
|
border-radius: 8rpx;
|
||||||
|
animation: skeleton-loading 1.5s infinite;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 标签栏骨架 */
|
||||||
|
.skeleton-tab-bar {
|
||||||
|
display: flex;
|
||||||
|
background-color: #ffffff;
|
||||||
|
padding: 20rpx 0 0;
|
||||||
|
border-bottom: 1rpx solid #e5e5e5;
|
||||||
|
}
|
||||||
|
|
||||||
|
.skeleton-tab-item {
|
||||||
|
flex: 1;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
align-items: center;
|
||||||
|
padding: 20rpx 0;
|
||||||
|
position: relative;
|
||||||
|
}
|
||||||
|
|
||||||
|
.skeleton-tab-text {
|
||||||
|
width: 100rpx;
|
||||||
|
height: 28rpx;
|
||||||
|
background-color: #e6e6e6;
|
||||||
|
border-radius: 8rpx;
|
||||||
|
animation: skeleton-loading 1.5s infinite;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 任务列表骨架 */
|
||||||
|
.skeleton-task-list {
|
||||||
|
padding: 0 20rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
.skeleton-task-section {
|
||||||
|
margin-top: 20rpx;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
background-color: #fff;
|
||||||
|
border-radius: 20rpx;
|
||||||
|
padding: 20rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 标签骨架 */
|
||||||
|
.skeleton-tag-row {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: space-between;
|
||||||
|
}
|
||||||
|
|
||||||
|
.skeleton-high-price-tag {
|
||||||
|
width: 120rpx;
|
||||||
|
height: 30rpx;
|
||||||
|
background-color: #e6e6e6;
|
||||||
|
border-radius: 20rpx;
|
||||||
|
animation: skeleton-loading 1.5s infinite;
|
||||||
|
}
|
||||||
|
|
||||||
|
.skeleton-phone-btn {
|
||||||
|
width: 150rpx;
|
||||||
|
height: 30rpx;
|
||||||
|
background-color: #e6e6e6;
|
||||||
|
border-radius: 8rpx;
|
||||||
|
animation: skeleton-loading 1.5s infinite;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 商家信息骨架 */
|
||||||
|
.skeleton-merchant-info {
|
||||||
|
margin-top: 20rpx;
|
||||||
|
display: flex;
|
||||||
|
justify-content: space-between;
|
||||||
|
align-items: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.skeleton-merchant-name {
|
||||||
|
width: 200rpx;
|
||||||
|
height: 34rpx;
|
||||||
|
background-color: #e6e6e6;
|
||||||
|
border-radius: 8rpx;
|
||||||
|
animation: skeleton-loading 1.5s infinite;
|
||||||
|
}
|
||||||
|
|
||||||
|
.skeleton-distance {
|
||||||
|
width: 80rpx;
|
||||||
|
height: 28rpx;
|
||||||
|
background-color: #e6e6e6;
|
||||||
|
border-radius: 8rpx;
|
||||||
|
animation: skeleton-loading 1.5s infinite;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 地址信息骨架 */
|
||||||
|
.skeleton-address-info {
|
||||||
|
display: flex;
|
||||||
|
align-items: baseline;
|
||||||
|
margin-top: 15rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
.skeleton-address-text {
|
||||||
|
width: 100%;
|
||||||
|
height: 28rpx;
|
||||||
|
background-color: #e6e6e6;
|
||||||
|
border-radius: 8rpx;
|
||||||
|
animation: skeleton-loading 1.5s infinite;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 价格和时间骨架 */
|
||||||
|
.skeleton-price-time-row {
|
||||||
|
margin-top: 20rpx;
|
||||||
|
display: flex;
|
||||||
|
justify-content: space-between;
|
||||||
|
align-items: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.skeleton-pickup-code {
|
||||||
|
width: 150rpx;
|
||||||
|
height: 30rpx;
|
||||||
|
background-color: #e6e6e6;
|
||||||
|
border-radius: 8rpx;
|
||||||
|
animation: skeleton-loading 1.5s infinite;
|
||||||
|
}
|
||||||
|
|
||||||
|
.skeleton-pickup-time {
|
||||||
|
width: 200rpx;
|
||||||
|
height: 30rpx;
|
||||||
|
background-color: #e6e6e6;
|
||||||
|
border-radius: 8rpx;
|
||||||
|
animation: skeleton-loading 1.5s infinite;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 按钮骨架 */
|
||||||
|
.skeleton-grab-btn {
|
||||||
|
margin-top: 25rpx;
|
||||||
|
height: 80rpx;
|
||||||
|
background-color: #e6e6e6;
|
||||||
|
border-radius: 40rpx;
|
||||||
|
animation: skeleton-loading 1.5s infinite;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 骨架屏动画 */
|
||||||
|
@keyframes skeleton-loading {
|
||||||
|
0% {
|
||||||
|
background-color: #e6e6e6;
|
||||||
|
}
|
||||||
|
|
||||||
|
50% {
|
||||||
|
background-color: #f0f0f0;
|
||||||
|
}
|
||||||
|
|
||||||
|
100% {
|
||||||
|
background-color: #e6e6e6;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
After Width: | Height: | Size: 566 B |
@@ -0,0 +1,580 @@
|
|||||||
|
<template>
|
||||||
|
<!-- 骨架屏 -->
|
||||||
|
<view v-if="loading" class="skeleton-container">
|
||||||
|
<!-- 余额区域骨架屏 -->
|
||||||
|
<view class="skeleton-balance-section">
|
||||||
|
<view class="skeleton-balance-label"></view>
|
||||||
|
<view class="skeleton-balance-amount"></view>
|
||||||
|
<view class="skeleton-balance-current"></view>
|
||||||
|
</view>
|
||||||
|
|
||||||
|
<!-- 账户选择区域骨架屏 -->
|
||||||
|
<view class="skeleton-account-section">
|
||||||
|
<view class="skeleton-section-title"></view>
|
||||||
|
<view class="skeleton-account-item">
|
||||||
|
<view class="skeleton-account-icon"></view>
|
||||||
|
<view class="skeleton-account-name"></view>
|
||||||
|
<view class="skeleton-account-radio"></view>
|
||||||
|
</view>
|
||||||
|
<view class="skeleton-account-item">
|
||||||
|
<view class="skeleton-account-icon"></view>
|
||||||
|
<view class="skeleton-account-name"></view>
|
||||||
|
<view class="skeleton-account-radio"></view>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
|
||||||
|
<!-- 提示信息骨架屏 -->
|
||||||
|
<view class="skeleton-tip-section">
|
||||||
|
<view class="skeleton-tip-icon"></view>
|
||||||
|
<view class="skeleton-tip-content">
|
||||||
|
<view class="skeleton-tip-line"></view>
|
||||||
|
<view class="skeleton-tip-line-small"></view>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
|
||||||
|
<!-- 确认按钮骨架屏 -->
|
||||||
|
<view class="skeleton-confirm-section">
|
||||||
|
<view class="skeleton-confirm-button"></view>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
<!-- 真实内容 -->
|
||||||
|
<view v-else class="withdraw-container">
|
||||||
|
<!-- 可提现金额 -->
|
||||||
|
<view class="balance-section">
|
||||||
|
<text class="balance-label">可提现金额</text>
|
||||||
|
<text class="balance-amount">¥{{ riderAcc.account }}</text>
|
||||||
|
<text class="current-balance">当前钱包余额</text>
|
||||||
|
</view>
|
||||||
|
|
||||||
|
<!-- 提现账户选择 -->
|
||||||
|
<view class="account-section">
|
||||||
|
<text class="section-title">提现账户</text>
|
||||||
|
<view class=""
|
||||||
|
style="display: flex;align-items: center; border-bottom: 4rpx solid #e2e2e2;padding-bottom: 10px; margin-bottom: 10px;">
|
||||||
|
<up-icon name="zhifubao-circle-fill" size="30" color="#1890ff"></up-icon>
|
||||||
|
<view style="flex: 1; margin-left: 30rpx; " class="">
|
||||||
|
支付宝
|
||||||
|
</view>
|
||||||
|
<view @click="changePay(0)" class="">
|
||||||
|
<view v-if="current==0" class="radio-circle">
|
||||||
|
<view class="radio-inner"></view>
|
||||||
|
</view>
|
||||||
|
<view v-else class="radio-no-circle">
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
<view class="" style="display: flex;align-items: center;">
|
||||||
|
<up-icon name="weixin-circle-fill" size="30" color="#28C445"></up-icon>
|
||||||
|
<view style="flex: 1; margin-left: 30rpx; " class="">
|
||||||
|
微信
|
||||||
|
</view>
|
||||||
|
<view @click="changePay(1)" class="">
|
||||||
|
<view v-if="current==1" class="radio-circle">
|
||||||
|
<view class="radio-inner"></view>
|
||||||
|
</view>
|
||||||
|
<view v-else class="radio-no-circle">
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
|
||||||
|
<!-- 提现账号 -->
|
||||||
|
<view class="" v-if="current!=null" style="margin: 20rpx 30rpx; ">
|
||||||
|
<view class="" style="font-size: 34rpx; font-weight: 600; ">
|
||||||
|
支付宝账号信息
|
||||||
|
</view>
|
||||||
|
|
||||||
|
<up-form labelPosition="top" label-width="200" :model="account" ref="form1">
|
||||||
|
<up-form-item label="姓名" prop="userInfo.name" :borderBottom="true" ref="item1">
|
||||||
|
<up-input v-model="account.name" @change="changePrice" placeholder="请输入姓名" border="none"></up-input>
|
||||||
|
</up-form-item>
|
||||||
|
<up-form-item :label="current==0? '支付宝账号':'微信账号'" prop="userInfo.name" :borderBottom="true" ref="item1">
|
||||||
|
<up-input v-model="account.id" :placeholder="current==0? '请输入支付宝账号':'请输入微信账号'"
|
||||||
|
border="none"></up-input>
|
||||||
|
</up-form-item>
|
||||||
|
<up-form-item label="提现金额" prop="userInfo.name" :borderBottom="true" ref="item1">
|
||||||
|
<up-input v-model="account.price" type="digit" placeholder="请输入提现金额" border="none"></up-input>
|
||||||
|
</up-form-item>
|
||||||
|
</up-form>
|
||||||
|
</view>
|
||||||
|
|
||||||
|
|
||||||
|
<!-- 提示信息 -->
|
||||||
|
<view class="tip-section">
|
||||||
|
<up-icon name="clock" size="18" color="#1890ff"></up-icon>
|
||||||
|
<view class="" style="margin-left: 10rpx;">
|
||||||
|
<view class="tip-text">预计 T+1 工作日到账</view>
|
||||||
|
<view class="tip-text" style="color: #666666; font-size: 24rpx; margin-top: 10rpx; ">无手续费</view>
|
||||||
|
</view>
|
||||||
|
|
||||||
|
</view>
|
||||||
|
|
||||||
|
<!-- 确认按钮 -->
|
||||||
|
<view class="confirm-section">
|
||||||
|
<button class="confirm-button" @click="confirmWithdraw">确认提现</button>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script setup lang="ts">
|
||||||
|
import { onLoad } from '@dcloudio/uni-app';
|
||||||
|
import { ref } from 'vue';
|
||||||
|
import { Service } from '@/Service/Service';
|
||||||
|
import { CNRiderOrderService } from '@/Service/CN/CNRiderOrderService'
|
||||||
|
import { CNRiderDataService } from '@/Service/CN/CNRiderDataService'
|
||||||
|
|
||||||
|
let current = ref(null)
|
||||||
|
let loading = ref(true)
|
||||||
|
|
||||||
|
|
||||||
|
let account = ref({
|
||||||
|
id: '',
|
||||||
|
price: "",
|
||||||
|
name: ''
|
||||||
|
})
|
||||||
|
|
||||||
|
let riderAcc=ref<any>({})
|
||||||
|
|
||||||
|
onLoad(() => {
|
||||||
|
getData()
|
||||||
|
})
|
||||||
|
|
||||||
|
|
||||||
|
const getData=()=>{
|
||||||
|
CNRiderDataService.GetRiderAccInfo().then(res=>{
|
||||||
|
loading.value = false
|
||||||
|
if(res.data){
|
||||||
|
riderAcc.value=res.data.riderAcc
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
const changePay = (item : any) => {
|
||||||
|
current.value = item
|
||||||
|
}
|
||||||
|
|
||||||
|
const changePrice = (e : string) => {
|
||||||
|
console.log(e);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// 确认提现
|
||||||
|
const confirmWithdraw = () => {
|
||||||
|
if(!account.value.name){
|
||||||
|
Service.Msg('请输入姓名!')
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if(!account.value.price){
|
||||||
|
Service.Msg('请输入提现金额!')
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if(!account.value.id){
|
||||||
|
Service.Msg('请输入账户号!')
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
uni.showModal({
|
||||||
|
title: '提示',
|
||||||
|
content: '请仔细确认身份信息?',
|
||||||
|
success: function (res) {
|
||||||
|
if (res.confirm) {
|
||||||
|
CNRiderOrderService.AddRiderWith(Number(account.value.price),current.value==0?'支付宝':'微信',account.value.name,account.value.id).then(res=>{
|
||||||
|
|
||||||
|
})
|
||||||
|
} else {
|
||||||
|
// 用户点击取消后的操作
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
};
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style scoped>
|
||||||
|
.withdraw-container {
|
||||||
|
min-height: 100vh;
|
||||||
|
background-color: #fff;
|
||||||
|
padding-bottom: 40rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 选择 */
|
||||||
|
|
||||||
|
.radio-circle {
|
||||||
|
width: 36rpx;
|
||||||
|
height: 36rpx;
|
||||||
|
border: 2rpx solid var(--nav-mian);
|
||||||
|
border-radius: 50%;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
margin-right: 20rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
.radio-inner {
|
||||||
|
width: 20rpx;
|
||||||
|
height: 20rpx;
|
||||||
|
background-color: var(--nav-mian);
|
||||||
|
border-radius: 50%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.radio-no-circle {
|
||||||
|
width: 36rpx;
|
||||||
|
height: 36rpx;
|
||||||
|
border: 2rpx solid #dadada;
|
||||||
|
border-radius: 50%;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
margin-right: 20rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/* 顶部导航栏 */
|
||||||
|
.nav-bar {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: space-between;
|
||||||
|
padding: 30rpx 20rpx;
|
||||||
|
background-color: #fff;
|
||||||
|
position: sticky;
|
||||||
|
top: 0;
|
||||||
|
z-index: 100;
|
||||||
|
box-shadow: 0 2rpx 10rpx rgba(0, 0, 0, 0.05);
|
||||||
|
}
|
||||||
|
|
||||||
|
.nav-title {
|
||||||
|
font-size: 36rpx;
|
||||||
|
font-weight: 600;
|
||||||
|
color: #000;
|
||||||
|
}
|
||||||
|
|
||||||
|
.back-icon {
|
||||||
|
width: 40rpx;
|
||||||
|
height: 40rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
.help-icon {
|
||||||
|
width: 40rpx;
|
||||||
|
height: 40rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 余额显示区域 */
|
||||||
|
.balance-section {
|
||||||
|
background-color: #fff;
|
||||||
|
padding: 40rpx 30rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
.balance-label {
|
||||||
|
font-size: 32rpx;
|
||||||
|
color: #333;
|
||||||
|
display: block;
|
||||||
|
margin-bottom: 10rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
.balance-amount {
|
||||||
|
font-size: 60rpx;
|
||||||
|
font-weight: bold;
|
||||||
|
color: #ff4757;
|
||||||
|
display: block;
|
||||||
|
margin-bottom: 10rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
.current-balance {
|
||||||
|
font-size: 28rpx;
|
||||||
|
color: #999;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 账户选择区域 */
|
||||||
|
.account-section {
|
||||||
|
background-color: #fff;
|
||||||
|
padding: 30rpx;
|
||||||
|
margin-bottom: 20rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
.section-title {
|
||||||
|
font-size: 32rpx;
|
||||||
|
font-weight: 600;
|
||||||
|
color: #333;
|
||||||
|
display: block;
|
||||||
|
margin-bottom: 20rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
.account-item {
|
||||||
|
display: flex;
|
||||||
|
justify-content: space-between;
|
||||||
|
align-items: center;
|
||||||
|
padding: 25rpx 0;
|
||||||
|
border-bottom: 1rpx solid #f0f0f0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.account-item:last-child {
|
||||||
|
border-bottom: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
.account-info {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.account-icon {
|
||||||
|
width: 60rpx;
|
||||||
|
height: 60rpx;
|
||||||
|
border-radius: 12rpx;
|
||||||
|
background-color: #1677ff;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
margin-right: 20rpx;
|
||||||
|
border: 2rpx solid #000;
|
||||||
|
}
|
||||||
|
|
||||||
|
.account-icon.wechat {
|
||||||
|
background-color: #07c160;
|
||||||
|
}
|
||||||
|
|
||||||
|
.icon-text {
|
||||||
|
color: #fff;
|
||||||
|
font-size: 32rpx;
|
||||||
|
font-weight: bold;
|
||||||
|
}
|
||||||
|
|
||||||
|
.account-name {
|
||||||
|
font-size: 32rpx;
|
||||||
|
color: #333;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 提示信息区域 */
|
||||||
|
.tip-section {
|
||||||
|
display: flex;
|
||||||
|
align-items: flex-start;
|
||||||
|
background-color: #e6f7ff;
|
||||||
|
padding: 20rpx 30rpx;
|
||||||
|
margin: 0 30rpx 20rpx;
|
||||||
|
border-radius: 10rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
.tip-text {
|
||||||
|
font-size: 28rpx;
|
||||||
|
margin-left: 10rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 确认按钮区域 */
|
||||||
|
.confirm-section {
|
||||||
|
background-color: #fff;
|
||||||
|
position: fixed;
|
||||||
|
width: 100vw;
|
||||||
|
left: 0;
|
||||||
|
bottom: 0;
|
||||||
|
padding: 30rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
.confirm-button {
|
||||||
|
width: 100%;
|
||||||
|
height: 90rpx;
|
||||||
|
background-color: #1677ff;
|
||||||
|
color: #fff;
|
||||||
|
font-size: 36rpx;
|
||||||
|
font-weight: 600;
|
||||||
|
border-radius: 45rpx;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
border: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
.confirm-button:active {
|
||||||
|
background-color: #0958d9;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 骨架屏样式 */
|
||||||
|
.skeleton-container {
|
||||||
|
min-height: 100vh;
|
||||||
|
background-color: #fff;
|
||||||
|
padding-bottom: 40rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 骨架屏动画 */
|
||||||
|
@keyframes shimmer {
|
||||||
|
0% {
|
||||||
|
background-position: -1000px 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
100% {
|
||||||
|
background-position: 1000px 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 骨架屏通用样式 */
|
||||||
|
.skeleton-balance-section,
|
||||||
|
.skeleton-account-section,
|
||||||
|
.skeleton-tip-section {
|
||||||
|
padding: 40rpx 30rpx;
|
||||||
|
margin-bottom: 20rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 余额区域骨架屏 */
|
||||||
|
.skeleton-balance-section {
|
||||||
|
background-color: #fff;
|
||||||
|
}
|
||||||
|
|
||||||
|
.skeleton-balance-label {
|
||||||
|
width: 30%;
|
||||||
|
height: 32rpx;
|
||||||
|
background-color: #e6e6e6;
|
||||||
|
margin-bottom: 20rpx;
|
||||||
|
border-radius: 4rpx;
|
||||||
|
animation: shimmer 1.5s infinite;
|
||||||
|
background-image: linear-gradient(90deg, #f0f0f0 25%, #e0e0e0 50%, #f0f0f0 75%);
|
||||||
|
background-size: 1000px 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.skeleton-balance-amount {
|
||||||
|
width: 40%;
|
||||||
|
height: 60rpx;
|
||||||
|
background-color: #e6e6e6;
|
||||||
|
margin-bottom: 20rpx;
|
||||||
|
border-radius: 4rpx;
|
||||||
|
animation: shimmer 1.5s infinite;
|
||||||
|
background-image: linear-gradient(90deg, #f0f0f0 25%, #e0e0e0 50%, #f0f0f0 75%);
|
||||||
|
background-size: 1000px 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.skeleton-balance-current {
|
||||||
|
width: 25%;
|
||||||
|
height: 28rpx;
|
||||||
|
background-color: #e6e6e6;
|
||||||
|
border-radius: 4rpx;
|
||||||
|
animation: shimmer 1.5s infinite;
|
||||||
|
background-image: linear-gradient(90deg, #f0f0f0 25%, #e0e0e0 50%, #f0f0f0 75%);
|
||||||
|
background-size: 1000px 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 账户选择区域骨架屏 */
|
||||||
|
.skeleton-account-section {
|
||||||
|
background-color: #fff;
|
||||||
|
}
|
||||||
|
|
||||||
|
.skeleton-section-title {
|
||||||
|
width: 25%;
|
||||||
|
height: 32rpx;
|
||||||
|
background-color: #e6e6e6;
|
||||||
|
margin-bottom: 30rpx;
|
||||||
|
border-radius: 4rpx;
|
||||||
|
animation: shimmer 1.5s infinite;
|
||||||
|
background-image: linear-gradient(90deg, #f0f0f0 25%, #e0e0e0 50%, #f0f0f0 75%);
|
||||||
|
background-size: 1000px 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.skeleton-account-item {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
margin-bottom: 30rpx;
|
||||||
|
padding-bottom: 30rpx;
|
||||||
|
border-bottom: 4rpx solid #e2e2e2;
|
||||||
|
}
|
||||||
|
|
||||||
|
.skeleton-account-item:last-child {
|
||||||
|
border-bottom: none;
|
||||||
|
padding-bottom: 0;
|
||||||
|
margin-bottom: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.skeleton-account-icon {
|
||||||
|
width: 60rpx;
|
||||||
|
height: 60rpx;
|
||||||
|
background-color: #e6e6e6;
|
||||||
|
border-radius: 12rpx;
|
||||||
|
margin-right: 20rpx;
|
||||||
|
animation: shimmer 1.5s infinite;
|
||||||
|
background-image: linear-gradient(90deg, #f0f0f0 25%, #e0e0e0 50%, #f0f0f0 75%);
|
||||||
|
background-size: 1000px 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.skeleton-account-name {
|
||||||
|
flex: 1;
|
||||||
|
height: 32rpx;
|
||||||
|
background-color: #e6e6e6;
|
||||||
|
border-radius: 4rpx;
|
||||||
|
margin-right: 20rpx;
|
||||||
|
animation: shimmer 1.5s infinite;
|
||||||
|
background-image: linear-gradient(90deg, #f0f0f0 25%, #e0e0e0 50%, #f0f0f0 75%);
|
||||||
|
background-size: 1000px 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.skeleton-account-radio {
|
||||||
|
width: 36rpx;
|
||||||
|
height: 36rpx;
|
||||||
|
background-color: #e6e6e6;
|
||||||
|
border-radius: 50%;
|
||||||
|
animation: shimmer 1.5s infinite;
|
||||||
|
background-image: linear-gradient(90deg, #f0f0f0 25%, #e0e0e0 50%, #f0f0f0 75%);
|
||||||
|
background-size: 1000px 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 提示信息骨架屏 */
|
||||||
|
.skeleton-tip-section {
|
||||||
|
display: flex;
|
||||||
|
align-items: flex-start;
|
||||||
|
background-color: #e6f7ff;
|
||||||
|
padding: 20rpx 30rpx;
|
||||||
|
margin: 0 30rpx 20rpx;
|
||||||
|
border-radius: 10rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
.skeleton-tip-icon {
|
||||||
|
width: 40rpx;
|
||||||
|
height: 40rpx;
|
||||||
|
background-color: #e6e6e6;
|
||||||
|
border-radius: 50%;
|
||||||
|
margin-right: 15rpx;
|
||||||
|
animation: shimmer 1.5s infinite;
|
||||||
|
background-image: linear-gradient(90deg, #f0f0f0 25%, #e0e0e0 50%, #f0f0f0 75%);
|
||||||
|
background-size: 1000px 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.skeleton-tip-content {
|
||||||
|
flex: 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
.skeleton-tip-line {
|
||||||
|
width: 70%;
|
||||||
|
height: 28rpx;
|
||||||
|
background-color: #e6e6e6;
|
||||||
|
margin-bottom: 15rpx;
|
||||||
|
border-radius: 4rpx;
|
||||||
|
animation: shimmer 1.5s infinite;
|
||||||
|
background-image: linear-gradient(90deg, #f0f0f0 25%, #e0e0e0 50%, #f0f0f0 75%);
|
||||||
|
background-size: 1000px 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.skeleton-tip-line-small {
|
||||||
|
width: 50%;
|
||||||
|
height: 24rpx;
|
||||||
|
background-color: #e6e6e6;
|
||||||
|
border-radius: 4rpx;
|
||||||
|
animation: shimmer 1.5s infinite;
|
||||||
|
background-image: linear-gradient(90deg, #f0f0f0 25%, #e0e0e0 50%, #f0f0f0 75%);
|
||||||
|
background-size: 1000px 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 确认按钮骨架屏 */
|
||||||
|
.skeleton-confirm-section {
|
||||||
|
position: fixed;
|
||||||
|
bottom: 0;
|
||||||
|
left: 0;
|
||||||
|
width: 100%;
|
||||||
|
background-color: #fff;
|
||||||
|
padding: 30rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
.skeleton-confirm-button {
|
||||||
|
width: 100%;
|
||||||
|
height: 90rpx;
|
||||||
|
background-color: #e6e6e6;
|
||||||
|
border-radius: 45rpx;
|
||||||
|
animation: shimmer 1.5s infinite;
|
||||||
|
background-image: linear-gradient(90deg, #f0f0f0 25%, #e0e0e0 50%, #f0f0f0 75%);
|
||||||
|
background-size: 1000px 100%;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
After Width: | Height: | Size: 6.8 KiB |
@@ -0,0 +1,661 @@
|
|||||||
|
<template>
|
||||||
|
|
||||||
|
<!-- 骨架屏 -->
|
||||||
|
<view v-if="isLoading" class="skeleton-container">
|
||||||
|
<!-- 顶部提示栏骨架 -->
|
||||||
|
<view class="skeleton-top-tip"></view>
|
||||||
|
|
||||||
|
<!-- 头像上传区域骨架 -->
|
||||||
|
<view class="skeleton-avatar-section">
|
||||||
|
<view class="skeleton-avatar"></view>
|
||||||
|
<view class="skeleton-avatar-text"></view>
|
||||||
|
</view>
|
||||||
|
|
||||||
|
<!-- 表单内容骨架 -->
|
||||||
|
<view class="skeleton-form-content">
|
||||||
|
<!-- 身份信息区域骨架 -->
|
||||||
|
<view class="skeleton-section">
|
||||||
|
<view class="skeleton-section-title"></view>
|
||||||
|
|
||||||
|
<!-- 姓名输入骨架 -->
|
||||||
|
<view class="skeleton-form-item">
|
||||||
|
<view class="skeleton-label"></view>
|
||||||
|
<view class="skeleton-input"></view>
|
||||||
|
</view>
|
||||||
|
|
||||||
|
<!-- 身份证号输入骨架 -->
|
||||||
|
<view class="skeleton-form-item">
|
||||||
|
<view class="skeleton-label"></view>
|
||||||
|
<view class="skeleton-input"></view>
|
||||||
|
</view>
|
||||||
|
|
||||||
|
<!-- 年龄输入骨架 -->
|
||||||
|
<view class="skeleton-form-item">
|
||||||
|
<view class="skeleton-label"></view>
|
||||||
|
<view class="skeleton-input"></view>
|
||||||
|
</view>
|
||||||
|
|
||||||
|
<!-- 性别选择骨架 -->
|
||||||
|
<view class="skeleton-form-item">
|
||||||
|
<view class="skeleton-label"></view>
|
||||||
|
<view class="skeleton-radio-group">
|
||||||
|
<view class="skeleton-radio-item"></view>
|
||||||
|
<view class="skeleton-radio-item"></view>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
|
||||||
|
<!-- 身份证照片区域骨架 -->
|
||||||
|
<view class="skeleton-section">
|
||||||
|
<view class="skeleton-section-title"></view>
|
||||||
|
|
||||||
|
<!-- 身份证正面上传骨架 -->
|
||||||
|
<view class="skeleton-upload-item">
|
||||||
|
<view class="skeleton-upload-area"></view>
|
||||||
|
</view>
|
||||||
|
|
||||||
|
<!-- 身份证反面上传骨架 -->
|
||||||
|
<view class="skeleton-upload-item">
|
||||||
|
<view class="skeleton-upload-area"></view>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
|
||||||
|
<!-- 占位空间骨架 -->
|
||||||
|
<view class="skeleton-placeholder"></view>
|
||||||
|
|
||||||
|
<!-- 提交按钮骨架 -->
|
||||||
|
<view class="skeleton-submit-section">
|
||||||
|
<view class="skeleton-submit-btn"></view>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
|
||||||
|
|
||||||
|
<view v-else class="real-name-auth-container">
|
||||||
|
<!-- 顶部提示栏 -->
|
||||||
|
<view class="top-tip">
|
||||||
|
<text class="tip-text">请完成实名认证,保障您的接单权益</text>
|
||||||
|
</view>
|
||||||
|
<view @click="uploadFImg(1)" class=""
|
||||||
|
style=" display: flex; flex-direction: column; justify-content: center; align-items: center; ">
|
||||||
|
<img v-if="formData.headImg!=''" :src="Service.GetMateUrlByImg(formData.headImg)"
|
||||||
|
style="width: 140rpx; height: 140rpx; border-radius: 50%; " alt="" />
|
||||||
|
<view v-else class=""
|
||||||
|
style="background-color: #EBEBEB; width: 140rpx; height: 140rpx; border-radius: 50%; display: flex; align-items: center; justify-content: center; ">
|
||||||
|
<image :src="Service.GetIconImg('/static/index/my/edit/photo.png')"
|
||||||
|
style="width: 50rpx; height: 50rpx; " alt=""> </image>
|
||||||
|
</view>
|
||||||
|
<view class="" style="margin-top: 15rpx; font-size: 26rpx; color: #999999; ">
|
||||||
|
点击更换头像
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
|
||||||
|
<!-- 表单内容 -->
|
||||||
|
<view class="form-content">
|
||||||
|
<!-- 身份信息区域 -->
|
||||||
|
<view class="section">
|
||||||
|
<view class="section-title">身份信息</view>
|
||||||
|
|
||||||
|
<!-- 姓名输入 -->
|
||||||
|
<view class="form-item">
|
||||||
|
<view class="label">姓名</view>
|
||||||
|
<u-input v-model="formData.name" placeholder="请输入真实姓名" placeholder-color="#999" border="none"
|
||||||
|
class="input" input-align="right" />
|
||||||
|
</view>
|
||||||
|
<!-- 身份证号输入 -->
|
||||||
|
<view class="form-item">
|
||||||
|
<view class="label">身份证号</view>
|
||||||
|
<u-input v-model="formData.idCard" placeholder="请输入18位身份证号" placeholder-color="#999" border="none"
|
||||||
|
class="input" input-align="right" maxlength="18" />
|
||||||
|
</view>
|
||||||
|
<!-- 年龄 -->
|
||||||
|
<view class="form-item">
|
||||||
|
<view class="label">年龄</view>
|
||||||
|
<u-input v-model="formData.age" placeholder="请输入年龄" placeholder-color="#999" border="none"
|
||||||
|
class="input" input-align="right" maxlength="18" />
|
||||||
|
</view>
|
||||||
|
<view class="form-item" style="justify-content: space-between;">
|
||||||
|
<view class="label">性别</view>
|
||||||
|
<view class="" style="">
|
||||||
|
<up-radio-group v-model="formData.sex" placement="row">
|
||||||
|
<up-radio v-for="(item, index) in radiolist1" activeColor='#FF6A00' :key="index"
|
||||||
|
iconPlacement="right" :label="item.name" :name="item.name">
|
||||||
|
</up-radio>
|
||||||
|
</up-radio-group>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
|
||||||
|
|
||||||
|
</view>
|
||||||
|
|
||||||
|
<!-- 身份证照片区域 -->
|
||||||
|
<view class="section">
|
||||||
|
<view class="section-title">身份证照片</view>
|
||||||
|
|
||||||
|
<!-- 上传身份证正面 -->
|
||||||
|
<view @click="uploadFImg(2)" class="upload-item">
|
||||||
|
<view class="upload-area bordered-area">
|
||||||
|
<view v-if="!formData.frontImage" class="upload-content">
|
||||||
|
<view class="upload-icon">+</view>
|
||||||
|
<view class="upload-text">上传身份证正面</view>
|
||||||
|
</view>
|
||||||
|
<!-- 显示上传后的占位图 -->
|
||||||
|
<view v-else class="uploaded-placeholder">
|
||||||
|
<image :src="Service.GetMateUrlByImg(formData.frontImage)"
|
||||||
|
style="width: 100%; height: 100%; " mode=""></image>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
|
||||||
|
<!-- 上传身份证反面 -->
|
||||||
|
<view @click="uploadFImg(3)" class="upload-item">
|
||||||
|
<view class="upload-area bordered-area">
|
||||||
|
<view v-if="!formData.backImage" class="upload-content">
|
||||||
|
<view class="upload-icon">+</view>
|
||||||
|
<view class="upload-text">上传身份证反面</view>
|
||||||
|
</view>
|
||||||
|
<!-- 显示上传后的占位图 -->
|
||||||
|
<view v-else class="uploaded-placeholder">
|
||||||
|
<image :src="Service.GetMateUrlByImg(formData.backImage)"
|
||||||
|
style="width: 100%; height: 100%; " mode=""></image>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
|
||||||
|
|
||||||
|
<view class="" style="width: 100vw; height: 180rpx;">
|
||||||
|
|
||||||
|
</view>
|
||||||
|
|
||||||
|
<!-- 提交按钮 -->
|
||||||
|
<view class="submit-section">
|
||||||
|
<button @click="save()" type="primary" class="submit-btn">
|
||||||
|
提交信息
|
||||||
|
</button>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script setup lang="ts">
|
||||||
|
import { onLoad } from '@dcloudio/uni-app';
|
||||||
|
import { ref, computed } from 'vue';
|
||||||
|
import { Service } from '@/Service/Service';
|
||||||
|
import { CNRiderDataService } from '@/Service/CN/CNRiderDataService';
|
||||||
|
|
||||||
|
|
||||||
|
let isLoading = ref(true)
|
||||||
|
|
||||||
|
// 表单数据
|
||||||
|
const formData = ref({
|
||||||
|
name: '',
|
||||||
|
idCard: '',
|
||||||
|
sex: '男',
|
||||||
|
frontImage: '',
|
||||||
|
backImage: '',
|
||||||
|
agreed: false,
|
||||||
|
headImg: '',
|
||||||
|
age: '',
|
||||||
|
phone: ''
|
||||||
|
});
|
||||||
|
|
||||||
|
const radiolist1 = ref([
|
||||||
|
{
|
||||||
|
name: '男',
|
||||||
|
disabled: false,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: '女',
|
||||||
|
disabled: false,
|
||||||
|
}
|
||||||
|
]);
|
||||||
|
|
||||||
|
|
||||||
|
let addressInfo = ref({
|
||||||
|
province: '',
|
||||||
|
city: '',
|
||||||
|
region: '',
|
||||||
|
lat: 0,
|
||||||
|
lon: 0
|
||||||
|
})
|
||||||
|
|
||||||
|
onLoad(() => {
|
||||||
|
getLocation()
|
||||||
|
})
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
const getLocation = () => {
|
||||||
|
console.log('开始定位');
|
||||||
|
uni.getLocation({
|
||||||
|
type: 'wgs84',
|
||||||
|
success: function (res) {
|
||||||
|
addressInfo.value.lat = res.latitude
|
||||||
|
addressInfo.value.lon = res.longitude
|
||||||
|
CNRiderDataService.GetAddressInfo(res.latitude, res.longitude).then(data => {
|
||||||
|
console.log(1111);
|
||||||
|
isLoading.value = false
|
||||||
|
addressInfo.value.province = data.data.addrInfo.province
|
||||||
|
addressInfo.value.city = data.data.addrInfo.city
|
||||||
|
addressInfo.value.region = data.data.addrInfo.district
|
||||||
|
})
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
const uploadFImg = (index : number) => {
|
||||||
|
uni.chooseImage({
|
||||||
|
count: 1, // 最多选择3张图片
|
||||||
|
sizeType: ['original', 'compressed'], // 支持原图和压缩图
|
||||||
|
sourceType: ['album', 'camera'], // 可从相册选择或使用相机拍照
|
||||||
|
success: function (res) {
|
||||||
|
let path = res.tempFiles[0].path
|
||||||
|
Service.uploadH5(path, 'Avatar', data => {
|
||||||
|
|
||||||
|
if (index === 1) {
|
||||||
|
formData.value.headImg = data
|
||||||
|
} else if (index === 2) {
|
||||||
|
formData.value.frontImage = data
|
||||||
|
} else {
|
||||||
|
formData.value.backImage = data
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
},
|
||||||
|
fail: function (err) {
|
||||||
|
console.error('选择失败:', err.errMsg);
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
const save = () => {
|
||||||
|
if (rules() === 1) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
CNRiderDataService.CompleteRider(formData.value.name, formData.value.headImg, formData.value.idCard, formData.value.sex, Number(formData.value.age), formData.value.frontImage, formData.value.backImage, addressInfo.value.province, addressInfo.value.city, addressInfo.value.region, addressInfo.value.lat, addressInfo.value.lon).then(res => {
|
||||||
|
if (res.data) {
|
||||||
|
Service.Msg('提交成功')
|
||||||
|
setTimeout(()=>{
|
||||||
|
Service.GoPageTab('/pages/index/index')
|
||||||
|
},1000)
|
||||||
|
} else {
|
||||||
|
Service.Msg(res.msg)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
const rules = () => {
|
||||||
|
if (!formData.value.headImg) {
|
||||||
|
Service.Msg('请上传头像!')
|
||||||
|
return 1
|
||||||
|
}
|
||||||
|
if (!formData.value.name) {
|
||||||
|
Service.Msg('请输入真实姓名!')
|
||||||
|
return 1
|
||||||
|
}
|
||||||
|
|
||||||
|
if (formData.value.idCard.split('').length !== 18) {
|
||||||
|
Service.Msg('请输入正确身份证号!')
|
||||||
|
return 1
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!formData.value.idCard) {
|
||||||
|
Service.Msg('请输入身份证号!')
|
||||||
|
return 1
|
||||||
|
}
|
||||||
|
if (!formData.value.age) {
|
||||||
|
Service.Msg('请输入年龄!')
|
||||||
|
return 1
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!formData.value.frontImage) {
|
||||||
|
Service.Msg('请输入身份证正面!')
|
||||||
|
return 1
|
||||||
|
}
|
||||||
|
if (!formData.value.backImage) {
|
||||||
|
Service.Msg('请输入身份证背面!')
|
||||||
|
return 1
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style scoped lang="scss">
|
||||||
|
page {
|
||||||
|
background-color: #f5f5f5;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 骨架屏样式 */
|
||||||
|
.skeleton-container {
|
||||||
|
padding: 0 20rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
.skeleton-top-tip {
|
||||||
|
width: 100%;
|
||||||
|
height: 80rpx;
|
||||||
|
background-color: #e6f7ff;
|
||||||
|
border-radius: 20rpx;
|
||||||
|
margin: 20rpx 0;
|
||||||
|
animation: skeleton-loading 1.5s infinite;
|
||||||
|
}
|
||||||
|
|
||||||
|
.skeleton-avatar-section {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
align-items: center;
|
||||||
|
margin-bottom: 30rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
.skeleton-avatar {
|
||||||
|
width: 140rpx;
|
||||||
|
height: 140rpx;
|
||||||
|
border-radius: 50%;
|
||||||
|
background-color: #e6e6e6;
|
||||||
|
margin-bottom: 20rpx;
|
||||||
|
animation: skeleton-loading 1.5s infinite;
|
||||||
|
}
|
||||||
|
|
||||||
|
.skeleton-avatar-text {
|
||||||
|
width: 200rpx;
|
||||||
|
height: 26rpx;
|
||||||
|
background-color: #e6e6e6;
|
||||||
|
border-radius: 8rpx;
|
||||||
|
animation: skeleton-loading 1.5s infinite;
|
||||||
|
}
|
||||||
|
|
||||||
|
.skeleton-form-content {
|
||||||
|
padding: 0 10rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
.skeleton-section {
|
||||||
|
margin-bottom: 40rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
.skeleton-section-title {
|
||||||
|
width: 150rpx;
|
||||||
|
height: 32rpx;
|
||||||
|
background-color: #e6e6e6;
|
||||||
|
border-radius: 8rpx;
|
||||||
|
margin-bottom: 20rpx;
|
||||||
|
padding-left: 10rpx;
|
||||||
|
animation: skeleton-loading 1.5s infinite;
|
||||||
|
}
|
||||||
|
|
||||||
|
.skeleton-form-item {
|
||||||
|
background-color: #fff;
|
||||||
|
padding: 30rpx;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
border-bottom: 1rpx solid #f0f0f0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.skeleton-form-item:last-child {
|
||||||
|
border-bottom: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
.skeleton-label {
|
||||||
|
width: 120rpx;
|
||||||
|
height: 28rpx;
|
||||||
|
background-color: #e6e6e6;
|
||||||
|
border-radius: 8rpx;
|
||||||
|
animation: skeleton-loading 1.5s infinite;
|
||||||
|
}
|
||||||
|
|
||||||
|
.skeleton-input {
|
||||||
|
flex: 1;
|
||||||
|
height: 28rpx;
|
||||||
|
background-color: #e6e6e6;
|
||||||
|
border-radius: 8rpx;
|
||||||
|
animation: skeleton-loading 1.5s infinite;
|
||||||
|
}
|
||||||
|
|
||||||
|
.skeleton-radio-group {
|
||||||
|
display: flex;
|
||||||
|
gap: 40rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
.skeleton-radio-item {
|
||||||
|
width: 120rpx;
|
||||||
|
height: 28rpx;
|
||||||
|
background-color: #e6e6e6;
|
||||||
|
border-radius: 8rpx;
|
||||||
|
animation: skeleton-loading 1.5s infinite;
|
||||||
|
}
|
||||||
|
|
||||||
|
.skeleton-upload-item {
|
||||||
|
margin-bottom: 20rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
.skeleton-upload-area {
|
||||||
|
width: 100%;
|
||||||
|
height: 250rpx;
|
||||||
|
background-color: #fff;
|
||||||
|
border-radius: 20rpx;
|
||||||
|
animation: skeleton-loading 1.5s infinite;
|
||||||
|
}
|
||||||
|
|
||||||
|
.skeleton-placeholder {
|
||||||
|
width: 100%;
|
||||||
|
height: 180rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
.skeleton-submit-section {
|
||||||
|
z-index: 1000;
|
||||||
|
width: 100%;
|
||||||
|
margin-top: 60rpx;
|
||||||
|
padding: 20rpx;
|
||||||
|
background-color: #fff;
|
||||||
|
position: fixed;
|
||||||
|
bottom: 0;
|
||||||
|
left: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.skeleton-submit-btn {
|
||||||
|
width: 100%;
|
||||||
|
height: 92rpx;
|
||||||
|
background-color: #e6e6e6;
|
||||||
|
border-radius: 46rpx;
|
||||||
|
animation: skeleton-loading 1.5s infinite;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 骨架屏动画 */
|
||||||
|
@keyframes skeleton-loading {
|
||||||
|
0% {
|
||||||
|
background-color: #e6e6e6;
|
||||||
|
}
|
||||||
|
50% {
|
||||||
|
background-color: #f0f0f0;
|
||||||
|
}
|
||||||
|
100% {
|
||||||
|
background-color: #e6e6e6;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.top-tip {
|
||||||
|
background-color: #E6F7FF;
|
||||||
|
padding: 20rpx 30rpx;
|
||||||
|
margin: 20rpx;
|
||||||
|
border-radius: 20rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
.tip-text {
|
||||||
|
color: #1890ff;
|
||||||
|
font-size: 28rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
.form-content {
|
||||||
|
padding: 0 30rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
.section {
|
||||||
|
margin-bottom: 40rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
.section-title {
|
||||||
|
font-size: 32rpx;
|
||||||
|
font-weight: bold;
|
||||||
|
color: #333;
|
||||||
|
margin-bottom: 20rpx;
|
||||||
|
padding-left: 10rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
.form-item {
|
||||||
|
background-color: #fff;
|
||||||
|
padding: 30rpx;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
border-bottom: 1rpx solid #f0f0f0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.form-item:last-child {
|
||||||
|
border-bottom: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
.label {
|
||||||
|
width: 120rpx;
|
||||||
|
font-size: 28rpx;
|
||||||
|
color: #333;
|
||||||
|
}
|
||||||
|
|
||||||
|
.input {
|
||||||
|
flex: 1;
|
||||||
|
font-size: 28rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
.upload-item {
|
||||||
|
margin-bottom: 20rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
.upload-area {
|
||||||
|
height: 250rpx;
|
||||||
|
overflow: hidden;
|
||||||
|
border-radius: 6rpx;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
justify-content: center;
|
||||||
|
align-items: center;
|
||||||
|
cursor: pointer;
|
||||||
|
position: relative;
|
||||||
|
}
|
||||||
|
|
||||||
|
.bordered-area {
|
||||||
|
background-color: #fff;
|
||||||
|
border-radius: 20rpx;
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.upload-content {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
justify-content: center;
|
||||||
|
align-items: center;
|
||||||
|
height: 100%;
|
||||||
|
z-index: 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
.upload-icon {
|
||||||
|
font-size: 60rpx;
|
||||||
|
color: #1890ff;
|
||||||
|
margin-bottom: 10rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
.upload-text {
|
||||||
|
font-size: 28rpx;
|
||||||
|
color: #1890ff;
|
||||||
|
}
|
||||||
|
|
||||||
|
.uploaded-placeholder {
|
||||||
|
position: absolute;
|
||||||
|
top: 0;
|
||||||
|
left: 0;
|
||||||
|
right: 0;
|
||||||
|
bottom: 0;
|
||||||
|
background-color: #fff;
|
||||||
|
display: flex;
|
||||||
|
justify-content: center;
|
||||||
|
align-items: center;
|
||||||
|
color: #333;
|
||||||
|
font-size: 28rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
.face-verify-area {
|
||||||
|
background-color: #fff;
|
||||||
|
height: 240rpx;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
justify-content: center;
|
||||||
|
align-items: center;
|
||||||
|
cursor: pointer;
|
||||||
|
border-radius: 8rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
.face-icon {
|
||||||
|
width: 120rpx;
|
||||||
|
height: 120rpx;
|
||||||
|
border-radius: 50%;
|
||||||
|
background-color: #e6f7ff;
|
||||||
|
display: flex;
|
||||||
|
justify-content: center;
|
||||||
|
align-items: center;
|
||||||
|
margin-bottom: 20rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
.face-text {
|
||||||
|
font-size: 28rpx;
|
||||||
|
color: #1890ff;
|
||||||
|
font-weight: 500;
|
||||||
|
}
|
||||||
|
|
||||||
|
.agreement-section {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
margin-bottom: 40rpx;
|
||||||
|
padding: 0 10rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
.checkbox {
|
||||||
|
margin-right: 10rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
.agreement-text {
|
||||||
|
font-size: 26rpx;
|
||||||
|
color: #666;
|
||||||
|
}
|
||||||
|
|
||||||
|
.agreement-link {
|
||||||
|
font-size: 26rpx;
|
||||||
|
color: #1890ff;
|
||||||
|
margin-left: 4rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
.input {
|
||||||
|
flex: 1;
|
||||||
|
font-size: 28rpx;
|
||||||
|
color: #333;
|
||||||
|
}
|
||||||
|
|
||||||
|
.submit-section {
|
||||||
|
z-index: 1000;
|
||||||
|
width: 100%;
|
||||||
|
margin-top: 60rpx;
|
||||||
|
padding: 20rpx;
|
||||||
|
background-color: #fff;
|
||||||
|
position: fixed;
|
||||||
|
bottom: 0;
|
||||||
|
left: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.submit-btn {
|
||||||
|
height: 92rpx;
|
||||||
|
font-size: 32rpx;
|
||||||
|
border-radius: 46rpx;
|
||||||
|
background-color: #1890ff;
|
||||||
|
}
|
||||||
|
|
||||||
|
.submit-btn[disabled] {
|
||||||
|
background-color: #a0cfff;
|
||||||
|
color: #ffffff;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
@@ -0,0 +1,770 @@
|
|||||||
|
<template>
|
||||||
|
|
||||||
|
<view v-if="isLoading" class="skeleton-container">
|
||||||
|
<!-- 统计数据区域骨架 -->
|
||||||
|
<view class="skeleton-stats-section">
|
||||||
|
<view class="skeleton-stat-item">
|
||||||
|
<view class="skeleton-stat-label"></view>
|
||||||
|
<view class="skeleton-stat-value"></view>
|
||||||
|
</view>
|
||||||
|
<view class="skeleton-stat-item">
|
||||||
|
<view class="skeleton-stat-label"></view>
|
||||||
|
<view class="skeleton-stat-value"></view>
|
||||||
|
</view>
|
||||||
|
<view class="skeleton-stat-item">
|
||||||
|
<view class="skeleton-stat-label"></view>
|
||||||
|
<view class="skeleton-stat-value"></view>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
|
||||||
|
<!-- 接单按钮骨架 -->
|
||||||
|
<view class="skeleton-action-section">
|
||||||
|
<view class="skeleton-accept-btn"></view>
|
||||||
|
</view>
|
||||||
|
|
||||||
|
<!-- 标签栏骨架 -->
|
||||||
|
<view class="skeleton-tab-bar">
|
||||||
|
<view class="skeleton-tab-item">
|
||||||
|
<view class="skeleton-tab-text"></view>
|
||||||
|
</view>
|
||||||
|
<view class="skeleton-tab-item">
|
||||||
|
<view class="skeleton-tab-text"></view>
|
||||||
|
</view>
|
||||||
|
<view class="skeleton-tab-item">
|
||||||
|
<view class="skeleton-tab-text"></view>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
|
||||||
|
<!-- 任务列表骨架 -->
|
||||||
|
<view class="skeleton-task-list">
|
||||||
|
<!-- 任务卡片骨架 -->
|
||||||
|
<view class="skeleton-task-section" v-for="i in 3" :key="i">
|
||||||
|
<!-- 高价单标签骨架 -->
|
||||||
|
<view class="skeleton-tag-row">
|
||||||
|
<view class="skeleton-high-price-tag"></view>
|
||||||
|
<view class="skeleton-phone-btn"></view>
|
||||||
|
</view>
|
||||||
|
|
||||||
|
<!-- 商家信息骨架 -->
|
||||||
|
<view class="skeleton-merchant-info">
|
||||||
|
<view class="skeleton-merchant-name"></view>
|
||||||
|
<view class="skeleton-distance"></view>
|
||||||
|
</view>
|
||||||
|
|
||||||
|
<!-- 地址信息骨架 -->
|
||||||
|
<view class="skeleton-address-info">
|
||||||
|
<view class="skeleton-address-text"></view>
|
||||||
|
</view>
|
||||||
|
|
||||||
|
<!-- 价格和取餐时间骨架 -->
|
||||||
|
<view class="skeleton-price-time-row">
|
||||||
|
<view class="skeleton-pickup-code"></view>
|
||||||
|
<view class="skeleton-pickup-time"></view>
|
||||||
|
</view>
|
||||||
|
|
||||||
|
<!-- 立即抢单按钮骨架 -->
|
||||||
|
<view class="skeleton-grab-btn"></view>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
|
||||||
|
<!-- 实际内容 -->
|
||||||
|
<view v-else class="rider-home">
|
||||||
|
<!-- 统计数据区域 -->
|
||||||
|
<view class="stats-section">
|
||||||
|
<view class="stat-item">
|
||||||
|
<text class="stat-label">今日收入</text>
|
||||||
|
<text class="stat-value income">¥{{userData.dayAmount.toFixed(2)}}</text>
|
||||||
|
</view>
|
||||||
|
<view class="stat-item">
|
||||||
|
<text class="stat-label">已完成</text>
|
||||||
|
<text class="stat-value completed">{{userData.dayOrderCount}}单</text>
|
||||||
|
</view>
|
||||||
|
<view class="stat-item">
|
||||||
|
<text class="stat-label">配送中</text>
|
||||||
|
<text class="stat-value ongoing">{{ userData.takeOrderCount }}单</text>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
|
||||||
|
<!-- 接单按钮 -->
|
||||||
|
<view class="action-section">
|
||||||
|
<up-button :disabled='riderInfo.status===0' type="primary" shape="circle" size="default"
|
||||||
|
class="accept-orders-btn"
|
||||||
|
@click="toggleAcceptOrders">{{ riderInfo.status==0?'审核中':(riderInfo.isOnline == 0 ? '已下线' : '已上线') }}</up-button>
|
||||||
|
</view>
|
||||||
|
|
||||||
|
<view class="tab-bar">
|
||||||
|
<view v-for="(tab, index) in tabs" :key="index" class="tab-item" :class="{ active: activeTab === index }"
|
||||||
|
@click="switchTab(index)">
|
||||||
|
<text class="tab-text">{{ tab }}</text>
|
||||||
|
<view v-if="activeTab === index" class="active-line"></view>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
|
||||||
|
<view v-if="riderInfo.status===1" class="" style="padding: 0 30rpx;">
|
||||||
|
<view @click="gopage(orderItem.orderId)" v-for="(orderItem,orderIndex) in orderList " :key="orderIndex"
|
||||||
|
class="task-section">
|
||||||
|
<!-- 高价单标签 -->
|
||||||
|
<view class="" style="display: flex; align-items: center; justify-content: space-between;">
|
||||||
|
|
||||||
|
<view class="high-price-tag"
|
||||||
|
:style="{'border':activeTab==0?'1rpx solid #FF7875':(activeTab==1?'1rpx solid #52C41A':'1rpx solid #FAAD14'),'color':activeTab==0?'#FF7875':(activeTab==1?'#52C41A':'#FAAD14') }"
|
||||||
|
style="background-color: #fff;">
|
||||||
|
<text class="high-price-text">{{activeTab==0? '新订单':(activeTab==1? '待取单':'配送中')}}</text>
|
||||||
|
</view>
|
||||||
|
<view class="" @click.stop="call(orderItem.phone)" style="display: flex; align-items: baseline;">
|
||||||
|
<up-icon name="phone" color="var(--nav-mian)" size="20"></up-icon>
|
||||||
|
<text style="margin-left: 10rpx; color: var(--nav-mian); ">拨打商家</text>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
|
||||||
|
<!-- 商家信息 -->
|
||||||
|
<view class="merchant-info">
|
||||||
|
<text class="merchant-name">{{ orderItem.storeName }}</text>
|
||||||
|
<text v-if="activeTab==1" class="distance">{{ distance(orderItem.distance) }}</text>
|
||||||
|
</view>
|
||||||
|
|
||||||
|
<!-- 地址信息 -->
|
||||||
|
<view class="address-info">
|
||||||
|
<up-icon name="map" color="#999" size="24rpx" />
|
||||||
|
<text class="address-text"> {{orderItem.address }}</text>
|
||||||
|
<!-- <text v-if="activeTab!==0" class="address-text">共3件商品</text> -->
|
||||||
|
</view>
|
||||||
|
<!-- 商品次数-->
|
||||||
|
<!-- <view class="address-info">
|
||||||
|
<text class="address-text">共3件商品</text>
|
||||||
|
<view class="">
|
||||||
|
<text class="price">¥5.50</text>
|
||||||
|
<text style="color: var(--nav-mian); font-weight: 600; margin-left: 10rpx; ">/单</text>
|
||||||
|
</view>
|
||||||
|
</view> -->
|
||||||
|
|
||||||
|
<!-- 价格和取餐时间 -->
|
||||||
|
<view class="price-time-row">
|
||||||
|
<view v-if="activeTab==1" class="">
|
||||||
|
<text style="font-size: 30rpx; font-weight: 600; color: #1890FF; ">取件码: </text>
|
||||||
|
<text style="color: var(--nav-mian); font-weight: 600; margin-left: 10rpx; ">A121</text>
|
||||||
|
</view>
|
||||||
|
<view v-if="activeTab!==1" class="">
|
||||||
|
<text class="address-text">据您{{ distance(orderItem.distance) }}</text>
|
||||||
|
</view>
|
||||||
|
<view class="pickup-time">
|
||||||
|
<up-icon name="clock" :color="activeTab==0?'#FAAD14':'#FF0000'" size="16" />
|
||||||
|
<text class="time-text"
|
||||||
|
:style="{'color':activeTab==0?'#FAAD14':'#FF0000'}">{{ orderItem.makeTime.split(' ').length==2?'预计'+orderItem.makeTime.split(' ')[1]+'送达':orderItem.makeTime }}</text>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
|
||||||
|
<!-- 立即抢单按钮 -->
|
||||||
|
<up-button type="primary"
|
||||||
|
@click="activeTab==0?takeOrder(orderItem.orderId):pickFood(orderItem.orderId)"
|
||||||
|
:color="activeTab==0?'#1890FF':'#52C41A'" size="large"
|
||||||
|
class="grab-btn">{{ activeTab==0?'立即接单':(activeTab==1?'我已取餐':'确认送达')}}</up-button>
|
||||||
|
</view>
|
||||||
|
<up-loadmore :status="status" />
|
||||||
|
</view>
|
||||||
|
|
||||||
|
|
||||||
|
<view v-else class="" style="font-weight: bold; text-align: center; font-size: 32rpx; margin-top: 100rpx; ">
|
||||||
|
信息审核中·暂时无法接单
|
||||||
|
</view>
|
||||||
|
|
||||||
|
|
||||||
|
<view class="" style="width: 100%; height: 60rpx; ">
|
||||||
|
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script setup lang="ts">
|
||||||
|
import { onLoad, onShow } from '@dcloudio/uni-app';
|
||||||
|
import { ref, onMounted } from 'vue';
|
||||||
|
import { Service } from '@/Service/Service';
|
||||||
|
import { CNRiderDataService } from '@/Service/CN/CNRiderDataService'
|
||||||
|
import { CNRiderOrderService } from '@/Service/CN/CNRiderOrderService'
|
||||||
|
|
||||||
|
// 加载状态
|
||||||
|
const isLoading = ref(true);
|
||||||
|
let status = ref('nomore')
|
||||||
|
let page = ref(1)
|
||||||
|
|
||||||
|
let userData = ref({
|
||||||
|
dayAmount: 0,
|
||||||
|
dayOrderCount: 0,
|
||||||
|
takeOrderCount: 0
|
||||||
|
})
|
||||||
|
|
||||||
|
const tabs = ['新订单', '待取货', '配送中']
|
||||||
|
const activeTab = ref(0)
|
||||||
|
let riderInfo = ref<any>({})
|
||||||
|
|
||||||
|
let orderList = ref<Array<any>>([])
|
||||||
|
|
||||||
|
|
||||||
|
onLoad(() => {
|
||||||
|
getData()
|
||||||
|
|
||||||
|
})
|
||||||
|
|
||||||
|
|
||||||
|
onShow(() => {
|
||||||
|
getOrderData()
|
||||||
|
})
|
||||||
|
|
||||||
|
const getData = () => {
|
||||||
|
CNRiderDataService.GetRiderHomeInfo().then(res => {
|
||||||
|
isLoading.value = false
|
||||||
|
riderInfo.value = res.data.riderInfo
|
||||||
|
userData.value=res.data
|
||||||
|
if (res.data.riderInfo.status === -1) {
|
||||||
|
Service.GoPage('/pages/my/completeData')
|
||||||
|
}
|
||||||
|
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
const getOrderData = () => {
|
||||||
|
status.value = 'loadmore'
|
||||||
|
page.value = 1
|
||||||
|
orderList.value = []
|
||||||
|
getOrderList()
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//获取订单
|
||||||
|
const getOrderList = () => {
|
||||||
|
if (status.value == 'nomore' || status.value == 'loading') {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
status.value == 'loadmore'
|
||||||
|
|
||||||
|
if (activeTab.value == 0) {
|
||||||
|
CNRiderOrderService.GetRiderOrderList(page.value).then(res => {
|
||||||
|
orderList.value = [...orderList.value, ...res.data.list]
|
||||||
|
status.value = res.data.list == 10 ? 'loadmore' : 'nomore'
|
||||||
|
page.value++
|
||||||
|
})
|
||||||
|
} else {
|
||||||
|
CNRiderOrderService.GetRiderTakeOrderList(activeTab.value == 1 ? 0 : 1, page.value).then(res => {
|
||||||
|
orderList.value = [...orderList.value, ...res.data.list]
|
||||||
|
status.value = res.data.list == 10 ? 'loadmore' : 'nomore'
|
||||||
|
page.value++
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 接单
|
||||||
|
const takeOrder = (orderId : string) => {
|
||||||
|
CNRiderOrderService.RiderTakeOrder(orderId).then(res => {
|
||||||
|
if (res.data) {
|
||||||
|
getOrderData()
|
||||||
|
getData()
|
||||||
|
} else {
|
||||||
|
Service.Msg(res.msg)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
// 取餐
|
||||||
|
const pickFood = (orderId : string) => {
|
||||||
|
CNRiderOrderService.UpdateRiderOrderTake(orderId,activeTab.value).then(res=>{
|
||||||
|
if (res.data) {
|
||||||
|
getOrderData()
|
||||||
|
getData()
|
||||||
|
} else {
|
||||||
|
Service.Msg(res.msg)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// 切换标签
|
||||||
|
const switchTab = (index : number) => {
|
||||||
|
activeTab.value = index
|
||||||
|
getOrderData()
|
||||||
|
}
|
||||||
|
|
||||||
|
// 切换接单状态
|
||||||
|
const toggleAcceptOrders = () => {
|
||||||
|
CNRiderDataService.UpdateRiderOnline().then(res => {
|
||||||
|
if (res.data) {
|
||||||
|
getData()
|
||||||
|
} else {
|
||||||
|
Service.Msg(res.msg)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
// 距离计算
|
||||||
|
const distance = (item : any) => {
|
||||||
|
if (item < 0) {
|
||||||
|
return Number(item * 100).toFixed(2) + 'm'
|
||||||
|
} else {
|
||||||
|
return Number(item).toFixed(2) + 'km'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 拨打电话
|
||||||
|
const call = (e : string) => {
|
||||||
|
uni.makePhoneCall({
|
||||||
|
phoneNumber: e
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// 页面跳转
|
||||||
|
const gopage = (id) => {
|
||||||
|
if (activeTab.value == 0) {
|
||||||
|
Service.GoPage('/pages/order/grabOrder?orderId=' + id)
|
||||||
|
} else {
|
||||||
|
Service.GoPage('/pages/order/orderDetail?orderId=' + id)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style scoped lang="scss">
|
||||||
|
page {
|
||||||
|
background-color: #F6f6f6;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* 统计数据区域 */
|
||||||
|
.stats-section {
|
||||||
|
background-color: #ffffff;
|
||||||
|
margin: 20rpx;
|
||||||
|
border-radius: 16rpx;
|
||||||
|
display: flex;
|
||||||
|
justify-content: space-around;
|
||||||
|
padding: 30rpx 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.stat-item {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
align-items: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.stat-label {
|
||||||
|
font-size: 28rpx;
|
||||||
|
color: #666666;
|
||||||
|
margin-bottom: 10rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
.stat-value {
|
||||||
|
font-size: 36rpx;
|
||||||
|
font-weight: 600;
|
||||||
|
}
|
||||||
|
|
||||||
|
.income {
|
||||||
|
color: var(--nav-diluted);
|
||||||
|
}
|
||||||
|
|
||||||
|
.completed {
|
||||||
|
color: var(--nav-vice);
|
||||||
|
}
|
||||||
|
|
||||||
|
.ongoing {
|
||||||
|
color: #FF9500;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 接单按钮 */
|
||||||
|
.action-section {
|
||||||
|
margin: 0 20rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
.accept-orders-btn {
|
||||||
|
width: 100%;
|
||||||
|
height: 90rpx;
|
||||||
|
font-size: 32rpx;
|
||||||
|
background-color: #52C41A;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* 顶部标签栏 */
|
||||||
|
.tab-bar {
|
||||||
|
margin-top: 20rpx;
|
||||||
|
display: flex;
|
||||||
|
background-color: #FFFFFF;
|
||||||
|
padding: 20rpx 0 0;
|
||||||
|
border-bottom: 1rpx solid #E5E5E5;
|
||||||
|
width: 100vw;
|
||||||
|
background-color: #fff;
|
||||||
|
}
|
||||||
|
|
||||||
|
.tab-item {
|
||||||
|
flex: 1;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
align-items: center;
|
||||||
|
padding: 20rpx 0;
|
||||||
|
position: relative;
|
||||||
|
}
|
||||||
|
|
||||||
|
.tab-text {
|
||||||
|
font-size: 28rpx;
|
||||||
|
color: #666666;
|
||||||
|
}
|
||||||
|
|
||||||
|
.tab-item.active .tab-text {
|
||||||
|
color: var(--nav-mian);
|
||||||
|
font-weight: 600;
|
||||||
|
}
|
||||||
|
|
||||||
|
.active-line {
|
||||||
|
position: absolute;
|
||||||
|
bottom: 0;
|
||||||
|
width: 110rpx;
|
||||||
|
height: 6rpx;
|
||||||
|
background-color: var(--nav-mian);
|
||||||
|
border-radius: 3rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
.task-section {
|
||||||
|
margin-top: 20rpx;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
background-color: #fff;
|
||||||
|
border-radius: 20rpx;
|
||||||
|
padding: 20rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* 标签样式 */
|
||||||
|
.high-price-tag {
|
||||||
|
width: fit-content;
|
||||||
|
background-color: #FF7875;
|
||||||
|
color: #FFFFFF;
|
||||||
|
padding: 5rpx 20rpx;
|
||||||
|
border-radius: 20rpx;
|
||||||
|
font-size: 24rpx;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.status-tag {
|
||||||
|
position: absolute;
|
||||||
|
top: 20rpx;
|
||||||
|
left: 20rpx;
|
||||||
|
padding: 5rpx 20rpx;
|
||||||
|
border-radius: 20rpx;
|
||||||
|
font-size: 24rpx;
|
||||||
|
z-index: 10;
|
||||||
|
}
|
||||||
|
|
||||||
|
.status-tag.pending {
|
||||||
|
background-color: #4CD964;
|
||||||
|
color: #FFFFFF;
|
||||||
|
}
|
||||||
|
|
||||||
|
.status-tag.delivering {
|
||||||
|
background-color: #FF9500;
|
||||||
|
color: #FFFFFF;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 右侧操作按钮 */
|
||||||
|
.right-action {
|
||||||
|
position: absolute;
|
||||||
|
top: 20rpx;
|
||||||
|
right: 20rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
.call-btn {
|
||||||
|
padding: 5rpx 15rpx;
|
||||||
|
font-size: 24rpx;
|
||||||
|
line-height: 36rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 信息展示 */
|
||||||
|
.merchant-info {
|
||||||
|
margin-top: 20rpx;
|
||||||
|
display: flex;
|
||||||
|
justify-content: space-between;
|
||||||
|
align-items: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.merchant-name {
|
||||||
|
font-size: 34rpx;
|
||||||
|
font-weight: 600;
|
||||||
|
color: #333333;
|
||||||
|
}
|
||||||
|
|
||||||
|
.distance {
|
||||||
|
font-size: 28rpx;
|
||||||
|
color: #666666;
|
||||||
|
}
|
||||||
|
|
||||||
|
.address-info {
|
||||||
|
display: flex;
|
||||||
|
align-items: baseline;
|
||||||
|
margin-top: 15rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
.address-text {
|
||||||
|
margin-left: 10rpx;
|
||||||
|
font-size: 28rpx;
|
||||||
|
color: #666666;
|
||||||
|
flex: 1;
|
||||||
|
overflow: hidden;
|
||||||
|
text-overflow: ellipsis;
|
||||||
|
white-space: nowrap;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 价格和时间 */
|
||||||
|
.price-time-row {
|
||||||
|
margin-top: 20rpx;
|
||||||
|
display: flex;
|
||||||
|
justify-content: space-between;
|
||||||
|
align-items: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.price {
|
||||||
|
font-size: 36rpx;
|
||||||
|
font-weight: 600;
|
||||||
|
color: #FF3B30;
|
||||||
|
}
|
||||||
|
|
||||||
|
.pickup-code {
|
||||||
|
font-size: 28rpx;
|
||||||
|
color: #333333;
|
||||||
|
font-weight: 500;
|
||||||
|
}
|
||||||
|
|
||||||
|
.pickup-time {
|
||||||
|
display: flex;
|
||||||
|
align-items: baseline;
|
||||||
|
}
|
||||||
|
|
||||||
|
.time-text {
|
||||||
|
margin-left: 8rpx;
|
||||||
|
font-size: 26rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 按钮样式 */
|
||||||
|
.grab-btn {
|
||||||
|
margin-top: 25rpx;
|
||||||
|
height: 80rpx;
|
||||||
|
line-height: 80rpx;
|
||||||
|
border-radius: 40rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
.grab-btn {
|
||||||
|
background-color: #007AFF;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/* uview组件样式覆盖 */
|
||||||
|
::v-deep .u-button--primary {
|
||||||
|
background-color: var(--nav-vice);
|
||||||
|
border-color: var(--nav-vice);
|
||||||
|
}
|
||||||
|
|
||||||
|
::v-deep .u-button--mini {
|
||||||
|
background-color: var(--nav-mian);
|
||||||
|
border-color: var(--nav-mian);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* 骨架屏样式 */
|
||||||
|
.skeleton-container {
|
||||||
|
padding: 20rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 统计数据区域骨架 */
|
||||||
|
.skeleton-stats-section {
|
||||||
|
background-color: #ffffff;
|
||||||
|
margin: 0 20rpx;
|
||||||
|
border-radius: 16rpx;
|
||||||
|
display: flex;
|
||||||
|
justify-content: space-around;
|
||||||
|
padding: 30rpx 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.skeleton-stat-item {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
align-items: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.skeleton-stat-label {
|
||||||
|
width: 120rpx;
|
||||||
|
height: 28rpx;
|
||||||
|
background-color: #e6e6e6;
|
||||||
|
border-radius: 8rpx;
|
||||||
|
margin-bottom: 10rpx;
|
||||||
|
animation: skeleton-loading 1.5s infinite;
|
||||||
|
}
|
||||||
|
|
||||||
|
.skeleton-stat-value {
|
||||||
|
width: 150rpx;
|
||||||
|
height: 36rpx;
|
||||||
|
background-color: #e6e6e6;
|
||||||
|
border-radius: 8rpx;
|
||||||
|
animation: skeleton-loading 1.5s infinite;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 接单按钮骨架 */
|
||||||
|
.skeleton-action-section {
|
||||||
|
margin: 20rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
.skeleton-accept-btn {
|
||||||
|
width: 100%;
|
||||||
|
height: 90rpx;
|
||||||
|
background-color: #e6e6e6;
|
||||||
|
border-radius: 8rpx;
|
||||||
|
animation: skeleton-loading 1.5s infinite;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 标签栏骨架 */
|
||||||
|
.skeleton-tab-bar {
|
||||||
|
display: flex;
|
||||||
|
background-color: #ffffff;
|
||||||
|
padding: 20rpx 0 0;
|
||||||
|
border-bottom: 1rpx solid #e5e5e5;
|
||||||
|
}
|
||||||
|
|
||||||
|
.skeleton-tab-item {
|
||||||
|
flex: 1;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
align-items: center;
|
||||||
|
padding: 20rpx 0;
|
||||||
|
position: relative;
|
||||||
|
}
|
||||||
|
|
||||||
|
.skeleton-tab-text {
|
||||||
|
width: 100rpx;
|
||||||
|
height: 28rpx;
|
||||||
|
background-color: #e6e6e6;
|
||||||
|
border-radius: 8rpx;
|
||||||
|
animation: skeleton-loading 1.5s infinite;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 任务列表骨架 */
|
||||||
|
.skeleton-task-list {
|
||||||
|
padding: 0 20rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
.skeleton-task-section {
|
||||||
|
margin-top: 20rpx;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
background-color: #fff;
|
||||||
|
border-radius: 20rpx;
|
||||||
|
padding: 20rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 标签骨架 */
|
||||||
|
.skeleton-tag-row {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: space-between;
|
||||||
|
}
|
||||||
|
|
||||||
|
.skeleton-high-price-tag {
|
||||||
|
width: 120rpx;
|
||||||
|
height: 30rpx;
|
||||||
|
background-color: #e6e6e6;
|
||||||
|
border-radius: 20rpx;
|
||||||
|
animation: skeleton-loading 1.5s infinite;
|
||||||
|
}
|
||||||
|
|
||||||
|
.skeleton-phone-btn {
|
||||||
|
width: 150rpx;
|
||||||
|
height: 30rpx;
|
||||||
|
background-color: #e6e6e6;
|
||||||
|
border-radius: 8rpx;
|
||||||
|
animation: skeleton-loading 1.5s infinite;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 商家信息骨架 */
|
||||||
|
.skeleton-merchant-info {
|
||||||
|
margin-top: 20rpx;
|
||||||
|
display: flex;
|
||||||
|
justify-content: space-between;
|
||||||
|
align-items: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.skeleton-merchant-name {
|
||||||
|
width: 200rpx;
|
||||||
|
height: 34rpx;
|
||||||
|
background-color: #e6e6e6;
|
||||||
|
border-radius: 8rpx;
|
||||||
|
animation: skeleton-loading 1.5s infinite;
|
||||||
|
}
|
||||||
|
|
||||||
|
.skeleton-distance {
|
||||||
|
width: 80rpx;
|
||||||
|
height: 28rpx;
|
||||||
|
background-color: #e6e6e6;
|
||||||
|
border-radius: 8rpx;
|
||||||
|
animation: skeleton-loading 1.5s infinite;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 地址信息骨架 */
|
||||||
|
.skeleton-address-info {
|
||||||
|
display: flex;
|
||||||
|
align-items: baseline;
|
||||||
|
margin-top: 15rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
.skeleton-address-text {
|
||||||
|
width: 100%;
|
||||||
|
height: 28rpx;
|
||||||
|
background-color: #e6e6e6;
|
||||||
|
border-radius: 8rpx;
|
||||||
|
animation: skeleton-loading 1.5s infinite;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 价格和时间骨架 */
|
||||||
|
.skeleton-price-time-row {
|
||||||
|
margin-top: 20rpx;
|
||||||
|
display: flex;
|
||||||
|
justify-content: space-between;
|
||||||
|
align-items: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.skeleton-pickup-code {
|
||||||
|
width: 150rpx;
|
||||||
|
height: 30rpx;
|
||||||
|
background-color: #e6e6e6;
|
||||||
|
border-radius: 8rpx;
|
||||||
|
animation: skeleton-loading 1.5s infinite;
|
||||||
|
}
|
||||||
|
|
||||||
|
.skeleton-pickup-time {
|
||||||
|
width: 200rpx;
|
||||||
|
height: 30rpx;
|
||||||
|
background-color: #e6e6e6;
|
||||||
|
border-radius: 8rpx;
|
||||||
|
animation: skeleton-loading 1.5s infinite;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 按钮骨架 */
|
||||||
|
.skeleton-grab-btn {
|
||||||
|
margin-top: 25rpx;
|
||||||
|
height: 80rpx;
|
||||||
|
background-color: #e6e6e6;
|
||||||
|
border-radius: 40rpx;
|
||||||
|
animation: skeleton-loading 1.5s infinite;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 骨架屏动画 */
|
||||||
|
@keyframes skeleton-loading {
|
||||||
|
0% {
|
||||||
|
background-color: #e6e6e6;
|
||||||
|
}
|
||||||
|
|
||||||
|
50% {
|
||||||
|
background-color: #f0f0f0;
|
||||||
|
}
|
||||||
|
|
||||||
|
100% {
|
||||||
|
background-color: #e6e6e6;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
After Width: | Height: | Size: 690 B |
@@ -0,0 +1,46 @@
|
|||||||
|
import { Service } from '@/Service/Service';
|
||||||
|
/*****连接*****/
|
||||||
|
class ImConnectService {
|
||||||
|
private static GetConnectPath: string = '/Im/GetConnect';
|
||||||
|
/*****获取连接*****/
|
||||||
|
static GetConnect() {
|
||||||
|
var result = Service.Request(this.GetConnectPath, 'POST', {type:3});
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static IsOnlinePath: string = '/Im/IsOnline';
|
||||||
|
/*****判断是否在线*****/
|
||||||
|
static IsOnline(id:number) {
|
||||||
|
var result = Service.Request(this.IsOnlinePath, 'POST', id);
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static JoinChatPath: string = '/Im/JoinChat';
|
||||||
|
/*****加入聊天室*****/
|
||||||
|
static JoinChat(id: number,chan:number) {
|
||||||
|
var result = Service.Request(this.JoinChatPath, 'POST', { id,chan });
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static SendChanMsgPath: string = '/Im/SendChanMsg';
|
||||||
|
/*****发送聊天室消息*****/
|
||||||
|
static SendChanMsg(id: number, user: string, chan: string, type: string,msg:string,media:string) {
|
||||||
|
var result = Service.Request(this.SendChanMsgPath, 'POST', { id, user, chan, type , msg , media });
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static ExitChatPath: string = '/Im/ExitChat';
|
||||||
|
/*****离开聊天室*****/
|
||||||
|
static ExitChat(id:number, chan: string) {
|
||||||
|
var result = Service.Request(this.ExitChatPath, 'POST', {id, chan });
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static GetOrderMessagePath: string = '/Order/GetOrderMessage';
|
||||||
|
/*****聊天记录*****/
|
||||||
|
static GetOrderMessage(orderId:string) {
|
||||||
|
var result = Service.Request(this.GetOrderMessagePath, 'GET', {orderId });
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
export { Service, ImConnectService };
|
||||||
@@ -0,0 +1,186 @@
|
|||||||
|
<template>
|
||||||
|
<view style=" padding: 20rpx 40rpx; background-color: #fff; ">
|
||||||
|
<up-form v-if="type!=='1'" labelPosition="left" labelWidth='90' :model="userData" ref="form1">
|
||||||
|
<up-form-item label="姓名:" prop="userInfo.name" :borderBottom="true" ref="item1">
|
||||||
|
<up-input inputAlign='right' v-model="userData.name" clearable='true' placeholder="请输入联系人姓名"
|
||||||
|
border="none"></up-input>
|
||||||
|
</up-form-item>
|
||||||
|
<up-form-item label="手机号:" prop="userInfo.name" :borderBottom="true" ref="item1">
|
||||||
|
<up-input inputAlign='right' v-model="userData.phone" clearable='true' placeholder="请输入手机号"
|
||||||
|
border="none"></up-input>
|
||||||
|
</up-form-item>
|
||||||
|
</up-form>
|
||||||
|
<up-form v-else labelPosition="left" labelWidth='90' :model="password" ref="form1">
|
||||||
|
|
||||||
|
<up-form-item label="手机号:" prop="userInfo.name" :borderBottom="true" ref="item1">
|
||||||
|
<up-input clearable='true' v-model="password.phone" placeholder="请输入手机号" border="none"></up-input>
|
||||||
|
</up-form-item>
|
||||||
|
<up-form-item label="验证码:" prop="userInfo.name" :borderBottom="true" ref="item1">
|
||||||
|
<up-input clearable='true' v-model="password.code" placeholder="请输入验证码" border="none">
|
||||||
|
<template #suffix>
|
||||||
|
<up-code :seconds="seconds" @end="end" @start="start" ref="uCodeRef"
|
||||||
|
@change="codeChange"></up-code>
|
||||||
|
<up-button @tap="getCode">{{tips}}</up-button>
|
||||||
|
</template>
|
||||||
|
</up-input>
|
||||||
|
</up-form-item>
|
||||||
|
</up-form>
|
||||||
|
</view>
|
||||||
|
<view class="" style=" position: fixed; bottom: 0; left: 0; width: 100%; padding: 20rpx; ">
|
||||||
|
<button @click="save()" class="logout-btn">确认修改</button>
|
||||||
|
</view>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script setup lang="ts">
|
||||||
|
import { onShow, onLoad } from "@dcloudio/uni-app";
|
||||||
|
import { ref } from "vue";
|
||||||
|
import { Service } from "../../Service/Service";
|
||||||
|
import { CNRiderDataService } from '@/Service/CN/CNRiderDataService'
|
||||||
|
import { CNRiderLoginService } from '@/Service/CN/CNRiderLoginService'
|
||||||
|
|
||||||
|
const tips = ref('');
|
||||||
|
const seconds = ref(60);
|
||||||
|
const uCodeRef = ref(null);
|
||||||
|
|
||||||
|
let password = ref({
|
||||||
|
phone: '',
|
||||||
|
code: ''
|
||||||
|
})
|
||||||
|
|
||||||
|
let userData = ref({
|
||||||
|
name: '',
|
||||||
|
phone: ''
|
||||||
|
})
|
||||||
|
|
||||||
|
let type = ref('')
|
||||||
|
onLoad((data : any) => {
|
||||||
|
if (data.type === '1') {
|
||||||
|
uni.setNavigationBarTitle({
|
||||||
|
title: '修改手机号'
|
||||||
|
})
|
||||||
|
}
|
||||||
|
type.value = data.type
|
||||||
|
console.log(type.value);
|
||||||
|
getData()
|
||||||
|
});
|
||||||
|
|
||||||
|
onShow(() => {
|
||||||
|
|
||||||
|
});
|
||||||
|
|
||||||
|
const getData = () => {
|
||||||
|
CNRiderDataService.GetRiderExigency().then(res => {
|
||||||
|
if (res.code == 0) {
|
||||||
|
if (res.data.info) {
|
||||||
|
userData.value = res.data.info
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
const save = () => {
|
||||||
|
if (type.value === '0') {
|
||||||
|
if (!userData.value.name) {
|
||||||
|
Service.Msg('请输入联系人姓名!')
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if (!userData.value.phone) {
|
||||||
|
Service.Msg('请输入联系人手机号!')
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if (userData.value.phone.split('').length !== 11) {
|
||||||
|
Service.Msg('请输入正确手机号!')
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
CNRiderDataService.AddRiderExigency(userData.value.name, userData.value.phone).then(res => {
|
||||||
|
if (res.data) {
|
||||||
|
Service.Msg('添加成功!')
|
||||||
|
setTimeout(() => {
|
||||||
|
Service.GoPageBack()
|
||||||
|
}, 1000)
|
||||||
|
} else {
|
||||||
|
Service.Msg(res.msg)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
} else {
|
||||||
|
if (!password.value.phone) {
|
||||||
|
Service.Msg('请输入手机号!')
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if (password.value.phone.split('').length !== 11) {
|
||||||
|
Service.Msg('请输入正确手机号!')
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if (!password.value.code) {
|
||||||
|
Service.Msg('请输入验证码!')
|
||||||
|
return
|
||||||
|
}
|
||||||
|
CNRiderLoginService.UpdateRiderPhone(password.value.phone, password.value.code).then(res => {
|
||||||
|
if (res.data) {
|
||||||
|
Service.Msg('修改成功!')
|
||||||
|
setTimeout(() => {
|
||||||
|
Service.GoPageBack()
|
||||||
|
}, 1000)
|
||||||
|
} else {
|
||||||
|
Service.Msg(res.msg)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
const codeChange = (text) => {
|
||||||
|
tips.value = text;
|
||||||
|
};
|
||||||
|
|
||||||
|
const getCode = () => {
|
||||||
|
|
||||||
|
if (uCodeRef.value.canGetCode) {
|
||||||
|
// 模拟向后端请求验证码
|
||||||
|
uni.showLoading({
|
||||||
|
title: '正在获取验证码',
|
||||||
|
});
|
||||||
|
CNRiderLoginService.SendUserSms(password.value.phone, 'RiderUpPhone').then(res => {
|
||||||
|
if (res.code == 0) {
|
||||||
|
uni.hideLoading();
|
||||||
|
// 这里此提示会被start()方法中的提示覆盖
|
||||||
|
Service.Msg('验证码已发送')
|
||||||
|
uCodeRef.value.start();
|
||||||
|
}
|
||||||
|
})
|
||||||
|
} else {
|
||||||
|
Service.Msg('倒计时结束后再发送')
|
||||||
|
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
const end = () => {
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
const start = () => {
|
||||||
|
|
||||||
|
};
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style lang="scss">
|
||||||
|
page {
|
||||||
|
background-color: #fff;
|
||||||
|
}
|
||||||
|
|
||||||
|
.logout-btn {
|
||||||
|
background-color: var(--nav-mian);
|
||||||
|
color: #fff;
|
||||||
|
font-weight: 500;
|
||||||
|
border-radius: 60rpx;
|
||||||
|
height: 90rpx;
|
||||||
|
line-height: 90rpx;
|
||||||
|
font-size: 30rpx;
|
||||||
|
margin: 0;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
@@ -0,0 +1,123 @@
|
|||||||
|
<template>
|
||||||
|
<view class="">
|
||||||
|
<web-view ref="webviewRef" v-if="isshow" :src="url" @message="handleMessage" @logData = "logData"></web-view>
|
||||||
|
|
||||||
|
<!-- ✅ 新增:一个绝对定位的遮罩层,用于在刷新时覆盖 web-view -->
|
||||||
|
<view v-else class="reloading-mask">
|
||||||
|
<up-loading-icon text="正在获取订单状态..." v-if="orderOver" textSize="16"></up-loading-icon>
|
||||||
|
|
||||||
|
<up-loading-icon text="订单已完成" v-else textSize="16"></up-loading-icon>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script setup lang="ts">
|
||||||
|
import { onLoad } from '@dcloudio/uni-app';
|
||||||
|
import { Service } from "@/Service/Service";
|
||||||
|
import { ref, onMounted } from 'vue';
|
||||||
|
import { CNRiderOrderService } from '@/Service/CN/CNRiderOrderService'
|
||||||
|
|
||||||
|
let orderId = ref<string>('')
|
||||||
|
let url = ref<string>('')
|
||||||
|
let isshow = ref<false>(false)
|
||||||
|
|
||||||
|
let orderInfo = ref<any>({
|
||||||
|
isFood: 0
|
||||||
|
})
|
||||||
|
|
||||||
|
let riderOrder = ref<any>({
|
||||||
|
status:0
|
||||||
|
})
|
||||||
|
|
||||||
|
let orderOver = ref<true>(false)
|
||||||
|
|
||||||
|
onLoad((data) => {
|
||||||
|
if (data.orderId) {
|
||||||
|
orderId.value = data.orderId
|
||||||
|
getData()
|
||||||
|
} else {
|
||||||
|
Service.Msg('为获取到订单ID')
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
// 初始化url
|
||||||
|
const getUrl = () => {
|
||||||
|
isshow.value = false
|
||||||
|
url.value = 'https://hmjz.327gzs.top?orderId=' + orderId.value + '&isFood=' + riderOrder.value.status
|
||||||
|
isshow.value = true
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
const getData = () => {
|
||||||
|
CNRiderOrderService.GetUnitOrderInfo(orderId.value).then(res => {
|
||||||
|
if (res.code==0) {
|
||||||
|
orderInfo.value = res.data.orderInfo
|
||||||
|
riderOrder.value = res.data.riderOrder
|
||||||
|
getUrl()
|
||||||
|
|
||||||
|
}else{
|
||||||
|
Service.Msg(res.mgs)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
// 点击完成送餐取餐调用
|
||||||
|
const handleMessage = (data) => {
|
||||||
|
|
||||||
|
let preat = data.detail.data[0]
|
||||||
|
if(preat.action =='message'){
|
||||||
|
if (riderOrder.value.status == 0) {
|
||||||
|
// 去商家、取餐
|
||||||
|
pickFood(1)
|
||||||
|
} else {
|
||||||
|
// 去用户,送餐
|
||||||
|
pickFood(2)
|
||||||
|
}
|
||||||
|
}else if(preat.action =='logData'){
|
||||||
|
CNRiderOrderService.UpdateRiderLocation(preat.data[0],preat.data[1]).then(res=>{
|
||||||
|
if(res.code==0){
|
||||||
|
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
return
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
// 骑手定位
|
||||||
|
const logData = (data) =>{
|
||||||
|
console.log(data,'骑手定位')
|
||||||
|
}
|
||||||
|
|
||||||
|
// 取餐
|
||||||
|
const pickFood = ( type:number) => {
|
||||||
|
CNRiderOrderService.UpdateRiderOrderTake(orderId.value, type).then(res => {
|
||||||
|
if (res.data) {
|
||||||
|
Service.Msg(type==1?'取餐成功':'订单完成')
|
||||||
|
setTimeout(()=>{Service.GoPageTab('/pages/index/index')},500)
|
||||||
|
getData()
|
||||||
|
} else {
|
||||||
|
Service.Msg(res.msg)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
};
|
||||||
|
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style lang="scss" scoped>
|
||||||
|
.reloading-mask {
|
||||||
|
position: absolute;
|
||||||
|
top: 0;
|
||||||
|
left: 0;
|
||||||
|
right: 0;
|
||||||
|
bottom: 0;
|
||||||
|
background-color: #f7f7f7; // 使用页面底色
|
||||||
|
display: flex;
|
||||||
|
justify-content: center;
|
||||||
|
align-items: center;
|
||||||
|
z-index: 10;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
10661
.svn/pristine/39/39b8e7d2b5fa559692b43fcaf6bcae3ac88317ea.svn-base
Normal file
@@ -0,0 +1,331 @@
|
|||||||
|
import { HttpRequest, StoreAssist, UploadAssist, ResultData } from '@/common/Common';
|
||||||
|
import { BaseConfig } from './BaseConfig';
|
||||||
|
export class Service extends BaseConfig {
|
||||||
|
//获取API地址
|
||||||
|
static ApiUrl(path : string) {
|
||||||
|
return `${this.servesUrl}${path}`;
|
||||||
|
}
|
||||||
|
|
||||||
|
//获取图片地址
|
||||||
|
static GetpayImg(path : string) {
|
||||||
|
if (path.startsWith('http') || path.startsWith('https')) {
|
||||||
|
return path;
|
||||||
|
} else {
|
||||||
|
return `${this.payuploadUrl}${path}`;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//获取图标地址
|
||||||
|
static GetIconImg(path : string) {
|
||||||
|
return path
|
||||||
|
if (path.startsWith('http') || path.startsWith('https')) {
|
||||||
|
return path;
|
||||||
|
} else {
|
||||||
|
return `${this.imgUrl}${path}`;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//获取图片地址
|
||||||
|
static GetMateUrlByImg(path : string) {
|
||||||
|
return path
|
||||||
|
if (path.startsWith('http') || path.startsWith('https')) {
|
||||||
|
return path;
|
||||||
|
} else {
|
||||||
|
return `${this.imgUrl}${path}`;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
//获取音视频地址
|
||||||
|
static GetMateUrlByMedia(path : string) {
|
||||||
|
if (path.startsWith('http') || path.startsWith('https')) {
|
||||||
|
return path;
|
||||||
|
} else {
|
||||||
|
return `${this.mediaUrl}${path}`;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
//获取登录账号token
|
||||||
|
static GetUserToken() {
|
||||||
|
return Service.GetStorageCache('token');
|
||||||
|
}
|
||||||
|
// 获取登录状态
|
||||||
|
static GetUserIsLogin() {
|
||||||
|
var token = this.GetUserToken();
|
||||||
|
if (token == null || token == '') {
|
||||||
|
return false;
|
||||||
|
} else {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
//设置登录账户Token
|
||||||
|
static SetUserToken(token : string) {
|
||||||
|
this.SetStorageCache('token', token);
|
||||||
|
}
|
||||||
|
//清理登录账户Token
|
||||||
|
static OffUserToken() {
|
||||||
|
Service.DelStorageCache('token');
|
||||||
|
uni.$emit('ImComOff', 'user');
|
||||||
|
this.ClearUserStateData();
|
||||||
|
}
|
||||||
|
//获取登录账号状态信息
|
||||||
|
static GetUserStateData() {
|
||||||
|
return Service.GetStorageCache('StateDomain');
|
||||||
|
}
|
||||||
|
//设置当前登录账号状态信息
|
||||||
|
static SetUserStateData() {
|
||||||
|
return Service.GetStorageCache('StateDomain');
|
||||||
|
}
|
||||||
|
//清理当前登录账号状态信息
|
||||||
|
static ClearUserStateData() {
|
||||||
|
Service.DelStorageCache('StateDomain');
|
||||||
|
}
|
||||||
|
|
||||||
|
//获取缓存
|
||||||
|
static GetStorageCache(key : string) {
|
||||||
|
return StoreAssist.Get(key);
|
||||||
|
}
|
||||||
|
//删除缓存
|
||||||
|
static DelStorageCache(key : string) {
|
||||||
|
StoreAssist.Delete(key);
|
||||||
|
}
|
||||||
|
//设置缓存
|
||||||
|
static SetStorageCache(key : string, data : any) {
|
||||||
|
StoreAssist.Set(key, data);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*****以下是基础方法调用与拦截器*****/
|
||||||
|
|
||||||
|
static Request(url : string, method : 'GET' | 'POST' | 'PUT' | undefined, data : object | any) {
|
||||||
|
const token = Service.GetUserToken();
|
||||||
|
|
||||||
|
const _url = Service.ApiUrl(url);
|
||||||
|
var result = HttpRequest.RequestWithToken(_url, method, token, data).then((retResult : any) => {
|
||||||
|
if (retResult.statusCode == '200') {
|
||||||
|
var obj = retResult.data;
|
||||||
|
if (obj.code == 401) {
|
||||||
|
//过期
|
||||||
|
this.OffUserToken();
|
||||||
|
this.Msg('登录过期,请重新登录')
|
||||||
|
this.GoPage('/pages/login/login')
|
||||||
|
return Promise.reject();
|
||||||
|
} else if (obj.code == 40101) {
|
||||||
|
//失效
|
||||||
|
this.OffUserToken();
|
||||||
|
this.GoPageDelse('/pages/mine/login/login');
|
||||||
|
return Promise.reject();
|
||||||
|
} else if (obj.code == 1004) {
|
||||||
|
//资源不存在
|
||||||
|
this.GoPageDelse('/pages/AppSet/404/404');
|
||||||
|
return Promise.reject();
|
||||||
|
// return new ResultData(-1, '', '');
|
||||||
|
} else if (obj.code == 40188) {
|
||||||
|
//无权限
|
||||||
|
|
||||||
|
this.GoPageDelse('/pages/AppSet/40188/40188');
|
||||||
|
return Promise.reject();
|
||||||
|
// return new ResultData(-1, '', '');
|
||||||
|
} else if (obj.code == 1008) {
|
||||||
|
//业务提示
|
||||||
|
return new ResultData(obj.code, obj.msg, obj.data);
|
||||||
|
} else {
|
||||||
|
return new ResultData(obj.code, obj.msg, obj.data);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
return new ResultData(-1, '', '');
|
||||||
|
}
|
||||||
|
});
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
/*****以下是腾讯云oss上传*****/
|
||||||
|
static UpLoadMedia(code : string, fileName : string, desire : string, path : string) {
|
||||||
|
var result = this.Request(this.uploadUrl, 'GET', { code, fileName, desire }).then((retResult) => {
|
||||||
|
if (retResult.code == 0) {
|
||||||
|
var upOk = UploadAssist.Upload(retResult.data.url, path, retResult.data.cosData).then((upRet : any) => {
|
||||||
|
if (upRet.statusCode == 200) {
|
||||||
|
const retData : any = { code: retResult.data.code, file: retResult.data.file, cache: retResult.data.cache };
|
||||||
|
return new ResultData(0, '上传成功!', retData);
|
||||||
|
} else {
|
||||||
|
this.Msg('上传失败!');
|
||||||
|
return new ResultData(-1, '', '');
|
||||||
|
}
|
||||||
|
});
|
||||||
|
return upOk;
|
||||||
|
} else {
|
||||||
|
this.Msg('上传失败!');
|
||||||
|
return new ResultData(-1, retResult.msg,retResult.data);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
/***********消息操作**************/
|
||||||
|
static Msg(message : any, icon ?: any) : void {
|
||||||
|
if (icon != null) {
|
||||||
|
uni.showToast({
|
||||||
|
title: message,
|
||||||
|
icon: icon
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
uni.showToast({
|
||||||
|
title: message,
|
||||||
|
icon: 'none'
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static Alert(msg : string, cb ?: any) {
|
||||||
|
uni.showModal({
|
||||||
|
title: '提示',
|
||||||
|
content: msg,
|
||||||
|
showCancel: false,
|
||||||
|
cancelText: '取消',
|
||||||
|
confirmText: '确定',
|
||||||
|
success: res => {
|
||||||
|
if (res.confirm) {
|
||||||
|
cb && cb();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
static LoadIng(text : any) : void {
|
||||||
|
uni.showLoading({
|
||||||
|
title: text,
|
||||||
|
icon: 'none'
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
static LoadClose() : void {
|
||||||
|
uni.hideLoading();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**********跳转操作*********/
|
||||||
|
|
||||||
|
|
||||||
|
static GoPageTab(path : string) : void {
|
||||||
|
uni.switchTab({
|
||||||
|
url: path
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/**********跳转操作*********/
|
||||||
|
static GoPage(path : string) : void {
|
||||||
|
uni.navigateTo({
|
||||||
|
url: path, //跳转的页面
|
||||||
|
success: function (res) {
|
||||||
|
// 通过eventChannel向被打开页面传送数据
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
/**********跳转并删除当前页面操作*********/
|
||||||
|
static GoPageDelse(path : string) : void {
|
||||||
|
uni.redirectTo({
|
||||||
|
url: path //跳转的页面
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/**********返回上一页*********/
|
||||||
|
static GoPageBack() : void {
|
||||||
|
uni.navigateBack({ delta: 1 });
|
||||||
|
}
|
||||||
|
|
||||||
|
/*****获取图片base64*****/
|
||||||
|
static UpLoadMediaBase64(path : string) {
|
||||||
|
return new Promise(function (resolve, reject) {
|
||||||
|
uni.uploadFile({
|
||||||
|
url: 'http://cloud.pccsh.com/DefUp/UploadFileImgBase64', //仅为示例,非真实的接口地址
|
||||||
|
filePath: path,
|
||||||
|
name: 'file',
|
||||||
|
success: (uploadFileRes) => {
|
||||||
|
resolve(uploadFileRes);
|
||||||
|
},
|
||||||
|
fail: (err) => {
|
||||||
|
reject(err);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
/*****获取图片位置信息*****/
|
||||||
|
//获取时间戳
|
||||||
|
static GetTimeSpan(milliSecond : number) {
|
||||||
|
return Date.now() + milliSecond;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 时间戳处理
|
||||||
|
static formatDate(time : any, type : number) : string {
|
||||||
|
const date = new Date(time);
|
||||||
|
const year = date.getFullYear();
|
||||||
|
const month = String(date.getMonth() + 1).padStart(2, '0'); // 月份从0开始,所以加1,并用0填充
|
||||||
|
const day = String(date.getDate()).padStart(2, '0'); // 用0填充
|
||||||
|
const hours = String(date.getHours()).padStart(2, '0'); // 用0填充
|
||||||
|
const minutes = String(date.getMinutes()).padStart(2, '0'); // 用0填充
|
||||||
|
const seconds = String(date.getSeconds()).padStart(2, '0'); // 用0填充
|
||||||
|
if (type == 0) {
|
||||||
|
return `${year}-${month}-${day} ${hours}:${minutes}:${seconds}`;
|
||||||
|
}
|
||||||
|
else if (type == 1) {
|
||||||
|
return `${year}-${month}-${day} ${hours}:${minutes}`;
|
||||||
|
} else if (type == 2) {
|
||||||
|
return `${year}-${month}-${day}`;
|
||||||
|
} else if (type == 3) {
|
||||||
|
return `${hours}:${minutes}`;
|
||||||
|
} else if (type == 4) {
|
||||||
|
return `${year}${month}${day}`;
|
||||||
|
}
|
||||||
|
|
||||||
|
else {
|
||||||
|
return `${hours}:${minutes}`;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*****节流*****/
|
||||||
|
static throttle(fn: () => void, time: number) {
|
||||||
|
let canRun: boolean = true;
|
||||||
|
return function () {
|
||||||
|
if (!canRun) return;
|
||||||
|
canRun = false;
|
||||||
|
setTimeout(() => {
|
||||||
|
fn(); //可以不执行
|
||||||
|
canRun = true;
|
||||||
|
}, time);
|
||||||
|
};
|
||||||
|
}
|
||||||
|
/*****防抖*****/
|
||||||
|
static debounce<T extends (...args: any[]) => void>(fn: T, time: number): (...args: Parameters<T>) => void {
|
||||||
|
let timerId: NodeJS.Timeout | null = null;
|
||||||
|
|
||||||
|
return (...args: Parameters<T>) => {
|
||||||
|
if (timerId) {
|
||||||
|
clearTimeout(timerId);
|
||||||
|
}
|
||||||
|
|
||||||
|
timerId = setTimeout(() => {
|
||||||
|
fn(...args); // 执行传入的函数
|
||||||
|
timerId = null; // 清除定时器ID
|
||||||
|
}, time);
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// 普通图片上传
|
||||||
|
static uploadH5(path, dic, callback) {
|
||||||
|
console.log(this.payuploadUrl,'xxx')
|
||||||
|
uni.uploadFile({
|
||||||
|
url: this.payuploadUrl+'/Upload/UploadFile',
|
||||||
|
method: "POST",
|
||||||
|
header: {
|
||||||
|
'Authorization': 'Bearer ' + Service.GetUserToken(),
|
||||||
|
},
|
||||||
|
formData: {
|
||||||
|
"path": dic,
|
||||||
|
},
|
||||||
|
filePath: path,
|
||||||
|
name: 'file',
|
||||||
|
success: (data) => {
|
||||||
|
let info = data.data
|
||||||
|
callback(info)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,372 @@
|
|||||||
|
<template>
|
||||||
|
<!-- 收入概览区域 -->
|
||||||
|
<view class="income-container">
|
||||||
|
<view class="income-overview">
|
||||||
|
<view class="" style="display: flex; align-items: center; justify-content: space-between; ">
|
||||||
|
<view class="">
|
||||||
|
<text class="income-title">账户余额</text>
|
||||||
|
<view class="" style="display: flex; align-items: center;">
|
||||||
|
<text class="income-amount">¥{{riderAcc.account}}</text>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
<u-button class="withdraw-button" @click="Service.GoPage('/pages/order/withdraw')"
|
||||||
|
type="primary">立即提现</u-button>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
|
||||||
|
<!-- 收入明细区域 -->
|
||||||
|
<view class="detail-header">
|
||||||
|
<text class="detail-title">收支明细</text>
|
||||||
|
</view>
|
||||||
|
<!-- 时间选择标签 -->
|
||||||
|
<view class="time-tabs">
|
||||||
|
<text v-for="(item ,index) in timeList" :key="index" @click="changeTab(index)"
|
||||||
|
:class="{ 'active':currentTime==index }" class="tab-item">{{item}}</text>
|
||||||
|
</view>
|
||||||
|
<view class="detail-list" v-for="(item, index) in accList" :key="index">
|
||||||
|
<view class="detail-content">
|
||||||
|
<view class="icon-placeholder">
|
||||||
|
<image :src="Service.GetIconImg('/static/index/income/order.png')"
|
||||||
|
style="width: 55rpx; height: 55rpx;" mode=""></image>
|
||||||
|
</view>
|
||||||
|
<view class="detail-info">
|
||||||
|
<text class="order-id">{{item.name}}</text>
|
||||||
|
<text class="order-time">{{ Service.formatDate(item.addTime,1) }}</text>
|
||||||
|
</view>
|
||||||
|
<view class="" style="" >
|
||||||
|
<view class="order-amount" style="text-align: right;" >{{ item.code=='收入'?'+':'-' }}{{item.amount}}</view>
|
||||||
|
<view class="order-time" >
|
||||||
|
账户余额 {{ item.balance }}
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
<up-loadmore :status="status" />
|
||||||
|
<view class="" style="width: 100vw; height: 100rpx; ">
|
||||||
|
|
||||||
|
</view>
|
||||||
|
|
||||||
|
</view>
|
||||||
|
<calender ref="calendar" :range='true' :insert="false" @confirm='dataConfirm' />
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script setup lang="ts">
|
||||||
|
import { onLoad } from '@dcloudio/uni-app';
|
||||||
|
import { ref, onMounted } from 'vue';
|
||||||
|
import * as echarts from 'echarts';
|
||||||
|
import { Service } from '@/Service/Service';
|
||||||
|
import { CNRiderDataService } from "@/Service/CN/CNRiderDataService"
|
||||||
|
import { CNRiderOrderService } from "@/Service/CN/CNRiderOrderService"
|
||||||
|
import calender from "@/uni_modules/uni-calendar/components/uni-calendar/uni-calendar"
|
||||||
|
|
||||||
|
let loading = ref(true)
|
||||||
|
let calendar = ref(null)
|
||||||
|
let timeList = ref([
|
||||||
|
'今日',
|
||||||
|
'本周',
|
||||||
|
'本月',
|
||||||
|
'自定义'
|
||||||
|
])
|
||||||
|
|
||||||
|
let currentTime = ref(0)
|
||||||
|
|
||||||
|
let status = ref('nomore')
|
||||||
|
let page = ref(1)
|
||||||
|
let riderAcc = ref<any>({})
|
||||||
|
|
||||||
|
let accList = ref<Array<any>>([])
|
||||||
|
|
||||||
|
let timeString=ref('')
|
||||||
|
|
||||||
|
|
||||||
|
onLoad(() => {
|
||||||
|
getData()
|
||||||
|
getIncome()
|
||||||
|
})
|
||||||
|
onMounted(() => {
|
||||||
|
})
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
const getData = () => {
|
||||||
|
CNRiderDataService.GetRiderAccInfo().then(res => {
|
||||||
|
loading.value = false
|
||||||
|
if (res.data) {
|
||||||
|
riderAcc.value = res.data.riderAcc
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// 收入列表
|
||||||
|
|
||||||
|
const getIncome = () => {
|
||||||
|
status.value = 'loadmore'
|
||||||
|
page.value = 1
|
||||||
|
accList.value=[]
|
||||||
|
getIncomeList()
|
||||||
|
}
|
||||||
|
|
||||||
|
const getIncomeList = () => {
|
||||||
|
if (status.value == 'nomore' || status.value == 'loading') {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
status.value == 'loadmore'
|
||||||
|
CNRiderOrderService.GetRiderAccLog(currentTime.value==0?'0':(currentTime.value==3?timeString.value:String(currentTime.value)), page.value).then(res => {
|
||||||
|
accList.value = [...accList.value, ...res.data.accLog]
|
||||||
|
status.value = res.data.accLog == 10 ? 'loadmore' : 'nomore'
|
||||||
|
page.value++
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
const changeTab = (index : number) => {
|
||||||
|
currentTime.value = index
|
||||||
|
if (index == 3) {
|
||||||
|
calendar.value.open()
|
||||||
|
return
|
||||||
|
}
|
||||||
|
getIncome()
|
||||||
|
}
|
||||||
|
|
||||||
|
const dataConfirm = (e) => {
|
||||||
|
timeString.value = e.range.data[0] + '_' + e.range.data.slice(-1)
|
||||||
|
if(e.range.data.length==0){
|
||||||
|
timeString.value=e.fulldate+'_'
|
||||||
|
getIncome()
|
||||||
|
return
|
||||||
|
}
|
||||||
|
getIncome()
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
<style scoped>
|
||||||
|
.income-container {
|
||||||
|
padding: 20rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 收入概览区域 */
|
||||||
|
.income-overview {
|
||||||
|
background-color: #fff;
|
||||||
|
border-radius: 20rpx;
|
||||||
|
padding: 30rpx;
|
||||||
|
margin-bottom: 20rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
.income-title {
|
||||||
|
font-size: 28rpx;
|
||||||
|
color: #666;
|
||||||
|
display: block;
|
||||||
|
margin-bottom: 10rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
.income-amount {
|
||||||
|
font-size: 48rpx;
|
||||||
|
font-weight: bold;
|
||||||
|
color: #ff4d4f;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 时间标签 */
|
||||||
|
.time-tabs {
|
||||||
|
display: flex;
|
||||||
|
margin-bottom: 10rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
.tab-item {
|
||||||
|
font-size: 28rpx;
|
||||||
|
color: #666;
|
||||||
|
margin-right: 40rpx;
|
||||||
|
padding-bottom: 10rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
.tab-item.active {
|
||||||
|
color: #1890ff;
|
||||||
|
border-bottom: 3rpx solid #1890ff;
|
||||||
|
}
|
||||||
|
|
||||||
|
.month-total {
|
||||||
|
font-size: 30rpx;
|
||||||
|
color: #666;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 收入构成区域 */
|
||||||
|
.income-composition {
|
||||||
|
background-color: #fff;
|
||||||
|
border-radius: 20rpx;
|
||||||
|
padding: 30rpx;
|
||||||
|
margin-bottom: 20rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 饼图占位 */
|
||||||
|
.pie-chart-placeholder {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.pie-chart {
|
||||||
|
width: 200rpx;
|
||||||
|
height: 200rpx;
|
||||||
|
margin-right: 30rpx;
|
||||||
|
position: relative;
|
||||||
|
overflow: hidden;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
.chart-legend {
|
||||||
|
flex: 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
.legend-item {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
margin-bottom: 15rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
.legend-dot {
|
||||||
|
width: 16rpx;
|
||||||
|
height: 16rpx;
|
||||||
|
border-radius: 50%;
|
||||||
|
margin-right: 10rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
.legend-dot.blue {
|
||||||
|
background-color: var(--nav-mian);
|
||||||
|
}
|
||||||
|
|
||||||
|
.legend-dot.orange {
|
||||||
|
background-color: var(--nav-vice);
|
||||||
|
}
|
||||||
|
|
||||||
|
.legend-dot.green {
|
||||||
|
background-color: var(--nav-diluted);
|
||||||
|
}
|
||||||
|
|
||||||
|
.legend-text {
|
||||||
|
font-size: 26rpx;
|
||||||
|
color: #666;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 钱包区域 */
|
||||||
|
.wallet-section {
|
||||||
|
background-color: #fff;
|
||||||
|
border-radius: 20rpx;
|
||||||
|
padding: 30rpx;
|
||||||
|
margin-bottom: 20rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
.wallet-header {
|
||||||
|
display: flex;
|
||||||
|
justify-content: space-between;
|
||||||
|
align-items: center;
|
||||||
|
margin-bottom: 20rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
.wallet-title {
|
||||||
|
font-size: 28rpx;
|
||||||
|
color: #333;
|
||||||
|
}
|
||||||
|
|
||||||
|
.wallet-amount {
|
||||||
|
font-size: 36rpx;
|
||||||
|
font-weight: bold;
|
||||||
|
color: #ff4d4f;
|
||||||
|
}
|
||||||
|
|
||||||
|
.withdraw-button {
|
||||||
|
margin: 0;
|
||||||
|
width: fit-content;
|
||||||
|
height: 60rpx;
|
||||||
|
line-height: 60rpx;
|
||||||
|
font-size: 24rpx;
|
||||||
|
border-radius: 40rpx;
|
||||||
|
background-color: #1890ff;
|
||||||
|
color: #fff;
|
||||||
|
}
|
||||||
|
|
||||||
|
.withdraw-tip {
|
||||||
|
display: block;
|
||||||
|
font-size: 22rpx;
|
||||||
|
color: #999;
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 收入明细区域 */
|
||||||
|
.income-detail {
|
||||||
|
background-color: #fff;
|
||||||
|
border-radius: 20rpx;
|
||||||
|
padding: 30rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
.detail-header {
|
||||||
|
margin-bottom: 20rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
.detail-title {
|
||||||
|
font-size: 34rpx;
|
||||||
|
font-weight: bold;
|
||||||
|
color: #333;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
.detail-content {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.detail-list {
|
||||||
|
margin: 15rpx 0 0;
|
||||||
|
background-color: #fff;
|
||||||
|
padding: 20rpx 30rpx;
|
||||||
|
border-radius: 20rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 图标占位符 - 黑边白底 */
|
||||||
|
.icon-placeholder {
|
||||||
|
width: 70rpx;
|
||||||
|
height: 70rpx;
|
||||||
|
background-color: #E6F7FF;
|
||||||
|
border-radius: 8rpx;
|
||||||
|
margin-right: 20rpx;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.detail-info {
|
||||||
|
flex: 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
.order-id {
|
||||||
|
display: block;
|
||||||
|
font-size: 26rpx;
|
||||||
|
color: #333;
|
||||||
|
margin-bottom: 5rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
.order-time {
|
||||||
|
font-size: 24rpx;
|
||||||
|
color: #999;
|
||||||
|
}
|
||||||
|
|
||||||
|
.order-amount {
|
||||||
|
font-size: 32rpx;
|
||||||
|
font-weight: bold;
|
||||||
|
color: #ff4d4f;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 没有更多记录 */
|
||||||
|
.no-more {
|
||||||
|
text-align: center;
|
||||||
|
padding: 40rpx 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.no-more-text {
|
||||||
|
font-size: 24rpx;
|
||||||
|
color: #999;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
@@ -0,0 +1,76 @@
|
|||||||
|
<template>
|
||||||
|
<view style="padding: 10rpx 30rpx;">
|
||||||
|
<view class="" v-for="(item,index) in withdrowList" :key="index"
|
||||||
|
style="margin-top: 20rpx; gap: 20rpx; background-color: #fff; border-radius: 20rpx; padding: 30rpx; display: flex; align-items: center; justify-content: space-between; ">
|
||||||
|
<view class="icon-placeholder">
|
||||||
|
<image :src="Service.GetIconImg('/static/index/income/order.png')" style="width: 55rpx; height: 55rpx;"
|
||||||
|
mode=""></image>
|
||||||
|
</view>
|
||||||
|
<view class="" style="flex: 1;">
|
||||||
|
<view class="" style="font-weight: bold;">
|
||||||
|
余额提现-到{{item.payway}}
|
||||||
|
</view>
|
||||||
|
|
||||||
|
<view style=" margin-top: 4rpx; color: #999; font-size: 24rpx;">2025-12-15</view>
|
||||||
|
</view>
|
||||||
|
<view class="" style="color: red; font-weight: bold; ">
|
||||||
|
+15.6
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
<up-loadmore :status="status" />
|
||||||
|
</view>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script setup lang="ts">
|
||||||
|
import { onShow, onLoad } from "@dcloudio/uni-app";
|
||||||
|
import { Service } from '@/Service/Service';
|
||||||
|
import { ref } from "vue";
|
||||||
|
import { CNRiderOrderService } from '@/Service/CN/CNRiderOrderService'
|
||||||
|
|
||||||
|
let withdrowList = ref<Array<any>>([])
|
||||||
|
let status = ref('nomore')
|
||||||
|
let page = ref(1)
|
||||||
|
|
||||||
|
onLoad(() => {
|
||||||
|
getData()
|
||||||
|
});
|
||||||
|
|
||||||
|
onShow(() => {
|
||||||
|
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
|
const getData = () => {
|
||||||
|
status.value = 'loadmore'
|
||||||
|
page.value = 1
|
||||||
|
withdrowList.value = []
|
||||||
|
getList()
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//获取订单
|
||||||
|
const getList = () => {
|
||||||
|
if (status.value == 'nomore' || status.value == 'loading') {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
status.value == 'loadmore'
|
||||||
|
CNRiderOrderService.GetRiderWithList(page.value).then(res => {
|
||||||
|
withdrowList.value = [...withdrowList.value, ...res.data.list]
|
||||||
|
status.value = res.data.list == 10 ? 'loadmore' : 'nomore'
|
||||||
|
page.value++
|
||||||
|
})
|
||||||
|
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style lang="scss">
|
||||||
|
.icon-placeholder {
|
||||||
|
width: 70rpx;
|
||||||
|
height: 70rpx;
|
||||||
|
background-color: #E6F7FF;
|
||||||
|
border-radius: 8rpx;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
@@ -0,0 +1,680 @@
|
|||||||
|
<template>
|
||||||
|
<!-- 导航栏 -->
|
||||||
|
<view class=""
|
||||||
|
style=" z-index: 100; padding:50rpx 20rpx 18rpx; box-sizing: border-box; position: fixed;top: 0; left: 0; width: 100vw; background-color: #fff; display: flex; align-items: center; justify-content: space-between;">
|
||||||
|
<view class="" @click="Service.GoPageBack()">
|
||||||
|
<up-icon name="arrow-left" size="32rpx"></up-icon>
|
||||||
|
</view>
|
||||||
|
<view class="">
|
||||||
|
订单详情
|
||||||
|
</view>
|
||||||
|
<view class="" @click="Service.GoPage('/pages/my/myKF')" style="color: var(--nav-banbacor);">
|
||||||
|
<image :src="Service.GetIconImg('/static/index/order/message.png')" style="width: 32rpx; height: 32rpx; "
|
||||||
|
mode=""></image>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
<view class="" style="width: 100%; height: 88rpx; ">
|
||||||
|
|
||||||
|
</view>
|
||||||
|
|
||||||
|
<!-- 骨架屏 -->
|
||||||
|
<view v-if="loading" class="skeleton-container">
|
||||||
|
<!-- 骨架屏订单状态 -->
|
||||||
|
<view class="skeleton-status"></view>
|
||||||
|
|
||||||
|
<!-- 骨架屏订单基本信息 -->
|
||||||
|
<view class="skeleton-basic-info">
|
||||||
|
<view class="skeleton-row">
|
||||||
|
<view class="skeleton-info-half"></view>
|
||||||
|
<view class="skeleton-info-half skeleton-right"></view>
|
||||||
|
</view>
|
||||||
|
<view class="skeleton-line"></view>
|
||||||
|
<view class="skeleton-line"></view>
|
||||||
|
<view class="skeleton-line"></view>
|
||||||
|
<view class="skeleton-row">
|
||||||
|
<view class="skeleton-info-third"></view>
|
||||||
|
<view class="skeleton-info-btn"></view>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
|
||||||
|
<!-- 骨架屏物品清单 -->
|
||||||
|
<view class="skeleton-basic-info">
|
||||||
|
<view class="skeleton-row">
|
||||||
|
<view class="" style="width: 45%;height: 40rpx;border-radius: 4rpx;animation: shimmer 1.5s infinite;">
|
||||||
|
<view class="" style="background-color: #e6e6e6; width: 60%;height: 40rpx; ">
|
||||||
|
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
<view class="skeleton-info-half skeleton-right"></view>
|
||||||
|
<view class="skeleton-info-half skeleton-right"></view>
|
||||||
|
</view>
|
||||||
|
<view class="skeleton-row" v-for="(item,index) in 3" :key="index">
|
||||||
|
<view class="" style="width: 45%;height: 40rpx;border-radius: 4rpx;animation: shimmer 1.5s infinite;">
|
||||||
|
<view class="" style="background-color: #e6e6e6; width: 90%;height: 40rpx; ">
|
||||||
|
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
<view class="skeleton-info-half skeleton-right"></view>
|
||||||
|
<view class="skeleton-info-half skeleton-right"></view>
|
||||||
|
</view>
|
||||||
|
<view class="skeleton-list-status"></view>
|
||||||
|
</view>
|
||||||
|
|
||||||
|
<!-- 骨架屏地图区域 -->
|
||||||
|
<view class="skeleton-map"></view>
|
||||||
|
|
||||||
|
<!-- 骨架屏取餐地址 -->
|
||||||
|
<view class="skeleton-address">
|
||||||
|
<view class="skeleton-title"></view>
|
||||||
|
<view class="skeleton-store-name"></view>
|
||||||
|
<view class="skeleton-address-line"></view>
|
||||||
|
<view class="skeleton-btn"></view>
|
||||||
|
<view class="skeleton-code"></view>
|
||||||
|
</view>
|
||||||
|
|
||||||
|
<!-- 骨架屏送餐地址 -->
|
||||||
|
<view class="skeleton-address">
|
||||||
|
<view class="skeleton-title"></view>
|
||||||
|
<view class="skeleton-store-name"></view>
|
||||||
|
<view class="skeleton-address-line"></view>
|
||||||
|
<view class="skeleton-btn"></view>
|
||||||
|
<view class="skeleton-remark"></view>
|
||||||
|
</view>
|
||||||
|
|
||||||
|
<!-- 骨架屏底部按钮 -->
|
||||||
|
<view class="skeleton-bottom">
|
||||||
|
<view class="skeleton-bottom-btn"></view>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
<!-- 实际内容 -->
|
||||||
|
<view v-else class="order-detail">
|
||||||
|
<!-- 订单状态 -->
|
||||||
|
<view class="order-status"
|
||||||
|
:style="{ 'background-color':orderStatus==0?'#E6F7FF':(orderStatus==1?'#FFFBE6':'#FFF2F0') }">
|
||||||
|
<text :style="{ 'color':orderStatus==0?'#1890FF':(orderStatus==1?'#FAAD14':'#FF4D4F') }"
|
||||||
|
style="font-size: 34rpx; font-weight: 600;">待取餐 · 请尽快到店取餐</text>
|
||||||
|
|
||||||
|
</view>
|
||||||
|
|
||||||
|
<!-- 订单基本信息 -->
|
||||||
|
<view class="order-basic-info">
|
||||||
|
<view class="info-item">
|
||||||
|
<view class="label" style="font-weight: 700; font-size: 30rpx;"> {{ orderInfo.distribution=='预约订单'?'预计'+orderInfo.makeTime.split(' ')[1]+'送达':orderInfo.makeTime }} </view>
|
||||||
|
</view>
|
||||||
|
<view class="info-item">
|
||||||
|
<text class="label">订单编号 : </text>
|
||||||
|
<text class="value">{{ orderId }}</text>
|
||||||
|
</view>
|
||||||
|
|
||||||
|
<view class="info-item" style="justify-content: space-between;" >
|
||||||
|
<view class="label" style="display: flex; align-items: baseline;">
|
||||||
|
<u-icon name="clock" size="16" class="clock-icon"></u-icon>
|
||||||
|
{{ Service.formatDate(orderInfo.addTime,1) }} 下单
|
||||||
|
</view>
|
||||||
|
<view class="">
|
||||||
|
<button @click="Service.GoPage('/pages/order/abnormal')" class="" style="padding: 0rpx 30rpx; height: 60rpx; font-size: 24rpx; border-radius: 40rpx; background-color: red; color: #fff; " >提交异常</button>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
|
||||||
|
</view>
|
||||||
|
|
||||||
|
<!-- 物品清单 -->
|
||||||
|
<view class="order-basic-info">
|
||||||
|
<view class="" style="display: flex; align-items: center; ">
|
||||||
|
<view class="" style="flex: 1; font-size: 34rpx; font-weight: 600; ">
|
||||||
|
物品清单
|
||||||
|
</view>
|
||||||
|
<view class="" style="width: 100rpx; text-align: right; font-size: 30rpx; ">
|
||||||
|
数量
|
||||||
|
</view>
|
||||||
|
<view class="" style="width: 120rpx; text-align: right; font-size: 30rpx; ">
|
||||||
|
金额
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
<!-- 商品列表 -->
|
||||||
|
<view class="" :style="{'height':isShow?'110rpx':'fit-content' }" style="overflow: hidden;">
|
||||||
|
<view class="" v-for="(goodsItem,goodsIndex) in JSON.parse(orderInfo.detail) " :key="goodsIndex"
|
||||||
|
style="display: flex; align-items: center; margin-top: 15rpx; ">
|
||||||
|
<view class="" style="flex: 1; ">
|
||||||
|
{{goodsItem.goodsName}}
|
||||||
|
</view>
|
||||||
|
<view class="" style="width: 100rpx; text-align: right; ">
|
||||||
|
×{{ goodsItem.count }}
|
||||||
|
</view>
|
||||||
|
<view class="" style="width: 120rpx; text-align: right; ">
|
||||||
|
¥{{ goodsItem.count*goodsItem.price }}
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
<view class="" style="display: flex; align-items: center;justify-content: space-between; margin-top: 10rpx; " >
|
||||||
|
<view class="">
|
||||||
|
|
||||||
|
</view>
|
||||||
|
<view class="info-item">
|
||||||
|
<text class="label" style="font-weight: 700;">配送费</text>
|
||||||
|
<text class="value price">¥{{ Number(orderInfo.postage).toFixed(2) }}</text>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
<view class="" v-if="JSON.parse(orderInfo.detail).length>2" @click="isShow=!isShow"
|
||||||
|
style=" margin-top: 20rpx; display: flex; align-items: center; justify-content: center; color: #666; ">
|
||||||
|
<up-icon :name="isShow?'arrow-down':'arrow-up'" color="#666" size="18"></up-icon>
|
||||||
|
{{isShow?'展开':'收入'}}
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
<!-- 地图区域 -->
|
||||||
|
<view class="map-section">
|
||||||
|
<view class="map-placeholder">
|
||||||
|
<text @click="Service.GoPage('/pages/order/navigation')" class="map-hint">点击查看完整导航</text>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
|
||||||
|
<!-- 取餐地址 -->
|
||||||
|
<view class="address-section">
|
||||||
|
<text class="section-title">取餐地址</text>
|
||||||
|
<view class="address-content">
|
||||||
|
<view class="store-name">{{ storeInfo.name }}</view>
|
||||||
|
<text class="address">{{ storeInfo.city }}{{storeInfo.region }}{{ storeInfo.address }}</text>
|
||||||
|
<view class="" style="margin-bottom: 20rpx;">
|
||||||
|
<up-button @click="call(storeInfo.phone)" icon="phone" type="primary" shape="circle" text="拨打商家"></up-button>
|
||||||
|
</view>
|
||||||
|
<view class="pickup-code">
|
||||||
|
<text class="code-label">取餐号:</text>
|
||||||
|
<text class="code-value">A123</text>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
|
||||||
|
<!-- 送餐地址 -->
|
||||||
|
<view class="address-section">
|
||||||
|
<text class="section-title">送餐地址</text>
|
||||||
|
<view class="address-content">
|
||||||
|
<text class="user-name">{{ JSON.parse(orderInfo.address).realName }}</text>
|
||||||
|
<text class="address">{{ JSON.parse(orderInfo.address).address }}</text>
|
||||||
|
<view class="" style="margin-bottom: 20rpx;">
|
||||||
|
<up-button @click="call(JSON.parse(orderInfo.address).phone)" icon="phone" type="primary" shape="circle" text="拨打商家"></up-button>
|
||||||
|
</view>
|
||||||
|
<view v-if="orderInfo.remark" class="remark">
|
||||||
|
<text class="remark-label">备注:</text>
|
||||||
|
<text class="remark-content">{{ orderInfo.remark }}</text>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
|
||||||
|
<view class="" style="width: 100vw; height: 140rpx; ">
|
||||||
|
|
||||||
|
</view>
|
||||||
|
|
||||||
|
<!-- 底部按钮 -->
|
||||||
|
<view class="bottom-action">
|
||||||
|
<up-button color="var(--nav-vice)" class="confirm-btn">我已取餐</up-button>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script setup lang="ts">
|
||||||
|
import { onLoad } from '@dcloudio/uni-app';
|
||||||
|
import { ref, onMounted } from 'vue';
|
||||||
|
import { Service } from '@/Service/Service';
|
||||||
|
import { CNRiderOrderService } from '@/Service/CN/CNRiderOrderService'
|
||||||
|
|
||||||
|
// 加载状态
|
||||||
|
const loading = ref(true);
|
||||||
|
|
||||||
|
let orderStatus = ref(0)
|
||||||
|
|
||||||
|
let isShow = ref(true)
|
||||||
|
|
||||||
|
let deliveryTime = ref('')
|
||||||
|
|
||||||
|
let orderInfo = ref<any>({})
|
||||||
|
let storeInfo = ref<any>({})
|
||||||
|
let storeLocation = ref<any>({})
|
||||||
|
|
||||||
|
let orderId = ref('')
|
||||||
|
onLoad((data : any) => {
|
||||||
|
orderId.value = data.orderId
|
||||||
|
getData()
|
||||||
|
})
|
||||||
|
|
||||||
|
|
||||||
|
const getData = () => {
|
||||||
|
CNRiderOrderService.GetUnitOrderInfo(orderId.value).then(res => {
|
||||||
|
loading.value = false
|
||||||
|
if (res.data) {
|
||||||
|
deliveryTime.value = res.data.deliveryTime
|
||||||
|
orderInfo.value = res.data.orderInfo
|
||||||
|
storeInfo.value = res.data.storeInfo
|
||||||
|
storeLocation.value = res.data.storeLocation
|
||||||
|
}
|
||||||
|
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
const call=(phone:string)=>{
|
||||||
|
uni.makePhoneCall({
|
||||||
|
phoneNumber:phone
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style scoped>
|
||||||
|
/* 骨架屏样式 */
|
||||||
|
.skeleton-container {
|
||||||
|
min-height: 100vh;
|
||||||
|
background-color: #f5f5f5;
|
||||||
|
padding-bottom: 140rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 骨架屏导航栏 */
|
||||||
|
.skeleton-nav {
|
||||||
|
height: 88rpx;
|
||||||
|
position: fixed;
|
||||||
|
top: 0;
|
||||||
|
left: 0;
|
||||||
|
width: 100vw;
|
||||||
|
background-color: #fff;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: space-between;
|
||||||
|
padding: 0 20rpx;
|
||||||
|
z-index: 100;
|
||||||
|
}
|
||||||
|
|
||||||
|
.skeleton-nav-item {
|
||||||
|
width: 32rpx;
|
||||||
|
height: 32rpx;
|
||||||
|
background-color: #e6e6e6;
|
||||||
|
border-radius: 4rpx;
|
||||||
|
animation: shimmer 1.5s infinite;
|
||||||
|
}
|
||||||
|
|
||||||
|
.skeleton-nav-title {
|
||||||
|
width: 180rpx;
|
||||||
|
height: 36rpx;
|
||||||
|
background-color: #e6e6e6;
|
||||||
|
border-radius: 4rpx;
|
||||||
|
animation: shimmer 1.5s infinite;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 骨架屏订单状态 */
|
||||||
|
.skeleton-status {
|
||||||
|
height: 100rpx;
|
||||||
|
background-color: #fff;
|
||||||
|
padding: 30rpx;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.skeleton-status::after {
|
||||||
|
content: '';
|
||||||
|
width: 350rpx;
|
||||||
|
height: 45rpx;
|
||||||
|
background-color: #e6e6e6;
|
||||||
|
border-radius: 4rpx;
|
||||||
|
animation: shimmer 1.5s infinite;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 骨架屏订单基本信息 */
|
||||||
|
.skeleton-basic-info {
|
||||||
|
background-color: #fff;
|
||||||
|
margin: 20rpx 20rpx;
|
||||||
|
padding: 30rpx;
|
||||||
|
border-radius: 20rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
.skeleton-row {
|
||||||
|
display: flex;
|
||||||
|
justify-content: space-between;
|
||||||
|
margin-bottom: 20rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
.skeleton-info-half {
|
||||||
|
width: 45%;
|
||||||
|
height: 40rpx;
|
||||||
|
background-color: #e6e6e6;
|
||||||
|
border-radius: 4rpx;
|
||||||
|
animation: shimmer 1.5s infinite;
|
||||||
|
}
|
||||||
|
|
||||||
|
.skeleton-right {
|
||||||
|
width: 10%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.skeleton-line {
|
||||||
|
width: 60%;
|
||||||
|
height: 40rpx;
|
||||||
|
background-color: #e6e6e6;
|
||||||
|
border-radius: 4rpx;
|
||||||
|
margin-bottom: 20rpx;
|
||||||
|
animation: shimmer 1.5s infinite;
|
||||||
|
}
|
||||||
|
|
||||||
|
.skeleton-info-third {
|
||||||
|
width: 60%;
|
||||||
|
height: 40rpx;
|
||||||
|
background-color: #e6e6e6;
|
||||||
|
border-radius: 4rpx;
|
||||||
|
animation: shimmer 1.5s infinite;
|
||||||
|
}
|
||||||
|
|
||||||
|
.skeleton-info-btn {
|
||||||
|
width: 20%;
|
||||||
|
height: 50rpx;
|
||||||
|
background-color: #e6e6e6;
|
||||||
|
border-radius: 25rpx;
|
||||||
|
animation: shimmer 1.5s infinite;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 列表状态 */
|
||||||
|
.skeleton-list-status {
|
||||||
|
height: 60rpx;
|
||||||
|
background-color: #fff;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.skeleton-list-status::after {
|
||||||
|
content: '';
|
||||||
|
width: 200rpx;
|
||||||
|
height: 45rpx;
|
||||||
|
background-color: #e6e6e6;
|
||||||
|
border-radius: 4rpx;
|
||||||
|
animation: shimmer 1.5s infinite;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 骨架屏地图区域 */
|
||||||
|
.skeleton-map {
|
||||||
|
margin: 20rpx;
|
||||||
|
height: 400rpx;
|
||||||
|
background-color: #e6e6e6;
|
||||||
|
border-radius: 20rpx;
|
||||||
|
animation: shimmer 1.5s infinite;
|
||||||
|
position: relative;
|
||||||
|
overflow: hidden;
|
||||||
|
}
|
||||||
|
|
||||||
|
.skeleton-map::after {
|
||||||
|
content: '';
|
||||||
|
position: absolute;
|
||||||
|
top: 0;
|
||||||
|
left: 0;
|
||||||
|
right: 0;
|
||||||
|
bottom: 0;
|
||||||
|
background: linear-gradient(135deg, transparent 25%, rgba(255, 255, 255, 0.2) 25%, rgba(255, 255, 255, 0.2) 50%, transparent 50%, transparent 75%, rgba(255, 255, 255, 0.2) 75%, rgba(255, 255, 255, 0.2));
|
||||||
|
background-size: 100rpx 100rpx;
|
||||||
|
animation: shimmer 1.5s infinite linear;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 骨架屏地址区域 */
|
||||||
|
.skeleton-address {
|
||||||
|
background-color: #fff;
|
||||||
|
margin: 20rpx;
|
||||||
|
padding: 30rpx;
|
||||||
|
border-radius: 20rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
.skeleton-title {
|
||||||
|
width: 120rpx;
|
||||||
|
height: 30rpx;
|
||||||
|
background-color: #e6e6e6;
|
||||||
|
border-radius: 4rpx;
|
||||||
|
margin-bottom: 25rpx;
|
||||||
|
animation: shimmer 1.5s infinite;
|
||||||
|
}
|
||||||
|
|
||||||
|
.skeleton-store-name {
|
||||||
|
width: 70%;
|
||||||
|
height: 50rpx;
|
||||||
|
background-color: #e6e6e6;
|
||||||
|
border-radius: 4rpx;
|
||||||
|
margin-bottom: 15rpx;
|
||||||
|
animation: shimmer 1.5s infinite;
|
||||||
|
}
|
||||||
|
|
||||||
|
.skeleton-address-line {
|
||||||
|
width: 90%;
|
||||||
|
height: 26rpx;
|
||||||
|
background-color: #e6e6e6;
|
||||||
|
border-radius: 4rpx;
|
||||||
|
margin-bottom: 15rpx;
|
||||||
|
animation: shimmer 1.5s infinite;
|
||||||
|
}
|
||||||
|
|
||||||
|
.skeleton-btn {
|
||||||
|
height: 70rpx;
|
||||||
|
background-color: #e6e6e6;
|
||||||
|
border-radius: 35rpx;
|
||||||
|
margin: 20rpx 0;
|
||||||
|
animation: shimmer 1.5s infinite;
|
||||||
|
}
|
||||||
|
|
||||||
|
.skeleton-code {
|
||||||
|
width: 50%;
|
||||||
|
height: 26rpx;
|
||||||
|
background-color: #e6e6e6;
|
||||||
|
border-radius: 4rpx;
|
||||||
|
animation: shimmer 1.5s infinite;
|
||||||
|
}
|
||||||
|
|
||||||
|
.skeleton-remark {
|
||||||
|
width: 80%;
|
||||||
|
height: 26rpx;
|
||||||
|
background-color: #e6e6e6;
|
||||||
|
border-radius: 4rpx;
|
||||||
|
animation: shimmer 1.5s infinite;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 骨架屏底部按钮 */
|
||||||
|
.skeleton-bottom {
|
||||||
|
background-color: #fff;
|
||||||
|
width: 100vw;
|
||||||
|
position: fixed;
|
||||||
|
bottom: 0;
|
||||||
|
left: 0;
|
||||||
|
padding: 20rpx 30rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
.skeleton-bottom-btn {
|
||||||
|
width: 100%;
|
||||||
|
height: 90rpx;
|
||||||
|
background-color: #e6e6e6;
|
||||||
|
border-radius: 45rpx;
|
||||||
|
animation: shimmer 1.5s infinite;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 骨架屏动画 */
|
||||||
|
@keyframes shimmer {
|
||||||
|
0% {
|
||||||
|
opacity: 0.6;
|
||||||
|
}
|
||||||
|
|
||||||
|
50% {
|
||||||
|
opacity: 0.8;
|
||||||
|
}
|
||||||
|
|
||||||
|
100% {
|
||||||
|
opacity: 0.6;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 骨架屏滑动动画 */
|
||||||
|
@keyframes shimmer-slide {
|
||||||
|
0% {
|
||||||
|
transform: translateX(-100%);
|
||||||
|
}
|
||||||
|
|
||||||
|
100% {
|
||||||
|
transform: translateX(100%);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* end */
|
||||||
|
|
||||||
|
.order-detail {
|
||||||
|
min-height: 100vh;
|
||||||
|
background-color: #f5f5f5;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 订单状态样式 */
|
||||||
|
.order-status {
|
||||||
|
background-color: #fff;
|
||||||
|
padding: 30rpx;
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* 订单基本信息样式 */
|
||||||
|
.order-basic-info {
|
||||||
|
background-color: #fff;
|
||||||
|
margin: 20rpx 20rpx;
|
||||||
|
padding: 30rpx;
|
||||||
|
border-radius: 20rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
.info-item {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
margin-bottom: 20rpx;
|
||||||
|
font-size: 28rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
.info-item:last-child {
|
||||||
|
margin-bottom: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.label {
|
||||||
|
color: #666;
|
||||||
|
margin-right: 10rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
.value {
|
||||||
|
color: #333;
|
||||||
|
}
|
||||||
|
|
||||||
|
.value.highlight {
|
||||||
|
color: var(--nav-diluted);
|
||||||
|
font-weight: 500;
|
||||||
|
}
|
||||||
|
|
||||||
|
.value.price {
|
||||||
|
color: var(--nav-diluted);
|
||||||
|
font-weight: 700;
|
||||||
|
}
|
||||||
|
|
||||||
|
.clock-icon {
|
||||||
|
color: #666;
|
||||||
|
margin-right: 8rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 地图区域样式 */
|
||||||
|
.map-section {
|
||||||
|
margin: 20rpx;
|
||||||
|
border-radius: 20rpx;
|
||||||
|
overflow: hidden;
|
||||||
|
}
|
||||||
|
|
||||||
|
.map-placeholder {
|
||||||
|
width: 100%;
|
||||||
|
height: 400rpx;
|
||||||
|
background-color: #f0f0f0;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
position: relative;
|
||||||
|
border: 1rpx solid #e8e8e8;
|
||||||
|
}
|
||||||
|
|
||||||
|
.map-placeholder::before {
|
||||||
|
content: '';
|
||||||
|
position: absolute;
|
||||||
|
top: 0;
|
||||||
|
left: 0;
|
||||||
|
right: 0;
|
||||||
|
bottom: 0;
|
||||||
|
background: linear-gradient(135deg, #f5f5f5 25%, #e6e6e6 25%, #e6e6e6 50%, #f5f5f5 50%, #f5f5f5 75%, #e6e6e6 75%, #e6e6e6 100%);
|
||||||
|
background-size: 20rpx 20rpx;
|
||||||
|
opacity: 0.3;
|
||||||
|
}
|
||||||
|
|
||||||
|
.map-hint {
|
||||||
|
font-size: 28rpx;
|
||||||
|
color: #666;
|
||||||
|
position: relative;
|
||||||
|
z-index: 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 地址区域样式 */
|
||||||
|
.address-section {
|
||||||
|
background-color: #fff;
|
||||||
|
margin: 20rpx;
|
||||||
|
padding: 30rpx;
|
||||||
|
border-radius: 20rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
.section-title {
|
||||||
|
font-size: 30rpx;
|
||||||
|
font-weight: 800;
|
||||||
|
color: #333;
|
||||||
|
margin-bottom: 25rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
.address-content {
|
||||||
|
position: relative;
|
||||||
|
}
|
||||||
|
|
||||||
|
.store-name,
|
||||||
|
.user-name {
|
||||||
|
font-size: 34rpx;
|
||||||
|
font-weight: 600;
|
||||||
|
margin: 10rpx 0;
|
||||||
|
display: block;
|
||||||
|
}
|
||||||
|
|
||||||
|
.address {
|
||||||
|
font-size: 26rpx;
|
||||||
|
color: #666;
|
||||||
|
line-height: 1.5;
|
||||||
|
margin-bottom: 25rpx;
|
||||||
|
display: block;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
.pickup-code,
|
||||||
|
.remark {
|
||||||
|
font-size: 26rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
.code-label,
|
||||||
|
.code-value {
|
||||||
|
color: var(--nav-mian);
|
||||||
|
font-weight: 600;
|
||||||
|
}
|
||||||
|
|
||||||
|
.remark-label,
|
||||||
|
.remark-content {
|
||||||
|
color: #FAAD14;
|
||||||
|
font-weight: 600;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 底部按钮样式 */
|
||||||
|
.bottom-action {
|
||||||
|
background-color: #fff;
|
||||||
|
width: 100vw;
|
||||||
|
position: fixed;
|
||||||
|
bottom: 0;
|
||||||
|
left: 0;
|
||||||
|
padding: 20rpx 30rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
.confirm-btn {
|
||||||
|
width: 100%;
|
||||||
|
height: 90rpx;
|
||||||
|
font-size: 32rpx;
|
||||||
|
line-height: 90rpx;
|
||||||
|
border-radius: 45rpx;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
@@ -0,0 +1,14 @@
|
|||||||
|
export class StoreAssist{
|
||||||
|
static Get(key:string):any
|
||||||
|
{
|
||||||
|
return uni.getStorageSync(key);
|
||||||
|
}
|
||||||
|
static Set(key:string,value:any):void
|
||||||
|
{
|
||||||
|
uni.setStorageSync(key, value);
|
||||||
|
}
|
||||||
|
static Delete(key:string):void
|
||||||
|
{
|
||||||
|
uni.removeStorageSync(key);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,274 @@
|
|||||||
|
<template>
|
||||||
|
|
||||||
|
<view v-if="loading" class="pure-css-skeleton">
|
||||||
|
<view style=" margin: 20rpx 0; padding: 20rpx; background-color: #fff; border-radius: 10rpx;">
|
||||||
|
<!-- 头像区域骨架 -->
|
||||||
|
<view class="avatar-skeleton-wrapper"
|
||||||
|
style="display: flex; flex-direction: column; justify-content: center; align-items: center;">
|
||||||
|
<view class="skeleton-circle animate-pulse"></view>
|
||||||
|
<view class="skeleton-text animate-pulse" style="margin-top: 15rpx;"></view>
|
||||||
|
</view>
|
||||||
|
|
||||||
|
<!-- 表单区域骨架 -->
|
||||||
|
<view class="form-skeleton-wrapper" style="margin-top: 30rpx;">
|
||||||
|
<!-- 昵称 -->
|
||||||
|
<view class="form-item-skeleton">
|
||||||
|
<view class="form-label-skeleton animate-pulse"></view>
|
||||||
|
<view class="form-input-skeleton animate-pulse"></view>
|
||||||
|
</view>
|
||||||
|
<!-- 性别 -->
|
||||||
|
<view class="form-item-skeleton">
|
||||||
|
<view class="form-label-skeleton animate-pulse"></view>
|
||||||
|
<view class="form-radio-skeleton">
|
||||||
|
<view class="radio-item-skeleton animate-pulse"></view>
|
||||||
|
<view class="radio-item-skeleton animate-pulse"></view>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
<!-- 生日 -->
|
||||||
|
<view class="form-item-skeleton">
|
||||||
|
<view class="form-label-skeleton animate-pulse"></view>
|
||||||
|
<view class="form-input-skeleton animate-pulse"></view>
|
||||||
|
</view>
|
||||||
|
<!-- 手机号 -->
|
||||||
|
<view class="form-item-skeleton">
|
||||||
|
<view class="form-label-skeleton animate-pulse"></view>
|
||||||
|
<view class="form-input-skeleton animate-pulse"></view>
|
||||||
|
</view>
|
||||||
|
<!-- 邮箱 -->
|
||||||
|
<view class="form-item-skeleton">
|
||||||
|
<view class="form-label-skeleton animate-pulse"></view>
|
||||||
|
<view class="form-input-skeleton animate-pulse"></view>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
|
||||||
|
<!-- 底部空间占位 -->
|
||||||
|
<view style="width: 100%; height: 200rpx;"></view>
|
||||||
|
</view>
|
||||||
|
|
||||||
|
<!-- 底部保存按钮骨架 -->
|
||||||
|
<view class="bottom-button-skeleton animate-pulse"></view>
|
||||||
|
</view>
|
||||||
|
|
||||||
|
<view v-else style=" margin: 20rpx; padding: 20rpx;">
|
||||||
|
<view @click="uploadFImg()" class=""
|
||||||
|
style=" display: flex; flex-direction: column; justify-content: center; align-items: center; ">
|
||||||
|
<img v-if="userInfo.headImg!=''" :src="Service.GetMateUrlByImg(userInfo.headImg)"
|
||||||
|
style="width: 140rpx; height: 140rpx; border-radius: 50%; " alt="" />
|
||||||
|
<view v-else class=""
|
||||||
|
style="background-color: #EBEBEB; width: 140rpx; height: 140rpx; border-radius: 50%; display: flex; align-items: center; justify-content: center; ">
|
||||||
|
<image :src="Service.GetIconImg('/static/index/my/edit/photo.png')"
|
||||||
|
style="width: 50rpx; height: 50rpx; " alt=""> </image>
|
||||||
|
</view>
|
||||||
|
<view class="" style="margin-top: 15rpx; font-size: 26rpx; color: #999999; ">
|
||||||
|
点击更换头像
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
|
||||||
|
<view class="" style=" margin-top: 30rpx; ">
|
||||||
|
<up-form labelWidth='90' labelPosition="left" :borderBottom="true" :model="userInfo" ref="form1">
|
||||||
|
<up-form-item label="昵称" prop="userInfo.name" ref="item1" :borderBottom="true">
|
||||||
|
<up-input inputAlign='right' v-model="userInfo.nick" border="none"></up-input>
|
||||||
|
</up-form-item>
|
||||||
|
|
||||||
|
<up-form-item label="性别" :borderBottom="true" style="position: relative;" prop="userInfo.sex">
|
||||||
|
<view class="" style=" position: absolute; top: 10rpx; right: 0; ">
|
||||||
|
<up-radio-group v-model="userInfo.sex" placement="row">
|
||||||
|
<up-radio v-for="(item, index) in radiolist1" activeColor='#FF6A00' :key="index"
|
||||||
|
iconPlacement="right" :label="item.name" :name="item.name">
|
||||||
|
</up-radio>
|
||||||
|
</up-radio-group>
|
||||||
|
</view>
|
||||||
|
</up-form-item>
|
||||||
|
<up-form-item label="生日" :borderBottom="true" prop="userInfo.sex" style="position: relative;">
|
||||||
|
<view @click="showDate=true" class=""
|
||||||
|
style=" position: absolute; top: 25rpx; right: 0; display: flex; align-items: center; ">
|
||||||
|
{{Service.formatDate(userInfo.date,2)}}
|
||||||
|
<u-icon name="arrow-right" size="24rpx" color="#000"></u-icon>
|
||||||
|
</view>
|
||||||
|
</up-form-item>
|
||||||
|
<up-form-item label="手机号" :borderBottom="true" prop="userInfo.sex">
|
||||||
|
<up-input inputAlign='right' v-model="userInfo.phone" border="none"></up-input>
|
||||||
|
</up-form-item>
|
||||||
|
</up-form>
|
||||||
|
</view>
|
||||||
|
|
||||||
|
<up-datetime-picker :maxDate="nowDate" :minDate="631123200000" :show="showDate" @cancel="showDate=!showDate"
|
||||||
|
@confirm="dateConfirm" v-model="userInfo.date" mode="date"></up-datetime-picker>
|
||||||
|
<view class="" style="width: 100%; height: 200rpx;">
|
||||||
|
|
||||||
|
</view>
|
||||||
|
<view class="" style=" width: 100% ; background-color: #fff; position: fixed; bottom: 15rpx; left: 0; ">
|
||||||
|
<view class=""
|
||||||
|
style=" margin: 0 20rpx; padding: 26rpx 0; color: #fff; display: flex; align-items: center; justify-content: center; border-radius: 60rpx; background-color: var(--nav-mian);">
|
||||||
|
保存信息
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script setup lang="ts">
|
||||||
|
import { onShow, onLoad } from "@dcloudio/uni-app";
|
||||||
|
import { Service } from '@/Service/Service';
|
||||||
|
import { ref } from "vue";
|
||||||
|
|
||||||
|
|
||||||
|
let loading = ref(true)
|
||||||
|
|
||||||
|
let showDate = ref(false)
|
||||||
|
const userInfo = ref({
|
||||||
|
headImg: '',
|
||||||
|
age: '1',
|
||||||
|
sex: '',
|
||||||
|
phone: '1',
|
||||||
|
date: Date.now(),
|
||||||
|
nick: '大大怪将军'
|
||||||
|
})
|
||||||
|
|
||||||
|
let nowDate = ref()
|
||||||
|
|
||||||
|
const radiolist1 = ref([
|
||||||
|
{
|
||||||
|
name: '男',
|
||||||
|
disabled: false,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: '女',
|
||||||
|
disabled: false,
|
||||||
|
}
|
||||||
|
]);
|
||||||
|
|
||||||
|
|
||||||
|
onLoad(() => {
|
||||||
|
setTimeout(() => {
|
||||||
|
loading.value = false;
|
||||||
|
}, 1500);
|
||||||
|
});
|
||||||
|
|
||||||
|
onShow(() => {
|
||||||
|
nowDate.value = new Date()
|
||||||
|
});
|
||||||
|
|
||||||
|
const dateConfirm = (e) => {
|
||||||
|
showDate.value = !showDate.value
|
||||||
|
userInfo.value.date = e.value
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
const uploadFImg = () => {
|
||||||
|
uni.chooseImage({
|
||||||
|
count: 1, // 最多选择3张图片
|
||||||
|
sizeType: ['original', 'compressed'], // 支持原图和压缩图
|
||||||
|
sourceType: ['album', 'camera'], // 可从相册选择或使用相机拍照
|
||||||
|
success: function (res) {
|
||||||
|
let path = res.tempFiles[0].path
|
||||||
|
userInfo.value.headImg = path
|
||||||
|
// Service.uploadH5(path, 'Avatar', data => {
|
||||||
|
// userInfo.value.headImg = data.split(',')[2].split(':')[1].split('"')[1]
|
||||||
|
// })
|
||||||
|
|
||||||
|
},
|
||||||
|
fail: function (err) {
|
||||||
|
console.error('选择失败:', err.errMsg);
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style lang="scss">
|
||||||
|
page {
|
||||||
|
background-color: #fff;
|
||||||
|
}
|
||||||
|
|
||||||
|
.pure-css-skeleton {
|
||||||
|
background-color: #f8f8f8;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 骨架屏基础样式 */
|
||||||
|
.skeleton-circle {
|
||||||
|
width: 140rpx;
|
||||||
|
height: 140rpx;
|
||||||
|
border-radius: 50%;
|
||||||
|
background-color: #e0e0e0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.skeleton-text {
|
||||||
|
width: 120rpx;
|
||||||
|
height: 26rpx;
|
||||||
|
background-color: #e0e0e0;
|
||||||
|
border-radius: 4rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
.form-item-skeleton {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
padding: 20rpx 0;
|
||||||
|
border-bottom: 1px solid #f5f5f5;
|
||||||
|
position: relative;
|
||||||
|
}
|
||||||
|
|
||||||
|
.form-item-skeleton:last-child {
|
||||||
|
border-bottom: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
.form-label-skeleton {
|
||||||
|
width: 90rpx;
|
||||||
|
height: 30rpx;
|
||||||
|
background-color: #e0e0e0;
|
||||||
|
border-radius: 4rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
.form-input-skeleton {
|
||||||
|
position: absolute;
|
||||||
|
right: 0;
|
||||||
|
width: 50%;
|
||||||
|
height: 30rpx;
|
||||||
|
background-color: #e0e0e0;
|
||||||
|
border-radius: 4rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
.form-radio-skeleton {
|
||||||
|
position: absolute;
|
||||||
|
right: 0;
|
||||||
|
display: flex;
|
||||||
|
gap: 20rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
.radio-item-skeleton {
|
||||||
|
width: 100rpx;
|
||||||
|
height: 30rpx;
|
||||||
|
background-color: #e0e0e0;
|
||||||
|
border-radius: 4rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
.bottom-button-skeleton {
|
||||||
|
position: fixed;
|
||||||
|
bottom: 15rpx;
|
||||||
|
left: 20rpx;
|
||||||
|
right: 20rpx;
|
||||||
|
height: 90rpx;
|
||||||
|
background-color: #e0e0e0;
|
||||||
|
border-radius: 60rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 动画效果 - 不使用组件,纯CSS实现 */
|
||||||
|
@keyframes pulse {
|
||||||
|
0% {
|
||||||
|
opacity: 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
50% {
|
||||||
|
opacity: 0.6;
|
||||||
|
}
|
||||||
|
|
||||||
|
100% {
|
||||||
|
opacity: 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.animate-pulse {
|
||||||
|
animation: pulse 1.5s ease-in-out infinite;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
@@ -0,0 +1,361 @@
|
|||||||
|
<template>
|
||||||
|
|
||||||
|
<view v-if="loading" class="skeleton-container">
|
||||||
|
<!-- 安全等级卡片骨架 -->
|
||||||
|
<view class="security-level-card skeleton-card">
|
||||||
|
<view class="security-level-header">
|
||||||
|
<view class="skeleton-line skeleton-line-sm"></view>
|
||||||
|
</view>
|
||||||
|
<view class="progress-bar skeleton-progress"></view>
|
||||||
|
<view class="skeleton-line skeleton-line-xs"></view>
|
||||||
|
</view>
|
||||||
|
|
||||||
|
<!-- 安全设置列表骨架 -->
|
||||||
|
<view class="security-settings skeleton-settings">
|
||||||
|
<view class="security-item skeleton-item" v-for="i in 3" :key="i">
|
||||||
|
<view class="item-left">
|
||||||
|
<view class="item-icon skeleton-icon"></view>
|
||||||
|
<view class="skeleton-line skeleton-line-md"></view>
|
||||||
|
</view>
|
||||||
|
<view class="item-right">
|
||||||
|
<view class="skeleton-line skeleton-line-sm"></view>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
|
||||||
|
<!-- 安全提示卡片骨架 -->
|
||||||
|
<view class="security-tip-card skeleton-tip-card">
|
||||||
|
<view class="tip-content">
|
||||||
|
<view class="skeleton-circle"></view>
|
||||||
|
<view class="skeleton-line skeleton-line-full"></view>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
|
||||||
|
<view v-else class="account-security-page" style="overflow: hidden;" >
|
||||||
|
<!-- 安全等级卡片 -->
|
||||||
|
<view class="security-level-card">
|
||||||
|
<view class="security-level-header">
|
||||||
|
<text class="security-level-label">账号安全等级:</text>
|
||||||
|
<text class="security-level-value">高</text>
|
||||||
|
</view>
|
||||||
|
<view class="progress-bar">
|
||||||
|
<view class="progress-fill"></view>
|
||||||
|
</view>
|
||||||
|
<view class="security-desc">您已完成所有安全设置</view>
|
||||||
|
</view>
|
||||||
|
|
||||||
|
<!-- 安全设置列表 -->
|
||||||
|
<view class="security-settings">
|
||||||
|
<!-- 实名认证 -->
|
||||||
|
<view class="security-item" @click="Service.GoPage(item.path)" v-for="(item,index) in funcList" :key="index">
|
||||||
|
<view class="item-left">
|
||||||
|
<view class="item-icon">
|
||||||
|
<image :src="Service.GetIconImg(item.icon)" style="width: 100%; height: 100%; " mode=""></image>
|
||||||
|
</view>
|
||||||
|
<text class="item-label">{{item.name}}</text>
|
||||||
|
</view>
|
||||||
|
<view class="item-right">
|
||||||
|
<text class="item-status">{{ item.des }}</text>
|
||||||
|
<up-icon name="arrow-right" size="19" color="#999"></up-icon>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
|
||||||
|
</view>
|
||||||
|
|
||||||
|
<!-- 安全提示卡片 -->
|
||||||
|
<view class="security-tip-card">
|
||||||
|
<view class="tip-content">
|
||||||
|
<up-icon name="info-circle-fill" size="24" color="#999"></up-icon>
|
||||||
|
<text class="tip-text">为保障您的账号安全,请勿泄露验证码,定期更新密码。</text>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script setup lang="ts">
|
||||||
|
import { onLoad, onShow } from '@dcloudio/uni-app'
|
||||||
|
import { Service } from "@/Service/Service"
|
||||||
|
import { ref } from 'vue'
|
||||||
|
import { CNRiderDataService } from "@/Service/CN/CNRiderDataService"
|
||||||
|
|
||||||
|
let loading = ref(true)
|
||||||
|
|
||||||
|
let riderInfo=ref<any>({})
|
||||||
|
|
||||||
|
|
||||||
|
const funcList = ref([
|
||||||
|
{
|
||||||
|
name: '实名认证',
|
||||||
|
icon: '/static/index/my/security/security.png',
|
||||||
|
des: "已认证",
|
||||||
|
path:'/pages/my/authentication'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: '手机号绑定',
|
||||||
|
icon: '/static/index/my/security/phone.png',
|
||||||
|
des: "",
|
||||||
|
path:'/pages/my/setConnect?type=1'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: '紧急联系人',
|
||||||
|
icon: '/static/index/my/security/user.png',
|
||||||
|
des: "",
|
||||||
|
path:'/pages/my/setConnect?type=0'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: '修改密码',
|
||||||
|
icon: '/static/index/my/security/mima.png',
|
||||||
|
des: "",
|
||||||
|
path:'/pages/my/editPasssword'
|
||||||
|
}
|
||||||
|
|
||||||
|
])
|
||||||
|
|
||||||
|
// 页面加载时的逻辑
|
||||||
|
onLoad(() => {
|
||||||
|
|
||||||
|
})
|
||||||
|
|
||||||
|
onShow(()=>{
|
||||||
|
getData()
|
||||||
|
getConnect()
|
||||||
|
})
|
||||||
|
|
||||||
|
|
||||||
|
const getData = () => {
|
||||||
|
CNRiderDataService.GetRiderInfo().then(res => {
|
||||||
|
loading.value = false
|
||||||
|
if(res.data){
|
||||||
|
riderInfo.value=res.data.riderInfo
|
||||||
|
funcList.value[0].des=riderInfo.value.status===-1?'未认证':(riderInfo.value.status===0?'审核中':'已认证')
|
||||||
|
funcList.value[1].des='已绑定'+' '+riderInfo.value.phone.slice(0,3)+'****'+riderInfo.value.phone.slice(-4)
|
||||||
|
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
const getConnect=()=>{
|
||||||
|
CNRiderDataService.GetRiderExigency().then(res=>{
|
||||||
|
if(res.data){
|
||||||
|
funcList.value[2].des= res.data.info? res.data.info.phone : '未绑定'
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style lang="scss">
|
||||||
|
page {
|
||||||
|
background-color: #f5f5f5;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 安全等级卡片样式
|
||||||
|
.security-level-card {
|
||||||
|
background-color: #E6F7FF;
|
||||||
|
margin: 30rpx 30rpx 30rpx;
|
||||||
|
padding: 30rpx;
|
||||||
|
border-radius: 16rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
.security-level-header {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
margin-bottom: 20rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
.security-level-label {
|
||||||
|
font-size: 28rpx;
|
||||||
|
color: #333;
|
||||||
|
}
|
||||||
|
|
||||||
|
.security-level-value {
|
||||||
|
font-size: 32rpx;
|
||||||
|
font-weight: 600;
|
||||||
|
color: #007AFF;
|
||||||
|
}
|
||||||
|
|
||||||
|
.progress-bar {
|
||||||
|
width: 100%;
|
||||||
|
height: 8rpx;
|
||||||
|
background-color: #B3D8FF;
|
||||||
|
border-radius: 4rpx;
|
||||||
|
overflow: hidden;
|
||||||
|
margin-bottom: 16rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
.progress-fill {
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
background-color: #007AFF;
|
||||||
|
border-radius: 4rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
.security-desc {
|
||||||
|
font-size: 24rpx;
|
||||||
|
color: #666;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 安全设置列表样式
|
||||||
|
.security-settings {
|
||||||
|
background-color: #fff;
|
||||||
|
margin: 0 30rpx 30rpx;
|
||||||
|
border-radius: 16rpx;
|
||||||
|
overflow: hidden;
|
||||||
|
}
|
||||||
|
|
||||||
|
.security-item {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: space-between;
|
||||||
|
padding: 30rpx;
|
||||||
|
border-bottom: 1rpx solid #f0f0f0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.security-item:last-child {
|
||||||
|
border-bottom: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
.item-left {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.item-icon {
|
||||||
|
width: 50rpx;
|
||||||
|
height: 50rpx;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
margin-right: 20rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
.item-label {
|
||||||
|
font-size: 32rpx;
|
||||||
|
color: #333;
|
||||||
|
}
|
||||||
|
|
||||||
|
.item-right {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.item-status {
|
||||||
|
font-size: 28rpx;
|
||||||
|
color: #4CD964;
|
||||||
|
margin-right: 10rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 安全提示卡片样式
|
||||||
|
.security-tip-card {
|
||||||
|
background-color: #FFF8E8;
|
||||||
|
margin: 0 30rpx;
|
||||||
|
padding: 24rpx;
|
||||||
|
border-radius: 16rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
.tip-content {
|
||||||
|
display: flex;
|
||||||
|
align-items: flex-start;
|
||||||
|
}
|
||||||
|
|
||||||
|
.tip-text {
|
||||||
|
flex: 1;
|
||||||
|
font-size: 24rpx;
|
||||||
|
color: #999;
|
||||||
|
line-height: 36rpx;
|
||||||
|
margin-left: 10rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 骨架屏基础样式
|
||||||
|
.skeleton-line {
|
||||||
|
background: linear-gradient(90deg, #f0f0f0 25%, #e0e0e0 50%, #f0f0f0 75%);
|
||||||
|
background-size: 200% 100%;
|
||||||
|
animation: skeleton-loading 1.5s infinite;
|
||||||
|
border-radius: 4rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
.skeleton-icon {
|
||||||
|
background: linear-gradient(90deg, #f0f0f0 25%, #e0e0e0 50%, #f0f0f0 75%);
|
||||||
|
background-size: 200% 100%;
|
||||||
|
animation: skeleton-loading 1.5s infinite;
|
||||||
|
border-radius: 8rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
.skeleton-circle {
|
||||||
|
background: linear-gradient(90deg, #f0f0f0 25%, #e0e0e0 50%, #f0f0f0 75%);
|
||||||
|
background-size: 200% 100%;
|
||||||
|
animation: skeleton-loading 1.5s infinite;
|
||||||
|
border-radius: 50%;
|
||||||
|
width: 40rpx;
|
||||||
|
height: 40rpx;
|
||||||
|
margin-right: 16rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
.skeleton-progress {
|
||||||
|
background: linear-gradient(90deg, #f0f0f0 25%, #e0e0e0 50%, #f0f0f0 75%);
|
||||||
|
background-size: 200% 100%;
|
||||||
|
animation: skeleton-loading 1.5s infinite;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 骨架屏线条尺寸
|
||||||
|
.skeleton-line-xs {
|
||||||
|
height: 28rpx;
|
||||||
|
width: 200rpx;
|
||||||
|
margin-top: 16rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
.skeleton-line-sm {
|
||||||
|
height: 32rpx;
|
||||||
|
width: 300rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
.skeleton-line-md {
|
||||||
|
height: 36rpx;
|
||||||
|
width: 240rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
.skeleton-line-full {
|
||||||
|
height: 36rpx;
|
||||||
|
width: calc(100% - 60rpx);
|
||||||
|
}
|
||||||
|
|
||||||
|
// 骨架屏动画
|
||||||
|
@keyframes skeleton-loading {
|
||||||
|
0% {
|
||||||
|
background-position: 200% 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
100% {
|
||||||
|
background-position: -200% 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 骨架屏容器样式
|
||||||
|
.skeleton-container {
|
||||||
|
overflow: hidden;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 骨架屏卡片样式
|
||||||
|
.skeleton-card {
|
||||||
|
background-color: #fff;
|
||||||
|
}
|
||||||
|
|
||||||
|
.skeleton-settings {
|
||||||
|
background-color: #fff;
|
||||||
|
}
|
||||||
|
|
||||||
|
.skeleton-item {
|
||||||
|
border-bottom: 1rpx solid #f0f0f0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.skeleton-item:last-child {
|
||||||
|
border-bottom: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
.skeleton-tip-card {
|
||||||
|
background-color: #fff;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
@@ -0,0 +1,600 @@
|
|||||||
|
<template>
|
||||||
|
<!-- 骨架屏 -->
|
||||||
|
<view v-if="loading" class="skeleton-container">
|
||||||
|
<!-- 余额区域骨架屏 -->
|
||||||
|
<view class="skeleton-balance-section">
|
||||||
|
<view class="skeleton-balance-label"></view>
|
||||||
|
<view class="skeleton-balance-amount"></view>
|
||||||
|
<view class="skeleton-balance-current"></view>
|
||||||
|
</view>
|
||||||
|
|
||||||
|
<!-- 账户选择区域骨架屏 -->
|
||||||
|
<view class="skeleton-account-section">
|
||||||
|
<view class="skeleton-section-title"></view>
|
||||||
|
<view class="skeleton-account-item">
|
||||||
|
<view class="skeleton-account-icon"></view>
|
||||||
|
<view class="skeleton-account-name"></view>
|
||||||
|
<view class="skeleton-account-radio"></view>
|
||||||
|
</view>
|
||||||
|
<view class="skeleton-account-item">
|
||||||
|
<view class="skeleton-account-icon"></view>
|
||||||
|
<view class="skeleton-account-name"></view>
|
||||||
|
<view class="skeleton-account-radio"></view>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
|
||||||
|
<!-- 提示信息骨架屏 -->
|
||||||
|
<view class="skeleton-tip-section">
|
||||||
|
<view class="skeleton-tip-icon"></view>
|
||||||
|
<view class="skeleton-tip-content">
|
||||||
|
<view class="skeleton-tip-line"></view>
|
||||||
|
<view class="skeleton-tip-line-small"></view>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
|
||||||
|
<!-- 确认按钮骨架屏 -->
|
||||||
|
<view class="skeleton-confirm-section">
|
||||||
|
<view class="skeleton-confirm-button"></view>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
<!-- 真实内容 -->
|
||||||
|
<view v-else class="withdraw-container">
|
||||||
|
<!-- 可提现金额 -->
|
||||||
|
<view class="balance-section">
|
||||||
|
<text class="balance-label">可提现金额</text>
|
||||||
|
<text class="balance-amount">¥{{ riderAcc.account }}</text>
|
||||||
|
<text class="current-balance">当前钱包余额</text>
|
||||||
|
</view>
|
||||||
|
|
||||||
|
<!-- 提现账户选择 -->
|
||||||
|
<view class="account-section">
|
||||||
|
<text class="section-title">提现账户</text>
|
||||||
|
<view class=""
|
||||||
|
style="display: flex;align-items: center; border-bottom: 4rpx solid #e2e2e2;padding-bottom: 10px; margin-bottom: 10px;">
|
||||||
|
<up-icon name="zhifubao-circle-fill" size="30" color="#1890ff"></up-icon>
|
||||||
|
<view style="flex: 1; margin-left: 30rpx; " class="">
|
||||||
|
支付宝
|
||||||
|
</view>
|
||||||
|
<view @click="changePay(0)" class="">
|
||||||
|
<view v-if="current==0" class="radio-circle">
|
||||||
|
<view class="radio-inner"></view>
|
||||||
|
</view>
|
||||||
|
<view v-else class="radio-no-circle">
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
<view class="" style="display: flex;align-items: center;">
|
||||||
|
<up-icon name="weixin-circle-fill" size="30" color="#28C445"></up-icon>
|
||||||
|
<view style="flex: 1; margin-left: 30rpx; " class="">
|
||||||
|
微信
|
||||||
|
</view>
|
||||||
|
<view @click="changePay(1)" class="">
|
||||||
|
<view v-if="current==1" class="radio-circle">
|
||||||
|
<view class="radio-inner"></view>
|
||||||
|
</view>
|
||||||
|
<view v-else class="radio-no-circle">
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
|
||||||
|
<!-- 提现账号 -->
|
||||||
|
<view class="" v-if="current!=null" style="margin: 20rpx 30rpx; ">
|
||||||
|
<view class="" style="font-size: 34rpx; font-weight: 600; ">
|
||||||
|
账号信息
|
||||||
|
</view>
|
||||||
|
|
||||||
|
<up-form labelPosition="top" label-width="200" :model="account" ref="form1">
|
||||||
|
<up-form-item label="姓名" prop="userInfo.name" :borderBottom="true" ref="item1">
|
||||||
|
<up-input v-model="account.name" @change="changePrice" placeholder="请输入姓名" border="none"></up-input>
|
||||||
|
</up-form-item>
|
||||||
|
<up-form-item :label="current==0? '支付宝账号':'微信账号'" prop="userInfo.name" :borderBottom="true" ref="item1">
|
||||||
|
<up-input v-model="account.id" :placeholder="current==0? '请输入支付宝账号':'请输入微信账号'"
|
||||||
|
border="none"></up-input>
|
||||||
|
</up-form-item>
|
||||||
|
<up-form-item label="提现金额" prop="userInfo.name" :borderBottom="true" ref="item1">
|
||||||
|
<up-input v-model="account.price" type="digit" placeholder="请输入提现金额" border="none"></up-input>
|
||||||
|
</up-form-item>
|
||||||
|
</up-form>
|
||||||
|
</view>
|
||||||
|
|
||||||
|
|
||||||
|
<!-- 提示信息 -->
|
||||||
|
<view class="tip-section">
|
||||||
|
<up-icon name="clock" size="18" color="#1890ff"></up-icon>
|
||||||
|
<view class="" style="margin-left: 10rpx;">
|
||||||
|
<view class="tip-text">预计 T+1 工作日到账</view>
|
||||||
|
<view class="tip-text" style="color: #666666; font-size: 24rpx; margin-top: 10rpx; ">无手续费</view>
|
||||||
|
</view>
|
||||||
|
|
||||||
|
</view>
|
||||||
|
|
||||||
|
<!-- 确认按钮 -->
|
||||||
|
<view class="confirm-section">
|
||||||
|
<button class="confirm-button" @click="confirmWithdraw">确认提现</button>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script setup lang="ts">
|
||||||
|
import { onLoad, onShow } from '@dcloudio/uni-app';
|
||||||
|
import { ref } from 'vue';
|
||||||
|
import { Service } from '@/Service/Service';
|
||||||
|
import { CNRiderOrderService } from '@/Service/CN/CNRiderOrderService'
|
||||||
|
import { CNRiderDataService } from '@/Service/CN/CNRiderDataService'
|
||||||
|
|
||||||
|
let current = ref(null)
|
||||||
|
let loading = ref(true)
|
||||||
|
|
||||||
|
|
||||||
|
let account = ref({
|
||||||
|
id: '',
|
||||||
|
price: "",
|
||||||
|
name: ''
|
||||||
|
})
|
||||||
|
|
||||||
|
let riderAcc = ref<any>({})
|
||||||
|
|
||||||
|
onLoad(() => {
|
||||||
|
|
||||||
|
})
|
||||||
|
|
||||||
|
onShow(()=>{
|
||||||
|
getData()
|
||||||
|
})
|
||||||
|
|
||||||
|
|
||||||
|
const getData = () => {
|
||||||
|
CNRiderDataService.GetRiderAccInfo().then(res => {
|
||||||
|
loading.value = false
|
||||||
|
if (res.data) {
|
||||||
|
riderAcc.value = res.data.riderAcc
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
const changePay = (item : any) => {
|
||||||
|
current.value = item
|
||||||
|
}
|
||||||
|
|
||||||
|
const changePrice = (e : string) => {
|
||||||
|
console.log(e);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// 确认提现
|
||||||
|
const confirmWithdraw = () => {
|
||||||
|
if(!current.value){
|
||||||
|
Service.Msg('请选择提现方式!')
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!account.value.name) {
|
||||||
|
Service.Msg('请输入姓名!')
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if (!account.value.price) {
|
||||||
|
Service.Msg('请输入提现金额!')
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if (!account.value.id) {
|
||||||
|
Service.Msg('请输入账户号!')
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
uni.showModal({
|
||||||
|
title: '提示',
|
||||||
|
content: '请仔细确认身份信息?',
|
||||||
|
success: function (res) {
|
||||||
|
if (res.confirm) {
|
||||||
|
CNRiderOrderService.AddRiderWith(Number(account.value.price), current.value == 0 ? '支付宝' : '微信', account.value.name, account.value.id).then(res => {
|
||||||
|
if (res.code == 0) {
|
||||||
|
Service.Msg('提现成功')
|
||||||
|
account.value.name=''
|
||||||
|
account.value.price=null
|
||||||
|
account.value.id=''
|
||||||
|
setTimeout(() => {
|
||||||
|
Service.GoPage('/pages/my/withDrowList')
|
||||||
|
}, 1000)
|
||||||
|
} else {
|
||||||
|
Service.Msg(res.msg)
|
||||||
|
}
|
||||||
|
|
||||||
|
})
|
||||||
|
} else {
|
||||||
|
// 用户点击取消后的操作
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
};
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style scoped>
|
||||||
|
.withdraw-container {
|
||||||
|
min-height: 100vh;
|
||||||
|
background-color: #fff;
|
||||||
|
padding-bottom: 40rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 选择 */
|
||||||
|
|
||||||
|
.radio-circle {
|
||||||
|
width: 36rpx;
|
||||||
|
height: 36rpx;
|
||||||
|
border: 2rpx solid var(--nav-mian);
|
||||||
|
border-radius: 50%;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
margin-right: 20rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
.radio-inner {
|
||||||
|
width: 20rpx;
|
||||||
|
height: 20rpx;
|
||||||
|
background-color: var(--nav-mian);
|
||||||
|
border-radius: 50%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.radio-no-circle {
|
||||||
|
width: 36rpx;
|
||||||
|
height: 36rpx;
|
||||||
|
border: 2rpx solid #dadada;
|
||||||
|
border-radius: 50%;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
margin-right: 20rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/* 顶部导航栏 */
|
||||||
|
.nav-bar {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: space-between;
|
||||||
|
padding: 30rpx 20rpx;
|
||||||
|
background-color: #fff;
|
||||||
|
position: sticky;
|
||||||
|
top: 0;
|
||||||
|
z-index: 100;
|
||||||
|
box-shadow: 0 2rpx 10rpx rgba(0, 0, 0, 0.05);
|
||||||
|
}
|
||||||
|
|
||||||
|
.nav-title {
|
||||||
|
font-size: 36rpx;
|
||||||
|
font-weight: 600;
|
||||||
|
color: #000;
|
||||||
|
}
|
||||||
|
|
||||||
|
.back-icon {
|
||||||
|
width: 40rpx;
|
||||||
|
height: 40rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
.help-icon {
|
||||||
|
width: 40rpx;
|
||||||
|
height: 40rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 余额显示区域 */
|
||||||
|
.balance-section {
|
||||||
|
background-color: #fff;
|
||||||
|
padding: 40rpx 30rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
.balance-label {
|
||||||
|
font-size: 32rpx;
|
||||||
|
color: #333;
|
||||||
|
display: block;
|
||||||
|
margin-bottom: 10rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
.balance-amount {
|
||||||
|
font-size: 60rpx;
|
||||||
|
font-weight: bold;
|
||||||
|
color: #ff4757;
|
||||||
|
display: block;
|
||||||
|
margin-bottom: 10rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
.current-balance {
|
||||||
|
font-size: 28rpx;
|
||||||
|
color: #999;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 账户选择区域 */
|
||||||
|
.account-section {
|
||||||
|
background-color: #fff;
|
||||||
|
padding: 30rpx;
|
||||||
|
margin-bottom: 20rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
.section-title {
|
||||||
|
font-size: 32rpx;
|
||||||
|
font-weight: 600;
|
||||||
|
color: #333;
|
||||||
|
display: block;
|
||||||
|
margin-bottom: 20rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
.account-item {
|
||||||
|
display: flex;
|
||||||
|
justify-content: space-between;
|
||||||
|
align-items: center;
|
||||||
|
padding: 25rpx 0;
|
||||||
|
border-bottom: 1rpx solid #f0f0f0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.account-item:last-child {
|
||||||
|
border-bottom: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
.account-info {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.account-icon {
|
||||||
|
width: 60rpx;
|
||||||
|
height: 60rpx;
|
||||||
|
border-radius: 12rpx;
|
||||||
|
background-color: #1677ff;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
margin-right: 20rpx;
|
||||||
|
border: 2rpx solid #000;
|
||||||
|
}
|
||||||
|
|
||||||
|
.account-icon.wechat {
|
||||||
|
background-color: #07c160;
|
||||||
|
}
|
||||||
|
|
||||||
|
.icon-text {
|
||||||
|
color: #fff;
|
||||||
|
font-size: 32rpx;
|
||||||
|
font-weight: bold;
|
||||||
|
}
|
||||||
|
|
||||||
|
.account-name {
|
||||||
|
font-size: 32rpx;
|
||||||
|
color: #333;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 提示信息区域 */
|
||||||
|
.tip-section {
|
||||||
|
display: flex;
|
||||||
|
align-items: flex-start;
|
||||||
|
background-color: #e6f7ff;
|
||||||
|
padding: 20rpx 30rpx;
|
||||||
|
margin: 0 30rpx 20rpx;
|
||||||
|
border-radius: 10rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
.tip-text {
|
||||||
|
font-size: 28rpx;
|
||||||
|
margin-left: 10rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 确认按钮区域 */
|
||||||
|
.confirm-section {
|
||||||
|
background-color: #fff;
|
||||||
|
position: fixed;
|
||||||
|
width: 100vw;
|
||||||
|
left: 0;
|
||||||
|
bottom: 0;
|
||||||
|
padding: 30rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
.confirm-button {
|
||||||
|
width: 100%;
|
||||||
|
height: 90rpx;
|
||||||
|
background-color: #1677ff;
|
||||||
|
color: #fff;
|
||||||
|
font-size: 36rpx;
|
||||||
|
font-weight: 600;
|
||||||
|
border-radius: 45rpx;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
border: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
.confirm-button:active {
|
||||||
|
background-color: #0958d9;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 骨架屏样式 */
|
||||||
|
.skeleton-container {
|
||||||
|
min-height: 100vh;
|
||||||
|
background-color: #fff;
|
||||||
|
padding-bottom: 40rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 骨架屏动画 */
|
||||||
|
@keyframes shimmer {
|
||||||
|
0% {
|
||||||
|
background-position: -1000px 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
100% {
|
||||||
|
background-position: 1000px 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 骨架屏通用样式 */
|
||||||
|
.skeleton-balance-section,
|
||||||
|
.skeleton-account-section,
|
||||||
|
.skeleton-tip-section {
|
||||||
|
padding: 40rpx 30rpx;
|
||||||
|
margin-bottom: 20rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 余额区域骨架屏 */
|
||||||
|
.skeleton-balance-section {
|
||||||
|
background-color: #fff;
|
||||||
|
}
|
||||||
|
|
||||||
|
.skeleton-balance-label {
|
||||||
|
width: 30%;
|
||||||
|
height: 32rpx;
|
||||||
|
background-color: #e6e6e6;
|
||||||
|
margin-bottom: 20rpx;
|
||||||
|
border-radius: 4rpx;
|
||||||
|
animation: shimmer 1.5s infinite;
|
||||||
|
background-image: linear-gradient(90deg, #f0f0f0 25%, #e0e0e0 50%, #f0f0f0 75%);
|
||||||
|
background-size: 1000px 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.skeleton-balance-amount {
|
||||||
|
width: 40%;
|
||||||
|
height: 60rpx;
|
||||||
|
background-color: #e6e6e6;
|
||||||
|
margin-bottom: 20rpx;
|
||||||
|
border-radius: 4rpx;
|
||||||
|
animation: shimmer 1.5s infinite;
|
||||||
|
background-image: linear-gradient(90deg, #f0f0f0 25%, #e0e0e0 50%, #f0f0f0 75%);
|
||||||
|
background-size: 1000px 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.skeleton-balance-current {
|
||||||
|
width: 25%;
|
||||||
|
height: 28rpx;
|
||||||
|
background-color: #e6e6e6;
|
||||||
|
border-radius: 4rpx;
|
||||||
|
animation: shimmer 1.5s infinite;
|
||||||
|
background-image: linear-gradient(90deg, #f0f0f0 25%, #e0e0e0 50%, #f0f0f0 75%);
|
||||||
|
background-size: 1000px 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 账户选择区域骨架屏 */
|
||||||
|
.skeleton-account-section {
|
||||||
|
background-color: #fff;
|
||||||
|
}
|
||||||
|
|
||||||
|
.skeleton-section-title {
|
||||||
|
width: 25%;
|
||||||
|
height: 32rpx;
|
||||||
|
background-color: #e6e6e6;
|
||||||
|
margin-bottom: 30rpx;
|
||||||
|
border-radius: 4rpx;
|
||||||
|
animation: shimmer 1.5s infinite;
|
||||||
|
background-image: linear-gradient(90deg, #f0f0f0 25%, #e0e0e0 50%, #f0f0f0 75%);
|
||||||
|
background-size: 1000px 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.skeleton-account-item {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
margin-bottom: 30rpx;
|
||||||
|
padding-bottom: 30rpx;
|
||||||
|
border-bottom: 4rpx solid #e2e2e2;
|
||||||
|
}
|
||||||
|
|
||||||
|
.skeleton-account-item:last-child {
|
||||||
|
border-bottom: none;
|
||||||
|
padding-bottom: 0;
|
||||||
|
margin-bottom: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.skeleton-account-icon {
|
||||||
|
width: 60rpx;
|
||||||
|
height: 60rpx;
|
||||||
|
background-color: #e6e6e6;
|
||||||
|
border-radius: 12rpx;
|
||||||
|
margin-right: 20rpx;
|
||||||
|
animation: shimmer 1.5s infinite;
|
||||||
|
background-image: linear-gradient(90deg, #f0f0f0 25%, #e0e0e0 50%, #f0f0f0 75%);
|
||||||
|
background-size: 1000px 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.skeleton-account-name {
|
||||||
|
flex: 1;
|
||||||
|
height: 32rpx;
|
||||||
|
background-color: #e6e6e6;
|
||||||
|
border-radius: 4rpx;
|
||||||
|
margin-right: 20rpx;
|
||||||
|
animation: shimmer 1.5s infinite;
|
||||||
|
background-image: linear-gradient(90deg, #f0f0f0 25%, #e0e0e0 50%, #f0f0f0 75%);
|
||||||
|
background-size: 1000px 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.skeleton-account-radio {
|
||||||
|
width: 36rpx;
|
||||||
|
height: 36rpx;
|
||||||
|
background-color: #e6e6e6;
|
||||||
|
border-radius: 50%;
|
||||||
|
animation: shimmer 1.5s infinite;
|
||||||
|
background-image: linear-gradient(90deg, #f0f0f0 25%, #e0e0e0 50%, #f0f0f0 75%);
|
||||||
|
background-size: 1000px 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 提示信息骨架屏 */
|
||||||
|
.skeleton-tip-section {
|
||||||
|
display: flex;
|
||||||
|
align-items: flex-start;
|
||||||
|
background-color: #e6f7ff;
|
||||||
|
padding: 20rpx 30rpx;
|
||||||
|
margin: 0 30rpx 20rpx;
|
||||||
|
border-radius: 10rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
.skeleton-tip-icon {
|
||||||
|
width: 40rpx;
|
||||||
|
height: 40rpx;
|
||||||
|
background-color: #e6e6e6;
|
||||||
|
border-radius: 50%;
|
||||||
|
margin-right: 15rpx;
|
||||||
|
animation: shimmer 1.5s infinite;
|
||||||
|
background-image: linear-gradient(90deg, #f0f0f0 25%, #e0e0e0 50%, #f0f0f0 75%);
|
||||||
|
background-size: 1000px 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.skeleton-tip-content {
|
||||||
|
flex: 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
.skeleton-tip-line {
|
||||||
|
width: 70%;
|
||||||
|
height: 28rpx;
|
||||||
|
background-color: #e6e6e6;
|
||||||
|
margin-bottom: 15rpx;
|
||||||
|
border-radius: 4rpx;
|
||||||
|
animation: shimmer 1.5s infinite;
|
||||||
|
background-image: linear-gradient(90deg, #f0f0f0 25%, #e0e0e0 50%, #f0f0f0 75%);
|
||||||
|
background-size: 1000px 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.skeleton-tip-line-small {
|
||||||
|
width: 50%;
|
||||||
|
height: 24rpx;
|
||||||
|
background-color: #e6e6e6;
|
||||||
|
border-radius: 4rpx;
|
||||||
|
animation: shimmer 1.5s infinite;
|
||||||
|
background-image: linear-gradient(90deg, #f0f0f0 25%, #e0e0e0 50%, #f0f0f0 75%);
|
||||||
|
background-size: 1000px 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 确认按钮骨架屏 */
|
||||||
|
.skeleton-confirm-section {
|
||||||
|
position: fixed;
|
||||||
|
bottom: 0;
|
||||||
|
left: 0;
|
||||||
|
width: 100%;
|
||||||
|
background-color: #fff;
|
||||||
|
padding: 30rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
.skeleton-confirm-button {
|
||||||
|
width: 100%;
|
||||||
|
height: 90rpx;
|
||||||
|
background-color: #e6e6e6;
|
||||||
|
border-radius: 45rpx;
|
||||||
|
animation: shimmer 1.5s infinite;
|
||||||
|
background-image: linear-gradient(90deg, #f0f0f0 25%, #e0e0e0 50%, #f0f0f0 75%);
|
||||||
|
background-size: 1000px 100%;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
@@ -0,0 +1,451 @@
|
|||||||
|
<template>
|
||||||
|
<!-- 骨架屏 -->
|
||||||
|
<view v-if="loading" class="order-detail skeleton-loading">
|
||||||
|
<!-- 订单基本信息骨架屏 -->
|
||||||
|
<view class="order-basic-info skeleton-section">
|
||||||
|
<view class="" style="display: flex; justify-content: space-between;align-items: center; ">
|
||||||
|
<view class="skeleton-block skeleton-short"></view>
|
||||||
|
<view class="skeleton-block skeleton-short"></view>
|
||||||
|
</view>
|
||||||
|
<view class="skeleton-block skeleton-long"></view>
|
||||||
|
<view class="" style="display: flex; align-items: center; justify-content: space-between;">
|
||||||
|
<view class="skeleton-block skeleton-medium"></view>
|
||||||
|
<view class="skeleton-block skeleton-medium"></view>
|
||||||
|
</view>
|
||||||
|
<view class="skeleton-block skeleton-medium"></view>
|
||||||
|
<view class="skeleton-block skeleton-long"></view>
|
||||||
|
</view>
|
||||||
|
|
||||||
|
<!-- 物品清单骨架屏 -->
|
||||||
|
<view class="order-basic-info skeleton-section">
|
||||||
|
<view v-for="item in 4" class="skeleton-block" style="width: 100%; height: 40rpx; "></view>
|
||||||
|
|
||||||
|
<view class="" style="display: flex; justify-content: center;">
|
||||||
|
<view class="skeleton-block skeleton-short"></view>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
|
||||||
|
<!-- 地图区域骨架屏 -->
|
||||||
|
<view class="map-section skeleton-section">
|
||||||
|
<view class="map-placeholder skeleton-map"></view>
|
||||||
|
</view>
|
||||||
|
|
||||||
|
<!-- 地址区域骨架屏 -->
|
||||||
|
<view class="address-section skeleton-section">
|
||||||
|
<view class="skeleton-block skeleton-medium"></view>
|
||||||
|
<view class="skeleton-block skeleton-long"></view>
|
||||||
|
<view class="skeleton-block skeleton-long"></view>
|
||||||
|
<view class="skeleton-block skeleton-medium"></view>
|
||||||
|
<view class="skeleton-block skeleton-long"></view>
|
||||||
|
<view class="skeleton-block skeleton-long"></view>
|
||||||
|
<view class="skeleton-block skeleton-long"></view>
|
||||||
|
</view>
|
||||||
|
|
||||||
|
<view class="bottom-padding"></view>
|
||||||
|
|
||||||
|
<!-- 底部按钮骨架屏 -->
|
||||||
|
<view class="bottom-action">
|
||||||
|
<view class="skeleton-button"></view>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
<!-- 实际内容 -->
|
||||||
|
<view v-else class="order-detail">
|
||||||
|
<!-- 订单基本信息 -->
|
||||||
|
<view class="order-basic-info">
|
||||||
|
<view class="info-item">
|
||||||
|
<view class="label" style="font-weight: 700; font-size: 30rpx;"> {{ orderInfo.distribution=='预约订单'?'预计'+orderInfo.makeTime.split(' ')[1]+'送达':orderInfo.makeTime }} </view>
|
||||||
|
</view>
|
||||||
|
<view class="info-item">
|
||||||
|
<text class="label">订单编号 : </text>
|
||||||
|
<text class="value">{{ orderId }}</text>
|
||||||
|
</view>
|
||||||
|
|
||||||
|
<view class="info-item">
|
||||||
|
<view class="label" style="display: flex; align-items: baseline;">
|
||||||
|
<u-icon name="clock" size="16" class="clock-icon"></u-icon>
|
||||||
|
{{ Service.formatDate(orderInfo.addTime,1) }} 下单
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
|
||||||
|
</view>
|
||||||
|
|
||||||
|
<!-- 物品清单 -->
|
||||||
|
<view class="order-basic-info">
|
||||||
|
<view class="" style="display: flex; align-items: center; ">
|
||||||
|
<view class="" style="flex: 1; font-size: 34rpx; font-weight: 600; ">
|
||||||
|
物品清单
|
||||||
|
</view>
|
||||||
|
<view class="" style="width: 100rpx; text-align: right; font-size: 30rpx; ">
|
||||||
|
数量
|
||||||
|
</view>
|
||||||
|
<view class="" style="width: 120rpx; text-align: right; font-size: 30rpx; ">
|
||||||
|
金额
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
<!-- 商品列表 -->
|
||||||
|
<view class="" :style="{'height':isShow?'110rpx':'fit-content' }" style="overflow: hidden;">
|
||||||
|
<view class="" v-for="(goodsItem,goodsIndex) in JSON.parse(orderInfo.detail) " :key="goodsIndex"
|
||||||
|
style="display: flex; align-items: center; margin-top: 15rpx; ">
|
||||||
|
<view class="" style="flex: 1; ">
|
||||||
|
{{goodsItem.goodsName}}
|
||||||
|
</view>
|
||||||
|
<view class="" style="width: 100rpx; text-align: right; ">
|
||||||
|
×{{ goodsItem.count }}
|
||||||
|
</view>
|
||||||
|
<view class="" style="width: 120rpx; text-align: right; ">
|
||||||
|
¥{{ goodsItem.count*goodsItem.price }}
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
<view class="" style="display: flex; align-items: center; justify-content: space-between;" >
|
||||||
|
<view class="">
|
||||||
|
|
||||||
|
</view>
|
||||||
|
<view class="info-item">
|
||||||
|
<text class="label" style="font-weight: 700;">配送费</text>
|
||||||
|
<text class="value price">¥{{ Number(orderInfo.postage).toFixed(2) }}</text>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
<view class="" v-if="JSON.parse(orderInfo.detail).length>2" @click="isShow=!isShow"
|
||||||
|
style=" margin-top: 20rpx; display: flex; align-items: center; justify-content: center; color: #666; ">
|
||||||
|
<up-icon :name="isShow?'arrow-down':'arrow-up'" color="#666" size="18"></up-icon>
|
||||||
|
{{isShow?'展开':'收入'}}
|
||||||
|
</view>
|
||||||
|
|
||||||
|
</view>
|
||||||
|
|
||||||
|
<!-- 地图区域 -->
|
||||||
|
<view class="map-section">
|
||||||
|
<view class="map-placeholder">
|
||||||
|
<text @click="Service.GoPage('/pages/order/navigation')" class="map-hint">点击查看完整导航</text>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
|
||||||
|
<!-- 取餐地址 -->
|
||||||
|
<view class="address-section">
|
||||||
|
<view class="" style=" border-bottom: 4rpx solid #e2e2e2; ">
|
||||||
|
<view class="section-title">取餐地址 : </view>
|
||||||
|
<view class="address-content">
|
||||||
|
<text class="store-name">{{ storeInfo.name }}</text>
|
||||||
|
<text class="address"> {{ storeInfo.city }}{{storeInfo.region }}{{ storeInfo.address }}</text>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
<view style="margin: 10rpx 0; font-size: 30rpx;font-weight: 800;color: #333;">送餐地址 : </view>
|
||||||
|
<view class="address-content">
|
||||||
|
<text class="user-name">{{ JSON.parse(orderInfo.address).realName }}</text>
|
||||||
|
<text class="address">{{ JSON.parse(orderInfo.address).address }}</text>
|
||||||
|
<view v-if="orderInfo.remark" class="remark">
|
||||||
|
<text class="remark-label">备注:</text>
|
||||||
|
<text class="remark-content">请放门口,勿按门铃</text>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
<view class="" style="width: 100vw; height: 140rpx; ">
|
||||||
|
|
||||||
|
</view>
|
||||||
|
|
||||||
|
<!-- 底部按钮 -->
|
||||||
|
<view class="bottom-action">
|
||||||
|
<up-button @click="placeOrder()" color="var(--nav-mian)" class="confirm-btn">立即接单</up-button>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script setup lang="ts">
|
||||||
|
import { onLoad } from '@dcloudio/uni-app';
|
||||||
|
import { ref, onMounted } from 'vue';
|
||||||
|
import { Service } from '@/Service/Service';
|
||||||
|
import { CNRiderOrderService } from '@/Service/CN/CNRiderOrderService'
|
||||||
|
|
||||||
|
// 加载状态
|
||||||
|
const loading = ref(true);
|
||||||
|
|
||||||
|
let orderStatus = ref(0)
|
||||||
|
|
||||||
|
let isShow = ref(true)
|
||||||
|
|
||||||
|
let deliveryTime = ref('')
|
||||||
|
|
||||||
|
let orderInfo = ref<any>({})
|
||||||
|
let storeInfo = ref<any>({})
|
||||||
|
let storeLocation = ref<any>({})
|
||||||
|
|
||||||
|
let orderId = ref('')
|
||||||
|
onLoad((data : any) => {
|
||||||
|
orderId.value = data.orderId
|
||||||
|
getData()
|
||||||
|
})
|
||||||
|
|
||||||
|
const getData = () => {
|
||||||
|
CNRiderOrderService.GetUnitOrderInfo(orderId.value).then(res => {
|
||||||
|
loading.value = false
|
||||||
|
|
||||||
|
if (res.data) {
|
||||||
|
deliveryTime.value = res.data.deliveryTime
|
||||||
|
orderInfo.value = res.data.orderInfo
|
||||||
|
storeInfo.value = res.data.storeInfo
|
||||||
|
storeLocation.value = res.data.storeLocation
|
||||||
|
}
|
||||||
|
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
const placeOrder = () => {
|
||||||
|
CNRiderOrderService.RiderTakeOrder(orderId.value).then(res => {
|
||||||
|
if (res.data) {
|
||||||
|
Service.Msg('接单成功!')
|
||||||
|
setTimeout(() => {
|
||||||
|
Service.GoPageBack()
|
||||||
|
},1000)
|
||||||
|
} else {
|
||||||
|
Service.Msg(res.msg)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style scoped>
|
||||||
|
.order-detail {
|
||||||
|
min-height: 100vh;
|
||||||
|
background-color: #f5f5f5;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 订单状态样式 */
|
||||||
|
.order-status {
|
||||||
|
background-color: #fff;
|
||||||
|
padding: 30rpx;
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* 订单基本信息样式 */
|
||||||
|
.order-basic-info {
|
||||||
|
background-color: #fff;
|
||||||
|
margin: 20rpx 20rpx;
|
||||||
|
padding: 30rpx;
|
||||||
|
border-radius: 20rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
.info-item {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
margin-bottom: 20rpx;
|
||||||
|
font-size: 28rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
.info-item:last-child {
|
||||||
|
margin-bottom: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.label {
|
||||||
|
color: #666;
|
||||||
|
margin-right: 10rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
.value {
|
||||||
|
color: #333;
|
||||||
|
}
|
||||||
|
|
||||||
|
.value.highlight {
|
||||||
|
color: var(--nav-diluted);
|
||||||
|
font-weight: 500;
|
||||||
|
}
|
||||||
|
|
||||||
|
.value.price {
|
||||||
|
color: var(--nav-diluted);
|
||||||
|
font-weight: 700;
|
||||||
|
}
|
||||||
|
|
||||||
|
.clock-icon {
|
||||||
|
color: #666;
|
||||||
|
margin-right: 8rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 地图区域样式 */
|
||||||
|
.map-section {
|
||||||
|
margin: 20rpx;
|
||||||
|
border-radius: 20rpx;
|
||||||
|
overflow: hidden;
|
||||||
|
}
|
||||||
|
|
||||||
|
.map-placeholder {
|
||||||
|
width: 100%;
|
||||||
|
height: 400rpx;
|
||||||
|
background-color: #f0f0f0;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
position: relative;
|
||||||
|
border: 1rpx solid #e8e8e8;
|
||||||
|
}
|
||||||
|
|
||||||
|
.map-placeholder::before {
|
||||||
|
content: '';
|
||||||
|
position: absolute;
|
||||||
|
top: 0;
|
||||||
|
left: 0;
|
||||||
|
right: 0;
|
||||||
|
bottom: 0;
|
||||||
|
background: linear-gradient(135deg, #f5f5f5 25%, #e6e6e6 25%, #e6e6e6 50%, #f5f5f5 50%, #f5f5f5 75%, #e6e6e6 75%, #e6e6e6 100%);
|
||||||
|
background-size: 20rpx 20rpx;
|
||||||
|
opacity: 0.3;
|
||||||
|
}
|
||||||
|
|
||||||
|
.map-hint {
|
||||||
|
font-size: 28rpx;
|
||||||
|
color: #666;
|
||||||
|
position: relative;
|
||||||
|
z-index: 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 地址区域样式 */
|
||||||
|
.address-section {
|
||||||
|
background-color: #fff;
|
||||||
|
margin: 20rpx;
|
||||||
|
padding: 30rpx;
|
||||||
|
border-radius: 20rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
.section-title {
|
||||||
|
font-size: 30rpx;
|
||||||
|
font-weight: 800;
|
||||||
|
color: #333;
|
||||||
|
margin: 10rpx 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.address-content {
|
||||||
|
position: relative;
|
||||||
|
}
|
||||||
|
|
||||||
|
.store-name,
|
||||||
|
.user-name {
|
||||||
|
font-size: 34rpx;
|
||||||
|
font-weight: 600;
|
||||||
|
margin-bottom: 15rpx;
|
||||||
|
display: block;
|
||||||
|
}
|
||||||
|
|
||||||
|
.address {
|
||||||
|
font-size: 26rpx;
|
||||||
|
color: #666;
|
||||||
|
line-height: 1.5;
|
||||||
|
margin-bottom: 25rpx;
|
||||||
|
display: block;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
.pickup-code,
|
||||||
|
.remark {
|
||||||
|
font-size: 26rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
.code-label,
|
||||||
|
.code-value {
|
||||||
|
color: var(--nav-mian);
|
||||||
|
font-weight: 600;
|
||||||
|
}
|
||||||
|
|
||||||
|
.remark-label,
|
||||||
|
.remark-content {
|
||||||
|
color: #FAAD14;
|
||||||
|
font-weight: 600;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 底部按钮样式 */
|
||||||
|
.bottom-action {
|
||||||
|
background-color: #fff;
|
||||||
|
width: 100vw;
|
||||||
|
position: fixed;
|
||||||
|
bottom: 0;
|
||||||
|
left: 0;
|
||||||
|
padding: 20rpx 30rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
.confirm-btn {
|
||||||
|
width: 100%;
|
||||||
|
height: 90rpx;
|
||||||
|
font-size: 32rpx;
|
||||||
|
line-height: 90rpx;
|
||||||
|
border-radius: 45rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 骨架屏样式 */
|
||||||
|
.skeleton-loading .skeleton-section {
|
||||||
|
margin: 20rpx 20rpx;
|
||||||
|
padding: 30rpx;
|
||||||
|
border-radius: 20rpx;
|
||||||
|
background-color: #fff;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
.skeleton-block {
|
||||||
|
background-color: #f0f0f0;
|
||||||
|
margin-bottom: 20rpx;
|
||||||
|
border-radius: 4rpx;
|
||||||
|
position: relative;
|
||||||
|
overflow: hidden;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
.skeleton-short {
|
||||||
|
height: 40rpx;
|
||||||
|
width: 30%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.skeleton-medium {
|
||||||
|
height: 30rpx;
|
||||||
|
width: 30%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.skeleton-long {
|
||||||
|
height: 30rpx;
|
||||||
|
width: 90%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.skeleton-map {
|
||||||
|
height: 400rpx;
|
||||||
|
background-color: #f0f0f0;
|
||||||
|
border-radius: 20rpx;
|
||||||
|
margin: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.skeleton-button {
|
||||||
|
height: 90rpx;
|
||||||
|
background-color: #f0f0f0;
|
||||||
|
border-radius: 45rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
.bottom-padding {
|
||||||
|
height: 140rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 骨架屏动画 */
|
||||||
|
.skeleton-block::after,
|
||||||
|
.skeleton-map::after,
|
||||||
|
.skeleton-button::after {
|
||||||
|
content: '';
|
||||||
|
position: absolute;
|
||||||
|
top: 0;
|
||||||
|
left: 0;
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
background: linear-gradient(90deg, transparent, rgba(255, 255, 255, 0.2), transparent);
|
||||||
|
animation: shimmer 1.5s infinite;
|
||||||
|
}
|
||||||
|
|
||||||
|
@keyframes shimmer {
|
||||||
|
0% {
|
||||||
|
transform: translateX(-100%);
|
||||||
|
}
|
||||||
|
|
||||||
|
100% {
|
||||||
|
transform: translateX(100%);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</style>
|
||||||
@@ -0,0 +1,131 @@
|
|||||||
|
<script setup lang="ts">
|
||||||
|
import { onLaunch, onShow, onHide } from "@dcloudio/uni-app";
|
||||||
|
import { onMounted, ref } from "vue";
|
||||||
|
import { WebSocket } from "@/Service/Comm/TwWebSocket";
|
||||||
|
import { Service } from "@/Service/Service"
|
||||||
|
import { CNRiderOrderService } from '@/Service/CN/CNRiderOrderService'
|
||||||
|
|
||||||
|
let isios = ref(false)
|
||||||
|
var socket = new WebSocket();
|
||||||
|
|
||||||
|
const currentLatitude = ref(0);
|
||||||
|
const currentLongitude = ref(0);
|
||||||
|
|
||||||
|
let locationTimer: ReturnType<typeof setInterval> | null = null;
|
||||||
|
|
||||||
|
|
||||||
|
onLaunch(() => {
|
||||||
|
isios.value = uni.getSystemInfoSync().platform != 'ios'//是否为ios
|
||||||
|
//#ifdef APP-PLUS//app
|
||||||
|
if (isios.value) {
|
||||||
|
// getVersion()//更新
|
||||||
|
}
|
||||||
|
//#endif
|
||||||
|
|
||||||
|
//链接服务器
|
||||||
|
uni.$on("ImCom", () => {
|
||||||
|
socket.ConnectSocketInit();
|
||||||
|
})
|
||||||
|
uni.$on("ImComOff", function (data) {
|
||||||
|
socket.CloseSocket(data);
|
||||||
|
})
|
||||||
|
startFetchingLocation();
|
||||||
|
});
|
||||||
|
onShow(() => {
|
||||||
|
Service.SetStorageCache('isHede',false)
|
||||||
|
//链接服务器
|
||||||
|
if (Service.GetUserIsLogin()) {
|
||||||
|
uni.$emit('ImCom')
|
||||||
|
}
|
||||||
|
|
||||||
|
});
|
||||||
|
onHide(() => {
|
||||||
|
Service.SetStorageCache('isHede',true)
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
|
const startFetchingLocation = () => {
|
||||||
|
// 安全检查:如果定时器已存在,先清除,防止重复启动
|
||||||
|
if (locationTimer) {
|
||||||
|
clearInterval(locationTimer);
|
||||||
|
}
|
||||||
|
|
||||||
|
console.log("开始定时获取位置,间隔1分钟...");
|
||||||
|
|
||||||
|
// 1. 立即执行第一次获取
|
||||||
|
getLocationNow();
|
||||||
|
|
||||||
|
// 2. 设置定时器,每 60000 毫秒 (1分钟) 执行一次
|
||||||
|
locationTimer = setInterval(() => {
|
||||||
|
getLocationNow();
|
||||||
|
}, 60000);
|
||||||
|
};
|
||||||
|
|
||||||
|
const getLocationNow = () => {
|
||||||
|
console.log("正在获取当前经纬度...");
|
||||||
|
|
||||||
|
uni.getLocation({
|
||||||
|
type: 'wgs84',
|
||||||
|
isHighAccuracy: true,
|
||||||
|
success: (res) => {
|
||||||
|
console.log('成功获取到新位置:', res);
|
||||||
|
|
||||||
|
// 更新页面上的数据显示
|
||||||
|
|
||||||
|
console.log(res.latitude,res.longitude,'===')
|
||||||
|
|
||||||
|
if(Service.GetUserIsLogin()){
|
||||||
|
CNRiderOrderService.UpdateRiderLocation(res.longitude,res.latitude).then(res=>{})
|
||||||
|
}
|
||||||
|
|
||||||
|
},
|
||||||
|
fail: (err) => {
|
||||||
|
console.error('获取经纬度失败:', err);
|
||||||
|
// (可选) 可以在这里添加失败提示
|
||||||
|
// uni.showToast({ title: '获取位置失败', icon: 'none' });
|
||||||
|
}
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 停止定时获取位置
|
||||||
|
*/
|
||||||
|
const stopFetchingLocation = () => {
|
||||||
|
if (locationTimer) {
|
||||||
|
clearInterval(locationTimer);
|
||||||
|
locationTimer = null; // 清理 ID
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
const getUpData = () => {
|
||||||
|
// #ifdef APP
|
||||||
|
// plus.runtime.getProperty(plus.runtime.appid, (wgtinfo) => {
|
||||||
|
// NvpMerchService.GetAppVersion().then(res=>{
|
||||||
|
// console.log('wgtinfo.versionCode',wgtinfo.versionCode);
|
||||||
|
// if (res.data.version > wgtinfo.versionCode) {
|
||||||
|
// setTimeout(function() {
|
||||||
|
// uni.navigateTo({
|
||||||
|
// url: "/pages/upData/upData?info=" +
|
||||||
|
// encodeURIComponent(
|
||||||
|
// JSON.stringify(res.data))
|
||||||
|
// })
|
||||||
|
// }, 1000)
|
||||||
|
// }
|
||||||
|
// })
|
||||||
|
// })
|
||||||
|
// #endif
|
||||||
|
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
<style lang="scss">
|
||||||
|
@import "uview-plus/index.scss";
|
||||||
|
@import "colorui/main.css";
|
||||||
|
@import "colorui/icon.css";
|
||||||
|
|
||||||
|
page {
|
||||||
|
--nav-mian: #1890FF; //全局颜色
|
||||||
|
--nav-vice: #52C41A; //副颜色
|
||||||
|
--nav-diluted: #FF4D4F; //次颜色
|
||||||
|
|
||||||
|
}
|
||||||
|
</style>
|
||||||