From f1aaecc9dc0a3d680f2f693ee963d5d060e75734 Mon Sep 17 00:00:00 2001
From: jhzh <1628036192@qq.com>
Date: Fri, 09 Jan 2026 16:18:43 +0800
Subject: [PATCH] 1

---
 src/page/home/listcomponents/dazongjiaoyi.vue |  608 +++++++++++++++++++++++++++++++++++++++++-------------
 1 files changed, 456 insertions(+), 152 deletions(-)

diff --git a/src/page/home/listcomponents/dazongjiaoyi.vue b/src/page/home/listcomponents/dazongjiaoyi.vue
index ff01761..5a93270 100644
--- a/src/page/home/listcomponents/dazongjiaoyi.vue
+++ b/src/page/home/listcomponents/dazongjiaoyi.vue
@@ -11,38 +11,111 @@
             </div>
         </div>
         <div class="dbox">
-            <div class="daz"><span class="d1">{{ $t("MingCheng") }}</span><span class="d2">{{ $t("hj81") }}</span><span class="d3"></span></div>
+            <div class="daz">
+                <span class="d1">{{ $t("MingCheng") }}</span>
+                <span class="d2">{{ $t("hj81") }}</span>
+            </div>
         </div>
         <div class="list" v-for="(item, index) in dazongList" :key="index">
             <div class="lbox">
-                <div class="lb1">
-                    <h6>{{ item.stockName }}</h6>
-                    <p>
-                        <span v-if="item.stockType == 'sz'">{{ $t("jy83") }}</span>
-                        <span class="sh" v-if="item.stockType == 'sh'">{{ $t("jy84") }}</span>
-                        <span class="bj" v-if="item.stockType == 'bj'">{{ $t("jy85") }}</span>
-                        <a :class="item.stockType == 'sh' ? 'shbg' : item.stockType == 'bj' ? 'bjbg' : ''">{{
-                                item.stockGid
-                        }}</a>
-                    </p>
+                <div class="top-section">
+                    <div class="lb1">
+                        <h6>{{ item.stockName }}</h6>
+                        <p>
+                            <span v-if="item.stockType == 'sz'">{{ $t("jy83") }}</span>
+                            <span class="sh" v-if="item.stockType == 'sh'">{{ $t("jy84") }}</span>
+                            <span class="bj" v-if="item.stockType == 'bj'">{{ $t("jy85") }}</span>
+                            <a :class="item.stockType == 'sh' ? 'shbg' : item.stockType == 'bj' ? 'bjbg' : ''">{{
+                                    item.stockGid
+                            }}</a>
+                        </p>
+                    </div>
+                    <div class="top-right">
+                        <div class="lb2">
+                            <div class="price-value">{{ item.price }}{{ $t('jy51') }}</div>
+                            <div class="price-label">{{ $t("hj81") }}</div>
+                        </div>
+                        <div class="lb3"><a @click="getdetail(item)">{{ $t("hj238") }}</a></div>
+                    </div>
                 </div>
-                <div class="lb2"> {{ item.price }} </div>
-                <div class="lb3"><a @click="getdetail(item)">{{ $t("hj238") }}</a></div>
+                <div class="middle-section">
+                    <div class="share-info">
+                        <span class="label">{{ $t('dz_share') }}:</span>
+                        <span class="value">{{ formatAmount(item.stockShare || 0) }}</span>
+                    </div>
+                    <div class="surplus-info">
+                        <span class="label">{{ $t('dz_completed') }}:</span>
+                        <span class="value">{{ formatAmount(item.stockSurplus || 0) }}</span>
+                    </div>
+                </div>
+                <div class="progress-section">
+                <div class="progress-bar">
+                    <div class="progress-fill" :style="{ width: getProgressPercent(item) + '%' }">
+                    <div class="progress-text-wrap">
+                        <div class="progress-text">{{ getProgressPercent(item) }}%</div>
+                    </div>
+                    </div>
+                </div>
+                </div>
             </div>
         </div>
         <van-popup v-model="show" round position="bottom">
             <div class="boxd">
-                <div class="boxh"> {{ $t("jy86") }} <span @click="show = false"></span></div>
-                <h5>{{ $t("hj130") }}</h5>
-                <h6>{{ currentItem.price ? currentItem.price : '' }}</h6>
-                <div class="erty tghj"><input :placeholder="$t('jy87')" type="number" class="inpy" v-model="num"
-                        @input="num = num.replace(/^(0+)|[^\d]+/g, '')"><a>{{ $t("hj117") }}</a></div>
-                <p class="plm"><span>{{ $t("jy88") }}</span><a>{{ currentItem.price ? (currentItem.price * num * 100).toFixed(2) :
-                        '0.00'
-                }}</a></p>
-                <div class="erty"><input :placeholder="$t('jy89')" type="password" class="inpy" v-model="password"></div>
-                <p class="plm"><span>{{ $t("hj54") }}</span><a>{{ userinfo.enableAmt }}</a></p>
-                <div class="maik" @click="getxiadan">{{ $t("hj85") }}</div>
+                <!-- 顶部份额和已完成金额 -->
+                <!-- <div class="popup-header">
+                    <span class="header-left">{{ $t("dz_share") }}: {{ formatAmount(currentItem.stockShare || 0) }}</span>
+                    <span class="header-right">{{ $t("dz_completed") }}: {{ formatAmount(currentItem.stockSurplus || 0) }}</span>
+                </div> -->
+                <!-- 标题和关闭按钮 -->
+                <div class="boxh">
+                    <span class="close-btn" @click="show = false">×</span>
+                    <h5>{{ $t("hj85") }}</h5>
+                </div>
+                <!-- 价格输入 -->
+                <div class="price-section">
+                    <div class="erty price-input">
+                        <input type="number" class="inpy" v-model="price" disabled :placeholder="currentItem.price || ''">
+                        <a class="current-price-btn" @click="setCurrentPrice">{{ $t("hj81") }}</a>
+                    </div>
+                </div>
+                <!-- 买入数量 -->
+                <div class="quantity-section">
+                    <label class="section-label">{{ $t("jy87") }}</label>
+                    <div class="erty quantity-input">
+                        <input :placeholder="$t('jy87')" type="number" class="inpy" v-model="num"
+                            @input="num = num.replace(/^(0+)|[^\d]+/g, '')">
+                        <a>{{ $t("hj117") }}</a>
+                    </div>
+                </div>
+                <!-- 仓位选择 -->
+                <div class="position-section">
+                    <label class="section-label">{{ $t("hj226") }}</label>
+                    <div class="position-buttons">
+                        <div class="position-btn" :class="{ active: selectedPosition === '1/4' }" @click="selectPosition('1/4')">{{ $t('hj258') }}</div>
+                        <div class="position-btn" :class="{ active: selectedPosition === '1/3' }" @click="selectPosition('1/3')">{{ $t('hj259') }}</div>
+                        <div class="position-btn" :class="{ active: selectedPosition === '1/2' }" @click="selectPosition('1/2')">{{ $t('hj260') }}</div>
+                        <div class="position-btn" :class="{ active: selectedPosition === 'full' }" @click="selectPosition('full')">{{ $t('hj261') }}</div>
+                    </div>
+                </div>
+                <!-- 金额信息 -->
+                <div class="amount-info">
+                    <p class="plm">
+                        <span>{{ $t("hj54") }}</span>
+                        <a>¥{{ (userinfo.enableAmt || 0).toFixed(2) }}</a>
+                    </p>
+                    <p class="plm">
+                        <span>{{ $t("jy88") }}</span>
+                        <a class="red-amount">¥{{ getActualAmount() }}</a>
+                    </p>
+                </div>
+                <!-- 密码输入 -->
+                <!-- <div class="password-section">
+                    <div class="erty">
+                        <input :placeholder="$t('jy89')" type="password" class="inpy" v-model="password">
+                    </div>
+                </div> -->
+                <!-- 下单按钮 -->
+                <div class="maik" @click="getxiadan">{{ $t("hj85") }}{{ $t("jy150") }}</div>
             </div>
         </van-popup>
     </div>
@@ -59,9 +132,11 @@
             show: false,
             dazongList: [],
             num: '',
-            currentItem: '',
-            userinfo: '',
-            password: ''
+            currentItem: {},
+            userinfo: {},
+            password: '',
+            price: '',
+            selectedPosition: ''
         }
     },
     mounted() {
@@ -74,31 +149,85 @@
         },
         getdetail(item) {
             this.currentItem = item
+            this.price = item.price || ''
+            this.num = ''
+            this.selectedPosition = ''
+            this.password = ''
             this.show = true
         },
+        setCurrentPrice() {
+            if (this.currentItem.price) {
+                this.price = this.currentItem.price
+            }
+        },
+        selectPosition(position) {
+            this.selectedPosition = position
+            if (this.userinfo.enableAmt && this.price) {
+                let availableAmount = parseFloat(this.userinfo.enableAmt) || 0
+                let currentPrice = parseFloat(this.price) || 0
+                let positionRatio = 0
+                
+                switch(position) {
+                    case '1/4':
+                        positionRatio = 0.25
+                        break
+                    case '1/3':
+                        positionRatio = 0.333
+                        break
+                    case '1/2':
+                        positionRatio = 0.5
+                        break
+                    case 'full':
+                        positionRatio = 1
+                        break
+                }
+                
+                // 计算可买入的手数(1手=100股)
+                let maxAmount = availableAmount * positionRatio
+                let maxHands = Math.floor(maxAmount / (currentPrice * 100))
+                this.num = maxHands.toString()
+            }
+        },
+        getActualAmount() {
+            if (this.price && this.num) {
+                let price = parseFloat(this.price) || 0
+                let num = parseFloat(this.num) || 0
+                return (price * num * 100).toFixed(2)
+            }
+            return '0.00'
+        },
         async getxiadan() {
+            if (!this.price) {
+                this.$toast('请输入价格')
+                return
+            }
             if (!this.num) {
-                this.show = false
-                this.$toast('请输入数量')
+                this.$toast(this.$t('jy87'))
                 return
             }
-            if (!this.password) {
-                this.show = false
-                this.$toast('请输入秘钥')
-                return
-            }
+            // if (!this.password) {
+            //     this.$toast(this.$t('jy89'))
+            //     return
+            // }
             var opt = {
                 stockCode: this.currentItem.stockCode,
                 password: this.password,
                 num: this.num * 100,
+                price: this.price
             }
             let res = await api.buyStockDz(opt)
-            if (res.status == 0) {
-                this.$toast('买入成功')
-            } else {
-                this.$toast(res.msg)
-            }
+            // 先关闭弹窗,避免遮罩层遮挡 Toast
             this.show = false
+            if (res.status == 0) {
+                this.$nextTick(() => {
+                    this.$toast(this.$t('dz_buySuccess'))
+                })
+                this.stockgetDzList()
+            } else {
+                this.$nextTick(() => {
+                    this.$toast(res.msg)
+                })
+            }
         },
         async stockgetDzList() {
             let res = await api.stockgetDzList()
@@ -112,6 +241,19 @@
             if (data.status === 0) {
                 this.userinfo = data.data;
             }
+        },
+        getProgressPercent(item) {
+            if (!item.stockShare || item.stockShare === 0) {
+                return 0;
+            }
+            const percent = (item.stockSurplus || 0) / item.stockShare * 100;
+            return Math.min(100, Math.max(0, Math.round(percent * 100) / 100));
+        },
+        formatAmount(amount) {
+            return Number(amount).toLocaleString('zh-CN', {
+                minimumFractionDigits: 2,
+                maximumFractionDigits: 2
+            });
         },
     },
 }
@@ -127,6 +269,7 @@
         margin: 0 auto;
         display: flex;
         justify-content: space-between;
+        align-items: center;
 
         span {
             color: #666;
@@ -134,16 +277,13 @@
         }
 
         .d1 {
-            width: 40%;
+            flex: 1;
+            text-align: left;
         }
 
         .d2 {
-            width: 20%;
-            text-align: center;
-        }
-
-        .d3 {
-            width: 40%;
+            flex: 1;
+            text-align: right;
         }
     }
 }
@@ -173,93 +313,191 @@
 
 .list {
     width: 100%;
-    padding: 0.4rem 0;
-    border-bottom: 1px solid #e0e0e0;
+    padding: 0.4rem 0.3rem;
+    margin-bottom: 0.3rem;
+    background: #fff;
+    border-radius: 0.25rem;
+    box-shadow: 0 2px 8px rgba(0, 0, 0, 0.08);
 
     .lbox {
         width: 9.35rem;
         margin: 0 auto;
-        display: flex;
-        justify-content: space-between;
 
-        .lb1 {
-            h6 {
-                color: #333;
-                font-size: .4rem;
-                font-weight: 600;
-            }
+        .top-section {
+            display: flex;
+            justify-content: space-between;
+            align-items: flex-start;
+            margin-bottom: 0.4rem;
 
-            p {
-                color: #333;
-                font-size: .32rem;
-                margin-top: 0.13rem;
-
-                span {
-                    width: 0.4rem;
-                    height: 0.4rem;
-                    background: #3b4fde;
-                    border-radius: 0.05rem;
-                    padding: 0.04rem;
-                    text-align: center;
-                    line-height: .4rem;
-                    color: #fff;
-                    font-size: .3rem;
+            .lb1 {
+                flex: 1;
+                h6 {
+                    color: #333;
+                    font-size: .4rem;
+                    font-weight: 600;
+                    margin-bottom: 0.13rem;
                 }
 
-                a {
-                    display: inline-block;
-                    height: 0.4rem;
-                    line-height: .4rem;
-                    padding: 0 0.11rem;
-                    background: rgba(59, 79, 222, .1);
-                    border-radius: 0.05rem;
-                    color: #3b4fde;
+                p {
+                    color: #333;
                     font-size: .32rem;
-                    vertical-align: middle;
+                    margin: 0;
+
+                    span {
+                        width: 0.4rem;
+                        height: 0.4rem;
+                        background: #4caf50;
+                        border-radius: 0.05rem;
+                        padding: 0.04rem;
+                        text-align: center;
+                        line-height: .4rem;
+                        color: #fff;
+                        font-size: .3rem;
+                        display: inline-block;
+                        margin-right: 0.1rem;
+                    }
+
+                    a {
+                        display: inline-block;
+                        height: 0.4rem;
+                        line-height: .4rem;
+                        padding: 0 0.11rem;
+                        background: rgba(59, 79, 222, .1);
+                        border-radius: 0.05rem;
+                        color: #3b4fde;
+                        font-size: .32rem;
+                        vertical-align: middle;
+                    }
+
+                    .bj {
+                        background: #ea6248;
+                    }
+
+                    .sh {
+                        background: #aa3bde;
+                    }
+
+                    .shbg {
+                        color: #aa3bde;
+                        background: rgba(170, 59, 222, .1);
+                    }
+
+                    .bjbg {
+                        color: #ea6248;
+                        background: rgba(234, 98, 72, .1);
+                    }
+                }
+            }
+
+            .top-right {
+                display: flex;
+                align-items: flex-end;
+                gap: 0.2rem;
+
+                .lb2 {
+                    // text-align: right;
+                    display: flex;
+                    flex-direction: column;
+                    align-items: center;
+                    .price-value {
+                        color: #d73d3d;
+                        font-size: .4rem;
+                        font-weight: 600;
+                    }
+                    .price-label {
+                        color: #999;
+                        font-size: .28rem;
+                        margin-top: 0.15rem;
+                    }
                 }
 
-                .bj {
-                    background: #ea6248;
-                }
-
-                .sh {
-                    background: #aa3bde;
-                }
-
-                .shbg {
-                    color: #aa3bde;
-                    background: rgba(170, 59, 222, .1);
-                }
-
-                .bjbg {
-                    color: #ea6248;
-                    background: rgba(234, 98, 72, .1);
+                .lb3 {
+                    a {
+                        display: inline-block;
+                        width: 1.6rem;
+                        height: 100%;
+                        background: linear-gradient(-55deg, rgb(241, 22, 20), rgb(240, 40, 37));
+                        border-radius: 0.35rem;
+                        text-align: center;
+                        color: #fff;
+                        font-size: .32rem;
+                        line-height: .67rem;
+                    }
                 }
             }
         }
 
-        .lb2 {
-            color: #d73d3d;
-            font-size: .32rem;
-            margin-top: 0.32rem;
-        }
+        .middle-section {
+            display: flex;
+            justify-content: space-between;
+            margin-bottom: 0.1rem;
 
-        .lb3 {
-            text-align: right;
+            .share-info, .surplus-info {
+                display: flex;
+                align-items: center;
+                gap: 0.1rem;
 
-            a {
-                display: inline-block;
-                width: 1.6rem;
-                height: 0.67rem;
-                background: linear-gradient(-55deg,rgb(241, 22, 20),rgb(240, 40, 37));
-                border-radius: 0.35rem;
-                text-align: center;
-                color: #fff;
-                font-sizE: .32rem;
-                line-height: .67rem;
-                margin-top: 0.08rem;
+                .label {
+                    color: #666;
+                    font-size: .32rem;
+                }
+
+                .value {
+                    color: #333;
+                    font-size: .32rem;
+                    font-weight: 500;
+                }
             }
         }
+
+        .progress-section {
+  width: 100%;
+  height: 10px; /* 核心:降低整体容器高度,匹配图片紧凑感 */
+  display: flex;
+  align-items: center;
+}
+
+.progress-bar {
+  position: relative;
+  width: 100%;
+  height: 100%; /* 跟随外层容器高度 */
+  background: #f0f0f0;
+  border-radius: 8px; /* 圆角适配小高度,更精致 */
+  overflow: visible;
+}
+
+.progress-fill {
+  position: relative;
+  height: 100%;
+  background: linear-gradient(-55deg, rgb(241, 22, 20), rgb(240, 40, 37));
+  transition: width 0.3s ease;
+  border-radius: 8px; /* 同步圆角 */
+  min-width: 40px;
+  display: flex;
+  align-items: center;
+}
+
+.progress-text-wrap {
+    position: absolute;
+    right: 0;
+    top: -0.15556rem;
+    height: 300%;
+}
+
+.progress-text {
+  font-size: 14px; /* 缩小字体适配小高度 */
+  color: #fff;
+  background-color: red;
+  padding: 0 10px; /* 紧凑内边距,不宽不高 */
+  height: 100%;
+  border-radius: 18px; /* 圆角和进度条一致,适配小高度 */
+  font-weight: 600;
+  white-space: nowrap;
+  display: flex;
+  align-items: center;
+  justify-content: center;
+  max-width: max-content;
+}
     }
 }
 
@@ -267,6 +505,19 @@
     background: #fff;
     border-radius: 0.266rem 0.266rem 0 0;
     padding-bottom: 0.53rem;
+
+    .popup-header {
+        background: #4a4a4a;
+        color: #fff;
+        padding: 0.3rem 0.53rem;
+        display: flex;
+        justify-content: space-between;
+        font-size: 0.32rem;
+        
+        .header-left, .header-right {
+            color: #fff;
+        }
+    }
 
     .boxh {
         height: 1.2rem;
@@ -278,76 +529,125 @@
         width: 9.48rem;
         margin: 0 auto;
         position: relative;
+        display: flex;
+        align-items: center;
+        justify-content: center;
 
-        span {
+        .close-btn {
             position: absolute;
-            width: 0.32rem;
-            height: 0.32rem;
-            background: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABgAAAAYCAYAAADgdz34AAAAAXNSR0IArs4c6QAAAStJREFUSEutlk1qhDAUgF+EzG5EWsYTzK6HKO0hcgB3gscR3IgH8BBTeojuegJLQWg3NqDlyUQwRn0xcWeQ7zMv7ycMAKCu61PTNOcsy77x3fUpy/IhDMNfIcQfQ3jbtvUwDFfO+UuSJF8ugqqqLlLKN8bYZxRFguV5/sg5fweAJwD4cJEouGJJKZ8Z/m1RFHEQBDcXiQ7v+/41TdNmFLhK1uDInQRHJVvwhcBWsgc3CqgSCnxVsCehwjcFaxJcxzynZtzskE0Fpqfw/RtyzewKDDvBJXJBkgRazP0K9AP1GiIdjn2q6zpm01ZWQ2SCq05r07uMgi24be9aCChwG8lMYAOnSibBEThFMgpc4HsSryNTz65xZPoe+koyDX3cou9rC14k4jj+wWvLP1ylVM57GzhpAAAAAElFTkSuQmCC) no-repeat 50%;
-            background-size: 100%;
-            right: 0.266rem;
-            top: 0.4rem;
+            left: 0.266rem;
+            width: 0.8rem;
+            height: 0.8rem;
+            font-size: 0.6rem;
+            color: #999;
+            line-height: 0.8rem;
+            text-align: center;
+            cursor: pointer;
+        }
+
+        h5 {
+            color: #333;
+            font-size: 0.43rem;
+            font-weight: 500;
+            margin: 0;
         }
     }
 
-    h5 {
-        color: #333;
-        font-size: .37rem;
-        font-weight: 500;
-        width: 9.48rem;
-        margin: 0 auto;
-        margin-top: 0.32rem;
+    .price-section {
+        padding: 0.4rem 0.53rem 0;
     }
 
-    h6 {
-        color: #ea3544;
-        font-size: .43rem;
-        width: 9.48rem;
-        margin: 0 auto;
-        margin-top: 0.32rem;
-        font-weight: 600;
+    .quantity-section, .position-section {
+        padding: 0.4rem 0.53rem 0;
+        
+        .section-label {
+            display: block;
+            color: #333;
+            font-size: 0.35rem;
+            margin-bottom: 0.2rem;
+        }
     }
 
     .erty {
-        width: 9.21rem;
+        width: 100%;
         height: 1.07rem;
         border: 0.0266rem solid #999;
         border-radius: 0.13rem;
         margin: 0 auto;
         display: flex;
         justify-content: space-between;
-        margin-top: 0.59rem;
+        align-items: center;
+
+        &.price-input {
+            margin-top: 0;
+        }
 
         .inpy {
             height: 1.07rem;
-            width: 5.34rem;
+            flex: 1;
             margin-left: 0.266rem;
             background: transparent;
             font-size: .37rem;
             color: #000;
+            border: none;
+            outline: none;
         }
 
         a {
             height: 0.64rem;
             border-left: 0.0266rem solid #999;
-            width: 1.15rem;
-            margin-top: 0.266rem;
+            width: 1.5rem;
+            margin-right: 0.266rem;
             text-align: center;
-            font-size: .37rem;
-            color: #000;
+            font-size: .32rem;
+            color: #666;
             line-height: .64rem;
+            
+            &.current-price-btn {
+                color: #666;
+                cursor: pointer;
+            }
         }
     }
 
-    .tghj {
-        border: 0.0266rem solid #3b4fde;
-        margin-top: 0.45rem;
+    .position-buttons {
+        display: flex;
+        gap: 0.2rem;
+        margin-top: 0.2rem;
+
+        .position-btn {
+            flex: 1;
+            height: 0.8rem;
+            border: 0.0266rem solid #999;
+            border-radius: 0.13rem;
+            text-align: center;
+            line-height: 0.8rem;
+            font-size: 0.32rem;
+            color: #666;
+            cursor: pointer;
+            transition: all 0.3s;
+
+            &.active {
+                border-color: #3b4fde;
+                background: rgba(59, 79, 222, 0.1);
+                color: #3b4fde;
+            }
+        }
+    }
+
+    .amount-info {
+        padding: 0.4rem 0.53rem 0;
+    }
+
+    .password-section {
+        padding: 0.4rem 0.53rem 0;
     }
 
     .plm {
-        width: 8.94rem;
-        margin: 0 auto;
-        margin-top: 0.266rem;
+        width: 100%;
+        margin: 0.2rem 0;
+        display: flex;
+        justify-content: space-between;
 
         span {
             color: #999;
@@ -355,8 +655,12 @@
         }
 
         a {
-            color: #f33030;
-            margin-left: 0.11rem;
+            color: #333;
+            font-size: .32rem;
+            
+            &.red-amount {
+                color: #f33030;
+            }
         }
     }
 
@@ -365,12 +669,12 @@
         height: 1.07rem;
         background: linear-gradient(-55deg,rgb(241, 22, 20),rgb(240, 40, 37));
         border-radius: 0.26rem;
-        margin: 0 auto;
-        margin-top: 0.56rem;
+        margin: 0.4rem auto 0;
         text-align: center;
         line-height: 1.07rem;
         color: #fff;
         font-size: .37rem;
+        cursor: pointer;
     }
 }
 </style>
\ No newline at end of file

--
Gitblit v1.9.3