Browse Source

feat: 新增快捷下单组件并优化订单相关功能

- 新增 `QuickOrderEntry` 组件,用于快捷下单入口
- 优化订单页面逻辑,支持订单状态筛选和操作
- 新增地址管理功能,支持地址的增删改查
- 优化支付流程,支持微信支付
- 修复部分样式问题,提升用户体验
master
前端-胡立永 1 month ago
parent
commit
8c2dfb4b2c
28 changed files with 2051 additions and 1050 deletions
  1. +1
    -1
      .cursor/rules/md.mdc
  2. +11
    -0
      api/model/index.js
  3. +207
    -0
      components/QuickOrderEntry.vue
  4. +2
    -1
      components/config/customerServicePopup.vue
  5. +4
    -1
      components/userShop/userShopCommission.vue
  6. +1
    -1
      config.js
  7. +2
    -2
      mixins/order.js
  8. +22
    -8
      pages.json
  9. +9
    -11
      pages/index/center.vue
  10. +31
    -71
      pages/index/index.vue
  11. +229
    -231
      pages/index/order.vue
  12. +5
    -5
      pages_order/auth/wxUserInfo.vue
  13. +0
    -1
      pages_order/components/address/addressList.vue
  14. +10
    -6
      pages_order/components/address/redactAddress.vue
  15. +227
    -0
      pages_order/components/address/redactAddressForm.vue
  16. +36
    -0
      pages_order/mine/about.vue
  17. +3
    -2
      pages_order/mine/address.vue
  18. +33
    -9
      pages_order/mine/individualTeam.vue
  19. +7
    -1
      pages_order/mine/purse.vue
  20. +203
    -173
      pages_order/mine/runningWater.vue
  21. +6
    -6
      pages_order/order/createOrder.vue
  22. +444
    -2
      pages_order/order/firmOrder.vue
  23. +518
    -507
      pages_order/order/orderDetail.vue
  24. +12
    -10
      pages_order/order/voiceOrder.vue
  25. BIN
      pages_order/static/address/icon.png
  26. BIN
      static/image/center/10.png
  27. BIN
      static/image/center/headImage.png
  28. +28
    -1
      utils/index.js

+ 1
- 1
.cursor/rules/md.mdc View File

@ -1,7 +1,7 @@
---
description:
globs:
alwaysApply: false
alwaysApply: true
---
请你写代码之前先查看一下README.md文件,按照这个文件中说的写


+ 11
- 0
api/model/index.js View File

@ -113,6 +113,17 @@ const api = {
method: 'POST',
limit : 1000,
},
// 获取团队信息
getTeamHeader: {
url: '/info/getTeamHeader',
method: 'GET',
},
// 取消订单
cancelOrder: {
url: '/order/cancelOrder',
method: 'POST',
limit : 1000,
},
}
export default api

+ 207
- 0
components/QuickOrderEntry.vue View File

@ -0,0 +1,207 @@
<template>
<view class="quick-order-container" @click="handleClick">
<view class="new-message" v-if="innerHasNewMessage">
你有新的快捷下单信息
</view>
<view class="quick-order">
<view class="number-order" v-if="innerMessageCount > 0">
{{ innerMessageCount }}
</view>
<image :src="imageUrl" mode=""></image>
</view>
</view>
</template>
<script>
export default {
name: 'QuickOrderEntry',
props: {
//
imageUrl: {
type: String,
default: '/static/image/home/7.png'
},
//
targetUrl: {
type: String,
default: '/pages_order/order/fastCreateOrder'
},
//
autoFetch: {
type: Boolean,
default: true
}
},
data() {
return {
orderInfo: null,
innerHasNewMessage: false,
innerMessageCount: 0,
isInitialized: false
}
},
methods: {
//
handleClick() {
// 便
this.$emit('click');
//
if (Array.isArray(this.orderInfo) && this.orderInfo.length > 0) {
this.$emit('order-info', this.orderInfo);
}
if(this.orderInfo.length > 0){
this.navigateTo('/pages_order/order/firmOrder');
return
}
//
if (this.targetUrl) {
this.navigateTo(this.targetUrl);
}
},
//
getQuickOrderInfo() {
//
this.$api('getOrderInfo', {}, res => {
if (res.code === 200 && res.result) {
//
const orderList = Array.isArray(res.result) ? res.result : [res.result];
if (orderList.length > 0) {
//
this.orderInfo = orderList;
//
this.innerHasNewMessage = true;
this.innerMessageCount = orderList.length;
//
this.$emit('order-loaded', this.orderInfo);
} else {
this.innerHasNewMessage = false;
this.innerMessageCount = 0;
this.orderInfo = [];
}
} else {
this.innerHasNewMessage = false;
this.innerMessageCount = 0;
this.orderInfo = [];
}
this.isInitialized = true;
}, err => {
console.error('获取快捷下单信息失败', err);
this.innerHasNewMessage = false;
this.innerMessageCount = 0;
this.orderInfo = [];
this.isInitialized = true;
});
},
//
navigateTo(url) {
// 使ID
if (Array.isArray(this.orderInfo) && this.orderInfo.length > 0 && this.orderInfo[0].id && url.indexOf('?') === -1) {
url += `?orderId=${this.orderInfo[0].id}`;
}
this.$utils.navigateTo(url);
},
//
refresh() {
this.getQuickOrderInfo();
return this; //
},
//
clearMessage() {
this.innerHasNewMessage = false;
this.innerMessageCount = 0;
return this; //
},
//
hasNewMessage() {
return this.innerHasNewMessage;
},
//
getMessageCount() {
return this.innerMessageCount;
},
//
getOrderInfo() {
return this.orderInfo;
}
},
}
</script>
<style scoped lang="scss">
.quick-order-container {
position: fixed;
right: 30rpx;
bottom: 30vh;
z-index: 99;
transition: transform 0.3s;
&:active {
transform: scale(0.95);
}
.new-message {
position: absolute;
top: 50rpx;
right: 100%;
white-space: nowrap;
background-color: #DC2828;
border-radius: 20rpx;
font-size: 25rpx;
color: #ffffff;
padding: 5rpx 15rpx;
margin-bottom: 10rpx;
box-shadow: 0 5rpx 10rpx rgba(220, 40, 40, 0.3);
animation: pulse 2s infinite;
}
.quick-order {
position: relative;
width: 230rpx;
height: 160rpx;
image {
width: 100%;
height: 100%;
}
.number-order {
background-color: #DC2828;
position: absolute;
font-size: 30rpx;
height: 40rpx;
width: 40rpx;
text-align: center;
border-radius: 20rpx;
color: #ffffff;
top: 10rpx;
left: 25rpx;
}
}
}
@keyframes pulse {
0% {
transform: scale(1);
}
50% {
transform: scale(1.05);
}
100% {
transform: scale(1);
}
}
</style>

+ 2
- 1
components/config/customerServicePopup.vue View File

@ -105,7 +105,8 @@
border-radius: 30rpx;
}
.btn1{
background-color: #ffb300;
background-color: rgba($color: $uni-color, $alpha: 0.2);
color: $uni-color;
}
.btn2{
background-color: $uni-color;


+ 4
- 1
components/userShop/userShopCommission.vue View File

@ -6,7 +6,7 @@
总佣金
</view>
<view class="num">
7890.34
{{ userInfo.money }}
</view>
</view>
@ -48,6 +48,9 @@
],
};
},
onLoad() {
this.$store.commit('getUserInfo');
},
methods : {
//
toPurse(){


+ 1
- 1
config.js View File

@ -7,7 +7,7 @@ import uvUI from '@/uni_modules/uv-ui-tools'
Vue.use(uvUI);
// 当前环境
const type = 'prod'
const type = 'dev'
// 环境配置


+ 2
- 2
mixins/order.js View File

@ -15,12 +15,12 @@ export default {
// if([0, 1].includes(item.shopState)){
// api = 'createOrderTwo'
// }else{
api = 'createSumOrderAgain'
api = 'payOrder'
// }
this.$api(api, {
orderId : item.id,
addressId : item.addressId
type : 1,
}, res => {
if(res.code == 200){
uni.requestPaymentWxPay(res)


+ 22
- 8
pages.json View File

@ -2,22 +2,24 @@
"pages": [{
"path": "pages/index/index",
"style": {
"navigationBarTitleText": "",
"navigationBarTextStyle": "white"
"navigationBarTextStyle": "white",
"enablePullDownRefresh": true
}
},
{
"path": "pages/index/order",
"style": {
"navigationBarTitleText": "",
"navigationBarTextStyle": "white"
"navigationBarTextStyle": "white",
"enablePullDownRefresh": true
}
},
{
"path": "pages/index/category",
"style": {
"navigationBarTitleText": "",
"navigationBarTextStyle": "white"
"navigationBarTextStyle": "white",
"enablePullDownRefresh": true
}
},
{
@ -49,14 +51,23 @@
}
},
{
"path": "mine/purse"
"path": "mine/purse",
"style": {
"navigationBarTextStyle": "white"
}
},
{
"path": "mine/runningWater"
"path": "mine/runningWater",
"style": {
"navigationBarTextStyle": "white",
"enablePullDownRefresh": true
}
},
{
"path": "mine/address"
"path": "mine/address",
"style": {
"enablePullDownRefresh": true
}
},
{
"path": "product/productDetail"
@ -96,6 +107,9 @@
},
{
"path": "mine/promotion"
},
{
"path": "mine/about"
}
]
}],


+ 9
- 11
pages/index/center.vue View File

@ -5,7 +5,7 @@
<view class="head">
<view class="headImage">
<image :src="userInfo.headImage || '/static/image/center/headImage.png'" mode=""></image>
<image :src="userInfo.headImage || '/static/image/center/headImage.png'" mode="aspectFill"></image>
</view>
<view class="info">
<view v-if="isLogin">
@ -34,23 +34,23 @@
<!-- 酒店 -->
<view class="user">
<view class="line">
<view class="item" style="">
<view class="line" @click="$utils.navigateTo('/pages_order/mine/purse')">
<view class="item">
<view class="image">
<image src="/static/image/center/1.png" mode=""></image>
</view>
<view class="">
我的佣金
<p style="color:#DC2828; font-weight: 700;">{{commission}}</p>
<p style="color:#DC2828; font-weight: 700;">{{ userInfo.money }}</p>
</view>
</view>
<view class="item">
<view class="item" @click="$utils.navigateTo('/pages_order/mine/purse')">
<view class="image">
<image src="/static/image/center/4.png" mode=""></image>
</view>
<view class="">
我的金额
<p style="color:#DC2828;font-weight: 700">{{balance}}</p>
<p style="color:#DC2828;font-weight: 700">{{ userInfo.price }}</p>
</view>
</view>
</view>
@ -99,10 +99,10 @@
<text class="grid-text">邀请好友</text>
</uv-grid-item>
<!-- <uv-grid-item @click="$utils.navigateTo('/pages_order/center/systemSet')">
<uv-grid-item @click="$utils.navigateTo('/pages_order/center/systemSet')">
<image class="image" src="/static/image/center/6.png" mode=""></image>
<text class="grid-text">系统设置</text>
</uv-grid-item> -->
</uv-grid-item>
<uv-grid-item @click="$utils.navigateTo('/pages_order/mine/help')">
<image class="image" src="/static/image/center/7.png" mode=""></image>
@ -110,7 +110,7 @@
</uv-grid-item>
<uv-grid-item
@click="$utils.navigateTo('/pages_order/auth/')">
@click="$utils.navigateTo('/pages_order/mine/about')">
<image class="image" src="/static/image/center/7.png" mode=""></image>
<text class="grid-text">关于本程序</text>
</uv-grid-item>
@ -140,8 +140,6 @@
data() {
return {
list: [],
commission: 0, //
balance: 0, //
isLogin: false, //
bannerList : [],
}


+ 31
- 71
pages/index/index.vue View File

@ -75,17 +75,11 @@
<PrivacyAgreementPoup />
<view class="quick-order-container" @click="toUrl">
<view class="new-message" v-if="false">
你有一条新的快捷下单信息
</view>
<view class="quick-order">
<view class="number-order" v-if="false">
1
</view>
<image src="../../static/image/home/7.png" mode=""></image>
</view>
</view>
<quick-order-entry
@click="handleQuickOrderClick"
@order-loaded="handleOrderLoaded"
ref="quickOrderEntry"
/>
<tabber select="home" />
</view>
@ -94,12 +88,14 @@
<script>
import PrivacyAgreementPoup from '@/components/config/PrivacyAgreementPoup.vue'
import tabber from '@/components/base/tabbar.vue'
import QuickOrderEntry from '@/components/QuickOrderEntry.vue'
import mixinsList from '@/mixins/list.js'
export default {
mixins: [mixinsList],
components: {
tabber,
PrivacyAgreementPoup,
QuickOrderEntry
},
data() {
return {
@ -107,6 +103,8 @@ export default {
bannerList : [],
menuList: [],
mixinsListApi: 'getProductList',
hasNewOrderMessage: false,
orderMessageCount: 0
}
},
computed: {
@ -115,17 +113,11 @@ export default {
this.getBanner()
this.getMenu()
if(uni.getStorageSync('token')){
this.getOrderInfo()
//
this.refreshQuickOrder()
}
},
methods: {
//
getOrderInfo(){
this.$api('getOrderInfo')
.then(res => {
})
},
//
getBanner() {
this.$api('getBanner', res => {
@ -160,6 +152,26 @@ export default {
url: item.url,
})
},
//
refreshQuickOrder() {
if (this.$refs.quickOrderEntry) {
this.$refs.quickOrderEntry.refresh();
}
},
//
handleQuickOrderClick() {
console.log('快捷下单按钮点击');
//
},
//
handleOrderLoaded(orderList) {
console.log('获取到快捷下单列表', orderList);
if (Array.isArray(orderList) && orderList.length > 0) {
//
//
}
},
}
}
</script>
@ -337,58 +349,6 @@ export default {
}
}
.quick-order-container {
position: fixed;
right: 30rpx;
bottom: 30vh;
z-index: 99;
transition: transform 0.3s;
&:active {
transform: scale(0.95);
}
}
.new-message {
position: absolute;
top: 50rpx;
right: 100%;
white-space: nowrap;
background-color: #DC2828;
border-radius: 20rpx;
font-size: 25rpx;
color: $uni-bg-color;
padding: 5rpx 15rpx;
margin-bottom: 10rpx;
box-shadow: 0 5rpx 10rpx rgba(220, 40, 40, 0.3);
animation: pulse 2s infinite;
}
.quick-order {
position: relative;
width: 230rpx;
height: 160rpx;
image {
width: 100%;
height: 100%;
}
.number-order {
background-color: #DC2828;
position: absolute;
font-size: 30rpx;
height: 40rpx;
width: 40rpx;
text-align: center;
border-radius: 20rpx;
color: #ffffff;
top: 10rpx;
left: 25rpx;
}
}
.shop-list {
width: 95%;
height: 222rpx;


+ 229
- 231
pages/index/order.vue View File

@ -1,239 +1,237 @@
<template>
<view class="page">
<navbar title="订单中心" bgColor="#DC2828" color="#fff" leftClick @leftClick="$utils.navigateBack" />
<uv-tabs :list="tabs"
:activeStyle="{color : '#FD5100', fontWeight : 600}"
lineColor="#FD5100"
lineHeight="8rpx"
lineWidth="50rpx"
:scrollable="false"
@click="clickTabs"></uv-tabs>
<view v-if="orderList.records.length > 0" class="list">
<view class="item" v-for="(item, index) in orderList.records" @click="toOrderDetail(item.id)" :key="index">
<!-- 顶部 -->
<view class="top">
<view class="service">
<text>{{item.projectId_dictText}}</text>
<text>{{item.type_dictText}}</text>
</view>
<view class="status">
<text> {{item.state_dictText}}</text>
</view>
</view>
<!-- -->
<view class="content">
<view class="left">
<image mode="aspectFill" :src="item.image"></image>
</view>
<view class="right">
<view class="text-hidden-1">
客户姓名{{item.name}}
</view>
<view class="text-hidden-1">
下单时间{{item.unit}}
</view>
<view class="text-hidden-1">
联系电话{{item.address}}
</view>
</view>
</view>
<!-- -->
<view class="bottom">
<view class="price">
总价格<text class="num">{{item.money}}</text>
</view>
<view class="b1">
查看详情
</view>
</view>
</view>
</view>
</view>
<view class="page">
<navbar title="订单中心" bgColor="#DC2828" color="#fff" leftClick @leftClick="$utils.navigateBack" />
<uv-tabs :list="tabs" :activeStyle="{ color: '#FD5100', fontWeight: 600 }" lineColor="#FD5100" lineHeight="8rpx"
lineWidth="50rpx" :scrollable="false" @click="clickTabs"></uv-tabs>
<view v-if="orderList.records.length > 0" class="list">
<view class="item" v-for="(item, index) in orderList.records" @click="toOrderDetail(item.id)" :key="index">
<!-- 顶部 -->
<view class="top">
<view class="service">
<text>{{ item.title }}</text>
<!-- <text>{{ item.type_dictText }}</text> -->
</view>
<view class="status">
<text> {{ tabs[item.status - 1 + 2].name }}</text>
</view>
</view>
<!-- -->
<view class="content">
<view class="left">
<image mode="aspectFill" :src="item.image"></image>
</view>
<view class="right">
<view class="text-hidden-1">
客户姓名{{ item.name }}
</view>
<view class="text-hidden-1">
下单时间{{ item.createTime }}
</view>
<view class="text-hidden-1">
联系电话{{ item.phone }}
</view>
</view>
</view>
<!-- -->
<view class="bottom">
<view class="price">
总价格<text class="num">{{ item.price }}</text>
</view>
<view class="b2" v-if="item.status == 0" @click.stop="toPayOrder(item)">
立即支付
</view>
<view class="b2" v-if="item.status == 1" @click.stop="confirmOrder(item)">
确认收货
</view>
<view class="b1" v-if="item.status == 0" @click.stop="cancelOrder(item)">
取消订单
</view>
<!-- <view class="b1" v-if="item.status != 0">
联系客服
</view> -->
</view>
</view>
</view>
</view>
</template>
<script>
import { mapGetters } from 'vuex'
export default {
components : {
},
computed : {
...mapGetters(['userShop']),
},
data() {
return {
tabs: [{
name: '全部'
},
{
name: '待付款'
},
{
name: '配送中'
},
{
name: '已完成'
},
{
name: '已取消'
}
],
queryParams: {
pageNo: 1,
pageSize: 10
},
orderList : {
records : [
{
projectId_dictText:"泰山工装石膏板",
money : 99.99,
address : '广东省广州市越秀区城南故事C3栋2802',
name : '李**',
phone : '150*****091',
unit : '120*40*75【桌子尺寸】',
image : 'https://img95.699pic.com/photo/50058/1378.jpg_wh860.jpg',
state_dictText : '已完成',
}
],
total : 0,
},
state : -1,
}
},
onShow() {
this.orderPage()
},
//
onReachBottom() {
if(this.queryParams.pageSize < this.orderList.total){
this.queryParams.pageSize += 10
this.orderPage()
}
},
methods: {
orderPage(){
let queryParams = {
...this.queryParams,
}
if(this.state != -1){
queryParams.state = this.state
}
this.$api('orderPage', queryParams, res => {
if(res.code == 200){
this.orderList = res.result
}
})
},
//tab
clickTabs(index) {
if (index == 0) {
this.state = -1;
} else {
this.state = index - 1;
}
this.queryParams.pageSize = 10
this.orderPage()
},
//
toOrderDetail(id) {
uni.navigateTo({
url: '/pages_order/order/orderDetail?id=' + id
})
},
getOrderList(){
},
}
}
import orderMixin from '@/mixins/order.js'
export default {
mixins: [orderMixin],
components: {
},
computed: {
},
data() {
return {
tabs: [
{
name: '全部'
},
{
name: '待付款'
},
{
name: '配送中'
},
{
name: '已完成'
},
{
name: '已取消'
}
],
queryParams: {
pageNo: 1,
pageSize: 10
},
orderList: {
records: [],
total: 0,
},
state: -1,
}
},
onShow() {
this.getData()
},
//
onReachBottom() {
if (this.queryParams.pageSize < this.orderList.total) {
this.queryParams.pageSize += 10
this.getData()
}
},
methods: {
getData() {
let queryParams = {
...this.queryParams,
}
if (this.state != -1) {
queryParams.state = this.state
}
this.$api('getOrderPageBean', queryParams, res => {
if (res.code == 200) {
this.orderList = res.result
}
})
},
//tab
clickTabs({ index }) {
if (index == 0) {
this.state = -1;
} else {
this.state = index - 1;
}
this.queryParams.pageSize = 10
this.getData()
},
//
toOrderDetail(id) {
uni.navigateTo({
url: '/pages_order/order/orderDetail?id=' + id
})
},
getOrderList() {
},
}
}
</script>
<style scoped lang="scss">
.page{
}
.list {
.item {
width: calc(100% - 40rpx);
background-color: #fff;
margin: 20rpx;
box-sizing: border-box;
border-radius: 16rpx;
padding: 30rpx;
.top {
display: flex;
justify-content: space-between;
align-items: center;
font-size: 30rpx;
.service {}
.status {
font-size: 26rpx;
font-weight: 600;
}
}
.content {
display: flex;
margin: 10rpx 0;
.left {
width: 150rpx;
height: 150rpx;
border-radius: 10rpx;
image {
width: 150rpx;
height: 150rpx;
border-radius: 10rpx;
}
}
.right {
width: calc(100% - 160rpx);
color: #777;
font-size: 24rpx;
padding-left: 20rpx;
line-height: 40rpx;
background-color: #F8F8F8;
}
}
.bottom {
display: flex;
justify-content: space-between;
font-size: 25rpx;
.price {
color: #787777;
font-weight: 900;
text {
color: #fd7d41;
font-size: 30rpx;
}
}
.b1 {
border: 1px solid #777;
color: #777;
box-sizing: border-box;
}
.b2 {
background: linear-gradient(178deg, #4FD3BC, #60C285);
color: #fff;
}
view {
margin: 12rpx;
border-radius: 28rpx;
padding: 8rpx 28rpx;
margin-bottom: 0;
}
}
}
}
.page {}
.list {
.item {
width: calc(100% - 40rpx);
background-color: #fff;
margin: 20rpx;
box-sizing: border-box;
border-radius: 16rpx;
padding: 30rpx;
.top {
display: flex;
justify-content: space-between;
align-items: center;
font-size: 30rpx;
.service {}
.status {
font-size: 26rpx;
font-weight: 600;
color: $uni-color;
}
}
.content {
display: flex;
margin: 10rpx 0;
.left {
width: 150rpx;
height: 150rpx;
border-radius: 10rpx;
image {
width: 150rpx;
height: 150rpx;
border-radius: 10rpx;
}
}
.right {
width: calc(100% - 160rpx);
color: #777;
font-size: 24rpx;
padding-left: 20rpx;
line-height: 40rpx;
background-color: #F8F8F8;
}
}
.bottom {
display: flex;
justify-content: space-between;
font-size: 25rpx;
.price {
color: #787777;
font-weight: 900;
text {
color: #fd7d41;
font-size: 26rpx;
}
}
.b1 {
border: 1px solid #777;
color: #777;
box-sizing: border-box;
}
.b2 {
background: linear-gradient(178deg, $uni-color, #d34f4f);
color: #fff;
}
view {
margin: 12rpx;
border-radius: 28rpx;
padding: 8rpx 28rpx;
margin-bottom: 0;
}
}
}
}
</style>

+ 5
- 5
pages_order/auth/wxUserInfo.vue View File

@ -32,7 +32,7 @@
v-model="userInfoForm.nickName" />
</view>
</view>
<!-- <view class="line">
<view class="line">
<view class="">
手机号
</view>
@ -53,7 +53,7 @@
获取电话号码
</button>
</view>
</view> -->
</view>
@ -76,7 +76,7 @@
},
onShow() {},
onLoad() {
// this.userInfoForm.phone = this.userInfo.phone || ''
this.userInfoForm.phone = this.userInfo.phone || ''
this.userInfoForm.nickName = this.userInfo.nickName || ''
this.userInfoForm.headImage = this.userInfo.headImage || ''
},
@ -120,7 +120,7 @@
if (self.$utils.verificationAll(self.userInfoForm, {
headImage: '请选择头像',
nickName: '请填写昵称',
// phone: '',
phone: '请填写手机号',
})) {
return
}
@ -128,7 +128,7 @@
self.$api('updateInfo', {
avatarUrl : self.userInfoForm.headImage,
nickName : self.userInfoForm.nickName,
// phone : self.userInfoForm.phone,
phone : self.userInfoForm.phone,
}, res => {
if (res.code == 200) {
uni.reLaunch({


+ 0
- 1
pages_order/components/address/addressList.vue View File

@ -95,7 +95,6 @@
this.addressList = res.result.records || [];
this.total = res.result.total || 0;
res.result.records.forEach(n => { //
console.log(n);
if (n.defaultFlag == 1) {
this.selectAddress = n.id
}


+ 10
- 6
pages_order/components/address/redactAddress.vue View File

@ -71,13 +71,13 @@
this.$emit('saveOrUpdate', this.addressDetail)
},
//
parameterVerification(addressDetaila) {
parameterVerification(addressForm) {
let {
name,
phone,
address,
addressDetails
} = addressDetaila
} = addressForm
if (name.trim() == '') {
return {
title: '请填写联系人',
@ -114,11 +114,11 @@
//
selectAddr() {
Position.getLocation(res => {
Position.selectAddress(res.longitude, res.latitude, success => {
// Position.getLocation(res => {
Position.selectAddress(0, 0, success => {
this.setAddress(success)
})
})
// })
},
//
@ -175,6 +175,11 @@
.uv-form {
padding: 30rpx 0rpx;
}
.uv-input__content__field-wrapper__field{
padding: 30rpx !important;
height: 180rpx !important;
}
&::v-deep .uv-cell {
padding: 0rpx 0rpx;
@ -188,7 +193,6 @@
display: flex;
align-items: center;
height: 80rpx;
}
.uv-field__control,


+ 227
- 0
pages_order/components/address/redactAddressForm.vue View File

@ -0,0 +1,227 @@
<template>
<view class="redact-address">
<uv-form label-width="210rpx" :model="addressDetail" ref="form">
<uv-form-item label="联系人" prop="name">
<uv-input v-model="addressDetail.name" placeholder="请输入联系人姓名" border="none">
</uv-input>
</uv-form-item>
<uv-form-item label="手机号" prop="phone">
<uv-input v-model="addressDetail.phone" placeholder="请输入手机号" border="none">
</uv-input>
</uv-form-item>
<uv-form-item label="所在地区" prop="address">
<uv-input v-model="addressDetail.address" placeholder="请选择所在地区" border="none">
</uv-input>
<template #right>
<view style="padding-right: 40rpx;color: #FBAB32;" @click.stop="selectAddr">
<image src="../../static/address/selectIcon.png" mode="aspectFit"></image>定位
</view>
</template>
</uv-form-item>
<uv-form-item label="详细地址" prop="addressDetail">
<uv-input v-model="addressDetail.addressDetails" placeholder="请输入详细地址" border="none">
</uv-input>
</uv-form-item>
</uv-form>
</view>
</template>
<script>
import Position from '@/utils/position.js'
export default {
data() {
return {
addressDetail: {
name: '',
phone: '',
address: '',
addressDetails: '',
defaultFlag: '',
latitude: '',
longitude: ''
}
}
},
props: {
title: {
type: String,
default: '新增地址'
}
},
methods: {
open(addressDetail) {
this.addressDetail = addressDetail
this.$refs.addressPopup.open('bottom')
},
close(){
this.$refs.addressPopup.close()
},
//
onSubmit() {
let isOk = this.parameterVerification(this.addressDetail)
if (isOk && !isOk.auth) {
return uni.showToast({
icon: 'none',
title: isOk.title,
'zIndex': 10000
})
}
this.$emit('saveOrUpdate', this.addressDetail)
},
//
parameterVerification(addressForm) {
let {
name,
phone,
address,
addressDetails
} = addressForm
if (name.trim() == '') {
return {
title: '请填写联系人',
auth: false
}
} else if (phone.trim() == '') {
return {
title: '请填写手机号',
auth: false
}
} else if (address.trim() == '') {
return {
title: '请填写所在地区',
auth: false
}
} else if (addressDetails.trim() == '') {
return {
title: '请填写详细地址',
auth: false
}
} else if (phone.trim() != '') {
if (!this.$utils.verificationPhone(phone)) {
return {
title: '手机号格式不合法',
auth: false
}
}
}
return {
title: '验证通过',
auth: true
}
},
//
selectAddr() {
// Position.getLocation(res => {
Position.selectAddress(0, 0, success => {
this.setAddress(success)
})
// })
},
//
setAddress(res) {
//
this.addressDetail.latitude = res.latitude
this.addressDetail.longitude = res.longitude
if (!res.address && res.name) { //
return this.addressDetail.address = res.name
}
if (res.address || res.name) {
return this.addressDetail.address = res.address + res.name
}
this.addressDetail.address = '' //
},
}
}
</script>
<style lang="scss" scoped>
.redact-address {
box-sizing: border-box;
.redact-address-title {
height: 80rpx;
line-height: 80rpx;
font-size: 30rpx;
color: #333333;
font-weight: 600;
}
.save {
display: flex;
align-items: center;
justify-content: center;
width: 90%;
height: 80rpx;
border-radius: 40rpx;
color: white;
font-size: 28rpx;
margin: 0rpx auto;
background: $uni-color;
margin-top: 150rpx;
}
image {
width: 25rpx;
height: 25rpx;
}
//
.uv-form {
padding: 30rpx 0rpx;
}
.uv-input__content__field-wrapper__field{
padding: 30rpx !important;
height: 180rpx !important;
}
&::v-deep .uv-cell {
padding: 0rpx 0rpx;
font-size: 26rpx;
&::after {
border: none !important;
}
.uv-field__label {
display: flex;
align-items: center;
height: 80rpx;
}
.uv-field__control,
.uv-field__right-icon {
height: 80rpx;
font-size: 26rpx;
border-bottom: 2rpx solid #cbc8c8;
}
.uv-field__right-icon {
display: flex;
align-items: center;
height: 78rpx;
color: #5FCC9F;
}
.uv-cell__value {
height: 120rpx;
}
}
&::v-deep .uv-field__error-message {
color: #5AC796;
font-size: 20rpx;
margin-top: 10rpx;
}
}
</style>

+ 36
- 0
pages_order/mine/about.vue View File

@ -0,0 +1,36 @@
<template>
<view class="page">
<navbar
title="关于本程序"
leftClick
@leftClick="$utils.navigateBack"
/>
<view class="content">
<uv-parse :content="configList.config_aboutus"></uv-parse>
</view>
</view>
</template>
<script>
export default {
data() {
return {
}
},
methods: {
}
}
</script>
<style scoped lang="scss">
.page{
.content{
padding: 20rpx;
background-color: #fff;
}
}
</style>

+ 3
- 2
pages_order/mine/address.vue View File

@ -62,6 +62,7 @@
//
editAddress(address) {
this.title = '编辑地址'
this.$refs.addressPopup.open({...address})
},
@ -78,7 +79,7 @@
phone: addressDetail.phone,
address: addressDetail.address,
addressDetails: addressDetail.addressDetails,
defaultId: addressDetail.defaultId || '0',
defaultFlag: addressDetail.defaultFlag || '0',
latitude: addressDetail.latitude,
longitude: addressDetail.longitude
}
@ -152,7 +153,7 @@
phone: '',
address: '',
addressDetails: '',
defaultId: '',
defaultFlag: '',
latitude: '',
longitude: ''
})


+ 33
- 9
pages_order/mine/individualTeam.vue View File

@ -11,12 +11,12 @@
<view class="team">
<view class="team-message">
<view class="leftImage">
<image src="" mode=""></image>
<image :src="userInfo.headImage" mode="aspectFill"></image>
</view>
<view class="number-team">
<view class="top-number">
<text style="font-weight: 500;">13845131854</text>
<view class="salesman">级业务员</view>
<text style="font-weight: 500;">{{ userInfo.phone }}</text>
<view class="salesman">{{ ['一', '二'][info.role] }}级业务员</view>
</view>
<view class="bottom-number">
<view class="performance">
@ -26,7 +26,7 @@
<view class="figure">
<text style="margin-left: 30rpx; color: #DC2828; font-weight: 600;"></text><text
class="money">66666</text>
class="money">{{ info.money }}</text>
</view>
</view>
<view class="withdraw" @click="toPurse">
@ -43,19 +43,21 @@
lineHeight="8rpx" lineWidth="50rpx" @click="clickTabs"></uv-tabs>
</view>
<view class="user-list">
<view class="head" v-for="(item,index) in 20">
<view class="head"
:key="index"
v-for="(item, index) in list">
<view class="headImage">
<image src="" mode=""></image>
<image :src="item.headImage" mode="aspectFill"></image>
</view>
<view class="info">
<view class="name">
用户138xxxxxxxx
{{ item.nickName }}{{ item.phone ? item.phone.replace(/(\d{3})\d{4}(\d{4})/, '$1****$2') : '' }}
</view>
<view class="headBtn">
下单量<text>12</text> | 佣金 <text style="color: darkorange;">120</text>
下单量<text>{{item.orderNum}}</text> | 佣金 <text style="color: darkorange;">{{item.commission}}</text>
</view>
<view class="tips">
加入平台<text>120</text>
加入<text>{{ $dayjs().diff($dayjs(item.createTime), 'day') }}</text>
</view>
</view>
</view>
@ -79,8 +81,14 @@
name: '间推用户'
},
],
info : {},
};
},
onLoad() {
this.queryParams.state = 0;
this.$store.commit('getUserInfo');
this.getTeamInfo();
},
methods: {
//tab
clickTabs(index) {
@ -98,6 +106,14 @@
url: '/pages_order/mine/purse'
})
},
//
getTeamInfo() {
this.$api('getTeamHeader', res => {
if (res.code == 200) {
this.info = res.result;
}
})
},
},
}
</script>
@ -129,6 +145,10 @@
position: absolute;
top: 25rpx;
left: 26rpx;
image{
width: 100%;
height: 100%;
}
}
.number-team {
@ -254,6 +274,10 @@
overflow: hidden;
border-radius: 50%;
margin-right: 15rpx;
image{
width: 100%;
height: 100%;
}
}
.info {


+ 7
- 1
pages_order/mine/purse.vue View File

@ -1,6 +1,9 @@
<template>
<view class="purse">
<navbar title="立即提现" leftClick @leftClick="$utils.navigateBack" />
<navbar title="立即提现" leftClick @leftClick="$utils.navigateBack"
bgColor="#DC2828"
color="#fff"
/>
<!-- 水洗店 -->
<view class="userShop">
@ -47,6 +50,9 @@
notice : ''
}
},
onLoad() {
this.$store.commit('getUserInfo');
},
methods: {
}


+ 203
- 173
pages_order/mine/runningWater.vue View File

@ -1,56 +1,47 @@
<template>
<view class="running-water">
<navbar :title="title[status]" leftClick @leftClick="leftClick" />
<navbar :title="title[status]" leftClick @leftClick="leftClick"
bgColor="#DC2828"
color="#fff"
/>
<view style="background-color: red;height: 250rpx;">
<view style="background-color: #DC2828;height: 150rpx;">
</view>
<view class="sum">
<view class="left">
<view class="tiele">总佣金()</view>
<view class="price">1240.00</view>
<view class="btn">去提现</view>
</view>
<view class="right">
<view class="tiele">累计提现()</view>
<view class="price">1240.00</view>
<view class="btn">提现记录</view>
<view class="card-wrapper">
<view class="card">
<view class="card-section">
<view class="amount-title">总佣金()</view>
<view class="amount-value">¥ {{ info.lj_money }}</view>
<!-- <view class="action-btn" @click="goWithdraw">提现</view> -->
</view>
<view class="card-divider"></view>
<view class="card-section">
<view class="amount-title">累计提现()</view>
<view class="amount-value">¥ {{ info.lj_price }}</view>
</view>
</view>
</view>
<view class="searchCondition">
<!--搜索框-->
<span style="margin-right: 40rpx;">金额明细</span>
<view class="date-filter">
<text class="filter-title">金额明细</text>
<view class="dateTimeCls">
<view class="date" @click="startDateOpen">
{{ queryParams.startDate }}
<uv-datetime-picker ref="startDateRef" v-model="queryParams.startDate" mode="date"
@confirm="startDateChange"></uv-datetime-picker>
</view>
<view class="image">
<image src="../static/order/2.svg" style="width: 100%;height: 100%"></image>
<view class="filter-actions">
<view class="date-select" @click="openCalendar">
<text class="date-text">{{queryParams.year || '全部'}} {{queryParams.month || ''}}</text>
<uv-icon name="calendar" size="32rpx" color="#666"></uv-icon>
</view>
</view>
<span style="margin: 0 20rpx;">-</span>
<view class="dateTimeCls">
<view class="date" @click="endDateOpen">
{{ queryParams.endDate }}
<uv-datetime-picker ref="endDateRef" v-model="queryParams.endDate" mode="date"
@confirm="endDateChange">
</uv-datetime-picker>
</view>
<view class="image">
<image src="../static/order/2.svg" style="width: 100%;height: 100%"></image>
<view v-if="queryParams.year" class="reset-btn" @click="resetFilter">
<uv-icon name="trash" size="28rpx" color="#999"></uv-icon>
</view>
</view>
</view>
<view class="tab-box">
<view class="tab-box1" v-if="agentFlow.records.length>0 && agentFlow.total>0">
<uv-cell center border :title="item.title" v-for="(item, index) in agentFlow.records"
<uv-cell center border :title="item.title" v-for="(item, index) in agentFlow.records" :key="item.id"
:value="x[item.type] + item.money" :label="item.createTime" />
</view>
<view style="padding: 100rpx 0;" v-else>
@ -58,82 +49,129 @@
</view>
</view>
<!-- 日历选择器 -->
<uv-calendars
ref="calendar"
:insert="false"
mode="year-month"
color="#DC2828"
@confirm="calendarConfirm"
></uv-calendars>
</view>
</template>
<script>
import dayjs from "dayjs";
export default {
data() {
return {
queryParams: {
pageNo: 1,
pageSize: 10,
startDate: dayjs(new Date()).subtract(30, 'day').format('YYYY-MM-DD'),
endDate: dayjs(new Date()).format('YYYY-MM-DD'),
year: '',
month: ''
},
title: ['余额记录', '提现记录', '佣金记录'],
agentFlow: {
total: 1,
records: [{
type: 0,
money: 100,
createTime: '2024-04-02 20:00',
title: "佣金提现",
},
{
type: 0,
money: 100,
createTime: '2024-04-02 20:00',
title: "佣金提现",
},
{
type: 0,
money: 100,
createTime: '2024-04-02 20:00',
title: "佣金提现",
},
]
records: []
},
x: ['+', '-', '-', '+'],
status: 0,
info : {},
}
},
onPullDownRefresh() {
this.getAgentFlow()
},
onReachBottom() {
this.loadMoreData()
},
onLoad(e) {
this.status = e.status
this.status = e.status || 0;
//
this.getAgentFlow();
this.$store.commit('getUserInfo');
this.getTeamInfo();
},
methods: {
//
getTeamInfo() {
this.$api('getTeamHeader', res => {
if (res.code == 200) {
this.info = res.result;
}
})
},
loadMoreData(){
if(this.queryParams.pageSize < this.total){
this.queryParams.pageSize += 10
this.getAgentFlow()
}
},
leftClick() { //
uni.navigateBack(-1)
},
getAgentFlow() { //
let type = this.status;
this.$api('getAgentFlow', {
type
}, res => {
const params = {
type,
pageNo: this.queryParams.pageNo,
pageSize: this.queryParams.pageSize
};
//
if (this.queryParams.year) {
//
const year = this.queryParams.year.replace('年', '');
params.year = year;
//
if (this.queryParams.month) {
const month = this.queryParams.month.replace('月', '');
params.month = month;
}
}
this.$api('getLogList', params, res => {
if (res.code == 200) {
this.agentFlow = res.result
this.agentFlow = res.result;
}
})
},
startDateChange(val) {
this.$nextTick(() => {
this.queryParams.startDate = dayjs(val.value).format("YYYY-MM-DD")
// this.getData()
goWithdraw() {
//
uni.navigateTo({
url: '/pages_order/mine/withdraw'
});
},
startDateOpen() {
this.$refs.startDateRef.open();
//
openCalendar() {
this.$refs.calendar.open();
},
endDateChange(val) {
this.$nextTick(() => {
this.queryParams.endDate = dayjs(val.value).format("YYYY-MM-DD")
// this.getData()
});
},
endDateOpen() {
this.$refs.endDateRef.open();
calendarConfirm(e) {
//
if (e.year && e.month) {
this.queryParams.year = e.year + '年';
this.queryParams.month = e.month + '月';
} else {
//
this.queryParams.year = '';
this.queryParams.month = '';
}
//
this.queryParams.pageNo = 1;
//
this.getAgentFlow();
},
//
resetFilter() {
this.queryParams.year = '';
this.queryParams.month = '';
this.queryParams.pageNo = 1;
this.getAgentFlow();
}
}
}
</script>
@ -143,115 +181,107 @@
width: 750rpx;
margin: 0 auto;
min-height: 100vh;
position: absolute;
position: relative;
background: #F5F5F5;
.tab-box {
margin: 20rpx;
// margin-top: 100rpx;
background-color: #fff;
border-radius: 20rpx;
overflow: hidden;
}
.sum {
display: flex;
justify-content: center;
gap: 100rpx;
width: 90%;
height: 200rpx;
margin-top: 20rpx;
padding: 20rpx;
border: 1px solid #fff;
background-color: #fff;
z-index: 999;
border-radius: 40rpx;
box-shadow: 2px 2px 5px rgba(0, 0, 0, 0.5);
position: absolute;
top: 220rpx;
left: 20rpx;
.left {
.card-wrapper {
position: relative;
padding: 0 30rpx;
margin-top: -90rpx;
z-index: 10;
.card {
display: flex;
flex-direction: column;
justify-content: space-between;
align-items: center;
.title {
font-size: 28rpx;
}
.price {
font-size: 30rpx;
font-weight: 700;
color: #dc2929;
background-color: #fff;
border-radius: 20rpx;
box-shadow: 0 4rpx 20rpx rgba(0, 0, 0, 0.08);
overflow: hidden;
.card-section {
flex: 1;
display: flex;
flex-direction: column;
align-items: center;
padding: 30rpx 0;
.amount-title {
font-size: 28rpx;
color: #666;
margin-bottom: 16rpx;
}
.amount-value {
font-size: 42rpx;
font-weight: bold;
color: #DC2828;
margin-bottom: 30rpx;
}
.action-btn {
width: 160rpx;
height: 70rpx;
line-height: 70rpx;
text-align: center;
border: 1px solid #DC2828;
color: #DC2828;
font-size: 28rpx;
border-radius: 35rpx;
}
}
.btn {
padding: 10rpx 15rpx;
border: 1px solid #dc2929;
color: #dc2929;
border-radius: 20rpx;
.card-divider {
width: 1px;
background-color: #eee;
}
}
.right {
}
.date-filter {
display: flex;
align-items: center;
justify-content: space-between;
margin: 0 20rpx;
margin-top: 30rpx;
padding: 30rpx;
background-color: #fff;
border-radius: 10rpx;
.filter-title {
font-size: 28rpx;
color: #333;
font-weight: 500;
}
.filter-actions {
display: flex;
flex-direction: column;
justify-content: space-between;
align-items: center;
.title {
font-size: 28rpx;
}
.price {
font-size: 30rpx;
font-weight: 700;
color: #dc2929;
}
.btn {
padding: 10rpx 15rpx;
border: 1px solid #dc2929;
color: #dc2929;
border-radius: 20rpx;
}
}
}
.searchCondition {
display: flex;
width: 100vw;
padding: 0 40rpx;
padding-top: 130rpx;
background-color: #fff;
.dateTimeCls {
.date-select {
display: flex;
justify-content: space-between;
align-items: center;
width: 30%;
border: 1px solid #b0b2b3;
padding: 5rpx;
border-radius: 20rpx;
.date {
font-size: 25rpx;
display: flex;
align-items: center;
width: 80%;
height: 100%;
color: #b0b2b3;
}
.image {
width: 20%;
height: 100%;
padding: 12rpx 20rpx;
border: 1px solid #ddd;
border-radius: 8rpx;
.date-text {
margin-right: 10rpx;
font-size: 26rpx;
color: #333;
}
}
.reset-btn {
margin-left: 20rpx;
padding: 12rpx;
}
}
.tab-box {
margin: 20rpx;
background-color: #fff;
border-radius: 20rpx;
overflow: hidden;
}
}
</style>

+ 6
- 6
pages_order/order/createOrder.vue View File

@ -115,13 +115,13 @@
<image src="@/pages_order/static/createOrder/account.png" mode="widthFix" class="cell-icon">
</image>
<view class="user-name">账户余额</view>
<view class="descript">(余额: {{ riceInfo.balance }})</view>
<view class="descript">(余额: {{ userInfo.price }})</view>
</view>
<view class="cell-item-right">
<uv-radio activeColor="#E3441A"
size="40rpx"
icon-size="30rpx"
:name="1"/>
:name="0"/>
</view>
</view>
@ -138,7 +138,7 @@
activeColor="#E3441A"
size="40rpx"
icon-size="30rpx"
:name="0"/>
:name="1"/>
</view>
</view>
</view>
@ -188,7 +188,7 @@
<uv-popup ref="addressPopup" :round="30" style="padding-bottom: 90rpx;">
<addressList ref="addressList" height="60vh" @select="selectAddress" />
<view class="add-btn">
<view @click="$utils.navigateTo('/pages_order/mine/address')" class="button-submit">新增地址</view>
<view @click="$utils.navigateTo('/pages_order/mine/address?type=back')" class="button-submit">新增地址</view>
</view>
</uv-popup>
@ -228,7 +228,7 @@
num: 1,
agreement: false,
coupon: {},
payMethod : 0,
payMethod : 1,
isGive : 0,
type : '',
titleMap : {
@ -391,7 +391,7 @@
this.$api(api, data, res => {
if (res.code == 200) {
if(this.payMethod == 1){
if(this.payMethod == 0){
// uni.showToast({
// title: '',
// icon: 'none'


+ 444
- 2
pages_order/order/firmOrder.vue View File

@ -5,19 +5,461 @@
leftClick
@leftClick="$utils.navigateBack"
/>
<!-- 商品信息 -->
<view class="content-wrapper">
<view class="section-wrapper">
<view class="section-title">
<view class="title-bar"></view>
<text>商品信息</text>
</view>
<view class="product-card">
<image class="product-image" :src="productInfo.image" mode="aspectFit"></image>
<view class="product-details">
<view class="product-name">{{productInfo.name || '泰山工装石膏板'}}</view>
<view class="product-tags">
<text class="tag">{{productInfo.categoryName || '建材材料'}}</text>
<text class="tag">快速下单</text>
</view>
<view class="product-price">
<text class="price-value">¥{{productInfo.price || '38.00'}}</text>
<text class="price-unit">/{{productInfo.unit || '米'}}</text>
</view>
</view>
</view>
</view>
<!-- 个人信息 -->
<view class="section-wrapper">
<view class="section-title">
<view class="title-bar"></view>
<text>填写个人信息</text>
</view>
<view class="address-section">
<view v-if="addressTotal > 0" class="has-address">
<view class="address-info" @click="openAddress">
<view class="address-user">
<text class="name">{{address.name}}</text>
<text class="phone">{{address.phone}}</text>
</view>
<view class="address-detail">
{{address.address}} {{address.addressDetails}}
</view>
<view class="address-action">
<text class="address-tip">已添加过的地址</text>
<view class="arrow-right"></view>
</view>
</view>
<view class="address-tag">
<text>已添加过的地址</text>
</view>
</view>
<!-- 地址表单 -->
<view v-else class="no-address">
<redact-address-form
ref="addressForm"
@saveOrUpdate="handleAddressSave"
></redact-address-form>
</view>
</view>
</view>
</view>
<!-- 底部按钮 -->
<view class="order-submit">
<button class="submit-btn" @click="submitOrder">快捷下单</button>
</view>
<!-- 地址选择弹窗 -->
<uv-popup ref="addressPopup" :round="30" style="padding-bottom: 90rpx;">
<addressList ref="addressList" height="60vh" @select="selectAddress" />
<view class="add-btn">
<view @click="$utils.navigateTo('/pages_order/mine/address?type=back')" class="button-submit">新增地址</view>
</view>
</uv-popup>
</view>
</template>
<script>
import redactAddressForm from '../components/address/redactAddressForm.vue';
import addressList from '../components/address/addressList.vue';
export default {
components: {
redactAddressForm,
addressList
},
data() {
return {
productInfo: {}, //
orderId: '', // ID
address: {
name: '请选择地址',
address: '',
phone: ''
},
addressTotal: 0,
orderInfo: [],
isLoading: false, //
shouldSubmitOrder: false //
};
},
onLoad(options) {
// ID
if (options.orderId) {
this.orderId = options.orderId;
this.getOrderInfo();
}
},
onShow() {
//
this.getAddressList();
},
methods: {
//
getOrderInfo() {
this.$api('getOrderInfo', res => {
if (res.code === 200 && res.result[0]) {
//
if (res.result[0].commonShop) {
this.productInfo = res.result[0].commonShop;
}
}
});
},
//
getAddressList() {
//
this.$refs.addressList.getAddressList().then(res => {
if (res && res.total) {
this.addressTotal = res.total;
//
if (res.records && res.records.length > 0) {
const defaultAddress = res.records.find(addr => addr.defaultFlag === '1');
if (defaultAddress) {
this.address = defaultAddress;
} else {
// 使
this.address = res.records[0];
}
//
if (this.shouldSubmitOrder) {
this.shouldSubmitOrder = false; //
this.submitOrder(true); // true
}
}
} else {
this.addressTotal = 0;
}
//
this.isLoading = false;
}).catch(err => {
console.error('获取地址列表失败', err);
this.addressTotal = 0;
this.isLoading = false;
});
},
//
openAddress() {
this.$refs.addressPopup.open('bottom');
},
//
selectAddress(address) {
this.address = address;
this.$refs.addressPopup.close();
},
//
handleAddressSave(address) {
//
this.isLoading = true;
//
this.$api('saveOrUpdateAddress', address, res => {
if (res.code === 200) {
uni.showToast({
title: '地址保存成功',
icon: 'success'
});
//
this.shouldSubmitOrder = true;
//
this.getAddressList();
} else {
uni.showToast({
title: res.message || '保存失败',
icon: 'none'
});
this.isLoading = false;
}
});
},
//
submitOrder(skipAddressCheck = false) {
if (!skipAddressCheck && this.addressTotal === 0) {
const addressForm = this.$refs.addressForm;
//
const isValid = addressForm.parameterVerification(addressForm.addressDetail);
if (!isValid.auth) {
uni.showToast({
title: isValid.title,
icon: 'none'
});
return;
}
//
this.isLoading = true;
//
addressForm.onSubmit();
return;
}
//
uni.showLoading({
title: '提交订单中...'
});
//
this.$api('createOrder', {
addressId: this.address.id,
productId: this.productInfo.id,
num : 1,
payType: 1, //
orderId: this.orderId
}, res => {
uni.hideLoading();
if (res.code === 200) {
uni.showToast({
title: '下单成功',
icon: 'success',
duration: 1500,
success: () => {
setTimeout(() => {
//
this.$utils.redirectTo('/pages_order/order/orderList');
}, 1500);
}
});
} else {
uni.showToast({
title: res.message || '下单失败',
icon: 'none'
});
}
});
}
}
}
</script>
<style scoped lang="scss">
.hand-firm {
min-height: 100vh;
background-color: #f6f6f6;
padding-bottom: 120rpx;
.content-wrapper {
padding: 20rpx;
}
.section-wrapper {
margin-bottom: 20rpx;
border-radius: 12rpx;
overflow: hidden;
background-color: #fff;
}
.section-title {
display: flex;
align-items: center;
padding: 30rpx;
border-bottom: 1rpx solid #f0f0f0;
.title-bar {
width: 6rpx;
height: 30rpx;
background-color: #D03F25;
margin-right: 15rpx;
border-radius: 3rpx;
}
text {
font-size: 32rpx;
font-weight: 500;
color: #333;
}
}
.product-card {
display: flex;
padding: 30rpx;
.product-image {
width: 180rpx;
height: 180rpx;
margin-right: 30rpx;
background-color: #f9f9f9;
border-radius: 8rpx;
}
.product-details {
flex: 1;
display: flex;
flex-direction: column;
justify-content: space-between;
.product-name {
font-size: 32rpx;
font-weight: 500;
color: #333;
margin-bottom: 15rpx;
}
.product-tags {
display: flex;
margin-bottom: 20rpx;
.tag {
font-size: 24rpx;
color: #D03F25;
padding: 4rpx 12rpx;
background-color: rgba(208, 63, 37, 0.1);
border-radius: 4rpx;
margin-right: 15rpx;
}
}
.product-price {
font-size: 28rpx;
color: #666;
.price-value {
font-size: 40rpx;
font-weight: 600;
color: #D03F25;
}
}
}
}
.address-section {
.has-address {
position: relative;
.address-info {
padding: 30rpx;
.address-user {
margin-bottom: 15rpx;
.name {
font-size: 32rpx;
font-weight: 500;
color: #333;
margin-right: 30rpx;
}
.phone {
font-size: 28rpx;
color: #666;
}
}
.address-detail {
font-size: 28rpx;
color: #666;
line-height: 1.5;
margin-bottom: 20rpx;
}
.address-action {
display: flex;
justify-content: space-between;
align-items: center;
padding-top: 20rpx;
border-top: 1px solid #eee;
.address-tip {
font-size: 28rpx;
color: #D03F25;
}
.arrow-right {
width: 16rpx;
height: 16rpx;
border-top: 2rpx solid #D03F25;
border-right: 2rpx solid #D03F25;
transform: rotate(45deg);
}
}
}
.address-tag {
position: absolute;
top: 20rpx;
right: 0;
background-color: #D03F25;
color: #fff;
font-size: 24rpx;
padding: 8rpx 20rpx;
border-radius: 30rpx 0 0 30rpx;
}
}
.no-address {
padding: 20rpx;
}
}
.order-submit {
position: fixed;
bottom: 0;
left: 0;
right: 0;
padding: 20rpx 30rpx;
background-color: #fff;
box-shadow: 0 -2rpx 10rpx rgba(0, 0, 0, 0.05);
.submit-btn {
width: 100%;
height: 90rpx;
line-height: 90rpx;
text-align: center;
background-color: #D03F25;
color: #fff;
font-size: 32rpx;
border-radius: 45rpx;
border: none;
}
}
.add-btn {
padding: 30rpx;
.button-submit {
display: flex;
align-items: center;
justify-content: center;
width: 100%;
height: 90rpx;
background-color: #D03F25;
color: #fff;
font-size: 32rpx;
border-radius: 45rpx;
}
}
}
</style>

+ 518
- 507
pages_order/order/orderDetail.vue
File diff suppressed because it is too large
View File


+ 12
- 10
pages_order/order/voiceOrder.vue View File

@ -65,7 +65,7 @@
audioPath: '', //
audioName: '录音文件01.mp3', //
audioSize: '0KB', //
uploadProgress: 100, //
uploadProgress: 0, //
recordStartTime: 0, //
recordTimeout: null, //
recordMaxDuration: 60000, //
@ -363,9 +363,9 @@
}
//
// uni.showLoading({
// title: '...'
// });
uni.showLoading({
title: '上传中...'
});
this.isUploading = true;
this.uploadProgress = 0;
@ -410,23 +410,25 @@
//
createVoiceOrder(audioUrl) {
this.$api('addOrder', {
this.$api('index.addOrder', {
voiceUrl: audioUrl,
type: '1', //1
type: '2', // 2
userId: uni.getStorageSync('userId') || ''
}, res => {
uni.hideLoading();
this.isUploading = false;
if (res.code === 0) {
if (res.code === 200) {
//
uni.showToast({
title: '下单成功',
icon: 'success',
duration: 1500,
success: () => {
uni.reLaunch({
url: '/pages/index/index'
})
setTimeout(() => {
//
this.$utils.redirectTo('/pages_order/order/orderList');
}, 1500);
}
});
} else {


BIN
pages_order/static/address/icon.png View File

Before After
Width: 96  |  Height: 96  |  Size: 4.5 KiB Width: 96  |  Height: 96  |  Size: 4.5 KiB

BIN
static/image/center/10.png View File

Before After
Width: 355  |  Height: 158  |  Size: 45 KiB Width: 720  |  Height: 320  |  Size: 113 KiB

BIN
static/image/center/headImage.png View File

Before After
Width: 116  |  Height: 116  |  Size: 16 KiB

+ 28
- 1
utils/index.js View File

@ -27,4 +27,31 @@ Vue.prototype.$dayjs = dayjs
Vue.prototype.$timeUtils = time
Vue.prototype.$utils = util
Vue.prototype.$md5 = md5
Vue.prototype.$md5 = md5
// 封装微信支付
uni.requestPaymentWxPay = function(res){
return new Promise((success, error) => {
uni.requestPayment({
provider: 'wxpay', // 服务提提供商
timeStamp: res.result.timeStamp, // 时间戳
nonceStr: res.result.nonceStr, // 随机字符串
package: res.result.packageValue,
signType: res.result.signType, // 签名算法
paySign: res.result.paySign, // 签名
success: function (res) {
console.log('支付成功',res);
success(res)
},
fail: function (err) {
console.log('支付失败',err);
error(err)
uni.showToast({
icon:'none',
title:"支付失败"
})
}
});
})
}

Loading…
Cancel
Save