xiongzhu vor 3 Jahren
Ursprung
Commit
9a0fb93a90

+ 5 - 1
.eslintrc.cjs

@@ -8,6 +8,10 @@ module.exports = {
         ecmaVersion: 'latest'
         ecmaVersion: 'latest'
     },
     },
     rules: {
     rules: {
-        'vue/no-deprecated-slot-attribute': 'on'
+        'vue/no-deprecated-slot-attribute': 'off',
+        'no-unused-vars': 'off'
+    },
+    globals: {
+        wx: true
     }
     }
 }
 }

+ 1 - 0
package.json

@@ -13,6 +13,7 @@
     "@ionic/vue-router": "^6.3.8",
     "@ionic/vue-router": "^6.3.8",
     "@vueuse/core": "^9.6.0",
     "@vueuse/core": "^9.6.0",
     "axios": "^1.2.0",
     "axios": "^1.2.0",
+    "date-fns": "^2.29.3",
     "ionicons": "^6.0.4",
     "ionicons": "^6.0.4",
     "less": "^4.1.3",
     "less": "^4.1.3",
     "less-loader": "^11.1.0",
     "less-loader": "^11.1.0",

+ 109 - 0
src/components/AddressItem.vue

@@ -0,0 +1,109 @@
+<template>
+    <div class="address">
+        <div class="radio" v-if="type == 'submit'" @click="chooseAddress">
+            <img class="radio-img" :src="isChoose ? activeIcon : inactiveIcon" />
+        </div>
+        <div class="content">
+            <div class="address-item">
+                <div class="address-name">收货人</div>
+                <div class="address-val">{{ info.name }} {{ info.phone }}</div>
+            </div>
+            <div class="address-item">
+                <div class="address-name">收货地址</div>
+                <div class="address-val">{{ info.fullAddress }}</div>
+            </div>
+
+            <div class="btn-list">
+                <van-button plain color="#000" size="small" round disabled v-if="info.isDefault">默认</van-button>
+                <van-button plain color="#FF8F00" size="small" round @click="goNext('editAddress', { id: info.id })">
+                    编辑
+                </van-button>
+                <van-button v-if="type == 'list'" plain type="danger" size="small" round>删除</van-button>
+            </div>
+        </div>
+    </div>
+</template>
+<script>
+import { userUserStore } from '@/stores/user'
+import { mapState } from 'pinia'
+import activeIcon from '@/assets/icon_xuanzhong_pre.png'
+import inactiveIcon from '@/assets/icon_xuanzhong.png'
+export default {
+    name: 'addressItem',
+    props: {
+        info: {
+            type: Object,
+            default: () => {
+                return {}
+            }
+        },
+        type: {
+            type: String,
+            default: 'list'
+        },
+        isChoose: {
+            type: Boolean,
+            default: false
+        }
+    },
+    data() {
+        return {
+            activeIcon,
+            inactiveIcon
+        }
+    },
+    computed: {
+        ...mapState(userUserStore, ['user'])
+    },
+    methods: {
+        chooseAddress() {
+            this.$emit('chooseAddress', this.info.id)
+        }
+    }
+}
+</script>
+<style lang="less" scoped>
+.address {
+    background: rgba(255, 255, 255, 1);
+    border-radius: 2px;
+    padding: 15px;
+    display: flex;
+    align-items: center;
+}
+.radio {
+    padding: 10px 10px 10px 0;
+}
+.radio-img {
+    width: 16px;
+    height: 16px;
+    margin-right: 10px;
+}
+.content {
+    flex-grow: 1;
+}
+
+.address-item {
+    display: flex;
+    padding: 0 0 10px;
+    .address-name {
+        font-size: 13px;
+        color: rgba(170, 172, 173, 1);
+        line-height: 20px;
+        min-width: 72px;
+    }
+
+    .address-val {
+        font-size: 14px;
+        color: rgba(0, 0, 0, 1);
+        line-height: 20px;
+    }
+}
+
+.btn-list {
+    display: flex;
+    justify-content: flex-end;
+    .van-button:not(:last-child) {
+        margin-right: 10px;
+    }
+}
+</style>

+ 117 - 0
src/components/DistributionOrder.vue

@@ -0,0 +1,117 @@
+<template>
+    <div class="orderInfo">
+        <div class="top">
+            <!-- <div class="label">一级分销</div> -->
+            <div class="value">预计佣金:+{{ info.commission }}</div>
+        </div>
+        <div class="center">
+            <van-image class="suk-img" width="50" height="50" fit="fill" :src="info.pic" />
+
+            <div class="right">
+                <div class="text1">{{ info.name }}</div>
+                <div class="text2">¥{{ info.price }}</div>
+            </div>
+            <div class="num">×1</div>
+        </div>
+
+        <div class="order-info">
+            <div class="order-item">订单编号:{{ info.orderId }}</div>
+            <div class="order-item">下单时间:{{ info.createdAt }}</div>
+        </div>
+    </div>
+</template>
+<script>
+import { mapState } from 'pinia';
+import { useUserStore } from '@/stores/user';
+export default {
+    name: 'orderInfo',
+    props: {
+        info: {
+            type: Object,
+            default: () => {
+                return {};
+            }
+        }
+    },
+    data() {
+        return {};
+    },
+    computed: {
+        ...mapState(userUserStore, ['user'])
+    }
+};
+</script>
+<style lang="less" scoped>
+.orderInfo {
+    background: rgba(255, 255, 255, 1);
+    border-radius: 2px;
+    padding: 0 15px 15px;
+    margin-bottom: 10px;
+}
+
+.top {
+    position: relative;
+    height: 44px;
+    text-align: right;
+    border-bottom: 1px solid #f2f4f5;
+    .label {
+        width: 70px;
+        height: 24px;
+        background: rgba(255, 143, 0, 1);
+        border-radius: 0px 100px 100px 0px;
+        font-size: 12px;
+        color: rgba(255, 255, 255, 1);
+        line-height: 24px;
+        text-align: center;
+        position: absolute;
+        left: 0;
+        top: 10px;
+    }
+
+    .value {
+        font-size: 13px;
+        font-weight: bold;
+        color: rgba(255, 143, 0, 1);
+        line-height: 44px;
+    }
+}
+.center {
+    display: flex;
+    // align-items: center;
+    padding: 15px 0 0;
+    .right {
+        flex-grow: 1;
+        margin-left: 10px;
+        .text1 {
+            font-size: 14px;
+            color: rgba(0, 0, 0, 1);
+            line-height: 20px;
+        }
+        .text2 {
+            font-size: 12px;
+            color: rgba(0, 0, 0, 1);
+            line-height: 17px;
+            margin-top: 5px;
+        }
+    }
+
+    .num {
+        font-size: 14px;
+        color: rgba(170, 172, 173, 1);
+        line-height: 20px;
+        align-self: flex-end;
+    }
+}
+
+.order-info {
+    margin-top: 10px;
+    .order-item {
+        font-size: 12px;
+        color: rgba(102, 102, 102, 1);
+        line-height: 17px;
+        &:not(:last-child) {
+            margin-bottom: 5px;
+        }
+    }
+}
+</style>

+ 109 - 0
src/components/GoodsInfo.vue

@@ -0,0 +1,109 @@
+<template>
+    <div class="goods-info" @click="goDetail">
+        <van-image class="suk-item" width="100%" :src="img" fit="fill" />
+        <div class="title">
+            {{ info.name }}
+        </div>
+        <div class="bottom">
+            <div class="price">¥{{ info.currentPrice }}</div>
+            <van-button type="primary" round size="small" :disabled="info.status == 'SOLD_OUT'">{{
+                info.status == 'IN_STOCK' ? '购买' : '已售罄'
+            }}</van-button>
+        </div>
+    </div>
+</template>
+<script>
+import { mapState } from 'pinia';
+import { useUserStore } from '@/stores/user';
+export default {
+    name: 'goods',
+    props: {
+        info: {
+            type: Object,
+            default: () => {
+                return {};
+            }
+        }
+    },
+    data() {
+        return {};
+    },
+    computed: {
+        ...mapState(userUserStore, ['user']),
+        pic() {
+            return this.info.pic || [];
+        },
+        img() {
+            if (this.pic.length > 0) {
+                return this.pic[0];
+            } else {
+                return null;
+            }
+        }
+    },
+    methods: {
+        goDetail() {
+            if (this.info.type != 'demo') {
+                this.goNext('detail', { id: this.info.id });
+            }
+        }
+    }
+};
+</script>
+<style lang="less" scoped>
+.goods-info {
+    width: calc((100% - 24px) / 2);
+    background: rgba(255, 255, 255, 1);
+    border-radius: 2px;
+    margin-right: 12px;
+    overflow: hidden;
+    padding-bottom: 10px;
+}
+.suk-item {
+    height: calc((100vw - 24px - 14px) / 2);
+}
+@media screen and (min-width: 555px) {
+    .goods-info {
+        width: calc((100% - 36px) / 3);
+    }
+    .suk-item {
+        height: calc((100vw - 36px - 14px) / 3);
+    }
+}
+@media screen and (min-width: 735px) {
+    .goods-info {
+        width: calc((100% - 48px) / 4);
+    }
+    .suk-item {
+        height: calc((100vw - 48px - 14px) / 4);
+    }
+}
+.title {
+    font-size: 14px;
+    font-weight: bold;
+    color: rgba(51, 51, 51, 1);
+    line-height: 17px;
+    padding: 8px 8px 0;
+    display: -webkit-box;
+    -webkit-box-orient: vertical;
+    -webkit-line-clamp: 2;
+    overflow: hidden;
+}
+
+.bottom {
+    display: flex;
+    align-items: center;
+    justify-content: space-between;
+    padding: 11px 8px 0;
+
+    .price {
+        font-size: 16px;
+        font-weight: bold;
+        color: rgba(255, 93, 93, 1);
+        line-height: 22px;
+    }
+}
+.van-button {
+    line-height: 0px;
+}
+</style>

+ 589 - 0
src/components/OrderInfo.vue

@@ -0,0 +1,589 @@
+<template>
+    <div class="order-info">
+        <div class="order-top">
+            <div class="order-no">订单编号:{{ info.id }}</div>
+            <div class="order-staus">
+                {{ info.locked && info.status === 'SELLING' ? '暂停出售' : orderStatus[info.status] }}
+            </div>
+        </div>
+
+        <div class="order-content" @click="goDetail">
+            <van-image class="suk-img" width="80" height="80" fit="fill" :src="pic" />
+
+            <div class="order-text">
+                <div class="van-ellipsis text1">{{ productInfo.name }}</div>
+
+                <div class="text2" v-if="productInfo.user">当前所有人为:{{ productInfo.user.nickname }}</div>
+
+                <div class="text3">
+                    <div class="price">¥{{ info.totalPrice }}</div>
+                    <div class="num">×1</div>
+                </div>
+            </div>
+        </div>
+
+        <div class="order-price">
+            <div class="price">
+                <span>实际支付:</span>
+                <span>¥{{ info.totalPrice }}</span>
+            </div>
+
+            <div class="order-tips" v-if="info.status == 'NOT_PAID'">付款倒计时过期自动取消订单 {{ times }}</div>
+        </div>
+
+        <div class="order-button">
+            <span class="problem" @click="problem">遇到问题?</span>
+            <template v-if="info.status == 'NOT_PAID'">
+                <!-- <van-button color="#FF8F00" round plain size="small" @click="confirmPayment">我已付款</van-button> -->
+                <van-button type="primary" round size="small" @click="pay">立即支付</van-button>
+            </template>
+
+            <template v-else-if="info.status == 'NOT_CONFIRMED'">
+                <van-button color="#AAACAD" round plain size="small" @click="goDetail">查看订单</van-button>
+            </template>
+
+            <template v-else-if="info.status == 'SOLD_NOT_CONFIRMED'">
+                <!-- <van-button color="#AAACAD" round plain size="small" @click="confirmPayment">未收到款</van-button> -->
+                <!-- <van-button type="primary" round size="small" @click="confirmReceipt">确认收款</van-button> -->
+            </template>
+
+            <template v-else-if="info.status == 'SELLING'">
+                <!-- <van-button color="#AAACAD" round plain size="small" @click="confirmPayment">未收到款</van-button> -->
+                <!-- <van-button type="primary" round size="small" @click="confirmReceipt">确认收款</van-button> -->
+                <van-button color="#AAACAD" round plain size="small" @click="applyShip">申请发货</van-button>
+                <van-button color="#AAACAD" round plain size="small" @click="goDetail">查看订单</van-button>
+            </template>
+
+            <template v-else-if="info.status == 'CONFIRMED'">
+                <van-button color="#AAACAD" round plain size="small" @click="applyShip">申请发货</van-button>
+                <van-button type="primary" round size="small" @click="show = true" v-if="delegationActive">
+                    委托代卖</van-button
+                >
+                <van-button color="#aaacad" round @click="showTip" v-else>委托代卖 </van-button>
+            </template>
+
+            <template v-else-if="info.status == 'SOLD'">
+                <van-button color="#AAACAD" round plain size="small" @click="goDetail">查看订单</van-button>
+            </template>
+            <template v-else-if="info.status == 'NOT_SHIPPED'">
+                <van-button color="#AAACAD" round plain size="small" @click="goDetail">查看订单</van-button>
+            </template>
+            <template v-else-if="info.status == 'RECEIVED'">
+                <van-button color="#AAACAD" round plain size="small" @click="goDetail">查看订单</van-button>
+            </template>
+            <template v-else-if="info.status == 'SHIPPED'">
+                <van-button type="primary" round size="small" @click="receive"> 确认收货</van-button>
+            </template>
+        </div>
+        <van-popup v-model="show" class="getsold">
+            <div class="title">委托代卖</div>
+            <div class="sold-list">
+                <div class="sold-item">
+                    <div class="name">原价</div>
+                    <div class="val">¥{{ info.totalPrice }}</div>
+                </div>
+                <div class="sold-item">
+                    <div class="name">加价</div>
+                    <van-stepper v-model="value" input-width="60px" step="1" integer min="1" :max="maxRiseRate" />
+                </div>
+                <div class="sold-item">
+                    <div class="name">卖价</div>
+                    <div class="val bold">¥{{ soldValue }}</div>
+                </div>
+            </div>
+            <div class="tips">
+                注:委托平台代卖服务,每次最高可将商品价格提高{{ maxRiseRate }}%,平台会收取{{
+                    serviceValue
+                }}%的托管服务费用
+            </div>
+
+            <van-button class="button" block type="primary" :disabled="loading" round @click="sale">
+                支付手续费 ¥{{ serviceCharge }}
+            </van-button>
+        </van-popup>
+    </div>
+</template>
+<script>
+import { mapState } from 'pinia'
+import { useUserStore } from '@/stores/user'
+import { orderStatus } from '../status'
+import { differenceInSeconds, addMinutes, parse } from 'date-fns'
+export default {
+    name: 'orderInfo',
+    props: {
+        info: {
+            type: Object,
+            default: () => {
+                return {}
+            }
+        },
+        delegationActive: {
+            type: Boolean,
+            default: true
+        },
+        delegationTime: {
+            type: String,
+            default: ''
+        }
+    },
+    data() {
+        return {
+            orderStatus,
+            times: 0,
+            show: false,
+            value: 6,
+            platformCommission: 0.02,
+            maxRiseRate: 6,
+            loading: false,
+            payType: 'balance'
+        }
+    },
+    computed: {
+        ...mapState(useUserStore, ['user']),
+        productInfo() {
+            return this.info.productInfo || {}
+        },
+        pic() {
+            if (this.productInfo.pic && this.productInfo.pic.length > 0) {
+                return this.productInfo.pic[0]
+            } else {
+                return ''
+            }
+        },
+        fromUserInfo() {
+            return this.info.fromUserInfo || {}
+        },
+        soldValue() {
+            var price = Number(this.info.totalPrice)
+            if (this.value) {
+                var more = this.mul(this.value, price)
+                more = this.mul(more, 0.01)
+                price = this.addNum(more, price)
+            }
+            return price.toFixed(2)
+        },
+        serviceCharge() {
+            let totalPrice = this.info ? this.info.totalPrice || 0 : 0
+            return (totalPrice * this.platformCommission).toFixed(2)
+        },
+        serviceValue() {
+            return this.platformCommission * 100
+        }
+    },
+    created() {
+        if (this.info.status == 'NOT_PAID') {
+            this.getTime()
+        }
+        this.$http.get('/sysConfig/get/platform_commission').then(res => {
+            this.platformCommission = res.value
+        })
+        this.$http.get('/sysConfig/get/max_rise_rate').then(res => {
+            this.maxRiseRate = res.value * 100
+            this.value = this.maxRiseRate
+        })
+        // this.$http.get('/sysConfig/get/pay_type').then(res => {
+        //     if (res.value == '0') {
+        //         if (this.isWeixin) {
+        //             this.payType = 'weixin';
+        //         } else {
+        //             this.payType = 'alipay';
+        //         }
+        //     } else {
+        //         this.payType = 'third';
+        //     }
+        // });
+    },
+    methods: {
+        goDetail() {
+            this.goNext('orderDetail', {
+                id: this.info.id
+            })
+        },
+        getTime() {
+            var times = differenceInSeconds(
+                addMinutes(parse(this.info.createdAt, 'yyyy-MM-dd HH:mm:ss', new Date()), 30),
+                new Date()
+            )
+            if (times <= 0) {
+                times = 0
+            }
+            var mint = parseInt(times / 60)
+            var seconds = parseInt(times % 60)
+            this.times = mint + '分 ' + seconds + '秒'
+            if (!times) {
+                return
+            }
+            setTimeout(this.getTime, 1000)
+        },
+        confirmPayment() {
+            this.$http
+                .post('/order/confirmPayment', {
+                    orderId: this.info.id
+                })
+                .then(res => {
+                    this.$toast.success('确认成功')
+                    setTimeout(() => {
+                        this.$emit('updateOrder', res)
+                    }, 1000)
+                })
+                .catch(e => {
+                    return this.$toast(e.error)
+                })
+        },
+        confirmReceipt() {
+            this.$http
+                .post('/order/confirmReceipt', {
+                    orderId: this.info.id
+                })
+                .then(res => {
+                    this.$toast.success('确认成功')
+                    setTimeout(() => {
+                        this.$emit('updateOrder', res)
+                    }, 1000)
+                })
+                .catch(e => {
+                    return this.$toast(e.error)
+                })
+        },
+        addNum(a, b) {
+            var c, d, e
+            try {
+                c = a.toString().split('.')[1].length
+            } catch (f) {
+                c = 0
+            }
+            try {
+                d = b.toString().split('.')[1].length
+            } catch (f) {
+                d = 0
+            }
+            return (e = Math.pow(10, Math.max(c, d))), (this.mul(a, e) + this.mul(b, e)) / e
+        },
+        mul(a, b) {
+            var c = 0,
+                d = a.toString(),
+                e = b.toString()
+            try {
+                c += d.split('.')[1].length
+            } catch (f) {
+                // eslint-disable-next-line no-empty
+            }
+            try {
+                c += e.split('.')[1].length
+            } catch (f) {
+                // eslint-disable-next-line no-empty
+            }
+            return (Number(d.replace('.', '')) * Number(e.replace('.', ''))) / Math.pow(10, c)
+        },
+        sale() {
+            this.show = false
+            if (this.payType === 'alipay') {
+                window.open(
+                    this.$baseUrl +
+                        `/payDelegation/alipay?userId=${this.user.id}&orderId=${this.info.id}&riseRate=${
+                            this.value / 100
+                        }&returnUrl=${encodeURIComponent(location.href)}`
+                )
+            } else if (this.payType === 'third') {
+                window.open(
+                    this.$baseUrl +
+                        `/payDelegation/third?userId=${this.user.id}&orderId=${this.info.id}&riseRate=${
+                            this.value / 100
+                        }&payType=` +
+                        (this.isWeixin ? 'WXGZH' : 'ZFBH5')
+                )
+            } else if (this.payType === 'weixin') {
+                this.loading = true
+                this.$toast.loading({
+                    mask: false,
+                    message: '加载中...',
+                    duration: 0,
+                    forbidClick: true
+                })
+                this.$http
+                    .get('/payDelegation/wx', {
+                        userId: this.user.id,
+                        orderId: this.info.id,
+                        riseRate: this.value / 100
+                    })
+                    .then(res => {
+                        this.$toast.clear()
+                        this.loading = false
+                        wx.chooseWXPay({
+                            appId: res.appId,
+                            timestamp: res.timeStamp,
+                            nonceStr: res.nonceStr,
+                            package: res.packageValue,
+                            signType: res.signType,
+                            paySign: res.paySign,
+                            success(res) {
+                                this.$toast.success('支付成功')
+                            }
+                        })
+                    })
+                    .catch(e => {
+                        this.$toast.clear()
+                        this.loading = false
+                        return this.$toast(e.error)
+                    })
+            } else if (this.payType === 'balance') {
+                this.$toast.loading('支付中')
+                this.$http
+                    .post('/payDelegation/balance', {
+                        userId: this.user.id,
+                        orderId: this.info.id,
+                        riseRate: this.value / 100
+                    })
+                    .then(res => {
+                        this.$toast.success('支付成功')
+                        this.$emit('updateOrder', res)
+                    })
+                    .catch(e => {
+                        this.$toast(e.error)
+                    })
+            }
+        },
+        applyShip() {
+            this.$dialog
+                .confirm({
+                    title: '提示',
+                    message: '确认申请发货?'
+                })
+                .then(() => {
+                    this.$http
+                        .post('/order/applyShip', {
+                            orderId: this.info.id
+                        })
+                        .then(res => {
+                            this.$toast.success('申请成功')
+                            setTimeout(() => {
+                                this.$emit('updateOrder', res)
+                            }, 1000)
+                        })
+                        .catch(e => {
+                            return this.$toast(e.error)
+                        })
+                })
+                .catch(() => {})
+        },
+        receive() {
+            this.$http
+                .post('/order/receive', {
+                    orderId: this.info.id
+                })
+                .then(res => {
+                    this.$toast.success('确认成功')
+                    setTimeout(() => {
+                        this.$emit('updateOrder', res)
+                    }, 1000)
+                })
+                .catch(e => {
+                    return this.$toast(e.error)
+                })
+        },
+        pay() {
+            this.$toast.loading('支付中')
+            this.$http
+                .post('/order/balancePay', { orderId: this.orderInfo.id })
+                .then(res => {
+                    this.$toast.success('支付成功')
+                    setTimeout(() => {
+                        this.getInfo()
+                    }, 1000)
+                })
+                .catch(e => {
+                    this.$toast(e.error)
+                })
+        },
+        showTip() {
+            this.$dialog.alert({
+                title: '提示',
+                message: '委托代卖暂未开始,将在今天' + this.delegationTime + '开始'
+            })
+        },
+        problem() {
+            this.$router.push({
+                name: 'workOrderction',
+                query: {
+                    orderId: this.info.id
+                },
+                params: {
+                    isNext: true
+                }
+            })
+        }
+    }
+}
+</script>
+<style lang="less" scoped>
+.order-info {
+    padding: 0 15px;
+    background: rgba(255, 255, 255, 1);
+    border-radius: 2px;
+}
+.order-top {
+    display: flex;
+    justify-content: space-between;
+    height: 43px;
+    align-items: center;
+
+    .order-staus {
+        color: #ff8f00;
+        font-size: 13px;
+        font-weight: bold;
+    }
+}
+
+.text1 {
+    font-size: 14px;
+    color: rgba(0, 0, 0, 1);
+    line-height: 20px;
+}
+
+.text2 {
+    font-size: 12px;
+    color: rgba(255, 143, 0, 1);
+    line-height: 22px;
+    height: 22px;
+    background: rgba(255, 143, 0, 0.12);
+    border-radius: 2px 100px 100px 100px;
+    padding: 0 8px;
+    margin-top: 5px;
+    display: inline-block;
+}
+
+.text3 {
+    display: flex;
+    align-items: center;
+    justify-content: space-between;
+    margin-top: 13px;
+
+    .price {
+        font-size: 14px;
+        font-weight: bold;
+        color: rgba(0, 0, 0, 1);
+        line-height: 20px;
+    }
+
+    .num {
+        font-size: 14px;
+        color: rgba(170, 172, 173, 1);
+        line-height: 20px;
+    }
+}
+.order-content {
+    display: flex;
+    padding-top: 10px;
+    border-top: 1px sold #f2f4f5;
+
+    .order-text {
+        margin-left: 10px;
+        flex-grow: 1;
+        overflow: hidden;
+    }
+}
+
+.order-price {
+    text-align: right;
+
+    .price {
+        font-size: 12px;
+        color: rgba(102, 102, 102, 1);
+        line-height: 17px;
+        margin-top: 18px;
+        span {
+            &:last-child {
+                font-size: 16px;
+                font-weight: bold;
+                color: rgba(255, 59, 48, 1);
+                line-height: 22px;
+            }
+        }
+    }
+    .order-tips {
+        font-size: 12px;
+        color: rgba(255, 143, 0, 1);
+        line-height: 17px;
+        margin-top: 8px;
+    }
+}
+
+.order-button {
+    padding: 15px 0;
+    display: flex;
+    justify-content: flex-end;
+    align-items: center;
+    border-top: 1px sold #f2f4f5;
+    margin-top: 15px;
+
+    .van-button {
+        margin-left: 10px;
+        height: 28px;
+    }
+    .problem {
+        flex-grow: 1;
+        text-align: left;
+        font-size: 12px;
+        font-weight: 400;
+        color: rgba(170, 172, 173, 1);
+    }
+}
+.getsold {
+    width: 300px;
+    height: 405px;
+    background: rgba(255, 255, 255, 1);
+    border-radius: 4px;
+    padding: 15px 20px;
+    box-sizing: border-box;
+    .title {
+        font-size: 16px;
+        font-weight: bold;
+        text-align: center;
+        color: rgba(0, 0, 0, 1);
+        line-height: 22px;
+    }
+
+    .sold-item {
+        display: flex;
+        align-items: center;
+        height: 28px;
+        padding: 22px 0 10px;
+        border-bottom: 1px solid #f2f4f5;
+        .name {
+            font-size: 18px;
+            font-weight: bold;
+            color: rgba(0, 0, 0, 1);
+            line-height: 25px;
+            min-width: 82px;
+        }
+
+        .val {
+            font-size: 14px;
+            font-weight: bold;
+            color: rgba(0, 0, 0, 1);
+            line-height: 20px;
+
+            &.bold {
+                font-size: 16px;
+                color: rgba(255, 59, 48, 1);
+                line-height: 22px;
+            }
+        }
+    }
+    .sold-list {
+        margin-top: 10px;
+    }
+    .tips {
+        font-size: 13px;
+        color: rgba(170, 172, 173, 1);
+        line-height: 18px;
+        margin-top: 20px;
+    }
+
+    .button {
+        width: 200px;
+        display: block;
+        margin: 50px auto 0;
+    }
+}
+</style>

+ 590 - 0
src/components/OrderItem.vue

@@ -0,0 +1,590 @@
+<template>
+    <div class="order-info">
+        <div class="order-top">
+            <div class="order-no">订单编号:{{ info.id }}</div>
+            <div class="order-staus">
+                {{ info.locked && info.status === 'SELLING' ? '暂停出售' : orderStatus[info.status] }}
+            </div>
+        </div>
+
+        <div class="order-content" @click="goDetail">
+            <van-image class="suk-img" width="80" height="80" fit="fill" :src="pic" />
+
+            <div class="order-text">
+                <div class="van-ellipsis text1">{{ productInfo.name }}</div>
+
+                <div class="text2" v-if="productInfo.user">当前所有人为:{{ productInfo.user.nickname }}</div>
+
+                <div class="text3">
+                    <div class="price">¥{{ info.totalPrice }}</div>
+                    <div class="num">×1</div>
+                </div>
+            </div>
+        </div>
+
+        <div class="order-price">
+            <div class="price">
+                <span>实际支付:</span>
+                <span>¥{{ info.totalPrice }}</span>
+            </div>
+
+            <div class="order-tips" v-if="info.status == 'NOT_PAID'">付款倒计时过期自动取消订单 {{ times }}</div>
+        </div>
+
+        <div class="order-button">
+            <span class="problem" @click="problem">遇到问题?</span>
+            <template v-if="info.status == 'NOT_PAID'">
+                <!-- <van-button color="#FF8F00" round plain size="small" @click="confirmPayment">我已付款</van-button> -->
+                <van-button type="primary" round size="small" @click="pay">立即支付</van-button>
+            </template>
+
+            <template v-else-if="info.status == 'NOT_CONFIRMED'">
+                <van-button color="#AAACAD" round plain size="small" @click="goDetail">查看订单</van-button>
+            </template>
+
+            <template v-else-if="info.status == 'SOLD_NOT_CONFIRMED'">
+                <!-- <van-button color="#AAACAD" round plain size="small" @click="confirmPayment">未收到款</van-button> -->
+                <!-- <van-button type="primary" round size="small" @click="confirmReceipt">确认收款</van-button> -->
+            </template>
+
+            <template v-else-if="info.status == 'SELLING'">
+                <!-- <van-button color="#AAACAD" round plain size="small" @click="confirmPayment">未收到款</van-button> -->
+                <!-- <van-button type="primary" round size="small" @click="confirmReceipt">确认收款</van-button> -->
+                <van-button color="#AAACAD" round plain size="small" @click="applyShip">申请发货</van-button>
+                <van-button color="#AAACAD" round plain size="small" @click="goDetail">查看订单</van-button>
+            </template>
+
+            <template v-else-if="info.status == 'CONFIRMED'">
+                <van-button color="#AAACAD" round plain size="small" @click="applyShip">申请发货</van-button>
+                <van-button type="primary" round size="small" @click="show = true" v-if="delegationActive">
+                    委托代卖</van-button
+                >
+                <van-button color="#aaacad" round @click="showTip" v-else>委托代卖 </van-button>
+            </template>
+
+            <template v-else-if="info.status == 'SOLD'">
+                <van-button color="#AAACAD" round plain size="small" @click="goDetail">查看订单</van-button>
+            </template>
+            <template v-else-if="info.status == 'NOT_SHIPPED'">
+                <van-button color="#AAACAD" round plain size="small" @click="goDetail">查看订单</van-button>
+            </template>
+            <template v-else-if="info.status == 'RECEIVED'">
+                <van-button color="#AAACAD" round plain size="small" @click="goDetail">查看订单</van-button>
+            </template>
+            <template v-else-if="info.status == 'SHIPPED'">
+                <van-button type="primary" round size="small" @click="receive"> 确认收货</van-button>
+            </template>
+        </div>
+        <van-popup v-model="show" class="getsold">
+            <div class="title">委托代卖</div>
+            <div class="sold-list">
+                <div class="sold-item">
+                    <div class="name">原价</div>
+                    <div class="val">¥{{ info.totalPrice }}</div>
+                </div>
+                <div class="sold-item">
+                    <div class="name">加价</div>
+                    <van-stepper v-model="value" input-width="60px" step="1" integer min="1" :max="maxRiseRate" />
+                </div>
+                <div class="sold-item">
+                    <div class="name">卖价</div>
+                    <div class="val bold">¥{{ soldValue }}</div>
+                </div>
+            </div>
+            <div class="tips">
+                注:委托平台代卖服务,每次最高可将商品价格提高{{ maxRiseRate }}%,平台会收取{{
+                    serviceValue
+                }}%的托管服务费用
+            </div>
+
+            <van-button class="button" block type="primary" :disabled="loading" round @click="sale">
+                支付手续费 ¥{{ serviceCharge }}
+            </van-button>
+        </van-popup>
+    </div>
+</template>
+<script>
+import { mapState } from 'pinia'
+import { useUserStore } from '@/stores/user'
+import { orderStatus } from '../status'
+import { differenceInSeconds, addMinutes, parse } from 'date-fns'
+export default {
+    name: 'orderInfo',
+    props: {
+        info: {
+            type: Object,
+            default: () => {
+                return {}
+            }
+        },
+        delegationActive: {
+            type: Boolean,
+            default: true
+        },
+        delegationTime: {
+            type: String,
+            default: ''
+        }
+    },
+    data() {
+        return {
+            orderStatus,
+            times: 0,
+            show: false,
+            value: 6,
+            platformCommission: 0.02,
+            maxRiseRate: 6,
+            loading: false,
+            payType: 'balance'
+        }
+    },
+    computed: {
+        ...mapState(useUserStore, ['user']),
+        productInfo() {
+            return this.info.productInfo || {}
+        },
+        pic() {
+            if (this.productInfo.pic && this.productInfo.pic.length > 0) {
+                return this.productInfo.pic[0]
+            } else {
+                return ''
+            }
+        },
+        fromUserInfo() {
+            return this.info.fromUserInfo || {}
+        },
+        soldValue() {
+            var price = Number(this.info.totalPrice)
+            if (this.value) {
+                var more = this.mul(this.value, price)
+                more = this.mul(more, 0.01)
+                price = this.addNum(more, price)
+            }
+            return price.toFixed(2)
+        },
+        serviceCharge() {
+            let totalPrice = this.info ? this.info.totalPrice || 0 : 0
+            return (totalPrice * this.platformCommission).toFixed(2)
+        },
+        serviceValue() {
+            return this.platformCommission * 100
+        }
+    },
+    created() {
+        if (this.info.status == 'NOT_PAID') {
+            this.getTime()
+        }
+        this.$http.get('/sysConfig/get/platform_commission').then(res => {
+            this.platformCommission = res.value
+        })
+        this.$http.get('/sysConfig/get/max_rise_rate').then(res => {
+            this.maxRiseRate = res.value * 100
+            this.value = this.maxRiseRate
+        })
+        // this.$http.get('/sysConfig/get/pay_type').then(res => {
+        //     if (res.value == '0') {
+        //         if (this.isWeixin) {
+        //             this.payType = 'weixin';
+        //         } else {
+        //             this.payType = 'alipay';
+        //         }
+        //     } else {
+        //         this.payType = 'third';
+        //     }
+        // });
+    },
+    methods: {
+        goDetail() {
+            this.goNext('orderDetail', {
+                id: this.info.id
+            })
+        },
+        getTime() {
+            var times = differenceInSeconds(
+                addMinutes(parse(this.info.createdAt, 'yyyy-MM-dd HH:mm:ss', new Date()), 30),
+                new Date()
+            )
+            if (times <= 0) {
+                times = 0
+            }
+            var mint = parseInt(times / 60)
+            var seconds = parseInt(times % 60)
+            this.times = mint + '分 ' + seconds + '秒'
+            if (!times) {
+                return
+            }
+            setTimeout(this.getTime, 1000)
+        },
+        confirmPayment() {
+            this.$http
+                .post('/order/confirmPayment', {
+                    orderId: this.info.id
+                })
+                .then(res => {
+                    this.$toast.success('确认成功')
+                    setTimeout(() => {
+                        this.$emit('updateOrder', res)
+                    }, 1000)
+                })
+                .catch(e => {
+                    return this.$toast(e.error)
+                })
+        },
+        confirmReceipt() {
+            this.$http
+                .post('/order/confirmReceipt', {
+                    orderId: this.info.id
+                })
+                .then(res => {
+                    this.$toast.success('确认成功')
+                    setTimeout(() => {
+                        this.$emit('updateOrder', res)
+                    }, 1000)
+                })
+                .catch(e => {
+                    return this.$toast(e.error)
+                })
+        },
+        addNum(a, b) {
+            var c, d, e
+            try {
+                c = a.toString().split('.')[1].length
+            } catch (f) {
+                c = 0
+            }
+            try {
+                d = b.toString().split('.')[1].length
+            } catch (f) {
+                d = 0
+            }
+            return (e = Math.pow(10, Math.max(c, d))), (this.mul(a, e) + this.mul(b, e)) / e
+        },
+        mul(a, b) {
+            var c = 0,
+                d = a.toString(),
+                e = b.toString()
+            try {
+                c += d.split('.')[1].length
+            } catch (f) {
+                // eslint-disable-next-line no-empty
+            }
+            try {
+                c += e.split('.')[1].length
+            } catch (f) {
+                // eslint-disable-next-line no-empty
+            }
+            return (Number(d.replace('.', '')) * Number(e.replace('.', ''))) / Math.pow(10, c)
+        },
+        sale() {
+            this.show = false
+            if (this.payType === 'alipay') {
+                window.open(
+                    this.$baseUrl +
+                        `/payDelegation/alipay?userId=${this.user.id}&orderId=${this.info.id}&riseRate=${
+                            this.value / 100
+                        }&returnUrl=${encodeURIComponent(location.href)}`
+                )
+            } else if (this.payType === 'third') {
+                window.open(
+                    this.$baseUrl +
+                        `/payDelegation/third?userId=${this.user.id}&orderId=${this.info.id}&riseRate=${
+                            this.value / 100
+                        }&payType=` +
+                        (this.isWeixin ? 'WXGZH' : 'ZFBH5')
+                )
+            } else if (this.payType === 'weixin') {
+                this.loading = true
+                this.$toast.loading({
+                    mask: false,
+                    message: '加载中...',
+                    duration: 0,
+                    forbidClick: true
+                })
+                this.$http
+                    .get('/payDelegation/wx', {
+                        userId: this.user.id,
+                        orderId: this.info.id,
+                        riseRate: this.value / 100
+                    })
+                    .then(res => {
+                        this.$toast.clear()
+                        this.loading = false
+                        wx.chooseWXPay({
+                            appId: res.appId,
+                            timestamp: res.timeStamp,
+                            nonceStr: res.nonceStr,
+                            package: res.packageValue,
+                            signType: res.signType,
+                            paySign: res.paySign,
+                            success(res) {
+                                this.$toast.success('支付成功')
+                            }
+                        })
+                    })
+                    .catch(e => {
+                        this.$toast.clear()
+                        this.loading = false
+                        return this.$toast(e.error)
+                    })
+            } else if (this.payType === 'balance') {
+                this.$toast.loading('支付中')
+                this.$http
+                    .post('/payDelegation/balance', {
+                        userId: this.user.id,
+                        orderId: this.info.id,
+                        riseRate: this.value / 100
+                    })
+                    .then(res => {
+                        this.$toast.success('支付成功')
+                        this.$emit('updateOrder', res)
+                    })
+                    .catch(e => {
+                        this.$toast(e.error)
+                    })
+            }
+        },
+        applyShip() {
+            this.$dialog
+                .confirm({
+                    title: '提示',
+                    message: '确认申请发货?'
+                })
+                .then(() => {
+                    this.$http
+                        .post('/order/applyShip', {
+                            orderId: this.info.id
+                        })
+                        .then(res => {
+                            this.$toast.success('申请成功')
+                            setTimeout(() => {
+                                this.$emit('updateOrder', res)
+                            }, 1000)
+                        })
+                        .catch(e => {
+                            return this.$toast(e.error)
+                        })
+                })
+                .catch(() => {})
+        },
+        receive() {
+            this.$http
+                .post('/order/receive', {
+                    orderId: this.info.id
+                })
+                .then(res => {
+                    this.$toast.success('确认成功')
+                    setTimeout(() => {
+                        this.$emit('updateOrder', res)
+                    }, 1000)
+                })
+                .catch(e => {
+                    return this.$toast(e.error)
+                })
+        },
+        pay() {
+            this.$toast.loading('支付中')
+            this.$http
+                .post('/order/balancePay', { orderId: this.orderInfo.id })
+                .then(res => {
+                    this.$toast.success('支付成功')
+                    setTimeout(() => {
+                        this.getInfo()
+                    }, 1000)
+                })
+                .catch(e => {
+                    this.$toast(e.error)
+                })
+        },
+        showTip() {
+            this.$dialog.alert({
+                title: '提示',
+                message: '委托代卖暂未开始,将在今天' + this.delegationTime + '开始'
+            })
+        },
+        problem() {
+            this.$router.push({
+                name: 'workOrderction',
+                query: {
+                    orderId: this.info.id
+                },
+                params: {
+                    isNext: true
+                }
+            })
+        }
+    }
+}
+</script>
+<style lang="less" scoped>
+.order-info {
+    padding: 0 15px;
+    background: rgba(255, 255, 255, 1);
+    border-radius: 2px;
+    margin: 12px 16px 0 16px;
+}
+.order-top {
+    display: flex;
+    justify-content: space-between;
+    height: 43px;
+    align-items: center;
+
+    .order-staus {
+        color: #ff8f00;
+        font-size: 13px;
+        font-weight: bold;
+    }
+}
+
+.text1 {
+    font-size: 14px;
+    color: rgba(0, 0, 0, 1);
+    line-height: 20px;
+}
+
+.text2 {
+    font-size: 12px;
+    color: rgba(255, 143, 0, 1);
+    line-height: 22px;
+    height: 22px;
+    background: rgba(255, 143, 0, 0.12);
+    border-radius: 2px 100px 100px 100px;
+    padding: 0 8px;
+    margin-top: 5px;
+    display: inline-block;
+}
+
+.text3 {
+    display: flex;
+    align-items: center;
+    justify-content: space-between;
+    margin-top: 13px;
+
+    .price {
+        font-size: 14px;
+        font-weight: bold;
+        color: rgba(0, 0, 0, 1);
+        line-height: 20px;
+    }
+
+    .num {
+        font-size: 14px;
+        color: rgba(170, 172, 173, 1);
+        line-height: 20px;
+    }
+}
+.order-content {
+    display: flex;
+    padding-top: 10px;
+    border-top: 1px sold #f2f4f5;
+
+    .order-text {
+        margin-left: 10px;
+        flex-grow: 1;
+        overflow: hidden;
+    }
+}
+
+.order-price {
+    text-align: right;
+
+    .price {
+        font-size: 12px;
+        color: rgba(102, 102, 102, 1);
+        line-height: 17px;
+        margin-top: 18px;
+        span {
+            &:last-child {
+                font-size: 16px;
+                font-weight: bold;
+                color: rgba(255, 59, 48, 1);
+                line-height: 22px;
+            }
+        }
+    }
+    .order-tips {
+        font-size: 12px;
+        color: rgba(255, 143, 0, 1);
+        line-height: 17px;
+        margin-top: 8px;
+    }
+}
+
+.order-button {
+    padding: 15px 0;
+    display: flex;
+    justify-content: flex-end;
+    align-items: center;
+    border-top: 1px sold #f2f4f5;
+    margin-top: 15px;
+
+    .van-button {
+        margin-left: 10px;
+        height: 28px;
+    }
+    .problem {
+        flex-grow: 1;
+        text-align: left;
+        font-size: 12px;
+        font-weight: 400;
+        color: rgba(170, 172, 173, 1);
+    }
+}
+.getsold {
+    width: 300px;
+    height: 405px;
+    background: rgba(255, 255, 255, 1);
+    border-radius: 4px;
+    padding: 15px 20px;
+    box-sizing: border-box;
+    .title {
+        font-size: 16px;
+        font-weight: bold;
+        text-align: center;
+        color: rgba(0, 0, 0, 1);
+        line-height: 22px;
+    }
+
+    .sold-item {
+        display: flex;
+        align-items: center;
+        height: 28px;
+        padding: 22px 0 10px;
+        border-bottom: 1px solid #f2f4f5;
+        .name {
+            font-size: 18px;
+            font-weight: bold;
+            color: rgba(0, 0, 0, 1);
+            line-height: 25px;
+            min-width: 82px;
+        }
+
+        .val {
+            font-size: 14px;
+            font-weight: bold;
+            color: rgba(0, 0, 0, 1);
+            line-height: 20px;
+
+            &.bold {
+                font-size: 16px;
+                color: rgba(255, 59, 48, 1);
+                line-height: 22px;
+            }
+        }
+    }
+    .sold-list {
+        margin-top: 10px;
+    }
+    .tips {
+        font-size: 13px;
+        color: rgba(170, 172, 173, 1);
+        line-height: 18px;
+        margin-top: 20px;
+    }
+
+    .button {
+        width: 200px;
+        display: block;
+        margin: 50px auto 0;
+    }
+}
+</style>

+ 87 - 0
src/components/RankItem.vue

@@ -0,0 +1,87 @@
+<template>
+    <div class="rankItem">
+        <div class="num" v-html="numContent"></div>
+        <van-image width="40" height="40" radius="100" fit="fill" :src="info.avatar" />
+        <div class="name">{{ info.nickname }}</div>
+        <div class="money">{{ info.money.toFixed(2) }}</div>
+    </div>
+</template>
+<script>
+export default {
+    name: 'rankItem',
+    props: {
+        rank: {
+            type: [Number, String],
+            default: 1
+        },
+        info: {
+            type: Object,
+            default: () => {
+                return {};
+            }
+        }
+    },
+    data() {
+        return {};
+    },
+    computed: {
+        numContent() {
+            if (this.rank > 3) {
+                return this.rank;
+            } else if (this.rank == 1) {
+                return '<img src="' + require('../assets/paihang_icon_no1.png') + '" style="width:20px"/>';
+            } else if (this.rank == 2) {
+                return '<img src="' + require('../assets/paihang_icon_no2.png') + '" style="width:20px"/>';
+            } else if (this.rank == 3) {
+                return '<img src="' + require('../assets/paihang_icon_no3.png') + '" style="width:20px"/>';
+            }
+            return '';
+        }
+    }
+};
+</script>
+<style lang="less" scoped>
+.rankItem {
+    height: 68px;
+    background: rgba(255, 255, 255, 0.2);
+    border-radius: 6px;
+    display: flex;
+    padding: 0 14px;
+    align-items: center;
+    margin-top: 10px;
+}
+
+.num {
+    font-size: 14px;
+    font-weight: bold;
+    text-align: center;
+    color: rgba(255, 255, 255, 1);
+    line-height: 20px;
+    width: 20px;
+    margin-right: 15px;
+    img {
+        width: 20px;
+        height: 25px;
+    }
+}
+
+.name {
+    font-size: 14px;
+    color: rgba(93, 52, 0, 1);
+    line-height: 20px;
+    margin-left: 10px;
+    overflow: hidden;
+    text-overflow: ellipsis;
+    white-space: nowrap;
+    margin-right: 10px;
+}
+
+.money {
+    flex-grow: 1;
+    text-align: right;
+    font-size: 15px;
+    font-weight: bold;
+    color: rgba(203, 41, 0, 1);
+    line-height: 21px;
+}
+</style>

+ 157 - 0
src/components/Record.vue

@@ -0,0 +1,157 @@
+<template>
+    <div class="record">
+        <div class="top">
+            <span>申请时间:{{ info.createdAt }}</span>
+            <span>{{ withdrawStatus[info.status] }}</span>
+        </div>
+        <div class="money">
+            <span>+{{ info.amount }}</span>
+            <span>元</span>
+        </div>
+        <div class="moeny-list">
+            <div class="money-item">
+                <div class="val">{{ info.amount }}</div>
+                <div class="name">申请佣金</div>
+            </div>
+            <div class="money-item">
+                <div class="val">{{ info.auditAmount || info.amount }}</div>
+                <div class="name">实际金额</div>
+            </div>
+            <div class="money-item">
+                <div class="val">0</div>
+                <div class="name">提现手续费</div>
+            </div>
+        </div>
+        <van-button
+            class="button"
+            color="#FF8F00"
+            block
+            plain
+            hairline
+            @click="goNext('commissionRecordList', { id: info.id })"
+        >
+            <div class="button-content">
+                <span>查看提现详情</span>
+                <img src="../assets/icon_inter_pre.png" class="next" alt="" />
+            </div>
+        </van-button>
+    </div>
+</template>
+<script>
+import { mapState } from 'pinia';
+import { useUserStore } from '@/stores/user';
+import { withdrawStatus } from '../status';
+export default {
+    name: 'record',
+    props: {
+        info: {
+            type: Object,
+            default: () => {
+                return {};
+            }
+        }
+    },
+    data() {
+        return {
+            withdrawStatus
+        };
+    },
+    computed: {
+        ...mapState(userUserStore, ['user'])
+    }
+};
+</script>
+<style lang="less" scoped>
+.record {
+    margin: 0 0 10px;
+    background: rgba(255, 255, 255, 1);
+    border-radius: 2px;
+    padding: 0 15px;
+}
+
+.button {
+    height: 36px;
+    border-color: #fff !important;
+    font-size: 12px;
+    line-height: 36px;
+
+    .next {
+        width: 24px;
+        height: 24px;
+    }
+
+    .button-content {
+        display: flex;
+        align-items: center;
+        justify-content: center;
+        border-top: 1px solid #f2f4f5;
+    }
+}
+
+.top {
+    height: 44px;
+    display: flex;
+    justify-content: space-between;
+    align-items: center;
+    font-size: 13px;
+    color: rgba(102, 102, 102, 1);
+    line-height: 18px;
+    span {
+        &:last-child {
+            font-size: 13px;
+            font-weight: bold;
+            color: rgba(255, 143, 0, 1);
+            line-height: 18px;
+        }
+    }
+}
+
+.money {
+    height: 64px;
+    background: rgba(255, 143, 0, 0.12);
+    border-radius: 2px;
+    display: flex;
+    align-items: center;
+    justify-content: center;
+    span {
+        &:first-child {
+            font-size: 24px;
+            font-weight: bold;
+            color: rgba(0, 0, 0, 1);
+            line-height: 28px;
+        }
+        &:last-child {
+            font-size: 12px;
+            font-weight: bold;
+            color: rgba(0, 0, 0, 1);
+            line-height: 17px;
+            margin-left: 4px;
+        }
+    }
+}
+.moeny-list {
+    display: flex;
+    align-items: center;
+    height: 81px;
+
+    .money-item {
+        width: 33%;
+        display: flex;
+        flex-direction: column;
+        align-items: center;
+        .val {
+            font-size: 14px;
+            font-weight: bold;
+            color: rgba(0, 0, 0, 1);
+            line-height: 20px;
+        }
+
+        .name {
+            font-size: 12px;
+            color: rgba(102, 102, 102, 1);
+            line-height: 17px;
+            margin-top: 4px;
+        }
+    }
+}
+</style>

+ 140 - 0
src/components/RecordOrder.vue

@@ -0,0 +1,140 @@
+<template>
+    <div class="orderInfo">
+        <div class="top">
+            <!-- <div class="label">一级分销</div> -->
+            <div class="value">{{ commissionStatus[status] }}</div>
+        </div>
+        <div class="center">
+            <van-image class="suk-img" width="50" height="50" fit="fill" :src="info.pic" />
+
+            <div class="right">
+                <div class="text1">{{ info.name }}</div>
+                <div class="text2">¥{{ info.price }}</div>
+            </div>
+            <div class="num">×1</div>
+        </div>
+
+        <div class="order-info">
+            <div class="order-item">订单编号:{{ info.orderId }}</div>
+            <div class="order-item">下单时间:{{ info.createdAt }}</div>
+        </div>
+
+        <div class="money">
+            <span>申请佣金: {{ info.commission }} 元</span>
+            <span>审核佣金:{{ info.commission }} 元</span>
+        </div>
+    </div>
+</template>
+<script>
+import { mapState } from 'pinia';
+import { useUserStore } from '@/stores/user';
+import { commissionStatus } from '../status';
+export default {
+    name: 'orderInfo',
+    props: {
+        info: {
+            type: Object,
+            default: () => {
+                return {};
+            }
+        },
+        status: {
+            type: String,
+            default: ''
+        }
+    },
+    data() {
+        return {
+            commissionStatus
+        };
+    },
+    computed: {
+        ...mapState(userUserStore, ['user'])
+    }
+};
+</script>
+<style lang="less" scoped>
+.orderInfo {
+    background: rgba(255, 255, 255, 1);
+    border-radius: 2px;
+    padding: 0 15px 15px;
+    margin-bottom: 10px;
+}
+
+.top {
+    position: relative;
+    height: 44px;
+    text-align: right;
+    border-bottom: 1px solid #f2f4f5;
+    .label {
+        width: 70px;
+        height: 24px;
+        background: rgba(255, 143, 0, 1);
+        border-radius: 0px 100px 100px 0px;
+        font-size: 12px;
+        color: rgba(255, 255, 255, 1);
+        line-height: 24px;
+        text-align: center;
+        position: absolute;
+        left: 0;
+        top: 10px;
+    }
+
+    .value {
+        font-size: 13px;
+        font-weight: bold;
+        color: rgba(255, 143, 0, 1);
+        line-height: 44px;
+    }
+}
+.center {
+    display: flex;
+    // align-items: center;
+    padding: 15px 0 0;
+    .right {
+        flex-grow: 1;
+        margin-left: 10px;
+        .text1 {
+            font-size: 14px;
+            color: rgba(0, 0, 0, 1);
+            line-height: 20px;
+        }
+        .text2 {
+            font-size: 12px;
+            color: rgba(0, 0, 0, 1);
+            line-height: 17px;
+            margin-top: 5px;
+        }
+    }
+
+    .num {
+        font-size: 14px;
+        color: rgba(170, 172, 173, 1);
+        line-height: 20px;
+        align-self: flex-end;
+    }
+}
+
+.order-info {
+    margin-top: 10px;
+    .order-item {
+        font-size: 12px;
+        color: rgba(102, 102, 102, 1);
+        line-height: 17px;
+        &:not(:last-child) {
+            margin-bottom: 5px;
+        }
+    }
+}
+
+.money {
+    padding: 15px 0 0;
+    font-size: 14px;
+    font-weight: bold;
+    color: rgba(0, 0, 0, 1);
+    line-height: 20px;
+    span {
+        margin-right: 20px;
+    }
+}
+</style>

+ 139 - 0
src/components/StatisticsOrder.vue

@@ -0,0 +1,139 @@
+<template>
+    <div class="orderInfo">
+        <div class="top">
+            <div class="person">
+                <van-image width="24" height="24" radius="100" fit="fill" :src="info.avatar" />
+
+                <span>{{ info.nickname }}</span>
+            </div>
+            <div class="value">{{ status }}</div>
+        </div>
+        <div class="center">
+            <van-image class="suk-img" width="50" height="50" fit="fill" :src="info.pic" />
+
+            <div class="right">
+                <div class="text1">{{ info.name }}</div>
+                <div class="text2">¥{{ info.price }}</div>
+            </div>
+            <div class="num">×1</div>
+        </div>
+
+        <div class="order-info">
+            <div class="order-item">订单编号:{{ info.orderId }}</div>
+            <div class="order-item">下单时间:{{ info.createdAt }}</div>
+        </div>
+    </div>
+</template>
+<script>
+import { mapState } from 'pinia';
+import { useUserStore } from '@/stores/user';
+export default {
+    name: 'orderInfo',
+    props: {
+        info: {
+            type: Object,
+            default: () => {
+                return {};
+            }
+        }
+    },
+    data() {
+        return {};
+    },
+    computed: {
+        ...mapState(userUserStore, ['user']),
+        status() {
+            switch (this.info.status) {
+                case 'NOT_PAID':
+                case 'CANCELED':
+                    return '未付款';
+                case 'NOT_CONFIRMED':
+                case 'CONFIRMED':
+                case 'SELLING':
+                case 'SOLD_NOT_PAID':
+                case 'SOLD_NOT_CONFIRMED':
+                case 'SOLD':
+                case 'NOT_SHIPPED':
+                case 'SHIPPED':
+                case 'RECEIVED':
+                    return '已付款';
+            }
+            return '';
+        }
+    }
+};
+</script>
+<style lang="less" scoped>
+.orderInfo {
+    background: rgba(255, 255, 255, 1);
+    border-radius: 2px;
+    padding: 0 15px 15px;
+    margin-top: 10px;
+}
+
+.top {
+    position: relative;
+    height: 44px;
+    text-align: right;
+    border-bottom: 1px solid #f2f4f5;
+    display: flex;
+    align-items: center;
+    justify-content: space-between;
+
+    .person {
+        display: flex;
+        align-items: center;
+        span {
+            font-size: 14px;
+            color: rgba(0, 0, 0, 1);
+            line-height: 20px;
+            margin-left: 6px;
+        }
+    }
+    .value {
+        font-size: 13px;
+        font-weight: bold;
+        color: rgba(255, 143, 0, 1);
+        line-height: 44px;
+    }
+}
+.center {
+    display: flex;
+    // align-items: center;
+    padding: 15px 0 0;
+    .right {
+        flex-grow: 1;
+        margin-left: 10px;
+        .text1 {
+            font-size: 14px;
+            color: rgba(0, 0, 0, 1);
+            line-height: 20px;
+        }
+        .text2 {
+            font-size: 12px;
+            color: rgba(0, 0, 0, 1);
+            line-height: 17px;
+            margin-top: 5px;
+        }
+    }
+
+    .num {
+        font-size: 14px;
+        color: rgba(170, 172, 173, 1);
+        line-height: 20px;
+        align-self: flex-end;
+    }
+}
+
+.order-info {
+    margin-top: 10px;
+    .order-item {
+        font-size: 12px;
+        color: rgba(102, 102, 102, 1);
+        line-height: 17px;
+        &:not(:last-child) {
+            margin-bottom: 5px;
+        }
+    }
+}
+</style>

+ 5 - 2
src/locales/zh.json

@@ -1,3 +1,6 @@
 {
 {
-  "login": "登录"
-}
+    "login": "登录",
+    "order": {
+        "my": "我的订单"
+    }
+}

+ 49 - 4
src/main.js

@@ -3,11 +3,25 @@ import { createPinia } from 'pinia'
 import App from './App.vue'
 import App from './App.vue'
 import router from './router'
 import router from './router'
 import http from '@/plugins/http'
 import http from '@/plugins/http'
-import { IonicVue, IonButton } from '@ionic/vue'
+import {
+    IonicVue,
+    IonButton,
+    IonPage,
+    IonContent,
+    IonHeader,
+    IonToolbar,
+    IonButtons,
+    IonBackButton,
+    IonList,
+    IonLabel,
+    IonInput,
+    IonItem,
+    IonTitle
+} from '@ionic/vue'
+import { Button, PullRefresh, Sticky, Tabs, Tab, List, Empty, Image, Popup, Stepper } from 'vant'
 import i18n from './locales'
 import i18n from './locales'
-import Vant from 'vant';
-import { ConfigProvider } from 'vant';
-import 'vant/lib/index.css';
+import Vant from 'vant'
+import { ConfigProvider } from 'vant'
 import { useDark } from '@vueuse/core'
 import { useDark } from '@vueuse/core'
 
 
 import 'normalize.css/normalize.css'
 import 'normalize.css/normalize.css'
@@ -27,6 +41,9 @@ import '@ionic/vue/css/text-alignment.css'
 import '@ionic/vue/css/text-transformation.css'
 import '@ionic/vue/css/text-transformation.css'
 import '@ionic/vue/css/flex-utils.css'
 import '@ionic/vue/css/flex-utils.css'
 import '@ionic/vue/css/display.css'
 import '@ionic/vue/css/display.css'
+
+import 'vant/lib/index.css'
+
 import './styles/main.less'
 import './styles/main.less'
 import './styles/theme/variables.less'
 import './styles/theme/variables.less'
 
 
@@ -39,7 +56,35 @@ app.use(http)
 app.use(Vant)
 app.use(Vant)
 app.use(ConfigProvider)
 app.use(ConfigProvider)
 
 
+// ionic components
+app.component('ion-button', IonButton)
+app.component('ion-page', IonPage)
+app.component('ion-content', IonContent)
+app.component('ion-header', IonHeader)
+app.component('ion-toolbar', IonToolbar)
+app.component('ion-buttons', IonButtons)
+app.component('ion-back-button', IonBackButton)
+app.component('ion-list', IonList)
+app.component('ion-label', IonLabel)
+app.component('ion-input', IonInput)
+app.component('ion-item', IonItem)
+app.component('ion-title', IonTitle)
+
+// vant components
+app.use(Button)
+app.use(PullRefresh)
+app.use(Sticky)
+app.use(Tabs)
+app.use(Tab)
+app.use(List)
+app.use(Empty)
+app.use(Image)
+app.use(Popup)
+app.use(Stepper)
+
+//dark mode
 useDark()
 useDark()
+
 router.isReady().then(() => {
 router.isReady().then(() => {
     app.mount('#app')
     app.mount('#app')
 })
 })

+ 5 - 0
src/router/index.js

@@ -30,6 +30,11 @@ const router = createRouter({
             path: '/login',
             path: '/login',
             name: 'login',
             name: 'login',
             component: () => import('@/views/LoginPage.vue')
             component: () => import('@/views/LoginPage.vue')
+        },
+        {
+            path: '/order',
+            name: 'order',
+            component: () => import('@/views/OrderPage.vue')
         }
         }
     ]
     ]
 })
 })

+ 29 - 0
src/status.js

@@ -0,0 +1,29 @@
+export const orderStatus = {
+    NOT_PAID: '待付款',
+    CANCELED: '已取消',
+    NOT_CONFIRMED: '待卖家确认收款',
+    CONFIRMED: '待上架',
+    SELLING: '出售中',
+    SOLD_NOT_PAID: '待买家付款',
+    SOLD_NOT_CONFIRMED: '待确认收款',
+    SOLD: '已售出',
+    NOT_SHIPPED: '待发货',
+    SHIPPED: '已发货',
+    RECEIVED: '已收货'
+}
+
+export const commissionStatus = {
+    NOT_CHECKED: '未确认',
+    CHECKED: '确认',
+    PENDING: '待审核',
+    WAIT_TRANSFER: '待打款',
+    TRANSFERRED: '已打款',
+    CANCELED: '作废'
+}
+
+export const withdrawStatus = {
+    PENDING: '待审核',
+    WAIT_TRANSFER: '待打款',
+    TRANSFERRED: '已打款',
+    CANCELLED: '无效'
+}

+ 2 - 0
src/styles/theme/variables.less

@@ -3,6 +3,8 @@ http://ionicframework.com/docs/theming/ */
 
 
 /** Ionic CSS Variables **/
 /** Ionic CSS Variables **/
 :root {
 :root {
+    --ion-background-color: #F5F7FA;
+    
     /** primary **/
     /** primary **/
     --ion-color-primary: #3880ff;
     --ion-color-primary: #3880ff;
     --ion-color-primary-rgb: 56, 128, 255;
     --ion-color-primary-rgb: 56, 128, 255;

+ 143 - 0
src/views/OrderPage.vue

@@ -0,0 +1,143 @@
+<template>
+    <ion-page>
+        <ion-content :fullscreen="true" class="list">
+            <ion-page>
+                <ion-header>
+                    <ion-toolbar>
+                        <ion-buttons slot="start">
+                            <ion-back-button default-href="#" @click="$router.back(-1)"></ion-back-button>
+                        </ion-buttons>
+                        <ion-title>{{ $t('order.my') }}</ion-title>
+                    </ion-toolbar>
+                </ion-header>
+                <ion-content :fullscreen="true" class="ion-content">
+                    <van-tabs v-model:active="status" :line-height="2">
+                        <van-tab v-for="item in statusOptions" :title="item.title" :name="item.value" :key="item.value">
+                        </van-tab>
+                    </van-tabs>
+                    <van-list
+                        v-model:loading="loading"
+                        :finished="finished"
+                        finished-text="没有更多了"
+                        @load="loadmore"
+                    >
+                        <order-item v-for="item in list" :key="item.id" :info="item"></order-item>
+                    </van-list>
+                </ion-content>
+            </ion-page>
+        </ion-content>
+    </ion-page>
+</template>
+<script>
+import { mapState } from 'pinia'
+import { useUserStore } from '@/stores/user'
+import OrderItem from '@/components/OrderItem.vue'
+import { parse } from 'date-fns'
+export default {
+    name: 'OrderPage',
+    components: { OrderItem },
+    data() {
+        return {
+            priceDirection: 0,
+            list: [],
+            refreshing: false,
+            loading: false,
+            finished: false,
+            statusOptions: [
+                { title: '全部', value: 'ALL' },
+                { title: '待付款', value: 'NOT_PAID' },
+                { title: '待上架', value: 'CONFIRMED' },
+                { title: '已上架', value: 'SELLING' },
+                { title: '已售出', value: 'SOLD' }
+            ],
+            status: 'ALL',
+            page: 0,
+            size: 20
+        }
+    },
+    computed: {
+        ...mapState(useUserStore, ['user'])
+    },
+    created() {
+        this.$http
+            .post(
+                '/order/my',
+                {
+                    query: {
+                        status: 'SELLING'
+                    },
+                    page: 0,
+                    size: 1
+                },
+                { body: 'json' }
+            )
+            .then(res => {
+                if (res.totalElements > 0) {
+                    this.SELLINGNUM = res.totalElements
+                } else {
+                    this.SELLINGNUM = ''
+                }
+            })
+            .catch(() => {
+                this.finished = true
+            })
+        this.loading = true
+        this.getData()
+    },
+    methods: {
+        refresh() {
+            this.loading = true
+            this.page = 0
+            this.getData()
+        },
+        loadmore() {
+            this.page++
+            this.getData()
+        },
+        getData() {
+            return this.$http
+                .post(
+                    '/order/my',
+                    {
+                        query: {
+                            status: this.status === 'ALL' ? undefined : this.status
+                        },
+                        page: this.page,
+                        size: 20,
+                        sort: 'createdAt,desc'
+                    },
+                    { body: 'json' }
+                )
+                .then(res => {
+                    if (res.first) {
+                        this.list = []
+                    }
+                    this.list = this.list.concat(res.content)
+                    this.refreshing = false
+                    this.loading = false
+                    this.finished = res.last
+                })
+                .catch(() => {
+                    this.finished = true
+                })
+        }
+    },
+    watch: {
+        status() {
+            this.list = []
+            this.page = 0
+            this.finished = false
+            this.$router
+                .replace({
+                    query: {
+                        ...this.$route.query,
+                        status: this.status
+                    }
+                })
+                .catch(() => {})
+            this.refresh()
+        }
+    }
+}
+</script>
+<style lang="less" scoped></style>

+ 5 - 0
yarn.lock

@@ -429,6 +429,11 @@ csstype@^2.6.8:
   resolved "https://registry.npmmirror.com/csstype/-/csstype-2.6.21.tgz#2efb85b7cc55c80017c66a5ad7cbd931fda3a90e"
   resolved "https://registry.npmmirror.com/csstype/-/csstype-2.6.21.tgz#2efb85b7cc55c80017c66a5ad7cbd931fda3a90e"
   integrity sha512-Z1PhmomIfypOpoMjRQB70jfvy/wxT50qW08YXO5lMIJkrdq4yOTR+AW7FqutScmB9NkLwxo+jU+kZLbofZZq/w==
   integrity sha512-Z1PhmomIfypOpoMjRQB70jfvy/wxT50qW08YXO5lMIJkrdq4yOTR+AW7FqutScmB9NkLwxo+jU+kZLbofZZq/w==
 
 
+date-fns@^2.29.3:
+  version "2.29.3"
+  resolved "https://registry.npmmirror.com/date-fns/-/date-fns-2.29.3.tgz#27402d2fc67eb442b511b70bbdf98e6411cd68a8"
+  integrity sha512-dDCnyH2WnnKusqvZZ6+jA1O51Ibt8ZMRNkDZdyAyK4YfbDwa/cEmuztzG5pk6hqlp9aSBPYcjOlktquahGwGeA==
+
 debug@^3.2.6:
 debug@^3.2.6:
   version "3.2.7"
   version "3.2.7"
   resolved "https://registry.npmmirror.com/debug/-/debug-3.2.7.tgz#72580b7e9145fb39b6676f9c5e5fb100b934179a"
   resolved "https://registry.npmmirror.com/debug/-/debug-3.2.7.tgz#72580b7e9145fb39b6676f9c5e5fb100b934179a"