巡检日,周,月完成,数据概况待修改

This commit is contained in:
Zy
2026-04-22 16:05:44 +08:00
parent 48852a33ec
commit 04eb40d0e4
55 changed files with 1583 additions and 422 deletions

View File

@@ -0,0 +1,68 @@
import request from '@/utils/request';
import { AxiosPromise } from 'axios';
/**
* 查询巡检数据
* @param query
* @returns {*}
*/
export const listItem = (query?: Request): AxiosPromise<any[]> => {
return request({
url: '/inspection/data/list',
method: 'get',
params: query
});
};
export interface Request {
/**
* 进行中的任务数
*/
activeTask?: string;
/**
* 按时完成任务数
*/
completedTask?: string;
/**
* 创建时间
*/
createTime?: string;
/**
* 详细数据
*/
dataContent?: string;
/**
* 数据类型0-概况/1-日报/2-周报/3-月报/4-统计
*/
dataType?: string;
/**
* 巡检人员id
*/
inspectorId?: string;
/**
* 完成率
*/
onTimeRate?: string;
/**
* 超时完成数
*/
outCompletedTasks?: string;
/**
* 超时未完成数
*/
outUncompletedTasks?: string;
/**
* 未开始的任务数
*/
pendingTask?: string;
statDate?: string;
/**
* 总任务数
*/
totalTasks?: string;
/**
* 更新时间
*/
updateTime?: string;
[property: string]: any;
}

View File

@@ -29,31 +29,11 @@ export interface TaskVO {
*/
taskTime: string;
/**
* 巡检设置0-必须拍照1-可以跳检
*/
inspectSetting: number;
/**
* 费用单位
*/
costUnit: string;
/**
* 状态0-待执行1-执行中2-已完成3-已超时
*/
status: string;
/**
* 实际开始时间
*/
actualStartTime: string;
/**
* 实际结束时间
*/
actualEndTime: string;
/**
* 备注
*/
@@ -96,31 +76,11 @@ export interface TaskForm extends BaseEntity {
*/
taskTime?: string;
/**
* 巡检设置0-必须拍照1-可以跳检
*/
inspectSetting?: number;
/**
* 费用单位
*/
costUnit?: string;
/**
* 状态0-待执行1-执行中2-已完成3-已超时
*/
status?: string;
/**
* 实际开始时间
*/
actualStartTime?: string;
/**
* 实际结束时间
*/
actualEndTime?: string;
/**
* 备注
*/
@@ -158,11 +118,6 @@ export interface TaskQuery extends PageQuery {
*/
taskTime?: string;
/**
* 巡检设置0-必须拍照1-可以跳检
*/
inspectSetting?: number;
/**
* 费用单位
*/
@@ -173,16 +128,6 @@ export interface TaskQuery extends PageQuery {
*/
status?: string;
/**
* 实际开始时间
*/
actualStartTime?: string;
/**
* 实际结束时间
*/
actualEndTime?: string;
/**
* 提醒时间
*/

View File

@@ -4,7 +4,7 @@
* @param date2 结束日期
* @returns 相差天数(绝对值)
*/
export function diffDays(date1: string | Date, date2: string | Date): number {
export function diffDays(date1: string | Date = new Date(), date2: string | Date = new Date()): number {
const d1 = new Date(date1);
const d2 = new Date(date2);
// 转为时间戳并取绝对值
@@ -12,6 +12,28 @@ export function diffDays(date1: string | Date, date2: string | Date): number {
// 一天的毫秒数
return Math.floor(diff / (1000 * 60 * 60 * 24));
}
/**
* 计算两个日期之间的自然日相差天数
* 规则:同一天 = 0昨天 = 1前天 = 2以此类推
* 忽略时分秒,纯日期对比
* @param date1 日期1默认为当前日期
* @param date2 日期2默认为当前日期
* @returns 自然日相差天数(非负整数)
* @example getNaturalDayDiff(今日, 今日) => 0
* @example getNaturalDayDiff(今日, 昨日) => 1
*/
export function getNaturalDayDiff(date1: string | Date = new Date(), date2: string | Date = new Date()): number {
const getDateTimestamp = (date: string | Date) => {
const d = new Date(date);
d.setHours(0, 0, 0, 0);
return d.getTime();
};
const time1 = getDateTimestamp(date1);
const time2 = getDateTimestamp(date2);
return Math.floor(Math.abs(time1 - time2) / (1000 * 60 * 60 * 24));
}
/**
* 格式化两个时间的差值,自动显示 年/月/天/时/分/秒
@@ -134,3 +156,108 @@ export const getLast7Days = (days = 7) => {
}
return dates;
};
/**
* 高性能生成从指定结束日期向前追溯 N 天的连续日期数组
* 规则0=今天1=昨天2=前天,以此类推
* 支持自定义日期格式YYYY/MM/DD/HH/mm/ss或传入格式化函数
* 优化正则模板仅编译1次、时间戳计算、数组预分配无性能损耗
* @category 日期工具
* @param days 向前追溯天数0=今天1=昨天,默认 30 天
* @param endDate 结束日期,支持 Date 对象 / 日期字符串,默认当前日期
* @param format 日期格式化规则,支持模板字符串或自定义格式化函数,默认 'YYYY-MM-DD'
* 支持模板占位符YYYY(年)、MM(月)、DD(日)、HH(时)、mm(分)、ss(秒)
* @returns 格式化后的日期字符串数组(按时间正序排列)
* @example
* // 获取今天
* getLastNDays(0)
* @example
* // 获取昨天
* getLastNDays(1)
* @example
* // 最近7天含今天
* getLastNDays(7)
*/
export function getLastNDays(
days: number = 30,
endDate: Date | string = new Date(),
format: string | ((date: Date) => string) = 'YYYY-MM-DD'
): string[] {
// 非法天数校验
if (!Number.isInteger(days) || days < 0) {
console.warn('getLastNDays: days 必须是大于等于 0 的整数');
return [];
}
// 安全解析结束日期,并【重置时分秒为 00:00:00】— 关键修复
const end = new Date(endDate);
if (isNaN(end.getTime())) {
console.warn('getLastNDays: 无效日期,已自动使用当前时间');
end.setTime(Date.now());
}
// ✅ 修复:统一把时间设为 00:00:00避免跨天计算错误
end.setHours(0, 0, 0, 0);
const endTime = end.getTime();
const oneDay = 86400000;
// 提前编译格式化函数(核心性能优化:正则只编译一次)
let formatter: (date: Date) => string;
if (typeof format === 'function') {
formatter = format;
} else {
formatter = (date: Date) => {
const YYYY = date.getFullYear().toString();
const MM = String(date.getMonth() + 1).padStart(2, '0');
const DD = String(date.getDate()).padStart(2, '0');
const HH = String(date.getHours()).padStart(2, '0');
const mm = String(date.getMinutes()).padStart(2, '0');
const ss = String(date.getSeconds()).padStart(2, '0');
return format.replace(/YYYY/g, YYYY).replace(/MM/g, MM).replace(/DD/g, DD).replace(/HH/g, HH).replace(/mm/g, mm).replace(/ss/g, ss);
};
}
// 生成日期
const result: string[] = [];
for (let i = 0; i <= days; i++) {
const currentDate = new Date(endTime - i * oneDay);
result.push(formatter(currentDate));
}
// 正序返回
return result.reverse();
}
/**
* 格式化 Date 对象为指定格式的字符串
* 高性能正则解析,支持任意分隔符,仅编译一次模板
* @param date 要格式化的日期,默认:当前时间 new Date()
* @param format 格式化模板默认YYYY-MM-DD
* 支持占位符YYYY(年)、MM(月)、DD(日)、HH(时)、mm(分)、ss(秒)
* @returns 格式化后的日期字符串
* @category 日期工具
* @example
* formatDate() // 今天 → 2025-12-20
* @example
* formatDate(new Date(), 'YYYY年MM月DD日')
* @example
* formatDate(new Date(), 'YYYY-MM-DD HH:mm:ss')
*/
export function formatDate(date: Date | string = new Date(), format: string = 'YYYY-MM-DD'): string {
// 解析并校验日期
const d = new Date(date);
if (isNaN(d.getTime())) {
console.warn('formatDate: 无效日期,返回空字符串');
return '';
}
// 获取并补零
const YYYY = d.getFullYear().toString();
const MM = String(d.getMonth() + 1).padStart(2, '0');
const DD = String(d.getDate()).padStart(2, '0');
const HH = String(d.getHours()).padStart(2, '0');
const mm = String(d.getMinutes()).padStart(2, '0');
const ss = String(d.getSeconds()).padStart(2, '0');
// 正则替换(通用、无需穷举)
return format.replace(/YYYY/g, YYYY).replace(/MM/g, MM).replace(/DD/g, DD).replace(/HH/g, HH).replace(/mm/g, mm).replace(/ss/g, ss);
}

View File

@@ -5,7 +5,6 @@
<navbar ref="navbarRef" />
</div>
<div class="container AddBuildingBox">
<PageHeader :title="isedit ? '编辑小区' : '添加小区'"> </PageHeader>
<el-form inline class="formBody" ref="formRef" :model="form" :rules="rules" label-width="100px">
<div class="AddBuildingBody">
<div class="title">基本信息</div>
@@ -112,7 +111,6 @@
<script setup lang="ts">
import Navbar from '@/layout/components/Navbar.vue';
import { ref } from 'vue';
import PageHeader from '@/components/Pageheader/index.vue';
import { pcaTextArr } from 'element-china-area-data';
import type { DataItem } from 'element-china-area-data';
import { useUserStore } from '@/store/modules/user';
@@ -364,7 +362,7 @@ const cancelForm = () => {
align-items: center;
height: 50px;
line-height: 50px;
background: linear-gradient(180deg, #deedff 0%, #f8f9fe 50%);
background: transparent;
& > div {
flex: 1;
}
@@ -372,6 +370,7 @@ const cancelForm = () => {
padding-left: 20px;
font-size: 20px;
color: white;
color: #000;
}
}
}

View File

@@ -4,11 +4,10 @@
<span class="">智慧物业后台管理系统</span>
<navbar ref="navbarRef" />
</div>
<div class="container">
<div class="containerbox">
<div class="community_nav_box">
<div class="currentbox">当前小区:{{ currentViliageInfo && currentViliageInfo.villageName }}</div>
<div class="subtitle flex align-center">
<div class="line"></div>
<div class="changecommunity">切换小区</div>
</div>
</div>
@@ -51,7 +50,7 @@ import { deleteVillageByIdAPI, switchVillageAPI, getCommunitylistAPI } from '@/a
import type { communitylist_rows_type } from '@/api/system/community/type';
import { Picture } from '@element-plus/icons-vue';
import { useHouseStore } from '@/store/modules/house';
import { splitImages } from '@/utils';
const houseStore = useHouseStore();
const router = useRouter();
const list = ref<communitylist_rows_type[]>([]);
@@ -60,6 +59,11 @@ const currentViliageInfo = ref<communitylist_rows_type>();
function getlist() {
getCommunitylistAPI().then((res) => {
list.value = res.rows;
const villageid = localStorage.getItem('villageid');
const find = list.value.find((item) => item.villageId === Number(villageid));
if (find) {
currentViliageInfo.value = find;
}
});
}
getlist();
@@ -154,15 +158,15 @@ function handleclick(item: communitylist_rows_type) {
height: 200px;
background: #fff;
}
.container {
width: 100%;
.containerbox {
width: 85%;
margin: 0 auto;
padding: 20px;
background: transparent;
.community_nav_box {
height: 98px;
border-radius: 5px;
background-color: rgba(255, 255, 255, 1);
background: linear-gradient(180deg, rgba(255, 255, 255, 0.2) 0%, #ffffff 70%);
border-radius: 16px 16px 16px 16px;
padding: 20px;
.currentbox {
height: 20px;
@@ -191,57 +195,68 @@ function handleclick(item: communitylist_rows_type) {
.communityBody {
padding: 20px;
color: #000;
display: flex;
flex-wrap: wrap;
display: grid;
grid-template-columns: repeat(5, minmax(292px, 1fr));
@media (max-width: 1540px) {
grid-template-columns: repeat(4, minmax(292px, 1fr));
grid-template-columns: repeat(5, 1fr);
@media (max-width: 1900px) {
grid-template-columns: repeat(4, 1fr);
}
@media (max-width: 1280px) {
grid-template-columns: repeat(3, minmax(292px, 1fr));
}
@media (max-width: 1030px) {
grid-template-columns: repeat(2, minmax(292px, 1fr));
@media (max-width: 1500px) {
grid-template-columns: repeat(3, 1fr);
}
.coummunity_card {
height: 300px;
border: 1px solid #ccc;
border-radius: 5px;
background-color: rgba(255, 255, 255, 1);
margin-right: 10px;
min-width: 369px;
max-width: 369px;
min-height: 358px;
border: 2px solid #ffffff;
background: linear-gradient(180deg, rgba(255, 255, 255, 0.2) 0%, #ffffff 70%);
box-shadow: 0px 4px 8px 0px rgba(0, 104, 255, 0.06);
border-radius: 16px 16px 16px 16px;
margin-right: 20px;
margin-bottom: 15px;
overflow: hidden;
display: flex;
flex-direction: column;
&:hover {
box-shadow: 0 0 10px rgba(0, 0, 0, 0.1);
}
.el-image {
height: 200px;
height: 179px;
width: 100%;
object-fit: cover;
}
.coummunityaction_box {
flex: 1;
padding: 10px 5px;
font-size: 15px;
padding: 30px;
font-weight: 500;
font-size: 20px;
color: #303133;
line-height: 25px;
.counmmunityaddress {
margin-top: 20px;
font-size: small;
color: #ccc;
margin-top: 10px;
font-weight: 400;
font-size: 16px;
color: #666666;
line-height: 20px;
}
}
.actions {
height: 30px;
line-height: 30px;
height: 60px;
div {
border-top: 1px solid #ccc;
border-right: 1px solid #ccc;
flex: 1;
text-align: center;
font-size: small;
color: #4791ff;
cursor: pointer;
line-height: 60px;
font-weight: 500;
font-size: 18px;
color: #036aff;
&:hover {
background-color: #f5f7fb;
}

View File

@@ -1,5 +1,6 @@
<template>
<div class="flex flex-col h-full p-2">
<Pageheader></Pageheader>
<transition :enter-active-class="proxy?.animate.searchAnimate.enter" :leave-active-class="proxy?.animate.searchAnimate.leave">
<div v-show="showSearch" class="mb-[10px]">
<el-card shadow="hover">

View File

@@ -27,6 +27,11 @@
<el-table v-loading="loading" border :data="electricityDeviceList" @selection-change="handleSelectionChange">
<el-table-column type="selection" width="55" align="center" />
<el-table-column label="设备编码" align="center" prop="deviceCode" />
<el-table-column label="户号" align="center" prop="address">
<template #default="{ $index }">
{{ huhao + $index }}
</template>
</el-table-column>
<el-table-column label="设备状态" align="center">
<template #default="scope">
<DictTag :options="com_waterdevice_on_status" :value="scope.row.status"></DictTag>
@@ -63,7 +68,7 @@
<span>{{ scope.row.waterRecord ? scope.row.waterRecord.readTime : '--' }}</span>
</template>
</el-table-column>
<el-table-column label="设备地址" align="center" prop="address" />
<el-table-column label="操作" align="center" fixed="right">
<template #default="scope">
<el-button link type="primary" @click="handleProject(scope.row)">生成二维码</el-button>
@@ -114,7 +119,7 @@ import {
} from '@/api/system/SdbElectricityDevice/index';
import { ElectricityDeviceVO, ElectricityDeviceQuery, ElectricityDeviceForm } from '@/api/system/SdbElectricityDevice/type';
import { splitImages } from '@/utils';
const huhao = 9649998338;
const { proxy } = getCurrentInstance() as ComponentInternalInstance;
const { com_waterdevice_on_status } = toRefs<any>(proxy?.useDict('com_waterdevice_on_status'));
const { com_electricity_readrecord_status } = toRefs<any>(proxy?.useDict('com_electricity_readrecord_status'));

View File

@@ -27,7 +27,11 @@
<el-table v-loading="loading" border :data="waterDeviceList" @selection-change="handleSelectionChange">
<el-table-column type="selection" width="55" align="center" />
<el-table-column label="水表设备编码" align="center" prop="deviceCode" />
<el-table-column label="地址" align="center" prop="address" />
<el-table-column label="户号" align="center" prop="address">
<template #default="{ $index }">
{{ huhao + $index }}
</template>
</el-table-column>
<el-table-column label="设备状态" align="center" prop="deleted">
<template #default="scope">
<dict-tag :options="com_waterdevice_on_status" :value="scope.row.deleted"></dict-tag>
@@ -95,6 +99,8 @@
import { listWaterDevice, getWaterDevice, delWaterDevice, addWaterDevice, updateWaterDevice } from '@/api/system/SdbWaterDevice/index';
import { WaterDeviceVO, WaterDeviceQuery, WaterDeviceForm } from '@/api/system/SdbWaterDevice/type';
const huhao = 3096371295;
const { proxy } = getCurrentInstance() as ComponentInternalInstance;
const { com_waterdevice_on_status } = toRefs<any>(proxy?.useDict('com_waterdevice_on_status'));

View File

@@ -21,7 +21,7 @@
</div>
</template>
</PageHeader>
<div class="houseBody mt-10px w-full flex align-center justify-center">
<div class="houseBody w-full flex align-center justify-center">
<building></building>
<unit></unit>
</div>
@@ -51,6 +51,7 @@ houseStore.initHouse(houseStore.buildingtype);
min-height: calc(100vh - 84px);
.houseBody {
height: calc(100% - 200px);
margin-top: 10px;
}
}
.houseAdressBox {

View File

@@ -1,12 +1,110 @@
<template>
<div class="p-2 h-full flex flex-col">
<div class="h-full flex flex-col p-2">
<Pageheader></Pageheader>
<div class="flex-1 color-gray flex h-full font-size-6 flex-center">系统还在维护中敬请期待...</div>
<transition :enter-active-class="proxy?.animate.searchAnimate.enter" :leave-active-class="proxy?.animate.searchAnimate.leave">
<div v-show="showSearch" class="mb-[10px]">
<el-card shadow="hover">
<el-form ref="queryFormRef" :model="queryParams" :inline="true">
<el-form-item label="选择日期" prop="statDate">
<el-date-picker
v-model="starDate"
type="daterange"
unlink-panels
range-separator=""
start-placeholder="开始日期"
end-placeholder="结束日期"
format="YYYY/MM/DD"
value-format="YYYY/MM/DD"
/>
</el-form-item>
<el-form-item>
<el-button type="primary" icon="Search" @click="handleQuery">搜索</el-button>
<el-button icon="Refresh" @click="resetQuery">重置</el-button>
</el-form-item>
</el-form>
</el-card>
</div>
</transition>
<el-card class="flex-1" shadow="never">
<template #header>
<el-row :gutter="10">
<el-col :span="1.5">
<span style="font-size: 1.2rem">日报列表</span>
</el-col>
<right-toolbar v-model:showSearch="showSearch" @queryTable="getList"></right-toolbar>
</el-row>
</template>
<el-table v-loading="loading" border :data="itemList">
<el-table-column label="日期" width="100" align="center" prop="statDate" />
<el-table-column label="计划巡检任务" width="120" align="center" prop="totalPlans" />
<el-table-column label="按时完成" align="center" prop="completedTasks" />
<el-table-column label="超时完成" align="center" prop="outCompletedTasks" />
<el-table-column label="超时未完成" align="center" prop="outUncompletedTasks" />
<el-table-column label="进行中" align="center" prop="activeTask" />
<el-table-column label="未开始" align="center" prop="pendingTask" />
</el-table>
<pagination v-show="total > 0" :total="total" v-model:page="queryParams.pageNum" v-model:limit="queryParams.pageSize" @pagination="getList" />
</el-card>
</div>
</template>
<script setup lang="ts">
import { ref } from 'vue';
<script setup name="Item" lang="ts">
import { listItem, type Request } from '@/api/system/Inspection/index';
const { proxy } = getCurrentInstance() as ComponentInternalInstance;
const itemList = ref<any[]>([]);
const loading = ref(true);
const showSearch = ref(true);
const total = ref(0);
const queryFormRef = ref<ElFormInstance>();
const data = reactive<{
queryParams: Request;
}>({
queryParams: {
pageNum: 1,
pageSize: 10,
statDate: '',
dataType: '1' // 1 日报
}
});
const starDate = ref([]);
const { queryParams } = toRefs(data);
/** 查询巡检项目列表 */
const getList = async () => {
queryParams.value.statDate = starDate.value.join('-');
loading.value = true;
const res = await listItem(queryParams.value);
itemList.value = res.rows;
total.value = res.total;
loading.value = false;
};
/** 搜索按钮操作 */
const handleQuery = () => {
queryParams.value.pageNum = 1;
getList();
};
/** 重置按钮操作 */
const resetQuery = () => {
queryFormRef.value?.resetFields();
starDate.value = [];
handleQuery();
};
onMounted(() => {
getList();
});
</script>
<style scoped lang="scss"></style>
<style lang="scss" scoped>
.el-table {
height: calc(100% - 80px);
}
</style>

View File

@@ -1,12 +1,110 @@
<template>
<div class="p-2 h-full flex flex-col">
<div class="h-full flex flex-col p-2">
<Pageheader></Pageheader>
<div class="flex-1 color-gray flex h-full font-size-6 flex-center">系统还在维护中敬请期待...</div>
<transition :enter-active-class="proxy?.animate.searchAnimate.enter" :leave-active-class="proxy?.animate.searchAnimate.leave">
<div v-show="showSearch" class="mb-[10px]">
<el-card shadow="hover">
<el-form ref="queryFormRef" :model="queryParams" :inline="true">
<el-form-item label="选择日期" prop="itemName">
<el-date-picker
v-model="starDate"
type="daterange"
unlink-panels
range-separator=""
start-placeholder="开始日期"
end-placeholder="结束日期"
format="YYYY/MM/DD"
value-format="YYYY/MM/DD"
/>
</el-form-item>
<el-form-item>
<el-button type="primary" icon="Search" @click="handleQuery">搜索</el-button>
<el-button icon="Refresh" @click="resetQuery">重置</el-button>
</el-form-item>
</el-form>
</el-card>
</div>
</transition>
<el-card class="flex-1" shadow="never">
<template #header>
<el-row :gutter="10">
<el-col :span="1.5">
<span style="font-size: 1.2rem">月报列表</span>
</el-col>
<right-toolbar v-model:showSearch="showSearch" @queryTable="getList"></right-toolbar>
</el-row>
</template>
<el-table v-loading="loading" border :data="itemList">
<el-table-column label="日期" width="100" align="center" prop="statDate" />
<el-table-column label="计划巡检任务" width="120" align="center" prop="totalPlans" />
<el-table-column label="按时完成" align="center" prop="completedTasks" />
<el-table-column label="超时完成" align="center" prop="outCompletedTasks" />
<el-table-column label="超时未完成" align="center" prop="outUncompletedTasks" />
<el-table-column label="进行中" align="center" prop="activeTask" />
<el-table-column label="未开始" align="center" prop="pendingTask" />
</el-table>
<pagination v-show="total > 0" :total="total" v-model:page="queryParams.pageNum" v-model:limit="queryParams.pageSize" @pagination="getList" />
</el-card>
</div>
</template>
<script setup lang="ts">
import { ref } from 'vue';
<script setup name="Item" lang="ts">
import { listItem, type Request } from '@/api/system/Inspection/index';
const { proxy } = getCurrentInstance() as ComponentInternalInstance;
const itemList = ref<any[]>([]);
const loading = ref(true);
const showSearch = ref(true);
const total = ref(0);
const queryFormRef = ref<ElFormInstance>();
const starDate = ref([]);
const data = reactive<{
queryParams: Request;
}>({
queryParams: {
pageNum: 1,
pageSize: 10,
dataType: '3' // 1 日报 3 月报
}
});
const { queryParams } = toRefs(data);
/** 查询巡检项目列表 */
const getList = async () => {
queryParams.value.statDate = starDate.value.join('-');
loading.value = true;
const res = await listItem(queryParams.value);
itemList.value = res.rows;
total.value = res.total;
loading.value = false;
};
/** 搜索按钮操作 */
const handleQuery = () => {
queryParams.value.pageNum = 1;
getList();
};
/** 重置按钮操作 */
const resetQuery = () => {
queryFormRef.value?.resetFields();
starDate.value = [];
handleQuery();
};
onMounted(() => {
getList();
});
</script>
<style scoped lang="scss"></style>
<style lang="scss" scoped>
.el-table {
height: calc(100% - 80px);
}
</style>

View File

@@ -1,13 +1,367 @@
<template>
<div class="p-2 h-full flex flex-col">
<PageHeader></PageHeader>
<div class="flex-1 color-gray flex h-full font-size-6 flex-center">系统还在维护中敬请期待...</div>
<div class="h-full flex flex-col p-2">
<transition :enter-active-class="proxy?.animate.searchAnimate.enter" :leave-active-class="proxy?.animate.searchAnimate.leave">
<div v-show="showSearch" class="mb-[10px]">
<el-card shadow="hover">
<div>
<div class="flex flex-items-center justify-between">
<div>
<div class="line"></div>
<div class="metatitle">巡更数据概况</div>
</div>
<div class="rightSearch flex flex-items-center justify-around">
<div>选择日期</div>
<el-date-picker
v-model="statDate"
value-format="YYYY/MM/DD"
format="YYYY/MM/DD"
@update:model-value="handleStateDate"
type="date"
placeholder="选择日期"
:disabled-date="disabledDate"
/>
<i @click="handleQueryDay(0)">今日</i>
<i @click="handleQueryDay(1)">昨日</i>
<i @click="handleQueryDay(7)">近7天</i>
<i @click="handleQueryDay(30)">近30日</i>
</div>
</div>
<div class="overviewBox">
<el-card v-for="(item, index) in list" :key="index">
<div class="overviewitem">
<div class="overviewitem_name">{{ item.name }}</div>
<div class="overviewitem_value">{{ item.value }}</div>
</div>
</el-card>
</div>
</div>
</el-card>
</div>
</transition>
<el-card class="flex-1" shadow="never">
<template #header>
<span style="font-size: 1.2rem">数据统计 </span>
</template>
<el-row :gutter="10" class="h-full">
<el-col :span="10">
<div class="echartsbox flex h-full flex-col">
<div class="echartsactions">
<div
@click="handleEcartsData(item)"
:class="{ active: activeEchartsindex === item.key }"
class="echartsactions_item"
v-for="(item, index) in ecartslist"
:key="index"
>
{{ item.name }}
</div>
</div>
<div class="echartsbody flex-1">
<EchartsCompontent :options="options"></EchartsCompontent>
</div>
</div>
</el-col>
<el-col :span="14">
<el-table v-loading="loading" border :data="itemList">
<el-table-column label="日期" width="100" align="center" prop="statDate" />
<el-table-column label="计划巡检任务" width="120" align="center" prop="totalPlans" />
<el-table-column label="按时完成" align="center" prop="completedTasks" />
<el-table-column label="超时完成" align="center" prop="outCompletedTasks" />
<el-table-column label="超时未完成" align="center" prop="outUncompletedTasks" />
<el-table-column label="进行中" align="center" prop="activeTask" />
<el-table-column label="未开始" align="center" prop="pendingTask" />
</el-table>
<pagination
v-show="total > 0"
:total="total"
v-model:page="queryParams.pageNum"
v-model:limit="queryParams.pageSize"
@pagination="getList"
/>
</el-col>
</el-row>
</el-card>
</div>
</template>
<script setup lang="ts">
import { ref } from 'vue';
import PageHeader from '@/components/Pageheader/index.vue';
<script setup name="Item" lang="ts">
import EchartsCompontent from '@/components/Echarts/index.vue';
import { listItem, type Request } from '@/api/system/Inspection/index';
import { getNaturalDayDiff, getLast7Days, getLastNDays, diffDays, formatDate } from '@/utils/time';
import { EChartsOption } from 'echarts';
const { proxy } = getCurrentInstance() as ComponentInternalInstance;
const itemList = ref<any[]>([]);
const loading = ref(true);
const showSearch = ref(true);
const total = ref(0);
const queryFormRef = ref<ElFormInstance>();
const disabledDate = (time: Date) => {
return time.getTime() > Date.now();
};
const statDate = ref('');
const data = reactive<{
queryParams: Request;
}>({
queryParams: {
pageNum: 1,
pageSize: 10,
statDate: '',
dataType: '0' // 0 总览 1 日报 3 月报
}
});
const list = ref([
{
name: '计划数量',
key: 'totalPlans',
value: 20
},
{
name: '任务数量',
key: 'totalPlans',
value: 200
},
{
name: '任务完成数量',
key: 'UncompletedTasks',
value: 40
},
{
name: ' 完成率',
key: 'onTimeRateDisplay',
value: '20%'
},
{
name: '未完成数量',
key: 'outUncompletedTasks',
value: 40
}
]);
// ! echarts =================================================================
const activeEchartsindex = ref('totalTasks');
const ecartslist = ref([
{
name: '全部任务',
key: 'totalTasks',
color: '#1a75ff',
offsetbottomColor: '#f2f9ff'
},
{
name: '按时完成',
key: 'completedTasks',
color: '#42b983',
offsetbottomColor: '#c6eada'
},
{
name: '超时未完成',
key: 'outUncompletedTasks',
color: '#f83333',
offsetbottomColor: '#fed6d6'
},
{
name: '进行中',
key: 'activeTask',
color: '#9d33f8',
offsetbottomColor: '#ebd6fe'
},
{
name: '未开始',
key: 'pendingTask',
color: '#909399',
offsetbottomColor: 'rgb(233, 233, 235)'
}
]);
const options = computed<EChartsOption>(() => ({
grid: {
left: '1%',
right: '1%',
top: '10%',
bottom: '1%',
containLabel: true
},
xAxis: { data: xAxislist.value },
yAxis: { type: 'value' as const },
tooltip: { trigger: 'axis' as const },
series: activeSeries.value // 动态系列
}));
//
const diffday = ref(0);
const activeSeries = ref();
const xAxislist = ref([]);
function handleEcartsOptions(data, name, colorlist = ['#1a75ff', '#f2f9ff']) {
const obj = {
data: data,
type: 'line' as const,
smooth: true,
name: name,
areaStyle: {
color: {
type: 'linear',
x: 0,
y: 0,
x2: 0,
y2: 1, // 从上到下渐变
colorStops: colorlist.map((item, index) => {
return {
offset: index / colorlist.length,
color: item
};
})
}
},
lineStyle: {
color: colorlist[0]
},
itemStyle: {
color: colorlist[0]
},
label: {
show: true,
color: colorlist[0],
position: 'top'
}
};
activeSeries.value = obj;
}
function handleEcartsData(row: (typeof ecartslist.value)[number]) {
if (row) {
xAxislist.value = [];
// 避免修改原数组,创建副本排序
const sortedList = [...itemList.value].sort((a, b) => new Date(a.statDate).getTime() - new Date(b.statDate).getTime());
console.log(sortedList);
// 创建日期到值的映射,标准化日期格式(假设 statDate 为 '2024-04-16 00:00:00'截取前10位
const dataMap = new Map<string, number>();
sortedList.forEach((item) => {
const dateKey = item.statDate.split(' ')[0]; // 截取 'YYYY-MM-DD'
dataMap.set(dateKey, Number(item[row.key]) || 0); // 确保为数字
});
// 根据 x 轴日期生成数据数组
console.log(diffday.value);
const xAxisDates = getLastNDays(diffday.value, undefined, 'YYYY.MM.DD'); // 确保格式为 ['2024-04-16', ...]
const arr = xAxisDates.map((date) => dataMap.get(date) || 0);
xAxislist.value = xAxisDates;
console.log('xAxisDates:', xAxisDates); // 调试
console.log('dataMap:', dataMap); // 调试
console.log('arr:', arr); // 调试
activeSeries.value = null;
handleEcartsOptions(arr, row.name, [row.color, row.offsetbottomColor]);
}
}
function handleStateDate(val) {
console.log(diffDays(val));
diffday.value = diffDays(val);
queryParams.value.statDate = `${formatDate(new Date(val), 'YYYY/MM/DD')}-${formatDate(new Date(), 'YYYY/MM/DD')}`;
getList();
}
// ! echarts =================================================================
const day = 1000 * 60 * 60 * 24;
function handleQueryDay(val: number) {
const newday = new Date(); // 当前日期
const time = new Date(newday.getTime() - val * day); // 指定日期
console.log(time, newday);
diffday.value = val; // 差值
diffday.value = getNaturalDayDiff(time, newday);
queryParams.value.statDate = formatDate(time, 'YYYY/MM/DD');
getList();
}
const { queryParams } = toRefs(data);
/** 查询巡检项目列表 */
const getList = async () => {
loading.value = true;
const res = await listItem(queryParams.value);
itemList.value = res.rows;
handleEcartsData(ecartslist.value[0]);
total.value = res.total;
loading.value = false;
};
onMounted(() => {
// getList();
handleQueryDay(7);
});
</script>
<style scoped lang="scss"></style>
<style lang="scss" scoped>
.el-table {
height: calc(100% - 80px);
}
.rightSearch {
div {
width: 60px;
}
i {
margin: 0 10px;
display: block;
padding: 5px 5px;
font-style: normal;
&:hover {
color: #409eff;
}
}
}
.overviewBox {
display: flex;
flex-wrap: nowrap;
align-items: center;
justify-content: space-between;
margin-top: 40px;
.overviewitem {
min-width: 150px;
padding: 5px -5px;
.overviewitem_name {
color: rgba(102, 102, 102, 1);
font-size: 12px;
}
.overviewitem_value {
color: rgba(51, 51, 51, 1);
font-size: 24px;
font-weight: 500;
margin-top: 10px;
}
}
}
.echartsbox {
.echartsactions {
display: flex;
align-items: center;
margin-bottom: 20px;
.echartsactions_item {
height: 40px;
line-height: 40px;
width: 100px;
text-align: center;
border: 1px solid rgba(220, 223, 230, 1);
color: rgba(16, 16, 16, 1);
border-left: none;
&:first-of-type {
border-radius: 4px 0px 0px 0px;
border-left: 1px solid rgba(220, 223, 230, 1);
}
&:last-of-type {
border-radius: 0px 4px 0px 0px;
}
&.active {
color: #fff;
background-color: rgba(26, 117, 255, 1);
}
}
}
}
</style>

View File

@@ -10,24 +10,6 @@
<el-form-item label="巡检计划名称" prop="planName">
<el-input v-model="form.planName" placeholder="请输入"></el-input>
</el-form-item>
<el-form-item label="巡检人员" prop="inspectorIds">
<div class="inspectorIdsBox">
<div v-for="(item, index) in checkoutUserlist" :key="index" class="inspector_items">
<div class="name">{{ item.nickName }}</div>
<i @click="handleDelete" class="deleteaction">
<el-icon><Delete /></el-icon>
</i>
</div>
<RepairUser @change="handleUserChange" returnvalue="*" :is-multiple="true" user-type="inspection" ref="RepairUserRef">
<template #default>
<div @click="handleAddUser" class="inspector_items add flex flex-items-center justify-center">
<el-icon><Plus /></el-icon>
<span class="ml-10px"> 添加 </span>
</div>
</template>
</RepairUser>
</div>
</el-form-item>
<el-form-item label="执行周期">
<el-date-picker
@update:model-value="handleTime"

View File

@@ -38,7 +38,6 @@
<el-table v-loading="loading" border :data="planList" @selection-change="handleSelectionChange">
<el-table-column type="selection" width="55" align="center" />
<el-table-column label="巡检计划名称" align="center" prop="planName" />
<el-table-column label="巡检人员" align="center" prop="inspectorNames" show-overflow-tooltip />
<el-table-column label="执行周期" align="center" prop="executeCycle" />
<el-table-column label="执行星期" align="center">
<template #default="scope">
@@ -146,7 +145,6 @@ const getList = async () => {
planList.value = res.rows;
planList.value.forEach((item) => {
item.routeNames = item.routeList.map((item) => item.routeName).join(',');
item.inspectorNames = item.inspectorList.map((item2) => item2.nickName).join(',');
item.executeDayNames = item.executeDay
.split(',')
.sort((a, b) => Number(a) - Number(b))

View File

@@ -74,7 +74,18 @@ const router = useRouter();
const route = useRoute();
const formRef = ref();
const form = ref<RecordVO>();
const form = ref<RecordVO>({
taskName: '',
inspectorName: '',
planName: '',
actualStartTime: '',
actualEndTime: '',
statusLabel: '',
createByName: '',
details: [],
createTime: '',
updateTime: ''
});
const userid = ref(null);
if (route.query.id) {
userid.value = route.query.id;

View File

@@ -170,7 +170,7 @@ const router = useRouter();
/** 新增按钮操作 */
const handleAdd = () => {
router.push({
path: '/Inspection/InspectionRecordMain'
path: '/Inspection/RecordMain'
});
};

View File

@@ -0,0 +1,12 @@
<template>
<div class="p-2 h-full flex flex-col">
<Pageheader></Pageheader>
<div class="flex-1 color-gray flex h-full font-size-6 flex-center">系统还在维护中敬请期待...</div>
</div>
</template>
<script setup lang="ts">
import { ref } from 'vue';
</script>
<style scoped lang="scss"></style>

View File

@@ -0,0 +1,354 @@
<template>
<div class="p-2">
<PageHeader></PageHeader>
<div class="EditBody">
<div class="title">
<div>基本信息</div>
</div>
<div class="bodybox">
<el-form ref="formRef" :model="form" :rules="rules" label-width="120px" label-position="right">
<el-form-item label="任务名称" prop="taskName">
<el-input v-model="form.taskName" placeholder="请输入"></el-input>
</el-form-item>
<el-form-item label="巡检人员" prop="inspectorIds">
<div class="inspectorIdsBox">
<div v-for="(item, index) in checkoutUserlist" :key="index" class="inspector_items">
<div class="name">{{ item.nickName }}</div>
<i @click="handleDelete" class="deleteaction">
<el-icon><Delete /></el-icon>
</i>
</div>
<RepairUser @change="handleUserChange" returnvalue="*" :is-multiple="true" user-type="inspection" ref="RepairUserRef">
<template #default>
<div @click="handleAddUser" class="inspector_items add flex flex-items-center justify-center">
<el-icon><Plus /></el-icon>
<span class="ml-10px"> 添加 </span>
</div>
</template>
</RepairUser>
</div>
</el-form-item>
<el-form-item label="巡更日期" prop="taskTime">
<el-date-picker placeholder="年/月/日" v-model="form.taskTime" type="date" format="YYYY-MM-DD" value-format="YYYY-MM-DD" />
</el-form-item>
<el-form-item label="提醒时间" prop="remindTime">
<el-select v-model="form.remindTime" placeholder="请选择" style="width: 100%">
<el-option v-for="item in remindTimeoptions" :key="item.value" :label="item.label" :value="item.value" />
</el-select>
</el-form-item>
<!-- <el-form-item label="巡检设置">
<el-checkbox-group @change="handleChagneSetting" v-model="Settinglist">
<el-checkbox v-for="(item, index) in com_inspection_plan_setting" :key="index" :label="item.label" :value="item.value" />
</el-checkbox-group>
</el-form-item> -->
<el-form-item label="关联计划" props="planId">
<el-select @change="handlChangeMap" v-model="form.planId" placeholder="请选择" style="width: 100%">
<el-option v-for="item in planlist" :key="item.id" :label="item.planName" :value="item.id" />
</el-select>
</el-form-item>
<el-form-item label="计划路线" props="planId">
<div class="mapbox" v-loading="maploading">
<div class="w-full h-full" id="TaskMapBox"></div>
</div>
</el-form-item>
<el-form-item>
<el-button type="primary" @click="submit">提交</el-button>
<el-button @click="routeback">返回</el-button>
</el-form-item>
</el-form>
</div>
</div>
</div>
</template>
<script setup lang="ts">
import RepairUser from '@/components/Holder/repairUser.vue';
import PageHeader from '@/components/Pageheader/index.vue';
import { Delete } from '@element-plus/icons-vue';
import { ref } from 'vue';
import AMapLoader from '@amap/amap-jsapi-loader';
import { addPlan, getPlan, listPlan, updatePlan } from '@/api/system/InspectionPlan';
import { addTask, getTask, updateTask } from '@/api/system/InspectionTask';
import { getRoute, listRoute } from '@/api/system/InspectionRoute';
import { RouteVO } from '@/api/system/InspectionRoute/type';
const { proxy } = getCurrentInstance() as ComponentInternalInstance;
const { com_inspection_plan_setting } = toRefs<any>(proxy?.useDict('com_inspection_plan_setting'));
const route = useRoute();
const router = useRouter();
const form = ref({
id: null,
taskName: '', // 巡检计划名称
inspectorId: '', // 巡检人员
taskTime: '', // 执行日期
remindTime: '', // 提醒时间
planId: '' // 计划路线id
});
const rules = ref({
taskName: [{ required: true, message: '请输入巡检任务名称', trigger: 'blur' }],
taskTime: [{ required: true, message: '请选择巡检任务时间', trigger: 'blur' }],
remindTime: [{ required: true, message: '请选择巡检任务提醒时间', trigger: 'blur' }],
inspectorIds: [{ required: true, message: '请选择巡检人员', trigger: 'blur' }],
planId: [{ required: true, message: '请选择巡检计划', trigger: 'blur' }]
});
// 提醒时间
const remindTimeoptions = ref([
{
value: 10,
label: '任务开始前10分钟'
},
{
value: 15,
label: '任务开始前15分钟'
},
{
value: 20,
label: '任务开始前30分钟'
}
]);
// 巡检计划id
const editid = ref(null);
// 初始化
// 路线列表
const planlist = ref([]);
async function init() {
// 获取 路线 列表
const res = await listPlan();
planlist.value = res.rows;
if (route.query.id) {
editid.value = route.query.id;
getTask(editid.value).then((res) => {
form.value = {
id: res.data.id,
taskName: res.data.taskName, // 巡检计划名称
inspectorIds: res.data.inspectorIds, // 巡检人员
remindTime: res.data.remindTime, // 提醒时间
routeIds: res.data.routeIds // 计划路线id
};
handlChangeMap(res.data.routeIds);
});
}
}
init();
// 选择 巡检人员
const RepairUserRef = ref<InstanceType<typeof RepairUser>>();
function handleAddUser() {
RepairUserRef.value.open();
}
const checkoutUserlist = ref([]);
function handleUserChange(val) {
checkoutUserlist.value = val;
}
function handleDelete(id) {
checkoutUserlist.value = checkoutUserlist.value.filter((item) => item.userId !== id);
}
// 返回
function routeback() {
router.back();
}
const AMapLib = ref(null);
const map = ref(null);
const mapReady = ref(false);
const maploading = ref(false);
// 地图覆盖物
const markerlist = [];
// 选择计划f
function handlChangeMap(val: string) {
// 清楚 覆盖物
if (markerlist.length > 0) {
map.value.remove(markerlist);
}
if (val) {
// 查找计划id
const find = planlist.value.find((item) => item.id === val);
if (find) {
const route = find.routeList.pop();
// 查找路线
getRoute(route.id).then((res) => {
handleRoute(res.data);
});
}
}
}
// 处理 巡检路线 巡检点数据
function handleRoute(route: RouteVO) {
maploading.value = true;
// ! 添加点
if (route.points && route.points.length > 0) {
route.points.forEach((item, index) => {
const lnglat = item.location.split(',').map(Number);
const marker = new AMapLib.value.Marker({
position: new AMapLib.value.LngLat(lnglat[0], lnglat[1]), //经纬度对象,也可以是经纬度构成的一维数组[116.39, 39.9]
title: item.pointName,
content: `
<div style="display:flex;align-items:center;justify-content:center;width:30px;height:30px;line-height:18px;border-radius:50%;background-color:rgba(26,117,255,0.3);">
<div
style=" width: 20px;
border-radius: 50%;
height: 20px;
line-height: 20px;
background-color: rgba(26,117,255,1);
color: #ffffff;
font-size: 20px;
text-align: center;"
>${index + 1}</div>
</div>`
});
//将创建的点标记添加到已有的地图实例:
map.value.add(marker);
markerlist.push(marker);
});
}
// ! 添加路线
if (route.pathPoints && typeof route.pathPoints === 'string') {
const path = JSON.parse(route.pathPoints);
console.log(path);
//创建 Polyline 实例
const polyline = new AMapLib.value.Polyline({
path: path,
strokeWeight: 2, //线条宽度
strokeColor: 'red', //线条颜色
lineJoin: 'round' //折线拐点连接处样式
});
map.value.add(polyline);
markerlist.push(polyline);
}
// 自动 适应 范围
map.value.setFitView();
maploading.value = false;
}
onMounted(async () => {
await nextTick();
window._AMapSecurityConfig = { securityJsCode: '09534b3534d8da53968529a9ce164118' };
AMapLoader.load({
key: '8e302fe1be5f4db62bc734db23dca149',
version: '2.0',
plugins: ['AMap.Scale', 'AMap.Marker']
}).then(async (AMap) => {
AMapLib.value = AMap;
map.value = new AMap.Map('TaskMapBox', {
viewMode: '3D',
zoom: 11,
center: [116.397428, 39.90923]
});
mapReady.value = true;
});
});
const formRef = ref();
function submit() {
form.value.inspectorId = checkoutUserlist.value.map((item) => item.userId).join(',');
formRef.value?.validate(async (valid: boolean) => {
if (valid) {
if (editid.value) {
updateTask(form.value).then(() => {
ElMessage.success('编辑成功');
routeback();
});
} else {
addTask(form.value).then(() => {
ElMessage.success('添加成功');
routeback();
});
}
}
});
}
</script>
<style scoped lang="scss">
.EditBody {
margin-top: 20px;
padding: 30px;
background-color: white;
.bodybox {
width: 600px;
margin: 0 auto;
margin-top: 20px;
}
.inspectorIdsBox {
display: flex;
flex-wrap: wrap;
align-items: center;
.inspector_items {
width: 120px;
height: 40px;
line-height: 40px;
margin: 5px;
text-align: center;
border-radius: 5px;
background-color: #ddeaff;
display: flex;
align-items: center;
justify-content: center;
padding: 0 2px;
.name {
overflow: hidden;
text-overflow: ellipsis;
text-wrap: nowrap;
}
&.add {
background-color: #ddeaff25;
border: 1px dashed #ccc;
cursor: pointer;
&:hover {
background-color: rgba(221, 234, 255, 0.199);
border-color: #44a0ff;
color: #44a0ff;
}
}
.deleteaction {
margin-left: 10px;
cursor: pointer;
&:hover {
color: red;
}
}
}
}
.week-items {
width: 90px;
height: 30px;
line-height: 30px;
border-radius: 5px;
cursor: pointer;
margin: 10px 5px;
border: 1px solid #ccc;
color: #000;
display: flex;
align-items: center;
.iconbox {
width: 30px;
height: 30px;
margin-left: 5px;
text-align: center;
line-height: 30px;
}
&.active {
color: rgba(26, 117, 255, 1);
background-color: rgba(26, 117, 255, 0.15);
border: none;
}
}
.mapbox {
margin-top: 20px;
width: 100%;
height: 400px;
border: 1px solid #ccc;
}
}
</style>

View File

@@ -1,24 +1,26 @@
<template>
<div class="p-2">
<div class="h-full flex flex-col p-2">
<transition :enter-active-class="proxy?.animate.searchAnimate.enter" :leave-active-class="proxy?.animate.searchAnimate.leave">
<div v-show="showSearch" class="mb-[10px]">
<el-card shadow="hover">
<el-form ref="queryFormRef" :model="queryParams" :inline="true">
<el-form ref="queryFormRef" label-width="100px" :model="queryParams" :inline="true">
<el-form-item label="执行状态" prop="taskName">
<el-input v-model="queryParams.taskName" placeholder="请输入巡检任务名称" clearable @keyup.enter="handleQuery" />
<el-select v-model="queryParams.status" placeholder="请选择执行状态" clearable>
<el-option v-for="(item, index) in com_inspection_task_status" :key="index" :value="item.value" :label="item.label"></el-option>
</el-select>
</el-form-item>
<el-form-item label="巡检任务名称" prop="taskName">
<el-input v-model="queryParams.taskName" placeholder="请输入巡检任务名称" clearable @keyup.enter="handleQuery" />
</el-form-item>
<el-form-item label="实际开始时间" prop="actualStartTime">
<!-- <el-form-item label="实际开始时间" prop="taskTime">
<el-date-picker
clearable
v-model="queryParams.actualStartTime"
v-model="queryParams.taskTime"
type="date"
value-format="YYYY-MM-DD"
placeholder="请选择实际开始时间"
/>
</el-form-item>
</el-form-item> -->
<el-form-item>
<el-button type="primary" icon="Search" @click="handleQuery">搜索</el-button>
<el-button icon="Refresh" @click="resetQuery">重置</el-button>
@@ -28,7 +30,7 @@
</div>
</transition>
<el-card shadow="never">
<el-card class="flex-1" shadow="never">
<template #header>
<el-row :gutter="10" class="mb8">
<el-col :span="1.5">
@@ -48,27 +50,21 @@
<el-table v-loading="loading" border :data="taskList" @selection-change="handleSelectionChange">
<el-table-column type="selection" width="55" align="center" />
<el-table-column label="主键ID" align="center" prop="id" v-if="true" />
<el-table-column label="巡检任务名称" align="center" prop="taskName" />
<el-table-column label="关联巡检计划ID" align="center" prop="planId" />
<el-table-column label="巡检人员ID" align="center" prop="inspectorId" />
<el-table-column label="巡检路线ID" align="center" prop="routeId" />
<el-table-column label="巡检人员" align="center" prop="inspectorId" />
<el-table-column label="起止日期" align="center" prop="taskTime" />
<el-table-column label="巡检设置0-必须拍照1-可以跳检" align="center" prop="inspectSetting" />
<el-table-column label="费用单位" align="center" prop="costUnit" />
<el-table-column label="状态0-待执行1-执行中2-已完成3-已超时" align="center" prop="status" />
<el-table-column label="实际开始时间" align="center" prop="actualStartTime" width="180">
<el-table-column label="巡检设置" align="center" prop="inspectSetting">
<template #default="scope">
<span>{{ parseTime(scope.row.actualStartTime, '{y}-{m}-{d}') }}</span>
<dict-tag :options="com_inspection_plan_setting" :value="scope.row.inspectSetting"></dict-tag>
</template>
</el-table-column>
<el-table-column label="实际结束时间" align="center" prop="actualEndTime" width="180">
<el-table-column label="状态" align="center" prop="status">
<template #default="scope">
<span>{{ parseTime(scope.row.actualEndTime, '{y}-{m}-{d}') }}</span>
<dict-tag :options="com_inspection_task_status" :value="scope.row.status"></dict-tag>
</template>
</el-table-column>
<el-table-column label="备注" align="center" prop="remark" />
<el-table-column label="提醒时间" align="center" prop="remindTime" />
<el-table-column label="关联巡检计划" align="center" prop="planId" />
<el-table-column label="操作" align="center" fixed="right" class-name="small-padding fixed-width">
<template #default="scope">
<el-tooltip content="修改" placement="top">
@@ -83,58 +79,6 @@
<pagination v-show="total > 0" :total="total" v-model:page="queryParams.pageNum" v-model:limit="queryParams.pageSize" @pagination="getList" />
</el-card>
<!-- 添加或修改巡检任务对话框 -->
<el-dialog :title="dialog.title" v-model="dialog.visible" width="500px" append-to-body>
<el-form ref="taskFormRef" :model="form" :rules="rules" label-width="80px">
<el-form-item label="巡检任务名称" prop="taskName">
<el-input v-model="form.taskName" placeholder="请输入巡检任务名称" />
</el-form-item>
<el-form-item label="关联巡检计划ID" prop="planId">
<el-input v-model="form.planId" placeholder="请输入关联巡检计划ID" />
</el-form-item>
<el-form-item label="巡检人员ID" prop="inspectorId">
<el-input v-model="form.inspectorId" placeholder="请输入巡检人员ID" />
</el-form-item>
<el-form-item label="巡检路线ID" prop="routeId">
<el-input v-model="form.routeId" placeholder="请输入巡检路线ID" />
</el-form-item>
<el-form-item label="起止日期" prop="taskTime">
<el-input v-model="form.taskTime" placeholder="请输入起止日期" />
</el-form-item>
<el-form-item label="巡检设置0-必须拍照1-可以跳检" prop="inspectSetting">
<el-input v-model="form.inspectSetting" placeholder="请输入巡检设置0-必须拍照1-可以跳检" />
</el-form-item>
<el-form-item label="费用单位" prop="costUnit">
<el-input v-model="form.costUnit" placeholder="请输入费用单位" />
</el-form-item>
<el-form-item label="实际开始时间" prop="actualStartTime">
<el-date-picker
clearable
v-model="form.actualStartTime"
type="datetime"
value-format="YYYY-MM-DD HH:mm:ss"
placeholder="请选择实际开始时间"
>
</el-date-picker>
</el-form-item>
<el-form-item label="实际结束时间" prop="actualEndTime">
<el-date-picker clearable v-model="form.actualEndTime" type="datetime" value-format="YYYY-MM-DD HH:mm:ss" placeholder="请选择实际结束时间">
</el-date-picker>
</el-form-item>
<el-form-item label="备注" prop="remark">
<el-input v-model="form.remark" type="textarea" placeholder="请输入内容" />
</el-form-item>
<el-form-item label="提醒时间" prop="remindTime">
<el-input v-model="form.remindTime" placeholder="请输入提醒时间" />
</el-form-item>
</el-form>
<template #footer>
<div class="dialog-footer">
<el-button :loading="buttonLoading" type="primary" @click="submitForm"> </el-button>
<el-button @click="cancel"> </el-button>
</div>
</template>
</el-dialog>
</div>
</template>
@@ -144,7 +88,9 @@ import { TaskVO, TaskQuery, TaskForm } from '@/api/system/InspectionTask/type';
const { proxy } = getCurrentInstance() as ComponentInternalInstance;
const { com_inspection_task_status } = toRefs<any>(proxy?.useDict('com_inspection_task_status'));
const { com_inspection_plan_setting } = toRefs<any>(proxy?.useDict('com_inspection_plan_setting'));
const router = useRouter();
const taskList = ref<TaskVO[]>([]);
const buttonLoading = ref(false);
const loading = ref(true);
@@ -245,19 +191,19 @@ const handleSelectionChange = (selection: TaskVO[]) => {
/** 新增按钮操作 */
const handleAdd = () => {
reset();
dialog.visible = true;
dialog.title = '添加巡检任务';
router.push({
path: '/inspection/addTask'
});
};
/** 修改按钮操作 */
const handleUpdate = async (row?: TaskVO) => {
reset();
const _id = row?.id || ids.value[0];
const res = await getTask(_id);
Object.assign(form.value, res.data);
dialog.visible = true;
dialog.title = '修改巡检任务';
router.push({
path: '/inspection/addTask',
query: {
id: row.id
}
});
};
/** 提交按钮 */
@@ -301,3 +247,9 @@ onMounted(() => {
getList();
});
</script>
<style lang="scss" scoped>
.el-table {
height: calc(100% - 80px);
}
</style>

View File

@@ -0,0 +1,12 @@
<template>
<div class="p-2 h-full flex flex-col">
<Pageheader></Pageheader>
<div class="flex-1 color-gray flex h-full font-size-6 flex-center">系统还在维护中敬请期待...</div>
</div>
</template>
<script setup lang="ts">
import { ref } from 'vue';
</script>
<style scoped lang="scss"></style>

View File

@@ -1,12 +1,109 @@
<template>
<div class="p-2 h-full flex flex-col">
<div class="h-full flex flex-col p-2">
<Pageheader></Pageheader>
<div class="flex-1 color-gray flex h-full font-size-6 flex-center">系统还在维护中敬请期待...</div>
<transition :enter-active-class="proxy?.animate.searchAnimate.enter" :leave-active-class="proxy?.animate.searchAnimate.leave">
<div v-show="showSearch" class="mb-[10px]">
<el-card shadow="hover">
<el-form ref="queryFormRef" :model="queryParams" :inline="true">
<el-form-item label="选择日期" prop="itemName">
<el-date-picker
v-model="starDate"
type="daterange"
unlink-panels
range-separator=""
start-placeholder="开始日期"
end-placeholder="结束日期"
format="YYYY/MM/DD"
value-format="YYYY/MM/DD"
/>
</el-form-item>
<el-form-item>
<el-button type="primary" icon="Search" @click="handleQuery">搜索</el-button>
<el-button icon="Refresh" @click="resetQuery">重置</el-button>
</el-form-item>
</el-form>
</el-card>
</div>
</transition>
<el-card class="flex-1" shadow="never">
<template #header>
<el-row :gutter="10">
<el-col :span="1.5">
<span style="font-size: 1.2rem">月报列表</span>
</el-col>
<right-toolbar v-model:showSearch="showSearch" @queryTable="getList"></right-toolbar>
</el-row>
</template>
<el-table v-loading="loading" border :data="itemList">
<el-table-column label="日期" width="100" align="center" prop="statDate" />
<el-table-column label="计划巡检任务" width="120" align="center" prop="totalPlans" />
<el-table-column label="按时完成" align="center" prop="completedTasks" />
<el-table-column label="超时完成" align="center" prop="outCompletedTasks" />
<el-table-column label="超时未完成" align="center" prop="outUncompletedTasks" />
<el-table-column label="进行中" align="center" prop="activeTask" />
<el-table-column label="未开始" align="center" prop="pendingTask" />
</el-table>
<pagination v-show="total > 0" :total="total" v-model:page="queryParams.pageNum" v-model:limit="queryParams.pageSize" @pagination="getList" />
</el-card>
</div>
</template>
<script setup lang="ts">
import { ref } from 'vue';
<script setup name="Item" lang="ts">
import { listItem, type Request } from '@/api/system/Inspection/index';
const { proxy } = getCurrentInstance() as ComponentInternalInstance;
const itemList = ref<any[]>([]);
const loading = ref(true);
const showSearch = ref(true);
const total = ref(0);
const queryFormRef = ref<ElFormInstance>();
const data = reactive<{
queryParams: Request;
}>({
queryParams: {
pageNum: 1,
pageSize: 10,
dataType: '2' // 1 日报 2 周报 3 月报
}
});
const starDate = ref([]);
const { queryParams } = toRefs(data);
/** 查询巡检项目列表 */
const getList = async () => {
queryParams.value.statDate = starDate.value.join('-');
loading.value = true;
const res = await listItem(queryParams.value);
itemList.value = res.rows;
total.value = res.total;
loading.value = false;
};
/** 搜索按钮操作 */
const handleQuery = () => {
queryParams.value.pageNum = 1;
getList();
};
/** 重置按钮操作 */
const resetQuery = () => {
queryFormRef.value?.resetFields();
starDate.value = [];
handleQuery();
};
onMounted(() => {
getList();
});
</script>
<style scoped lang="scss"></style>
<style lang="scss" scoped>
.el-table {
height: calc(100% - 80px);
}
</style>

View File

@@ -114,7 +114,6 @@ import { validator } from '@/utils/Reg';
import { useHouseStore } from '@/store/modules/house';
const houseStore = useHouseStore();
const { treedata } = storeToRefs(houseStore);
const uploadUrl = import.meta.env.VITE_APP_BASE_API + '/resident/uploadImage';
const { proxy } = getCurrentInstance() as ComponentInternalInstance;
@@ -161,6 +160,14 @@ const rules = ref({
]
});
const treedata = ref([]);
function getTree() {
houseStore.getCurrentVilageTreeHouse().then((res) => {
treedata.value = res;
gettreedata();
});
}
getTree();
// !== 楼栋房屋 =============================================================================
const userid = ref(null);
function gettreedata() {
@@ -176,7 +183,7 @@ function gettreedata() {
});
}
}
gettreedata();
function handleChange(val: CascaderValue) {
userHousepath.value = val;
form.value.buildingId = val[0];

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 815 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.7 KiB

View File

@@ -1,6 +1,6 @@
<template>
<!-- 外层缩放容器 -->
<div class="scale-container">
<div class="scale-container h-full">
<div class="w-full h-full workBenchBox">
<el-row>
<el-col :span="18">
@@ -60,89 +60,104 @@
</el-col>
<!-- tabs -->
<el-col :span="6">
<div class="villageInfoBox">
<div class="iconbox">
<el-image :src="summicon"></el-image>
</div>
<div class="villageinfo">
<div class="villagename">{{ villageinfo.villageName }}</div>
<div class="week">{{ new Date().toLocaleDateString().replaceAll('/', '-') }} {{ numToWeek2(new Date().getDay()) }}</div>
</div>
<i class="white1"></i>
<i class="white2"></i>
<i class="white3"></i>
</div>
<div class="tabsbox flex flex-col">
<div class="topbox">
<div
:class="{
active: Sideactive === 1
}"
@click="handleSelect(1)"
>
<span>快捷入口</span>
<i></i>
<div class="flex flex-col h-full">
<div class="villageInfoBox">
<div class="iconbox">
<el-image :src="summicon"></el-image>
</div>
<div
:class="{
active: Sideactive === 2
}"
@click="handleSelect(2)"
>
<span>创建办事记录</span>
<i class="righti"></i>
</div>
</div>
<div class="body flex-1">
<div class="quicly_box" v-if="Sideactive === 1">
<div class="quickly_item" v-for="(item, index) in quickBox" :key="index" @click="handleRouter(item.url)">
<div class="quickly_item_icon"></div>
<div class="quickly_item_content">{{ item.name }}</div>
<div class="villageinfo">
<div class="villagename">{{ villageinfo.villageName }}</div>
<div class="week">
<span>{{ new Date().toLocaleDateString().replaceAll('/', '-') }}</span>
<span>{{ numToWeek2(new Date().getDay()) }}</span>
</div>
<!-- <div class="quickly_item add">
<el-icon><Plus /></el-icon>
<span>添加</span>
</div> -->
</div>
<div v-else>
<div class="noticeNav">
<div>创建办事记录</div>
<el-button type="primary">提交</el-button>
<i class="white1"></i>
<i class="white2"></i>
<i class="white3"></i>
</div>
<div class="tabbox1 flex flex-col flex-1 h-full">
<div class="tabsbox flex flex-col flex-1">
<div
class="topbox"
:class="{
quickbg: Sideactive === 1,
todobg: Sideactive === 2
}"
>
<div
:class="{
active: Sideactive === 1
}"
@click="handleSelect(1)"
>
<span>快捷入口</span>
<i></i>
</div>
<div
:class="{
active: Sideactive === 2
}"
@click="handleSelect(2)"
>
<span>创建办事记录</span>
<i class="righti"></i>
</div>
</div>
<div class="noticeBox">
<el-form label-position="top">
<el-form-item label="需求方姓名">
<el-input placeholder="请输入姓名" v-model="noticForm.seekName"></el-input>
</el-form-item>
<el-form-item label="办事时间">
<el-date-picker
v-model="noticForm.handleTime"
type="datetime"
clearable
placeholder="年-月-日 时:分"
value-format="YYYY-MM-DD HH:MM"
format="YYYY-MM-DD HH:MM"
>
</el-date-picker>
</el-form-item>
<el-form-item label="办事内容">
<el-input type="textarea" v-model="noticForm.content" :rows="2" placeholder="请输入办事内容"></el-input>
</el-form-item>
<el-form-item label="附件">
<el-upload
v-model:file-list="fileList"
:auto-upload="false"
class="upload-demo"
action="https://run.mocky.io/v3/9d059bf9-4660-45f2-925d-ce80ad6c4d15"
multiple
>
<div class="uploadBtn flex flex-items-center">
<el-icon><Upload /></el-icon>
<span>上传文件</span>
</div>
</el-upload>
</el-form-item>
</el-form>
<div class="body flex-1">
<div class="quicly_box" v-if="Sideactive === 1">
<div class="quickly_item" v-for="(item, index) in quickBox" :key="index" @click="handleRouter(item.url)">
<div class="quickly_item_icon">
<el-image :src="item.img"></el-image>
</div>
<div class="quickly_item_content">{{ item.name }}</div>
</div>
<div class="quickly_item add">
<el-icon><Plus /></el-icon>
<span>添加</span>
</div>
</div>
<div v-else>
<div class="noticeNav">
<div class="noticNav_title">创建办事记录</div>
<el-button type="primary">提交</el-button>
</div>
<div class="noticeBox">
<el-form label-position="top">
<el-form-item label="需求方姓名">
<el-input placeholder="请输入姓名" v-model="noticForm.seekName"></el-input>
</el-form-item>
<el-form-item label="办事时间">
<el-date-picker
v-model="noticForm.handleTime"
type="datetime"
clearable
placeholder="年-月-日 时:分"
value-format="YYYY-MM-DD HH:MM"
format="YYYY-MM-DD HH:MM"
>
</el-date-picker>
</el-form-item>
<el-form-item label="办事内容">
<el-input type="textarea" v-model="noticForm.content" :rows="2" placeholder="请输入办事内容"></el-input>
</el-form-item>
<el-form-item label="附件">
<el-upload
v-model:file-list="fileList"
:auto-upload="false"
class="upload-demo"
action="https://run.mocky.io/v3/9d059bf9-4660-45f2-925d-ce80ad6c4d15"
multiple
>
<div class="uploadBtn flex flex-items-center">
<el-icon><Upload /></el-icon>
<span>上传文件</span>
</div>
</el-upload>
</el-form-item>
</el-form>
</div>
</div>
</div>
</div>
</div>
@@ -170,25 +185,25 @@
<div class="tablebox">
<el-table :data="tableData" stripe style="width: 100%">
<el-table-column type="index" :index="indexMethod" label="序号" width="60" align="center" />
<el-table-column prop="name" align="center" label="姓名" width="180" />
<el-table-column prop="type" align="center" label="类型" width="180">
<el-table-column prop="name" align="center" label="姓名" width="80" />
<el-table-column prop="type" align="center" label="类型" width="100">
<template #default="scope">
<DictTag :options="com_resident_type" :value="scope.row.status"></DictTag>
</template>
</el-table-column>
<el-table-column prop="status" align="center" label="状态" width="180">
<el-table-column prop="status" align="center" label="状态" width="120">
<template #default="scope">
<DictTag :options="com_review" :value="scope.row.type"></DictTag>
</template>
</el-table-column>
<el-table-column prop="idCard" align="center" label="证件号码" />
<el-table-column prop="phone" align="center" label="手机号" />
<el-table-column prop="phone" align="center" label="手机号" width="120" />
<el-table-column prop="houseName" align="center" label="房间" />
<el-table-column prop="address" align="center" label="操作">
<template #default>
<el-button type="primary" text> 审核</el-button>
<el-button type="primary" text> 编辑</el-button>
<el-button type="primary" text> 删除</el-button>
<template #default="scope">
<el-button type="primary" text @click="shenhe(scope.row)"> 审核</el-button>
<el-button type="primary" text @click="edit(scope.row)"> 编辑</el-button>
<el-button type="primary" text @click="deleteFun(scope.row)"> 删除</el-button>
</template>
</el-table-column>
</el-table>
@@ -211,7 +226,7 @@
<script lang="ts" setup>
import summicon from '@/assets/images/index/summer.png';
import repairEcharts from './components/repairEcharts.vue';
import { listResident } from '@/api/system/resident';
import { delResident, listResident } from '@/api/system/resident';
import { useHouseStore } from '@/store/modules/house';
const houseStore = useHouseStore();
@@ -221,11 +236,20 @@ const villageinfo = ref({
'villageName': ''
});
import icon1 from '@/assets/images/index/1.png';
import icon2 from '@/assets/images/index/2.png';
import icon3 from '@/assets/images/index/3.png';
import icon5 from '@/assets/images/index/5.png';
import icon6 from '@/assets/images/index/6.png';
import icon1 from './assets/user.png';
import icon2 from './assets/user.png';
import icon3 from './assets/car.png';
import icon4 from './assets/device.png';
import icon5 from './assets/wuliao.png';
import icon6 from './assets/tousu.png';
import home from './assets/home.png';
import chart from './assets/chart.png';
import add from './assets/add.png';
import info from './assets/info.png';
import profile from './assets/profile.png';
import star from './assets/star.png';
import { UploadUserFile } from 'element-plus';
import { getVillageByIdAPI } from '@/api/system/community';
import { getLast7Days, numToWeek2 } from '@/utils/time';
@@ -240,8 +264,8 @@ const list = ref([
{ name: '住户总数量', value: 10000, icon: icon1 },
{ name: '房屋总数量', value: 458, icon: icon2 },
{ name: '车位总数量', value: 2539, icon: icon3 },
{ name: '设备总数量', value: 22, icon: icon5 },
{ name: '物料总数量', value: 458, icon: icon6 },
{ name: '设备总数量', value: 22, icon: icon4 },
{ name: '物料总数量', value: 458, icon: icon5 },
{ name: '投诉总数量', value: 458, icon: icon6 }
]);
@@ -376,27 +400,33 @@ function handleSelect(val: number) {
const quickBox = ref([
{
name: '新建用户',
url: '/house/resident'
url: '/house/resident',
img: home
},
{
name: '车位管理',
url: '/carArea/parking'
url: '/carArea/parking',
img: chart
},
{
name: '新建月卡',
url: '/carArea/monthCard'
url: '/carArea/monthCard',
img: add
},
{
name: '新建报修',
url: '/repair/repairlist'
url: '/repair/repairlist',
img: info
},
{
name: '访客记录',
url: '/repair/visitorList'
url: '/repair/visitorList',
img: profile
},
{
name: '账单管理',
url: '/sdb/sdbbill'
url: '/sdb/sdbbill',
img: star
}
]);
const router = useRouter();
@@ -420,14 +450,17 @@ const fileList = ref<UploadUserFile[]>([]);
// ! 创建办事记录
// ! table
const seachervalue = ref('');
const seachervalue = ref('name');
const searchInput = ref('');
const loading = ref(true);
const total = ref(100);
const data = reactive({
queryParams: {
pageNum: 1,
pageSize: 10
pageSize: 10,
name: '',
idCard: '',
phone: ''
}
});
const { queryParams } = toRefs(data);
@@ -450,7 +483,15 @@ const options = [
}
];
function handleSearch() {
queryParams[seachervalue.value] = searchInput.value;
queryParams.value = {
pageNum: 1,
pageSize: 10,
name: '',
idCard: '',
phone: ''
};
queryParams.value[seachervalue.value] = searchInput.value;
console.log(queryParams.value);
getList();
}
const tableData = ref([]);
@@ -459,6 +500,30 @@ async function getList() {
tableData.value = res.rows;
}
getList();
function shenhe(row) {
router.push({
path: '/house/ResidentMain',
query: {
id: row.id
}
});
}
function edit(row) {
router.push({
path: '/house/addResident',
query: {
id: row.id
}
});
}
async function deleteFun(row) {
const _ids = row?.id;
await proxy?.$modal.confirm('该信息删除后无法恢复,确定要删除吗?').finally(() => (loading.value = false));
await delResident(_ids);
proxy?.$modal.msgSuccess('删除成功');
await getList();
}
// ! table
</script>
@@ -490,7 +555,6 @@ getList();
.village_items {
flex: 1;
min-width: 160px; /* 小屏自动单列 */
margin-right: 10px;
min-height: 109px;
background: linear-gradient(180deg, rgba(255, 255, 255, 0.5) 0%, #ffffff 100%);
@@ -503,7 +567,6 @@ getList();
.icon {
width: 40px;
height: 46px;
background: #f4f0ff;
box-shadow: inset 0px 0px 20px 0px #ffffff;
border-radius: 10px 10px 10px 10px;
border: 1px solid #ffffff;
@@ -520,7 +583,7 @@ getList();
font-weight: 400;
color: #4e5969;
line-height: 18px;
font-size: 14px;
font-size: 0.85rem;
}
.infoNum {
height: 35px;
@@ -550,10 +613,11 @@ getList();
&:last-child {
margin-right: 0;
}
.nav {
.ecarts_title {
font-weight: 500;
font-size: 20px;
font-size: 1rem;
color: #303133;
line-height: 25px;
}
@@ -632,7 +696,7 @@ getList();
.villagename {
height: 30px;
font-weight: 500;
font-size: 24px;
font-size: 1.55rem;
color: #ffffff;
line-height: 30px;
}
@@ -643,6 +707,8 @@ getList();
font-size: 18px;
color: #ffffff;
line-height: 23px;
display: flex;
flex-wrap: wrap;
}
}
@@ -676,18 +742,21 @@ getList();
}
// tabs
.tabsbox {
.tabbox1 {
margin-left: 20px;
border: 2px solid;
background: linear-gradient(180deg, #ebf4ff 0%, rgba(247, 252, 255, 0.5) 21.14%);
border-image: linear-gradient(180deg, rgba(255, 255, 255, 1), rgba(255, 255, 255, 0)) 2 2;
background-image: url(./assets/Rectangle.png);
background-repeat: no-repeat;
background-size: 100% 100%;
}
.tabsbox {
background-size: 100% auto;
background-blend-mode: multiply;
overflow: hidden;
.topbox {
display: flex;
align-items: center;
div {
flex: 1;
border-bottom: 4px solid;
border-image: linear-gradient(to bottom, #fff, rgba(255, 255, 255, 0)) 100% 1;
text-align: center;
padding: 14px;
cursor: pointer;
@@ -697,75 +766,6 @@ getList();
border-image: none;
position: relative;
color: #000;
$width: 8px;
$greePer: 60%;
& i {
display: block;
position: absolute;
right: 10px;
top: 0;
width: calc($width / 2);
height: 100%;
transform: skew(30deg);
background: white;
transition: all 0.3s;
z-index: 10;
&::after {
content: '';
display: block;
width: $width;
height: $width;
background: radial-gradient(circle at bottom left, #ecf4fe $greePer, #ffffff (1 - $greePer));
position: absolute;
left: -$width;
top: 0;
}
&::before {
content: '';
display: block;
width: $width;
height: $width;
background: radial-gradient(circle at top right, #ecf4fe $greePer, #ffffff (1 - $greePer));
position: absolute;
right: -$width;
bottom: 0;
}
}
& i.righti {
display: block;
position: absolute;
left: 10px;
top: 0;
width: calc($width / 2);
height: 100%;
transform: skew(-30deg);
background: white;
z-index: 10;
&::after {
content: '';
display: block;
width: $width;
height: $width;
background: radial-gradient(circle at bottom right, #ecf4fe $greePer, #ffffff (1 - $greePer));
position: absolute;
right: -$width;
left: initial;
top: 0;
}
&::before {
content: '';
display: block;
width: $width;
height: $width;
background: radial-gradient(circle at top left, #ecf4fe $greePer, #ffffff (1 - $greePer));
position: absolute;
left: -$width;
right: none;
bottom: 0;
}
}
&::after {
content: '';
display: block;
@@ -780,41 +780,59 @@ getList();
}
}
}
&.quickbg {
background-image: url(./assets/tabs/Union_tabl.png);
background-repeat: no-repeat;
background-size: 100% 100%;
}
&.todobg {
background-size: 100% 100%;
background-repeat: no-repeat;
background-image: url(./assets/tabs/Union_tabr.png);
}
}
.body {
color: #222222;
padding: 20px;
font-size: 0.7rem;
font-size: 0.75rem;
background-image: url(./assets/tabs/Union_body.png);
background-repeat: no-repeat;
background-size: 100% 100%;
.quicly_box {
display: flex;
align-items: center;
justify-content: start;
flex-wrap: wrap;
padding-top: 20px;
display: grid;
grid-template-columns: repeat(3, 1fr);
@media (max-width: 1750px) {
grid-template-columns: repeat(2, 1fr);
}
gap: 10px;
.quickly_item {
min-width: 30%;
max-width: 33%;
margin-bottom: 20px;
text-align: center;
height: 56px;
background: #ffffff;
border-radius: 12px 12px 12px 12px;
border: 1px solid #c0daff;
display: flex;
align-items: center;
justify-content: center;
cursor: pointer;
&:hover {
background-color: #0084ff09;
}
.quickly_item_icon {
width: 25px;
height: 25px;
}
.quickly_item_content {
margin-left: 5px;
width: 64px;
height: 23px;
margin-left: 8px;
font-weight: 500;
color: #222222;
line-height: 23px;
}
&.add {
@@ -833,6 +851,9 @@ getList();
align-items: center;
justify-content: space-between;
margin-bottom: 20px;
& .noticNav_title {
font-size: 1rem;
}
}
.noticeBox {
:deep(.el-date-editor.el-input, .el-date-editor.el-input__wrapper) {
@@ -909,7 +930,7 @@ getList();
.tablebox {
flex: 1;
.el-table {
height: calc(100% - 60px);
min-height: calc(100% - 60px);
}
}
}