|
@@ -0,0 +1,514 @@
|
|
|
+<template>
|
|
|
+ <el-card class="box-card">
|
|
|
+ <div slot="header" class="clearfix">
|
|
|
+ <div class="header-content">
|
|
|
+ <div class="header-title">
|
|
|
+ <span>已安装统计</span>
|
|
|
+ <span class="update-time">{{ updateTime }}</span>
|
|
|
+ </div>
|
|
|
+ <div class="filter-section">
|
|
|
+ <el-select v-model="productFilter" placeholder="货品" size="small" @change="handleFilterChange">
|
|
|
+ <el-option
|
|
|
+ v-for="item in productOptions"
|
|
|
+ :key="item.value"
|
|
|
+ :label="item.label"
|
|
|
+ :value="item.value"
|
|
|
+ />
|
|
|
+ </el-select>
|
|
|
+ <el-select v-model="monthFilter" placeholder="时间" size="small" @change="handleFilterChange">
|
|
|
+ <el-option
|
|
|
+ v-for="item in monthOptions"
|
|
|
+ :key="item.value"
|
|
|
+ :label="item.label"
|
|
|
+ :value="item.value"
|
|
|
+ />
|
|
|
+ </el-select>
|
|
|
+ <el-select v-model="personnelFilter" placeholder="人员" size="small" @change="handleFilterChange">
|
|
|
+ <el-option
|
|
|
+ v-for="item in personnelOptions"
|
|
|
+ :key="item.value"
|
|
|
+ :label="item.label"
|
|
|
+ :value="item.value"
|
|
|
+ />
|
|
|
+ </el-select>
|
|
|
+ <el-select v-model="customerFilter" placeholder="客户" size="small" @change="handleFilterChange">
|
|
|
+ <el-option
|
|
|
+ v-for="item in customerOptions"
|
|
|
+ :key="item.value"
|
|
|
+ :label="item.label"
|
|
|
+ :value="item.value"
|
|
|
+ />
|
|
|
+ </el-select>
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+ <el-table
|
|
|
+ :data="displayData"
|
|
|
+ style="width: 100%"
|
|
|
+ border
|
|
|
+ size="small"
|
|
|
+ >
|
|
|
+ <el-table-column prop="customerName" label="客户名称" align="center"/>
|
|
|
+ <el-table-column prop="productName" label="安装货品" align="center"/>
|
|
|
+ <el-table-column prop="installer" label="安装人员" align="center"/>
|
|
|
+ <el-table-column prop="planQuantity" label="计划量" align="center"/>
|
|
|
+ <el-table-column prop="completedQuantity" label="已完成量" align="center"/>
|
|
|
+ <el-table-column prop="installStartTime" label="接单时间/开始安装时间" align="center"/>
|
|
|
+ <el-table-column prop="expectedEndTime" label="预计完成时间" align="center"/>
|
|
|
+ <el-table-column prop="actualEndTime" label="实际完成时间" align="center"/>
|
|
|
+ <el-table-column prop="planDays" label="工时" align="center"/>
|
|
|
+ <el-table-column prop="actualDays" label="实际工时" align="center">
|
|
|
+ <template slot-scope="scope">
|
|
|
+ <span :style="{ color: getWorkDaysColor(scope.row) }">{{ scope.row.actualDays }}</span>
|
|
|
+ </template>
|
|
|
+ </el-table-column>
|
|
|
+ <el-table-column prop="completionRate" label="完成效率" align="center">
|
|
|
+ <template slot-scope="scope">
|
|
|
+ <span :style="{ color: getCompletionRateColor(scope.row) }">{{ scope.row.completionRate }}%</span>
|
|
|
+ </template>
|
|
|
+ </el-table-column>
|
|
|
+ <el-table-column prop="personCount" label="人数" align="center"/>
|
|
|
+ </el-table>
|
|
|
+ <div class="expand-button" v-if="tableData.length > 10">
|
|
|
+ <el-button type="text" @click="isExpanded = !isExpanded" class="expand-btn">
|
|
|
+ <div class="button-content">
|
|
|
+ <i :class="['el-icon-arrow-' + (isExpanded ? 'up' : 'down')]"></i>
|
|
|
+ <span class="expand-text">{{ isExpanded ? '收起' : '展开更多' }}</span>
|
|
|
+ </div>
|
|
|
+ </el-button>
|
|
|
+ </div>
|
|
|
+ </el-card>
|
|
|
+</template>
|
|
|
+
|
|
|
+<script>
|
|
|
+export default {
|
|
|
+ name: 'InstallationStatistics',
|
|
|
+ props: {
|
|
|
+ updateTime: {
|
|
|
+ type: String,
|
|
|
+ default: ''
|
|
|
+ }
|
|
|
+ },
|
|
|
+ data() {
|
|
|
+ return {
|
|
|
+ isExpanded: false,
|
|
|
+ productFilter: '',
|
|
|
+ monthFilter: '',
|
|
|
+ personnelFilter: '',
|
|
|
+ customerFilter: '',
|
|
|
+ productOptions: [],
|
|
|
+ monthOptions: [],
|
|
|
+ personnelOptions: [],
|
|
|
+ customerOptions: [],
|
|
|
+ tableData: [
|
|
|
+ {
|
|
|
+ customerName: '现代牧业二场',
|
|
|
+ productName: '智能膜环',
|
|
|
+ installer: '张明星',
|
|
|
+ planQuantity: 5000,
|
|
|
+ completedQuantity: 5000,
|
|
|
+ installStartTime: '2024-10-01',
|
|
|
+ expectedEndTime: '2024-10-30',
|
|
|
+ actualEndTime: '2024-10-28',
|
|
|
+ planDays: 30,
|
|
|
+ actualDays: 28,
|
|
|
+ completionRate: 107,
|
|
|
+ personCount: 1785
|
|
|
+ },
|
|
|
+ {
|
|
|
+ customerName: '现代牧业和林',
|
|
|
+ productName: '精准阉割',
|
|
|
+ installer: '陈希多',
|
|
|
+ planQuantity: 5000,
|
|
|
+ completedQuantity: 5000,
|
|
|
+ installStartTime: '2024-10-01',
|
|
|
+ expectedEndTime: '2024-10-30',
|
|
|
+ actualEndTime: '2024-10-25',
|
|
|
+ planDays: 30,
|
|
|
+ actualDays: 25,
|
|
|
+ completionRate: 120,
|
|
|
+ personCount: 2000
|
|
|
+ },
|
|
|
+ {
|
|
|
+ customerName: '现代牧业三场',
|
|
|
+ productName: '精准阉割',
|
|
|
+ installer: '李九联',
|
|
|
+ planQuantity: 5000,
|
|
|
+ completedQuantity: 5000,
|
|
|
+ installStartTime: '2024-10-30',
|
|
|
+ expectedEndTime: '2024-11-30',
|
|
|
+ actualEndTime: '2024-11-28',
|
|
|
+ planDays: 31,
|
|
|
+ actualDays: 29,
|
|
|
+ completionRate: 106,
|
|
|
+ personCount: 1724
|
|
|
+ },
|
|
|
+ {
|
|
|
+ customerName: '蜂谷牧场',
|
|
|
+ productName: '体况评分',
|
|
|
+ installer: '李季冬',
|
|
|
+ planQuantity: 2000,
|
|
|
+ completedQuantity: 2000,
|
|
|
+ installStartTime: '2024-09-28',
|
|
|
+ expectedEndTime: '2024-10-20',
|
|
|
+ actualEndTime: '2024-10-24',
|
|
|
+ planDays: 23,
|
|
|
+ actualDays: 27,
|
|
|
+ completionRate: 85,
|
|
|
+ personCount: 1481
|
|
|
+ },
|
|
|
+ {
|
|
|
+ customerName: '海丰牧场',
|
|
|
+ productName: '体况评分',
|
|
|
+ installer: '谭性成',
|
|
|
+ planQuantity: 3000,
|
|
|
+ completedQuantity: 3000,
|
|
|
+ installStartTime: '2024-08-01',
|
|
|
+ expectedEndTime: '2024-08-20',
|
|
|
+ actualEndTime: '2024-08-22',
|
|
|
+ planDays: 20,
|
|
|
+ actualDays: 22,
|
|
|
+ completionRate: 90,
|
|
|
+ personCount: 1346
|
|
|
+ },
|
|
|
+ {
|
|
|
+ customerName: '大丰牧场',
|
|
|
+ productName: '精准阉割',
|
|
|
+ installer: '柯凡',
|
|
|
+ planQuantity: 1000,
|
|
|
+ completedQuantity: 1000,
|
|
|
+ installStartTime: '2024-09-01',
|
|
|
+ expectedEndTime: '2024-09-20',
|
|
|
+ actualEndTime: '2024-09-25',
|
|
|
+ planDays: 20,
|
|
|
+ actualDays: 25,
|
|
|
+ completionRate: 80,
|
|
|
+ personCount: 1200
|
|
|
+ },
|
|
|
+ {
|
|
|
+ customerName: '马鞍山牧场',
|
|
|
+ productName: '智能膜环',
|
|
|
+ installer: '郑福超',
|
|
|
+ planQuantity: 2000,
|
|
|
+ completedQuantity: 2000,
|
|
|
+ installStartTime: '2024-09-01',
|
|
|
+ expectedEndTime: '2024-09-20',
|
|
|
+ actualEndTime: '2024-09-15',
|
|
|
+ planDays: 20,
|
|
|
+ actualDays: 15,
|
|
|
+ completionRate: 133,
|
|
|
+ personCount: 1700
|
|
|
+ },
|
|
|
+ {
|
|
|
+ customerName: '新希望',
|
|
|
+ productName: '显示大屏',
|
|
|
+ installer: '韩佳维',
|
|
|
+ planQuantity: 3000,
|
|
|
+ completedQuantity: 3000,
|
|
|
+ installStartTime: '2024-08-10',
|
|
|
+ expectedEndTime: '2024-08-20',
|
|
|
+ actualEndTime: '2024-08-20',
|
|
|
+ planDays: 11,
|
|
|
+ actualDays: 11,
|
|
|
+ completionRate: 100,
|
|
|
+ personCount: 1600
|
|
|
+ },
|
|
|
+ {
|
|
|
+ customerName: '宝塔牧场',
|
|
|
+ productName: '车载控制器',
|
|
|
+ installer: '卫承乾',
|
|
|
+ planQuantity: 4000,
|
|
|
+ completedQuantity: 4000,
|
|
|
+ installStartTime: '2024-10-05',
|
|
|
+ expectedEndTime: '2024-10-20',
|
|
|
+ actualEndTime: '2024-10-20',
|
|
|
+ planDays: 16,
|
|
|
+ actualDays: 16,
|
|
|
+ completionRate: 100,
|
|
|
+ personCount: 1600
|
|
|
+ },
|
|
|
+ {
|
|
|
+ customerName: '泰安牧场',
|
|
|
+ productName: '智能膜环',
|
|
|
+ installer: '王建国',
|
|
|
+ planQuantity: 3500,
|
|
|
+ completedQuantity: 3500,
|
|
|
+ installStartTime: '2024-10-01',
|
|
|
+ expectedEndTime: '2024-10-25',
|
|
|
+ actualEndTime: '2024-10-23',
|
|
|
+ planDays: 25,
|
|
|
+ actualDays: 23,
|
|
|
+ completionRate: 109,
|
|
|
+ personCount: 1820
|
|
|
+ },
|
|
|
+ {
|
|
|
+ customerName: '云牧场',
|
|
|
+ productName: '精准阉割',
|
|
|
+ installer: '李明',
|
|
|
+ planQuantity: 2800,
|
|
|
+ completedQuantity: 2800,
|
|
|
+ installStartTime: '2024-09-15',
|
|
|
+ expectedEndTime: '2024-10-05',
|
|
|
+ actualEndTime: '2024-10-08',
|
|
|
+ planDays: 21,
|
|
|
+ actualDays: 24,
|
|
|
+ completionRate: 88,
|
|
|
+ personCount: 1550
|
|
|
+ },
|
|
|
+ {
|
|
|
+ customerName: '宝塔牧场二场',
|
|
|
+ productName: '佳沃评分',
|
|
|
+ installer: '张伟',
|
|
|
+ planQuantity: 1800,
|
|
|
+ completedQuantity: 1800,
|
|
|
+ installStartTime: '2024-09-10',
|
|
|
+ expectedEndTime: '2024-09-30',
|
|
|
+ actualEndTime: '2024-09-28',
|
|
|
+ planDays: 21,
|
|
|
+ actualDays: 19,
|
|
|
+ completionRate: 111,
|
|
|
+ personCount: 1680
|
|
|
+ },
|
|
|
+ {
|
|
|
+ customerName: '五河牧场',
|
|
|
+ productName: '智能喷淋',
|
|
|
+ installer: '刘强',
|
|
|
+ planQuantity: 2500,
|
|
|
+ completedQuantity: 2500,
|
|
|
+ installStartTime: '2024-08-20',
|
|
|
+ expectedEndTime: '2024-09-10',
|
|
|
+ actualEndTime: '2024-09-10',
|
|
|
+ planDays: 22,
|
|
|
+ actualDays: 22,
|
|
|
+ completionRate: 100,
|
|
|
+ personCount: 1450
|
|
|
+ },
|
|
|
+ {
|
|
|
+ customerName: '和祥牧场',
|
|
|
+ productName: '智能称重',
|
|
|
+ installer: '赵四',
|
|
|
+ planQuantity: 3200,
|
|
|
+ completedQuantity: 3200,
|
|
|
+ installStartTime: '2024-09-05',
|
|
|
+ expectedEndTime: '2024-09-25',
|
|
|
+ actualEndTime: '2024-09-22',
|
|
|
+ planDays: 21,
|
|
|
+ actualDays: 18,
|
|
|
+ completionRate: 117,
|
|
|
+ personCount: 1900
|
|
|
+ },
|
|
|
+ {
|
|
|
+ customerName: '现代牧业四场',
|
|
|
+ productName: '智能膜环',
|
|
|
+ installer: '孙立',
|
|
|
+ planQuantity: 4200,
|
|
|
+ completedQuantity: 4200,
|
|
|
+ installStartTime: '2024-08-15',
|
|
|
+ expectedEndTime: '2024-09-15',
|
|
|
+ actualEndTime: '2024-09-18',
|
|
|
+ planDays: 32,
|
|
|
+ actualDays: 35,
|
|
|
+ completionRate: 91,
|
|
|
+ personCount: 1650
|
|
|
+ },
|
|
|
+ {
|
|
|
+ customerName: '金牛牧场',
|
|
|
+ productName: '体况评分',
|
|
|
+ installer: '周强',
|
|
|
+ planQuantity: 2800,
|
|
|
+ completedQuantity: 2800,
|
|
|
+ installStartTime: '2024-09-20',
|
|
|
+ expectedEndTime: '2024-10-10',
|
|
|
+ actualEndTime: '2024-10-08',
|
|
|
+ planDays: 21,
|
|
|
+ actualDays: 19,
|
|
|
+ completionRate: 111,
|
|
|
+ personCount: 1580
|
|
|
+ },
|
|
|
+ {
|
|
|
+ customerName: '双峰牧场',
|
|
|
+ productName: '智能喷淋',
|
|
|
+ installer: '吴勇',
|
|
|
+ planQuantity: 3600,
|
|
|
+ completedQuantity: 3600,
|
|
|
+ installStartTime: '2024-10-01',
|
|
|
+ expectedEndTime: '2024-10-25',
|
|
|
+ actualEndTime: '2024-10-28',
|
|
|
+ planDays: 25,
|
|
|
+ actualDays: 28,
|
|
|
+ completionRate: 89,
|
|
|
+ personCount: 1750
|
|
|
+ }
|
|
|
+ ]
|
|
|
+ }
|
|
|
+ },
|
|
|
+ computed: {
|
|
|
+ displayData() {
|
|
|
+ return this.isExpanded ? this.tableData : this.tableData.slice(0, 10)
|
|
|
+ }
|
|
|
+ },
|
|
|
+ created() {
|
|
|
+ this.initFilterOptions()
|
|
|
+ },
|
|
|
+ methods: {
|
|
|
+ initFilterOptions() {
|
|
|
+ // 初始化货品选项
|
|
|
+ const products = [...new Set(this.tableData.map(item => item.productName))]
|
|
|
+ this.productOptions = products.map(product => ({
|
|
|
+ label: product,
|
|
|
+ value: product
|
|
|
+ }))
|
|
|
+
|
|
|
+ // 初始化月份选项
|
|
|
+ const months = ['1月', '2月', '3月', '4月', '5月', '6月', '7月', '8月', '9月', '10月', '11月', '12月']
|
|
|
+ this.monthOptions = months.map((month, index) => ({
|
|
|
+ label: month,
|
|
|
+ value: index + 1
|
|
|
+ }))
|
|
|
+
|
|
|
+ // 初始化人员选项
|
|
|
+ const personnel = [...new Set(this.tableData.map(item => item.installer))]
|
|
|
+ this.personnelOptions = personnel.map(person => ({
|
|
|
+ label: person,
|
|
|
+ value: person
|
|
|
+ }))
|
|
|
+
|
|
|
+ // 初始化客户选项
|
|
|
+ const customers = [...new Set(this.tableData.map(item => item.customerName))]
|
|
|
+ this.customerOptions = customers.map(customer => ({
|
|
|
+ label: customer,
|
|
|
+ value: customer
|
|
|
+ }))
|
|
|
+ },
|
|
|
+ handleFilterChange() {
|
|
|
+ // 处理筛选条件变化
|
|
|
+ console.log('Filter changed:', {
|
|
|
+ product: this.productFilter,
|
|
|
+ month: this.monthFilter,
|
|
|
+ personnel: this.personnelFilter,
|
|
|
+ customer: this.customerFilter
|
|
|
+ })
|
|
|
+ },
|
|
|
+ getWorkDaysColor(row) {
|
|
|
+ if (row.actualDays > row.planDays) {
|
|
|
+ return '#F56C6C' // 红色
|
|
|
+ } else if (row.actualDays < row.planDays) {
|
|
|
+ return '#67C23A' // 绿色
|
|
|
+ }
|
|
|
+ return '#409EFF' // 蓝色
|
|
|
+ },
|
|
|
+ getCompletionRateColor(row) {
|
|
|
+ if (row.completionRate < 100) {
|
|
|
+ return '#F56C6C' // 红色
|
|
|
+ } else if (row.completionRate > 100) {
|
|
|
+ return '#67C23A' // 绿色
|
|
|
+ }
|
|
|
+ return '#409EFF' // 蓝色
|
|
|
+ }
|
|
|
+ }
|
|
|
+}
|
|
|
+</script>
|
|
|
+
|
|
|
+<style lang="scss" scoped>
|
|
|
+.box-card {
|
|
|
+ margin-top: 20px;
|
|
|
+}
|
|
|
+
|
|
|
+.header-content {
|
|
|
+ display: flex;
|
|
|
+ justify-content: space-between;
|
|
|
+ align-items: center;
|
|
|
+}
|
|
|
+
|
|
|
+.header-title {
|
|
|
+ display: flex;
|
|
|
+ align-items: center;
|
|
|
+ gap: 8px;
|
|
|
+ font-size: 13px;
|
|
|
+
|
|
|
+ .update-time {
|
|
|
+ color: #666;
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+.filter-section {
|
|
|
+ display: flex;
|
|
|
+ gap: 10px;
|
|
|
+
|
|
|
+ .el-select {
|
|
|
+ width: 120px;
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+.expand-button {
|
|
|
+ text-align: center;
|
|
|
+ border-top: 1px solid #EBEEF5;
|
|
|
+ margin-top: -1px;
|
|
|
+
|
|
|
+ .el-button {
|
|
|
+ font-size: 13px;
|
|
|
+ color: #909399;
|
|
|
+ padding: 8px;
|
|
|
+
|
|
|
+ .button-content {
|
|
|
+ display: inline-flex;
|
|
|
+ align-items: center;
|
|
|
+ position: relative;
|
|
|
+
|
|
|
+ i {
|
|
|
+ font-size: 12px;
|
|
|
+ color: #C0C4CC;
|
|
|
+ transition: all 0.3s;
|
|
|
+ }
|
|
|
+
|
|
|
+ .expand-text {
|
|
|
+ max-width: 0;
|
|
|
+ overflow: hidden;
|
|
|
+ white-space: nowrap;
|
|
|
+ transition: all 0.3s ease-in-out;
|
|
|
+ opacity: 0;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ &:hover {
|
|
|
+ color: #409EFF;
|
|
|
+
|
|
|
+ .button-content {
|
|
|
+ i {
|
|
|
+ color: #409EFF;
|
|
|
+ margin-right: 4px;
|
|
|
+ }
|
|
|
+
|
|
|
+ .expand-text {
|
|
|
+ max-width: 100px;
|
|
|
+ opacity: 1;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+:deep(.el-table) {
|
|
|
+ font-size: 12px;
|
|
|
+
|
|
|
+ .el-table__header th {
|
|
|
+ padding: 8px 0;
|
|
|
+ background-color: #f5f7fa;
|
|
|
+ }
|
|
|
+
|
|
|
+ .el-table__body td {
|
|
|
+ padding: 8px 0;
|
|
|
+ background-color: #fff;
|
|
|
+ }
|
|
|
+
|
|
|
+ // 添加表格行的hover效果
|
|
|
+ .el-table__body tr:hover > td {
|
|
|
+ background-color: #f5f7fa !important;
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+// 添加表格内容的过渡效果
|
|
|
+:deep(.el-table__body-wrapper) {
|
|
|
+ transition: max-height 0.3s cubic-bezier(0.4, 0, 0.2, 1);
|
|
|
+}
|
|
|
+</style>
|