| | |
| | | <template> |
| | | <div class="data-dashboard"> |
| | | <!-- 全屏按钮 - 移动到左上角 --> |
| | | <button class="fullscreen-btn" @click="toggleFullscreen" :title="isFullscreen ? '退出全屏' : '全屏显示'"> |
| | | <svg v-if="!isFullscreen" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"> |
| | | <path d="M8 3v3a2 2 0 0 1-2 2H3m18 0h-3a2 2 0 0 1-2-2V3m0 18v-3a2 2 0 0 1 2-2h3M3 16h3a2 2 0 0 1 2 2v3"/> |
| | | </svg> |
| | | <svg v-else width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"> |
| | | <path d="M8 3H5a2 2 0 0 0-2 2v3m18 0V5a2 2 0 0 0-2-2h-3m0 18h3a2 2 0 0 0 2-2v-3M3 16v3a2 2 0 0 0 2 2h3"/> |
| | | </svg> |
| | | </button> |
| | | |
| | | <!-- 顶部标题栏 --> |
| | | <div class="dashboard-header"> |
| | | <div class="factory-name">{{ userStore.currentFactoryName }}</div> |
| | | </div> |
| | | |
| | | <!-- 主要内容区域 --> |
| | | <div class="dashboard-content"> |
| | | <!-- 左侧区域 --> |
| | | <div class="left-panel"> |
| | | <!-- 客户信息统计分析 --> |
| | | <div class="data-dashboard"> |
| | | <!-- 全屏按钮 - 移动到左上角 --> |
| | | <button class="fullscreen-btn" @click="toggleFullscreen" :title="isFullscreen ? '退出全屏' : '全屏显示'"> |
| | | <svg v-if="!isFullscreen" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"> |
| | | <path d="M8 3v3a2 2 0 0 1-2 2H3m18 0h-3a2 2 0 0 1-2-2V3m0 18v-3a2 2 0 0 1 2-2h3M3 16h3a2 2 0 0 1 2 2v3"/> |
| | | </svg> |
| | | <svg v-else width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"> |
| | | <path d="M8 3H5a2 2 0 0 0-2 2v3m18 0V5a2 2 0 0 0-2-2h-3m0 18h3a2 2 0 0 0 2-2v-3M3 16v3a2 2 0 0 0 2 2h3"/> |
| | | </svg> |
| | | </button> |
| | | |
| | | <!-- 顶部标题栏 --> |
| | | <div class="dashboard-header"> |
| | | <div class="factory-name">{{ userStore.currentFactoryName }}</div> |
| | | </div> |
| | | |
| | | <!-- 主要内容区域 --> |
| | | <div class="dashboard-content"> |
| | | <!-- 左侧区域 --> |
| | | <div class="left-panel"> |
| | | <!-- 客户信息统计分析 --> |
| | | <div class="panel-header"> |
| | | <span class="panel-title">客户信息统计分析</span> |
| | | </div> |
| | | <div class="panel-item-customers"> |
| | | <div class="panel-item-customers"> |
| | | <div class="panel-title-second"> |
| | | <div class="panel-title-icon"></div> |
| | | <div class="total-customers"> |
| | | <span class="label">总合同金额(元)</span> |
| | | <span class="value">{{sum}}</span> |
| | | </div> |
| | | <!-- <div class="jiantou"></div>--> |
| | | <!-- <div class="jiantou"></div>--> |
| | | </div> |
| | | <!-- 饼图区域 --> |
| | | <div style="display: flex;align-items: center;gap: 20px;justify-content: space-evenly;height: 82%;margin-top: 20px"> |
| | |
| | | </li> |
| | | </ul> |
| | | </div> |
| | | </div> |
| | | |
| | | <!-- 质量统计 --> |
| | | <div class="panel-header"> |
| | | <span class="panel-title">质量统计</span> |
| | | </div> |
| | | |
| | | <!-- 质量统计 --> |
| | | <!-- <div class="panel-header">--> |
| | | <!-- <span class="panel-title">近4个月质量统计</span>--> |
| | | <!-- </div>--> |
| | | <!-- <div class="main-panel">--> |
| | | <!-- <div class="panel-item-customers">--> |
| | | <!-- <div class="quality-cards">--> |
| | | <!-- <div class="quality-cardSec">--> |
| | | <!-- <div class="quality-card one"></div>--> |
| | | <!-- <div class="quality-cardTitle">--> |
| | | <!-- <div>原材料已检测数</div>--> |
| | | <!-- <div>{{qualityStatisticsObject.supplierNum}}件</div>--> |
| | | <!-- </div>--> |
| | | <!-- </div>--> |
| | | <!-- <div class="quality-cardSec">--> |
| | | <!-- <div class="quality-card two"></div>--> |
| | | <!-- <div class="quality-cardTitle">--> |
| | | <!-- <div>过程检验数量</div>--> |
| | | <!-- <div>{{qualityStatisticsObject.processNum}}件</div>--> |
| | | <!-- </div>--> |
| | | <!-- </div>--> |
| | | <!-- <div class="quality-cardSec">--> |
| | | <!-- <div class="quality-card three"></div>--> |
| | | <!-- <div class="quality-cardTitle">--> |
| | | <!-- <div>出厂已检数量</div>--> |
| | | <!-- <div>{{qualityStatisticsObject.factoryNum}}件</div>--> |
| | | <!-- </div>--> |
| | | <!-- </div>--> |
| | | <!-- </div>--> |
| | | <!-- <Echarts ref="chart"--> |
| | | <!-- :chartStyle="chartStyle"--> |
| | | <!-- :grid="grid"--> |
| | | <!-- :legend="barLegend"--> |
| | | <!-- :series="barSeries1"--> |
| | | <!-- :tooltip="tooltip"--> |
| | | <!-- :xAxis="xAxis1"--> |
| | | <!-- :yAxis="yAxis1"--> |
| | | <!-- :options="{backgroundColor: 'transparent', textStyle: {color: '#B8C8E0'}}"--> |
| | | <!-- style="height: 260px"></Echarts>--> |
| | | <!-- </div>--> |
| | | <!-- </div>--> |
| | | <!-- </div>--> |
| | | <div class="panel-header"> |
| | | <span class="panel-title">近4个月仓库统计</span> |
| | | </div> |
| | | <div class="main-panel"> |
| | | <div class="panel-item-customers"> |
| | |
| | | <div class="quality-cardSec"> |
| | | <div class="quality-card one"></div> |
| | | <div class="quality-cardTitle"> |
| | | <div>原材料已检测数</div> |
| | | <div>{{qualityStatisticsObject.supplierNum}}件</div> |
| | | <div>入库数量</div> |
| | | <div>{{supplierNum}}件</div> |
| | | </div> |
| | | </div> |
| | | <div class="quality-cardSec"> |
| | | <div class="quality-card two"></div> |
| | | <div class="quality-cardTitle"> |
| | | <div>过程检验数量</div> |
| | | <div>{{qualityStatisticsObject.processNum}}件</div> |
| | | <div>出库数量</div> |
| | | <div>{{factoryNum}}件</div> |
| | | </div> |
| | | </div> |
| | | <div class="quality-cardSec"> |
| | | <div class="quality-card three"></div> |
| | | <div class="quality-cardTitle"> |
| | | <div>出厂已检数量</div> |
| | | <div>{{qualityStatisticsObject.factoryNum}}件</div> |
| | | </div> |
| | | </div> |
| | | <!-- <div class="quality-cardSec">--> |
| | | <!-- <div class="quality-card three"></div>--> |
| | | <!-- <div class="quality-cardTitle">--> |
| | | <!-- <div>出厂已检数量</div>--> |
| | | <!-- <div>{{qualityStatisticsObject.factoryNum}}件</div>--> |
| | | <!-- </div>--> |
| | | <!-- </div>--> |
| | | </div> |
| | | <Echarts ref="chart" |
| | | :chartStyle="chartStyle" |
| | |
| | | style="height: 260px"></Echarts> |
| | | </div> |
| | | </div> |
| | | </div> |
| | | |
| | | <!-- 中间区域 --> |
| | | <div class="center-panel"> |
| | | <!-- 顶部统计卡片 --> |
| | | <div class="stats-cards"> |
| | | <div class="stat-card"> |
| | | <img src="@/assets/BI/icon@2x.png" alt="图标" class="card-icon" /> |
| | | <div class="card-content"> |
| | | <span class="card-label">员工总数</span> |
| | | <span class="card-value">{{totalStaff}}</span> |
| | | </div> |
| | | </div> |
| | | <div class="stat-card"> |
| | | <img src="@/assets/BI/icon@2x.png" alt="图标" class="card-icon" /> |
| | | <div class="card-content"> |
| | | <span class="card-label">客户总数</span> |
| | | <span class="card-value">{{totalCustomers}}</span> |
| | | </div> |
| | | </div> |
| | | <div class="stat-card"> |
| | | <img src="@/assets/BI/icon@2x.png" alt="图标" class="card-icon" /> |
| | | <div class="card-content"> |
| | | <span class="card-label">供应商总数</span> |
| | | <span class="card-value">{{totalSuppliers}}</span> |
| | | </div> |
| | | </div> |
| | | </div> |
| | | |
| | | <!-- 设备统计 --> |
| | | <div class="equipment-stats"> |
| | | <div class="equipment-header"> |
| | | <img src="@/assets/BI/shujutongjiicon@2x.png" alt="图标" class="equipment-icon" /> |
| | | <span class="equipment-title">设备统计</span> |
| | | </div> |
| | | <div class="equipment-items"> |
| | | <div class="equipment-item"> |
| | | <span class="equipment-value">{{equipmentNum}}</span> |
| | | <span class="equipment-label">设备总数</span> |
| | | </div> |
| | | <div class="equipment-item"> |
| | | <span class="equipment-value">{{equipmentRepair}}</span> |
| | | <span class="equipment-label">待维修设备</span> |
| | | </div> |
| | | <div class="equipment-item"> |
| | | <span class="equipment-value">{{equipmentMaintain}}</span> |
| | | <span class="equipment-label">待保养设备</span> |
| | | </div> |
| | | <div class="equipment-item"> |
| | | <span class="equipment-value">{{totalMeasuring}}</span> |
| | | <span class="equipment-label">计量器具总数</span> |
| | | </div> |
| | | </div> |
| | | </div> |
| | | |
| | | <!-- 事件名称 --> |
| | | <div class="event-info"> |
| | | <div class="event-header"> |
| | | <img src="@/assets/BI/shijianmingxiicon@2x.png" alt="图标" class="event-icon" /> |
| | | <span class="event-title">事件名称</span> |
| | | </div> |
| | | <div class="event-content"> |
| | | <ul class="todo-list" v-if="todoList.length > 0" ref="refTodoList"> |
| | | <li v-for="item in todoList" :key="item.id"> |
| | | <div style="display: flex;flex-direction: column;justify-content: space-between;width: 100%;gap: 20px"> |
| | | <div style="display: flex;justify-content: space-between;align-items: center;"> |
| | | <div class="todo-title">待办编号:{{item.approveId}}</div> |
| | | <div class="todo-division">部门:{{item.approveDeptName}}</div> |
| | | <div class="todo-time">{{item.approveTime}}</div> |
| | | </div> |
| | | <div class="todo-division">待办事由:{{item.approveReason}}</div> |
| | | </div> |
| | | </li> |
| | | </ul> |
| | | <div v-else style="text-align: center"> |
| | | 暂无数据 |
| | | </div> |
| | | |
| | | <!-- 中间区域 --> |
| | | <div class="center-panel"> |
| | | <!-- 顶部统计卡片 --> |
| | | <div class="stats-cards"> |
| | | <div class="stat-card"> |
| | | <img src="@/assets/BI/icon@2x.png" alt="图标" class="card-icon" /> |
| | | <div class="card-content"> |
| | | <span class="card-label">员工总数</span> |
| | | <span class="card-value">{{totalStaff}}</span> |
| | | </div> |
| | | </div> |
| | | </div> |
| | | </div> |
| | | <div class="stat-card"> |
| | | <img src="@/assets/BI/icon@2x.png" alt="图标" class="card-icon" /> |
| | | <div class="card-content"> |
| | | <span class="card-label">客户总数</span> |
| | | <span class="card-value">{{totalCustomers}}</span> |
| | | </div> |
| | | </div> |
| | | <div class="stat-card"> |
| | | <img src="@/assets/BI/icon@2x.png" alt="图标" class="card-icon" /> |
| | | <div class="card-content"> |
| | | <span class="card-label">供应商总数</span> |
| | | <span class="card-value">{{totalSuppliers}}</span> |
| | | </div> |
| | | </div> |
| | | </div> |
| | | |
| | | <!-- 设备统计 --> |
| | | <div class="equipment-stats"> |
| | | <div class="equipment-header"> |
| | | <img src="@/assets/BI/shujutongjiicon@2x.png" alt="图标" class="equipment-icon" /> |
| | | <span class="equipment-title">生产统计</span> |
| | | </div> |
| | | <div class="equipment-items"> |
| | | <div class="equipment-item"> |
| | | <span class="equipment-value">{{noWorkListLength}}</span> |
| | | <span class="equipment-label">待排产</span> |
| | | </div> |
| | | <div class="equipment-item"> |
| | | <span class="equipment-value">{{workListLength}}</span> |
| | | <span class="equipment-label">已排产</span> |
| | | </div> |
| | | <div class="equipment-item"> |
| | | <span class="equipment-value">{{noListPageProcessLength}}</span> |
| | | <span class="equipment-label">待报工</span> |
| | | </div> |
| | | <div class="equipment-item"> |
| | | <span class="equipment-value">{{listPageProcessLength}}</span> |
| | | <span class="equipment-label">已报工</span> |
| | | </div> |
| | | </div> |
| | | </div> |
| | | <!-- 合格率 --> |
| | | <div class="equipment-stats"> |
| | | <div class="equipment-header"> |
| | | <img src="@/assets/BI/shujutongjiicon@2x.png" alt="图标" class="equipment-icon" /> |
| | | <span class="equipment-title">质检统计</span> |
| | | </div> |
| | | <div class="equipment-items"> |
| | | <div class="equipment-item"> |
| | | <span class="equipment-value">{{rawMaterialQualifiedRate}}%</span> |
| | | <span class="equipment-label">原材料合格率</span> |
| | | </div> |
| | | <div class="equipment-item"> |
| | | <span class="equipment-value">{{processQualifiedRate}}%</span> |
| | | <span class="equipment-label">过程合格率</span> |
| | | </div> |
| | | <div class="equipment-item"> |
| | | <span class="equipment-value">{{factoryQualifiedRate}}%</span> |
| | | <span class="equipment-label">出厂合格率</span> |
| | | </div> |
| | | <div class="equipment-item"> |
| | | <span class="equipment-value">{{inventoryTurnoverRate}}%</span> |
| | | <span class="equipment-label">库存周转率</span> |
| | | </div> |
| | | </div> |
| | | </div> |
| | | |
| | | <!-- 事件名称 --> |
| | | <!-- <div class="event-info">--> |
| | | <!-- <div class="event-header">--> |
| | | <!-- <img src="@/assets/BI/shijianmingxiicon@2x.png" alt="图标" class="event-icon" />--> |
| | | <!-- <span class="event-title">事件名称</span>--> |
| | | <!-- </div>--> |
| | | <!-- <div class="event-content">--> |
| | | <!-- <ul class="todo-list" v-if="todoList.length > 0" ref="refTodoList"> --> |
| | | <!-- <li v-for="item in todoList" :key="item.id"> --> |
| | | <!-- <div style="display: flex;flex-direction: column;justify-content: space-between;width: 100%;gap: 20px"> --> |
| | | <!-- <div style="display: flex;justify-content: space-between;align-items: center;"> --> |
| | | <!-- <div class="todo-title">待办编号:{{item.approveId}}</div> --> |
| | | <!-- <div class="todo-division">部门:{{item.approveDeptName}}</div> --> |
| | | <!-- <div class="todo-time">{{item.approveTime}}</div> --> |
| | | <!-- </div> --> |
| | | <!-- <div class="todo-division">待办事由:{{item.approveReason}}</div> --> |
| | | <!-- </div> --> |
| | | <!-- </li> --> |
| | | <!-- </ul>--> |
| | | <!-- <div v-else style="text-align: center">--> |
| | | <!-- 暂无数据--> |
| | | <!-- </div>--> |
| | | <!-- </div>--> |
| | | <!-- </div>--> |
| | | |
| | | <div class="financial-header"> |
| | | <span class="financial-title">财务分析</span> |
| | |
| | | :xAxis="xAxis3" |
| | | :yAxis="yAxis3" |
| | | :options="{backgroundColor: 'transparent', textStyle: {color: '#B8C8E0'}}" |
| | | style="height: 300px"></Echarts> |
| | | style="height: 280px"></Echarts> |
| | | </div> |
| | | </div> |
| | | </div> |
| | | |
| | | <!-- 右侧区域 --> |
| | | <div class="right-panel"> |
| | | <!-- 应收应付统计 --> |
| | | </div> |
| | | |
| | | <!-- 右侧区域 --> |
| | | <div class="right-panel"> |
| | | <!-- 应收应付统计 --> |
| | | <div class="panel-header"> |
| | | <span class="panel-title">应收应付统计</span> |
| | | </div> |
| | | <div class="panel-item-customers"> |
| | | <div style="display: flex;justify-content: space-between;margin-bottom: 20px;"> |
| | | <div class="section-title">应收应付统计</div> |
| | | <el-radio-group v-model="radio1" size="large" @change="statisticsReceivable" class="custom-radio-group"> |
| | | <el-radio-button label="按周" :value="1" /> |
| | | <el-radio-button label="按月" :value="2" /> |
| | | <el-radio-button label="按季度" :value="3" /> |
| | | </el-radio-group> |
| | | <!-- <el-radio-group v-model="radio1" size="large" @change="statisticsReceivable" class="custom-radio-group">--> |
| | | <!-- <el-radio-button label="按周" :value="1" />--> |
| | | <!-- <el-radio-button label="按月" :value="2" />--> |
| | | <!-- <el-radio-button label="按季度" :value="3" />--> |
| | | <!-- </el-radio-group>--> |
| | | </div> |
| | | <Echarts ref="chart" |
| | | :color="barColors2" |
| | | :chartStyle="chartStyle" |
| | | :grid="grid" |
| | | :legend="barLegend2" |
| | | :legend="barLegend2" |
| | | :series="barSeries" |
| | | :tooltip="tooltip" |
| | | :xAxis="xAxis" |
| | |
| | | :options="{backgroundColor: 'transparent', textStyle: {color: '#B8C8E0'}}" |
| | | style="height: 260px"></Echarts> |
| | | </div> |
| | | |
| | | <!-- 回款与开票分析 --> |
| | | <div class="panel-header"> |
| | | |
| | | <!-- 回款与开票分析 --> |
| | | <div class="panel-header"> |
| | | <span class="panel-title">回款与开票分析</span> |
| | | </div> |
| | | <div class="panel-item-customers" style="padding-top: 60px;"> |
| | | <div class="panel-item-customers" style="padding-top: 60px;"> |
| | | <Echarts ref="chart" :chartStyle="chartStyle" :grid="grid" :legend="lineLegend" :series="lineSeries" |
| | | :tooltip="tooltipLine" :xAxis="xAxis2" :yAxis="yAxis2" :options="{backgroundColor: 'transparent', textStyle: {color: '#FFFFFF'}}" style="height: 270px;"></Echarts> |
| | | :tooltip="tooltipLine" :xAxis="xAxis2" :yAxis="yAxis2" :options="{backgroundColor: 'transparent', textStyle: {color: '#FFFFFF'}}" style="height: 270px;"></Echarts> |
| | | </div> |
| | | </div> |
| | | </div> |
| | | </div> |
| | | </div> |
| | | </div> |
| | | </div> |
| | | </template> |
| | | |
| | | <script setup> |
| | |
| | | import useUserStore from '@/store/modules/user' |
| | | import { |
| | | analysisCustomerContractAmounts, getAmountHalfYear, |
| | | homeTodos, |
| | | homeTodos, inventoryStatistics, qualityProductQualifiedRate, |
| | | qualityStatistics, |
| | | statisticsReceivablePayable |
| | | } from "@/api/viewIndex.js"; |
| | |
| | | import {getUpkeepPage} from "@/api/equipmentManagement/upkeep.js"; |
| | | import {measuringInstrumentListPage} from "@/api/equipmentManagement/measurementEquipment.js"; |
| | | import {listPageAnalysis} from "@/api/financialManagement/expenseManagement.js"; |
| | | import {workListPage} from "@/api/productionManagement/productionReporting.js"; |
| | | import {listPageProcess} from "@/api/productionManagement/operationScheduling.js"; |
| | | |
| | | // 全屏相关状态 |
| | | const isFullscreen = ref(false); |
| | |
| | | const equipmentRepair = ref(0) |
| | | const equipmentMaintain = ref(0) |
| | | const totalMeasuring = ref(0) |
| | | const rawMaterialQualifiedRate = ref(0) |
| | | const processQualifiedRate = ref(0) |
| | | const factoryQualifiedRate = ref(0) |
| | | const inventoryTurnoverRate = ref(0) |
| | | const noWorkListLength = ref(0) |
| | | const workListLength = ref(0) |
| | | const noListPageProcessLength = ref(0) |
| | | const listPageProcessLength = ref(0) |
| | | const supplierNum = ref(0) |
| | | const factoryNum = ref(0) |
| | | const pieTooltip = reactive({ |
| | | trigger: 'item', |
| | | formatter: function (params) { |
| | |
| | | } |
| | | const lineLegend = { |
| | | show: true, |
| | | textStyle: { color: '#B8C8E0' }, |
| | | textStyle: { color: '#B8C8E0' }, |
| | | data: ['开票', '回款'] |
| | | } |
| | | const lineSeries = ref([ |
| | |
| | | const barLegend = { |
| | | show: true, |
| | | textStyle: { color: '#B8C8E0' }, |
| | | data: ['原材料不合格数', '过程不合格数', '出厂不合格数'] |
| | | data: ['原材料合格数', '过程合格数', '出厂合格数'] |
| | | } |
| | | const barLegend1 = { |
| | | show: true, |
| | |
| | | ]) |
| | | const barSeries1 = ref([ |
| | | { |
| | | name: '原材料不合格数', |
| | | name: '入库数量', |
| | | type: 'bar', |
| | | barGap: 0, |
| | | emphasis: { |
| | |
| | | data: [] |
| | | }, |
| | | { |
| | | name: '过程不合格数', |
| | | name: '出库数量', |
| | | type: 'bar', |
| | | emphasis: { |
| | | focus: 'series' |
| | |
| | | colorStops: [ |
| | | { offset: 1, color: '#3378FF' }, |
| | | { offset: 0, color: '#4E8AFF' } |
| | | ] |
| | | } |
| | | }, |
| | | data: [] |
| | | }, |
| | | { |
| | | name: '出厂不合格数', |
| | | type: 'bar', |
| | | emphasis: { |
| | | focus: 'series' |
| | | }, |
| | | itemStyle: { |
| | | color: { |
| | | type: 'linear', |
| | | x: 0, |
| | | y: 0, |
| | | x2: 0, |
| | | y2: 1, |
| | | colorStops: [ |
| | | { offset: 1, color: '#537EF5' }, |
| | | { offset: 0, color: '#9061F8' } |
| | | ] |
| | | } |
| | | }, |
| | |
| | | |
| | | // 窗口大小变化处理 |
| | | const handleResize = () => { |
| | | charts.value.forEach(chart => { |
| | | if (chart && chart.resize) { |
| | | chart.resize() |
| | | } |
| | | }) |
| | | charts.value.forEach(chart => { |
| | | if (chart && chart.resize) { |
| | | chart.resize() |
| | | } |
| | | }) |
| | | } |
| | | |
| | | // 销毁图表实例 |
| | | const disposeCharts = () => { |
| | | charts.value.forEach(chart => { |
| | | if (chart && chart.dispose) { |
| | | chart.dispose() |
| | | } |
| | | }) |
| | | charts.value = [] |
| | | charts.value.forEach(chart => { |
| | | if (chart && chart.dispose) { |
| | | chart.dispose() |
| | | } |
| | | }) |
| | | charts.value = [] |
| | | } |
| | | // 合同金额 |
| | | const analysisCustomer = () => { |
| | |
| | | qualityStatisticsObject.value.factoryNum = res.data.factoryNum |
| | | }) |
| | | } |
| | | // 产品合格率 |
| | | const qualityProductQualifiedRateInfo = () => { |
| | | qualityProductQualifiedRate().then((res) => { |
| | | rawMaterialQualifiedRate.value = res.data.rawMaterialQualifiedRate |
| | | processQualifiedRate.value = res.data.processQualifiedRate |
| | | factoryQualifiedRate.value = res.data.factoryQualifiedRate |
| | | inventoryTurnoverRate.value = res.data.inventoryTurnoverRate |
| | | }) |
| | | } |
| | | // 产品合格率 |
| | | const inventoryStatisticsInfo = () => { |
| | | inventoryStatistics().then((res) => { |
| | | supplierNum.value = res.data.supplierNum |
| | | factoryNum.value = res.data.factoryNum |
| | | res.data.item.forEach(item => { |
| | | xAxis1.value[0].data.push(item.date) |
| | | barSeries1.value[0].data.push(item.supplierNum) |
| | | barSeries1.value[1].data.push(item.factoryNum) |
| | | }) |
| | | }) |
| | | } |
| | | // 财务统计 |
| | | const accountStatisticsInfo = () => { |
| | | listPageAnalysis().then((res) => { |
| | |
| | | barSeries11.value[2].data = res.data.netIncome |
| | | }) |
| | | } |
| | | // 生产数据 |
| | | const workListPageInfo = () => { |
| | | const params = { |
| | | current: -1, |
| | | size: -1, |
| | | status: 3 |
| | | } |
| | | const params1 = { |
| | | current: -1, |
| | | size: -1, |
| | | status: 1 |
| | | } |
| | | // 已报工查询 |
| | | workListPage(params).then(res => { |
| | | workListLength.value = res.data.records.length |
| | | }) |
| | | // 已排产查询 |
| | | listPageProcess(params).then(res => { |
| | | listPageProcessLength.value = res.data.records.length |
| | | }) |
| | | // 待报工查询 |
| | | workListPage(params1).then(res => { |
| | | noWorkListLength.value = res.data.records.length |
| | | }) |
| | | // 待排产查询 |
| | | listPageProcess(params1).then(res => { |
| | | noListPageProcessLength.value = res.data.records.length |
| | | }) |
| | | } |
| | | |
| | | const getNum = () => { |
| | | const params = { |
| | | pageNum: -1, |
| | |
| | | pageNum: -1, |
| | | pageSize: -1, |
| | | } |
| | | getLedgerPage(params).then((res) => { |
| | | getLedgerPage({}).then((res) => { |
| | | equipmentNum.value = res.data.total |
| | | }); |
| | | getRepairPage(params).then((res) => { |
| | |
| | | |
| | | // 更新时间 |
| | | const updateTime = () => { |
| | | const now = new Date() |
| | | currentTime.value = now.toLocaleTimeString('zh-CN', { hour12: false }) |
| | | currentDate.value = now.toLocaleDateString('zh-CN', { |
| | | year: 'numeric', |
| | | month: '2-digit', |
| | | day: '2-digit', |
| | | weekday: 'long' |
| | | }) |
| | | const now = new Date() |
| | | currentTime.value = now.toLocaleTimeString('zh-CN', { hour12: false }) |
| | | currentDate.value = now.toLocaleDateString('zh-CN', { |
| | | year: 'numeric', |
| | | month: '2-digit', |
| | | day: '2-digit', |
| | | weekday: 'long' |
| | | }) |
| | | } |
| | | |
| | | // 初始化时间 |
| | | const initTime = () => { |
| | | updateTime() |
| | | timer.value = setInterval(updateTime, 1000) |
| | | updateTime() |
| | | timer.value = setInterval(updateTime, 1000) |
| | | } |
| | | // 全屏功能实现 - 针对data-dashboard元素 |
| | | const toggleFullscreen = () => { |
| | |
| | | |
| | | // 监听全屏变化事件 |
| | | const handleFullscreenChange = () => { |
| | | const fullscreenElement = document.fullscreenElement || |
| | | document.webkitFullscreenElement || |
| | | document.msFullscreenElement |
| | | isFullscreen.value = fullscreenElement && fullscreenElement.classList.contains('data-dashboard') |
| | | const fullscreenElement = document.fullscreenElement || |
| | | document.webkitFullscreenElement || |
| | | document.msFullscreenElement |
| | | isFullscreen.value = fullscreenElement && fullscreenElement.classList.contains('data-dashboard') |
| | | } |
| | | |
| | | // 生命周期钩子 |
| | | onMounted(() => { |
| | | initTime() |
| | | // 使用nextTick确保DOM完全渲染后再初始化图表 |
| | | nextTick(() => { |
| | | // 初始化autofit自适应 |
| | | autofit.init({ dh: 1080, dw: 1920, el: '.data-dashboard', resize: true }, false) |
| | | |
| | | // 添加自动滚动动画效果 - 客户信息列表 |
| | | const contractList = refContractList.value |
| | | if (contractList && contractList.scrollHeight > contractList.clientHeight) { |
| | | // 创建一个克隆项,用于实现无缝滚动 |
| | | const scrollItems = Array.from(contractList.querySelectorAll('li')) |
| | | const itemHeight = scrollItems[0]?.offsetHeight || 0 |
| | | const containerHeight = contractList.clientHeight |
| | | const cloneCount = Math.ceil(containerHeight / itemHeight) + 2 |
| | | |
| | | // 克隆前几个项目并添加到列表末尾,实现无缝滚动 |
| | | for (let i = 0; i < cloneCount; i++) { |
| | | const clone = scrollItems[i % scrollItems.length].cloneNode(true) |
| | | contractList.appendChild(clone) |
| | | } |
| | | |
| | | let scrollPosition = 0 |
| | | const scrollSpeed = 1.5 // 增加滚动速度,使滚动更加明显 |
| | | const pauseTime = 3000 // 滚动暂停时间 |
| | | let isPaused = false |
| | | let lastTimestamp = 0 |
| | | |
| | | // 连续滚动动画函数 |
| | | function scrollAnimation(timestamp) { |
| | | if (!lastTimestamp) lastTimestamp = timestamp |
| | | const deltaTime = timestamp - lastTimestamp |
| | | lastTimestamp = timestamp |
| | | |
| | | if (!isPaused) { |
| | | scrollPosition += scrollSpeed * (deltaTime / 16) // 标准化为60fps的速度 |
| | | |
| | | // 当滚动超过原始内容长度时,重置位置实现无缝滚动 |
| | | if (scrollPosition >= contractList.scrollHeight - containerHeight - cloneCount * itemHeight) { |
| | | scrollPosition = 0 |
| | | contractList.scrollTop = 0 |
| | | } else { |
| | | contractList.scrollTop = scrollPosition |
| | | } |
| | | } |
| | | |
| | | timerScroll.value = requestAnimationFrame(scrollAnimation) |
| | | } |
| | | |
| | | // 启动滚动动画 |
| | | timerScroll.value = requestAnimationFrame(scrollAnimation) |
| | | |
| | | // 设置滚动-暂停-滚动的循环效果 |
| | | const pauseTimer = setInterval(() => { |
| | | isPaused = !isPaused |
| | | }, pauseTime) |
| | | |
| | | // 清理定时器 |
| | | contractList._pauseTimer = pauseTimer |
| | | } |
| | | |
| | | // 待办事项列表滚动功能已移至todoInfoS函数中,在获取数据后初始化 |
| | | }) |
| | | |
| | | window.addEventListener('resize', handleResize) |
| | | analysisCustomer() |
| | | qualityStatisticsInfo() |
| | | initTime() |
| | | // 使用nextTick确保DOM完全渲染后再初始化图表 |
| | | nextTick(() => { |
| | | // 初始化autofit自适应 |
| | | autofit.init({ dh: 1080, dw: 1920, el: '.data-dashboard', resize: true }, false) |
| | | |
| | | // 添加自动滚动动画效果 - 客户信息列表 |
| | | const contractList = refContractList.value |
| | | if (contractList && contractList.scrollHeight > contractList.clientHeight) { |
| | | // 创建一个克隆项,用于实现无缝滚动 |
| | | const scrollItems = Array.from(contractList.querySelectorAll('li')) |
| | | const itemHeight = scrollItems[0]?.offsetHeight || 0 |
| | | const containerHeight = contractList.clientHeight |
| | | const cloneCount = Math.ceil(containerHeight / itemHeight) + 2 |
| | | |
| | | // 克隆前几个项目并添加到列表末尾,实现无缝滚动 |
| | | for (let i = 0; i < cloneCount; i++) { |
| | | const clone = scrollItems[i % scrollItems.length].cloneNode(true) |
| | | contractList.appendChild(clone) |
| | | } |
| | | |
| | | let scrollPosition = 0 |
| | | const scrollSpeed = 1.5 // 增加滚动速度,使滚动更加明显 |
| | | const pauseTime = 3000 // 滚动暂停时间 |
| | | let isPaused = false |
| | | let lastTimestamp = 0 |
| | | |
| | | // 连续滚动动画函数 |
| | | function scrollAnimation(timestamp) { |
| | | if (!lastTimestamp) lastTimestamp = timestamp |
| | | const deltaTime = timestamp - lastTimestamp |
| | | lastTimestamp = timestamp |
| | | |
| | | if (!isPaused) { |
| | | scrollPosition += scrollSpeed * (deltaTime / 16) // 标准化为60fps的速度 |
| | | |
| | | // 当滚动超过原始内容长度时,重置位置实现无缝滚动 |
| | | if (scrollPosition >= contractList.scrollHeight - containerHeight - cloneCount * itemHeight) { |
| | | scrollPosition = 0 |
| | | contractList.scrollTop = 0 |
| | | } else { |
| | | contractList.scrollTop = scrollPosition |
| | | } |
| | | } |
| | | |
| | | timerScroll.value = requestAnimationFrame(scrollAnimation) |
| | | } |
| | | |
| | | // 启动滚动动画 |
| | | timerScroll.value = requestAnimationFrame(scrollAnimation) |
| | | |
| | | // 设置滚动-暂停-滚动的循环效果 |
| | | const pauseTimer = setInterval(() => { |
| | | isPaused = !isPaused |
| | | }, pauseTime) |
| | | |
| | | // 清理定时器 |
| | | contractList._pauseTimer = pauseTimer |
| | | } |
| | | |
| | | // 待办事项列表滚动功能已移至todoInfoS函数中,在获取数据后初始化 |
| | | }) |
| | | |
| | | window.addEventListener('resize', handleResize) |
| | | analysisCustomer() |
| | | // qualityStatisticsInfo() |
| | | qualityProductQualifiedRateInfo() |
| | | inventoryStatisticsInfo() |
| | | accountStatisticsInfo() |
| | | getNum() |
| | | getLedgerNum() |
| | | todoInfoS() |
| | | workListPageInfo() |
| | | getNum() |
| | | getLedgerNum() |
| | | todoInfoS() |
| | | statisticsReceivable() |
| | | getAmountHalfYearNum() |
| | | |
| | | // 设置自动轮换周、月、季度的定时器,每10秒切换一次 |
| | | autoSwitchTimer.value = setInterval(() => { |
| | | // 循环切换:1(周) -> 2(月) -> 3(季度) -> 1(周) |
| | | radio1.value = radio1.value === 3 ? 1 : radio1.value + 1 |
| | | statisticsReceivable() |
| | | }, 10000) // 10秒切换一次 |
| | | |
| | | // 设置自动轮换周、月、季度的定时器,每10秒切换一次 |
| | | autoSwitchTimer.value = setInterval(() => { |
| | | // 循环切换:1(周) -> 2(月) -> 3(季度) -> 1(周) |
| | | radio1.value = radio1.value === 3 ? 1 : radio1.value + 1 |
| | | statisticsReceivable() |
| | | }, 10000) // 10秒切换一次 |
| | | }) |
| | | |
| | | onBeforeUnmount(() => { |
| | | if (timer.value) { |
| | | clearInterval(timer.value) |
| | | } |
| | | if (timerScroll.value) { |
| | | cancelAnimationFrame(timerScroll.value) |
| | | } |
| | | // 清理滚动列表的暂停定时器 |
| | | const contractList = refContractList.value |
| | | if (contractList && contractList._pauseTimer) { |
| | | clearInterval(contractList._pauseTimer) |
| | | } |
| | | |
| | | // 清理待办事项列表的动画和定时器 |
| | | const todoList = refTodoList.value |
| | | if (todoList) { |
| | | if (todoList._animationFrame) { |
| | | cancelAnimationFrame(todoList._animationFrame) |
| | | todoList._animationFrame = null |
| | | } |
| | | if (todoList._pauseTimer) { |
| | | clearInterval(todoList._pauseTimer) |
| | | todoList._pauseTimer = null |
| | | } |
| | | } |
| | | |
| | | // 清理自动轮换周、月、季度的定时器 |
| | | if (autoSwitchTimer.value) { |
| | | clearInterval(autoSwitchTimer.value) |
| | | autoSwitchTimer.value = null |
| | | } |
| | | |
| | | window.removeEventListener('resize', handleResize) |
| | | window.removeEventListener('fullscreenchange', handleFullscreenChange) |
| | | window.removeEventListener('webkitfullscreenchange', handleFullscreenChange) |
| | | window.removeEventListener('MSFullscreenChange', handleFullscreenChange) |
| | | // 移除我们添加的autofit动态调整监听器 |
| | | if (window._autofitUpdateHandler) { |
| | | window.removeEventListener('resize', window._autofitUpdateHandler) |
| | | delete window._autofitUpdateHandler |
| | | } |
| | | disposeCharts() |
| | | // 关闭autofit |
| | | autofit.off() |
| | | if (timer.value) { |
| | | clearInterval(timer.value) |
| | | } |
| | | if (timerScroll.value) { |
| | | cancelAnimationFrame(timerScroll.value) |
| | | } |
| | | // 清理滚动列表的暂停定时器 |
| | | const contractList = refContractList.value |
| | | if (contractList && contractList._pauseTimer) { |
| | | clearInterval(contractList._pauseTimer) |
| | | } |
| | | |
| | | // 清理待办事项列表的动画和定时器 |
| | | const todoList = refTodoList.value |
| | | if (todoList) { |
| | | if (todoList._animationFrame) { |
| | | cancelAnimationFrame(todoList._animationFrame) |
| | | todoList._animationFrame = null |
| | | } |
| | | if (todoList._pauseTimer) { |
| | | clearInterval(todoList._pauseTimer) |
| | | todoList._pauseTimer = null |
| | | } |
| | | } |
| | | |
| | | // 清理自动轮换周、月、季度的定时器 |
| | | if (autoSwitchTimer.value) { |
| | | clearInterval(autoSwitchTimer.value) |
| | | autoSwitchTimer.value = null |
| | | } |
| | | |
| | | window.removeEventListener('resize', handleResize) |
| | | window.removeEventListener('fullscreenchange', handleFullscreenChange) |
| | | window.removeEventListener('webkitfullscreenchange', handleFullscreenChange) |
| | | window.removeEventListener('MSFullscreenChange', handleFullscreenChange) |
| | | // 移除我们添加的autofit动态调整监听器 |
| | | if (window._autofitUpdateHandler) { |
| | | window.removeEventListener('resize', window._autofitUpdateHandler) |
| | | delete window._autofitUpdateHandler |
| | | } |
| | | disposeCharts() |
| | | // 关闭autofit |
| | | autofit.off() |
| | | }) |
| | | </script> |
| | | |
| | | <style scoped> |
| | | .data-dashboard { |
| | | position: relative; |
| | | width: 100%; |
| | | position: relative; |
| | | width: 100%; |
| | | height: 100%; |
| | | background-image: url("@/assets/BI/backImage@2x.png"); |
| | | background-size: cover; |
| | |
| | | |
| | | /* 全屏状态的样式 */ |
| | | .data-dashboard:fullscreen { |
| | | width: 100%; |
| | | height: 100%; |
| | | margin: 0; |
| | | padding: 0; |
| | | background-color: inherit; |
| | | z-index: 9999; |
| | | width: 100%; |
| | | height: 100%; |
| | | margin: 0; |
| | | padding: 0; |
| | | background-color: inherit; |
| | | z-index: 9999; |
| | | } |
| | | |
| | | /* Webkit浏览器前缀 */ |
| | | .data-dashboard:-webkit-full-screen { |
| | | width: 100%; |
| | | height: 100%; |
| | | margin: 0; |
| | | padding: 0; |
| | | background-color: inherit; |
| | | z-index: 9999; |
| | | width: 100%; |
| | | height: 100%; |
| | | margin: 0; |
| | | padding: 0; |
| | | background-color: inherit; |
| | | z-index: 9999; |
| | | } |
| | | |
| | | /* MS浏览器前缀 */ |
| | | .data-dashboard:-ms-fullscreen { |
| | | width: 100%; |
| | | height: 100%; |
| | | margin: 0; |
| | | padding: 0; |
| | | background-color: inherit; |
| | | z-index: 9999; |
| | | width: 100%; |
| | | height: 100%; |
| | | margin: 0; |
| | | padding: 0; |
| | | background-color: inherit; |
| | | z-index: 9999; |
| | | } |
| | | |
| | | |
| | | .dashboard-header { |
| | | position: relative; |
| | | z-index: 1; |
| | | height: 170px; |
| | | position: relative; |
| | | z-index: 1; |
| | | height: 170px; |
| | | background-image: url("@/assets/BI/biaoti.png"); |
| | | background-size: cover; |
| | | background-position: center; |
| | | background-repeat: no-repeat; |
| | | display: flex; |
| | | align-items: center; |
| | | justify-content: center; |
| | | display: flex; |
| | | align-items: center; |
| | | justify-content: center; |
| | | } |
| | | |
| | | .factory-name { |
| | | font-weight: 600; |
| | | font-size: 52px; |
| | | color: #FFFFFF; |
| | | top: 32px; |
| | | position: absolute; |
| | | font-weight: 600; |
| | | font-size: 52px; |
| | | color: #FFFFFF; |
| | | top: 32px; |
| | | position: absolute; |
| | | } |
| | | |
| | | .fullscreen-btn { |
| | | position: absolute; |
| | | top: 10px; |
| | | left: 20px; |
| | | width: 40px; |
| | | height: 40px; |
| | | background: rgba(0, 20, 60, 0.8); |
| | | border: 1px solid rgba(0, 212, 255, 0.3); |
| | | border-radius: 6px; |
| | | color: #00d4ff; |
| | | cursor: pointer; |
| | | display: flex; |
| | | align-items: center; |
| | | justify-content: center; |
| | | transition: all 0.3s; |
| | | z-index: 10000; |
| | | position: absolute; |
| | | top: 10px; |
| | | left: 20px; |
| | | width: 40px; |
| | | height: 40px; |
| | | background: rgba(0, 20, 60, 0.8); |
| | | border: 1px solid rgba(0, 212, 255, 0.3); |
| | | border-radius: 6px; |
| | | color: #00d4ff; |
| | | cursor: pointer; |
| | | display: flex; |
| | | align-items: center; |
| | | justify-content: center; |
| | | transition: all 0.3s; |
| | | z-index: 10000; |
| | | } |
| | | |
| | | .fullscreen-btn:hover { |
| | | background: rgba(0, 30, 90, 0.9); |
| | | border-color: rgba(0, 212, 255, 0.5); |
| | | background: rgba(0, 30, 90, 0.9); |
| | | border-color: rgba(0, 212, 255, 0.5); |
| | | } |
| | | |
| | | .dashboard-content { |
| | | position: relative; |
| | | z-index: 1; |
| | | display: flex; |
| | | gap: 30px; |
| | | padding: 0 30px; |
| | | height: calc(100% - 120px); |
| | | overflow: hidden; |
| | | position: relative; |
| | | z-index: 1; |
| | | display: flex; |
| | | gap: 30px; |
| | | padding: 0 30px; |
| | | height: calc(100% - 120px); |
| | | overflow: hidden; |
| | | } |
| | | |
| | | /* 确保各面板能够正确显示 */ |
| | | .left-panel, .center-panel, .right-panel { |
| | | overflow: hidden; |
| | | overflow: hidden; |
| | | } |
| | | |
| | | .left-panel, |
| | | .right-panel { |
| | | flex: 1; |
| | | display: flex; |
| | | flex-direction: column; |
| | | gap: 24px; |
| | | flex: 1; |
| | | display: flex; |
| | | flex-direction: column; |
| | | gap: 24px; |
| | | width: 520px; |
| | | } |
| | | |
| | | .center-panel { |
| | | flex: 1.5; |
| | | display: flex; |
| | | flex-direction: column; |
| | | gap: 20px; |
| | | flex: 1.5; |
| | | display: flex; |
| | | flex-direction: column; |
| | | gap: 20px; |
| | | } |
| | | .panel-item-customers { |
| | | border: 1px solid #1A58B0; |
| | | padding: 18px; |
| | | width: 100%; |
| | | height: 540px; |
| | | height: 520px; |
| | | } |
| | | .panel-title-second { |
| | | height: 60px; |
| | |
| | | margin-top: 10px; |
| | | } |
| | | .stats-cards { |
| | | display: flex; |
| | | gap: 30px; |
| | | display: flex; |
| | | gap: 30px; |
| | | } |
| | | |
| | | .stat-card { |
| | | flex: 1; |
| | | display: flex; |
| | | align-items: center; |
| | | flex: 1; |
| | | display: flex; |
| | | align-items: center; |
| | | background-image: url("@/assets/BI/border@2x.png"); |
| | | background-size: 100% 100%; |
| | | background-position: center; |
| | | background-repeat: no-repeat; |
| | | height: 142px; |
| | | height: 142px; |
| | | } |
| | | |
| | | .card-icon { |
| | | width: 100px; |
| | | height: 100px; |
| | | margin: 20px 20px 0 10px; |
| | | width: 100px; |
| | | height: 100px; |
| | | margin: 20px 20px 0 10px; |
| | | } |
| | | |
| | | .card-content { |
| | | display: flex; |
| | | flex-direction: column; |
| | | display: flex; |
| | | flex-direction: column; |
| | | gap: 10px; |
| | | } |
| | | |
| | | .card-value { |
| | | font-weight: 500; |
| | | font-size: 40px; |
| | | background: linear-gradient(360deg, #008BFD 0%, #FFFFFF 100%); |
| | | -webkit-background-clip: text; |
| | | -webkit-text-fill-color: transparent; |
| | | background-clip: text; |
| | | background: linear-gradient(360deg, #008BFD 0%, #FFFFFF 100%); |
| | | -webkit-background-clip: text; |
| | | -webkit-text-fill-color: transparent; |
| | | background-clip: text; |
| | | } |
| | | |
| | | .card-label { |
| | |
| | | |
| | | .equipment-stats { |
| | | border: 1px solid #1A58B0; |
| | | padding: 18px; |
| | | height: 240px; |
| | | padding: 18px; |
| | | height: 240px; |
| | | } |
| | | .equipment-header { |
| | | font-weight: 500; |
| | |
| | | height: 50px; |
| | | } |
| | | .equipment-items { |
| | | display: flex; |
| | | justify-content: space-around; |
| | | gap: 30px; |
| | | display: flex; |
| | | justify-content: space-around; |
| | | gap: 30px; |
| | | } |
| | | |
| | | .equipment-item { |
| | | text-align: center; |
| | | text-align: center; |
| | | } |
| | | |
| | | .equipment-value { |
| | | display: block; |
| | | display: block; |
| | | font-weight: 500; |
| | | font-size: 40px; |
| | | color: #FFFFFF; |
| | |
| | | background-size: 100% 100%; |
| | | background-position: center; |
| | | background-repeat: no-repeat; |
| | | margin-bottom: 8px; |
| | | margin-bottom: 8px; |
| | | } |
| | | |
| | | .equipment-label { |
| | |
| | | background-size: 100% 100%; |
| | | background-position: center; |
| | | background-repeat: no-repeat; |
| | | padding: 20px; |
| | | height: 186px; |
| | | padding: 20px; |
| | | height: 186px; |
| | | } |
| | | .event-header { |
| | | display: flex; |
| | |
| | | line-height: 30px; |
| | | } |
| | | .todo-list { |
| | | list-style: none; |
| | | padding: 0; |
| | | margin: 0; |
| | | height: 120px; /* 按用户要求调整高度 */ |
| | | overflow: hidden; |
| | | font-size: 15px; |
| | | list-style: none; |
| | | padding: 0; |
| | | margin: 0; |
| | | height: 120px; /* 按用户要求调整高度 */ |
| | | overflow: hidden; |
| | | font-size: 15px; |
| | | } |
| | | .todo-list li { |
| | | border-radius: 8px; |
| | |
| | | |
| | | /* 自定义单选按钮组样式 */ |
| | | .custom-radio-group :deep(.el-radio-button__inner) { |
| | | background-color: transparent; |
| | | color: white; |
| | | border-color: rgba(255, 255, 255, 0.3); |
| | | background-color: transparent; |
| | | color: white; |
| | | border-color: rgba(255, 255, 255, 0.3); |
| | | } |
| | | |
| | | .custom-radio-group :deep(.el-radio-button__original-radio:checked + .el-radio-button__inner) { |
| | | background-color: rgba(255, 255, 255, 0.2); |
| | | color: white; |
| | | border-color: rgba(255, 255, 255, 0.5); |
| | | box-shadow: -1px 0 0 0 rgba(255, 255, 255, 0.5); |
| | | background-color: rgba(255, 255, 255, 0.2); |
| | | color: white; |
| | | border-color: rgba(255, 255, 255, 0.5); |
| | | box-shadow: -1px 0 0 0 rgba(255, 255, 255, 0.5); |
| | | } |
| | | </style> |