| | |
| | | <div class="right-panel-top"> |
| | | <div class="data-card"> |
| | | <div class="data-header flex"> |
| | | <div class="data-title">本月新增用户</div> |
| | | <div class="data-title">本月新增租户数</div> |
| | | <div class="data-tabs"> |
| | | <div class="tab-value">{{ newUsers }}<span class="unit">户</span></div> |
| | | <div class="tab-value">{{ staticsData.newTenantCount }}<span class="unit">户</span></div> |
| | | <div class="tab-chart"></div> |
| | | </div> |
| | | </div> |
| | | </div> |
| | | <div class="data-card"> |
| | | <div class="data-header flex"> |
| | | <div class="data-title">本季度交租率</div> |
| | | <div class="data-title">总计租户数</div> |
| | | <div class="data-tabs"> |
| | | <div class="tab-value">{{ quarterlyRate }}<span class="unit">元</span></div> |
| | | <div class="tab-value">{{ staticsData.totalTenantCount }}<span class="unit">户</span></div> |
| | | <div class="tab-chart"></div> |
| | | </div> |
| | | </div> |
| | |
| | | <div class="right-panel-top1"> |
| | | <div class="data-card"> |
| | | <div class="data-header flex"> |
| | | <div class="data-title">本月新增用户</div> |
| | | <div class="data-title">本季度已交租金</div> |
| | | <div class="data-tabs"> |
| | | <div class="tab-value">{{ newUsers }}<span class="unit">万元</span></div> |
| | | <div class="tab-value">{{ staticsData.totalRentPaid }}<span class="unit">万元</span></div> |
| | | <div class="tab-chart"></div> |
| | | </div> |
| | | </div> |
| | | </div> |
| | | <div class="data-card"> |
| | | <div class="data-header flex"> |
| | | <div class="data-title">本季度交租率</div> |
| | | <div class="data-title">本季度应交租金</div> |
| | | <div class="data-tabs"> |
| | | <div class="tab-value">{{ quarterlyRate }}<span class="unit">万元</span></div> |
| | | <div class="tab-value">{{ staticsData.totalRentShould }}<span class="unit">万元</span></div> |
| | | <div class="tab-chart"></div> |
| | | </div> |
| | | </div> |
| | |
| | | <div class="status-title">实时租赁数据</div> |
| | | <div class="status-items-container"> |
| | | <div class="status-items"> |
| | | <div v-for="(item, index) in rentList" :key="index" class="status-item"> |
| | | <span class="area-name">{{ item.area }}</span> |
| | | <div v-for="(item, index) in realTimeRentData" :key="'original-' + index" class="status-item"> |
| | | <span class="area-name">{{ item.streetName }}</span> |
| | | <span class="area-name">{{ item.roomName }}</span> |
| | | <div class="status-actions"> |
| | | <span class="action-btn">启用中</span> |
| | | <span class="action-btn">合同签署</span> |
| | | <span class="action-btn" :style="{ backgroundColor: item.leaseStatus == 2 ? '#FFB822' : item.leaseStatus == 1 ? '#66BAF8' : '#FF6B6B' }">{{ ['待出租', '已出租', '维修中'][item.leaseStatus - 1] }}</span> |
| | | </div> |
| | | </div> |
| | | <div v-for="(item, index) in realTimeRentData" v-if="realTimeRentData.length>10" :key="'duplicate-' + index" class="status-item"> |
| | | <span class="area-name">{{ item.streetName }}</span> |
| | | <span class="area-name">{{ item.roomName }}</span> |
| | | <div class="status-actions"> |
| | | <span class="action-btn" :style="{ backgroundColor: item.leaseStatus == 2 ? '#FFB822' : item.leaseStatus == 1 ? '#66BAF8' : '#FF6B6B' }">{{ ['待出租', '已出租', '维修中'][item.leaseStatus - 1] }}</span> |
| | | </div> |
| | | </div> |
| | | </div> |
| | |
| | | </template> |
| | | |
| | | <script> |
| | | import { getRealTimeRentData } from './service' |
| | | export default { |
| | | name: 'RightPanel', |
| | | props: { |
| | | staticsData: { |
| | | type: Object, |
| | | default: () => { } |
| | | }, |
| | | }, |
| | | data() { |
| | | return { |
| | | newUsers: '877', |
| | | quarterlyRate: '4302', |
| | | rentList: [ |
| | | { area: '新城大道', status: 'online' }, |
| | | { area: '拉萨路', status: 'offline' }, |
| | | { area: '新城大道', status: 'online' }, |
| | | { area: '拉萨路', status: 'online' }, |
| | | { area: '新城大道', status: 'offline' }, |
| | | { area: '拉萨路', status: 'online' }, |
| | | { area: '新城大道', status: 'offline' }, |
| | | { area: '新城大道', status: 'online' } |
| | | ] |
| | | realTimeRentData: [] |
| | | } |
| | | }, |
| | | created() { |
| | | |
| | | getRealTimeRentData().then(res => { |
| | | this.realTimeRentData = res.data |
| | | }) |
| | | setInterval(() => { |
| | | getRealTimeRentData().then(res => { |
| | | this.realTimeRentData = res.data |
| | | }) |
| | | }, 10000) |
| | | } |
| | | } |
| | | </script> |
| | |
| | | } |
| | | |
| | | .right-panel { |
| | | width: 300px; |
| | | width: 400px; |
| | | display: flex; |
| | | position: fixed; |
| | | top: 0; |
| | |
| | | z-index: 1000; |
| | | flex-direction: column; |
| | | gap: 10px; |
| | | padding-right: 20px; |
| | | } |
| | | |
| | | .data-card { |
| | |
| | | border-radius: 8px; |
| | | padding: 15px; |
| | | height: 80px; |
| | | min-width: 0; |
| | | flex: 1; |
| | | display: flex; |
| | | align-items: center; |
| | | } |
| | | |
| | | .data-header { |
| | | display: flex; |
| | | justify-content: space-between; |
| | | align-items: center; |
| | | width: 100%; |
| | | height: 100%; |
| | | } |
| | | |
| | | .data-title { |
| | | font-size: 16px; |
| | | color: #fff; |
| | | white-space: nowrap; |
| | | margin-right: 10px; |
| | | } |
| | | |
| | | .data-tabs { |
| | | display: flex; |
| | | align-items: center; |
| | | gap: 10px; |
| | | flex: 1; |
| | | justify-content: flex-end; |
| | | min-width: 0; |
| | | } |
| | | |
| | | .tab-value { |
| | |
| | | font-family: 'DIN ', 'DIN', sans-serif; |
| | | font-weight: bold; |
| | | color: #fff; |
| | | white-space: nowrap; |
| | | overflow: hidden; |
| | | text-overflow: ellipsis; |
| | | text-align: right; |
| | | } |
| | | |
| | | .right-panel-top, |
| | | .right-panel-top1 { |
| | | display: flex; |
| | | background: rgba(146, 146, 146, 0.7); |
| | | padding: 15px; |
| | | border-radius: 8px; |
| | | gap: 10px; |
| | | height: 110px; |
| | | } |
| | | |
| | | .right-panel-top { |
| | | display: flex; |
| | | background: rgba(146, 146, 146, 0.5); |
| | | margin-top: 50px; |
| | | padding-top: 10px; |
| | | padding-bottom: 30px; |
| | | border-radius: 2px; |
| | | margin-right: 20px; |
| | | border-left: 4px solid #87F7C7; |
| | | } |
| | | |
| | | .right-panel-top1 { |
| | | display: flex; |
| | | background: rgba(146, 146, 146, 0.5); |
| | | margin-top: 10px; |
| | | padding-top: 10px; |
| | | padding-bottom: 30px; |
| | | border-radius: 2px; |
| | | margin-right: 20px; |
| | | border-left: 4px solid #FFB822; |
| | | } |
| | | |
| | | .status-list { |
| | | background: rgba(146, 146, 146, 0.5); |
| | | border-radius: 2px; |
| | | margin-right: 20px; |
| | | background: rgba(146, 146, 146, 0.7); |
| | | border-radius: 8px; |
| | | margin-top: 10px; |
| | | padding: 15px; |
| | | height: 500px; |
| | | max-height: 600px; |
| | | min-height: 500px; |
| | | overflow: hidden; |
| | | flex: 1; |
| | | } |
| | | |
| | | .status-title { |
| | | font-size: 16px; |
| | | color: #fff; |
| | | margin-bottom: 15px; |
| | | } |
| | | |
| | | .status-items { |
| | | display: flex; |
| | | flex-direction: column; |
| | | gap: 10px; |
| | | height: calc(100% - 45px); |
| | | animation: scrollUp 20s linear infinite; |
| | | } |
| | | |
| | |
| | | .status-items-container { |
| | | height: 100%; |
| | | overflow: hidden; |
| | | position: relative; |
| | | } |
| | | |
| | | .status-items-container::before, |
| | | .status-items-container::after { |
| | | content: ''; |
| | | position: absolute; |
| | | left: 0; |
| | | right: 0; |
| | | height: 10px; |
| | | z-index: 1; |
| | | } |
| | | |
| | | .status-items-container::before { |
| | | top: 0; |
| | | background: linear-gradient(to bottom, rgba(0, 0, 0, 0.1) 0%, transparent 100%); |
| | | } |
| | | |
| | | .status-items-container::after { |
| | | bottom: 0; |
| | | background: linear-gradient(to top, rgba(0, 0, 0, 0.1) 0%, transparent 100%); |
| | | } |
| | | |
| | | @keyframes scrollUp { |
| | | 0% { |
| | | transform: translateY(0); |
| | | } |
| | | |
| | | 100% { |
| | | transform: translateY(-50%); |
| | | } |
| | | } |
| | | |
| | | .status-items::-webkit-scrollbar { |
| | | display: none; |
| | | } |
| | | |
| | | .status-items { |
| | | -ms-overflow-style: none; |
| | | scrollbar-width: none; |
| | | } |
| | | |
| | | .status-item { |
| | | display: flex; |
| | | justify-content: space-between; |
| | | display: grid; |
| | | grid-template-columns: minmax(80px, 1fr) minmax(80px, 1fr) 80px; /* 设置最小宽度确保文字显示 */ |
| | | gap: 10px; |
| | | align-items: center; |
| | | background: rgba(255, 255, 255, 0.05); |
| | | border-radius: 4px; |
| | | padding: 10px; |
| | | margin-bottom: 8px; |
| | | } |
| | | |
| | | .area-name { |
| | | font-size: 12px; |
| | | font-size: 14px; |
| | | color: #fff; |
| | | white-space: normal; /* 允许文字换行 */ |
| | | line-height: 1.2; /* 添加适当的行高 */ |
| | | } |
| | | |
| | | .status-actions { |
| | | display: flex; |
| | | gap: 10px; |
| | | justify-self: end; |
| | | } |
| | | |
| | | .action-btn { |
| | | padding: 2px 8px; |
| | | padding: 4px 12px; |
| | | border-radius: 4px; |
| | | font-size: 12px; |
| | | background: rgba(0, 255, 255, 0.2); |
| | | color: #fff; |
| | | white-space: nowrap; |
| | | } |
| | | |
| | | .unit { |
| | |
| | | margin-left: 4px; |
| | | color: #fff; |
| | | } |
| | | </style> |
| | | </style> |