| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715 |
- <template>
- <ContentWrap>
- <!-- 搜索工作栏 -->
- <el-form
- class="-mb-15px"
- :model="queryParams"
- ref="queryFormRef"
- :inline="true"
- label-width="68px"
- >
- <!-- 基本信息查询部分 -->
- <div class="flex flex-wrap items-start gap-x-2">
- <el-form-item label="单位名称" prop="unitName">
- <el-input
- v-model="queryParams.unitName"
- placeholder="请输入单位名称"
- clearable
- @keyup.enter="getList"
- class="!w-240px"
- />
- </el-form-item>
- <el-form-item label="单位地址" prop="unitAddress">
- <el-input
- v-model="queryParams.unitAddress"
- placeholder="请输入单位地址"
- clearable
- @keyup.enter="getList"
- class="!w-240px"
- />
- </el-form-item>
- <el-form-item label="设备代码" prop="equipCode">
- <el-input
- v-model="queryParams.equipCode"
- placeholder="请输入设备注册代码"
- clearable
- @keyup.enter="getList"
- class="!w-240px"
- />
- </el-form-item>
- <el-form-item label="部门" prop="relateDepartment">
- <DeptSelect
- v-model="queryParams.relateDepartment"
- placeholder="请选择部门"
- clearable
- class="!w-240px"
- />
- </el-form-item>
- </div>
- <!-- 区域和时间查询部分 -->
- <div class="flex flex-wrap items-start gap-x-2">
- <el-form-item label="区域" prop="equipDistrict">
- <AreaSelect
- v-model="queryParams.equipDistrict"
- placeholder="请选择区域"
- class="!w-[240px]"
- multiple
- collapse-tags
- collapse-tags-tooltip
- :clearable="true"
- @clear="handleAreaClear"
- @change="handleAreaChange"
- @area-type-change="handleAreaTypeChange"
- />
- </el-form-item>
- <el-form-item label="街道" prop="equipStreet">
- <StreetSelect
- v-model="queryParams.equipStreet"
- :district-ids="queryParams.equipDistrict"
- placeholder="请选择街道"
- class="!w-[240px]"
- multiple
- collapse-tags
- collapse-tags-tooltip
- :clearable="true"
- @clear="handleStreetClear"
- @change="handleStreetChange"
- />
- </el-form-item>
- <el-form-item label="使用状态" prop="useStatus">
- <el-select
- v-model="queryParams.useStatus"
- placeholder="选择使用状态"
- clearable
- multiple
- collapse-tags
- collapse-tags-tooltip
- class="!w-240px"
- >
- <el-option
- v-for="dict in getStrDictOptions(DICT_TYPE.SYSTEM_EQUIP_BOILER_STATUS)"
- :key="dict.value"
- :label="dict.label"
- :value="dict.value"
- />
- </el-select>
- </el-form-item>
- <el-form-item label="临检时间" prop="checkDate">
- <div class="flex items-center gap-x-2">
- <el-select v-model="datePickerType" class="!w-[90px]">
- <el-option label="时间段" value="daterange" />
- <el-option label="月份" value="month" />
- </el-select>
- <el-date-picker
- v-if="datePickerType === 'daterange'"
- v-model="daterange"
- type="daterange"
- value-format="YYYY-MM-DD"
- start-placeholder="开始日期"
- end-placeholder="结束日期"
- class="!w-[220px]"
- @change="handleDateChange"
- />
- <el-date-picker
- v-else
- v-model="month"
- type="month"
- value-format="YYYY-MM"
- placeholder="选择月份"
- class="!w-[150px]"
- @change="handleMonthChange"
- />
- </div>
- </el-form-item>
- </div>
- <!-- 锅炉相关查询条件 -->
- <div class="bg-gray-50 p-3 rounded mt-2">
- <el-form-item label="锅炉归类" prop="typeList" class="mb-2">
- <div class="flex items-center flex-1">
- <el-checkbox-group
- v-model="queryParams.typeList"
- class="flex flex-wrap gap-2"
- @change="handleTypeListChange"
- >
- <el-checkbox
- v-for="dict in containerTypeOptions"
- :key="dict.value"
- :label="dict.label"
- :value="dict.value"
- />
- </el-checkbox-group>
- </div>
- </el-form-item>
- </div>
- <!-- 操作按钮 -->
- <div class="flex justify-center mt-3">
- <el-form-item class="mb-0">
- <el-button @click="handleQuery"><Icon icon="ep:search" class="mr-5px" /> 搜索</el-button>
- <el-button @click="resetQuery"><Icon icon="ep:refresh" class="mr-5px" /> 重置</el-button>
- <el-button
- type="primary"
- v-if="source === 'pressure'"
- @click="handleBatchSchedule"
- :disabled="selectedRows.length === 0"
- >
- <Icon icon="ep:calendar" class="mr-5px" /> 批量排期
- </el-button>
- <el-button
- type="success"
- plain
- @click="handleExport"
- :loading="exportLoading"
- >
- <Icon icon="ep:download" class="mr-5px" /> 导出
- </el-button>
- </el-form-item>
- </div>
- </el-form>
- </ContentWrap>
- <!-- 列表 -->
- <ContentWrap>
- <el-table
- v-loading="loading"
- :data="list"
- stripe
- @selection-change="handleSelectionChange"
- @sort-change="handleSortChange"
- ref="tableRef"
- :cell-style="getCellStyle"
- border
- >
- <el-table-column v-if="source === 'pressure'" type="selection" width="30" />
- <el-table-column
- label="区域"
- align="center"
- prop="equipDistrictName"
- min-width="80"
- sortable="custom"
- />
- <el-table-column
- label="街道"
- align="center"
- prop="equipStreetName"
- min-width="100"
- sortable="custom"
- />
- <el-table-column label="使用单位名称" align="center" prop="unitName" min-width="180">
- <template #default="{ row }">
- <el-link
- type="primary"
- :underline="false"
- @click="handleEdit(row)"
- style="cursor: pointer"
- >
- {{ row.unitName }}
- </el-link>
- </template>
- </el-table-column>
- <el-table-column label="使用单位地址" align="center" prop="unitAddress" min-width="150" />
- <!-- 内部检验 -->
- <el-table-column
- label="内部检验"
- align="center"
- prop="nextInCheckDate"
- min-width="140"
- sortable="custom"
- >
- <template #default="{ row }">
- <!-- <div class="check-number regular-check">{{ row.countIn }}</div>-->
- <div v-if="row.nextInCheckDate !== null" :class="['text-sm']">
- {{ dayjs(row.nextInCheckDate).format('YYYY-MM-DD') }}
- </div>
- <div v-else class="text-xs text-gray-500">
- -
- </div>
- <div class="text-xs text-gray-400" v-if="hasPlanSchedule(row, 'in')">
- {{ row.planInCheckDate ? `(已排时间:${dayjs(row.planInCheckDate).format('YYYY-MM-DD')})` : '' }}
- </div>
- </template>
- </el-table-column>
- <!-- 外部检验 -->
- <el-table-column
- label="外部检验"
- align="center"
- prop="nextOutCheckDate"
- min-width="140"
- sortable="custom"
- >
- <template #default="{ row }">
- <!-- <div class="check-number year-check">{{ row.countOut }}</div>-->
- <div
- v-if="row.nextOutCheckDate !== null"
- :class="['text-sm']"
- >
- {{ dayjs(row.nextOutCheckDate).format('YYYY-MM-DD') }}
- </div>
- <div v-else class="text-xs text-gray-500">
- -
- </div>
- <div class="text-xs text-gray-400" v-if="hasPlanSchedule(row, 'out')">
- {{ row.planOutCheckDate ? `(已排时间:${dayjs(row.planOutCheckDate).format('YYYY-MM-DD')})` : '' }}
- </div>
- </template>
- </el-table-column>
- <!-- 耐压检验 -->
- <el-table-column
- label="耐压检验"
- align="center"
- prop="nextPressureCheckDate"
- min-width="140"
- sortable="custom"
- >
- <template #default="{ row }">
- <!-- <div class="check-number expired-check">{{ row.countOut }}</div>-->
- <div
- v-if="row.nextPressureCheckDate !== null"
- :class="['text-sm']"
- >
- {{ dayjs(row.nextPressureCheckDate).format('YYYY-MM-DD') }}
- </div>
- <div v-else class="text-xs text-gray-500">
- -
- </div>
- <div class="text-xs text-gray-400" v-if="hasPlanSchedule(row, 'pressure')">
- {{ row.planPressureCheckDate ? `(已排时间:${dayjs(row.planPressureCheckDate).format('YYYY-MM-DD')})` : '' }}
- </div>
- </template>
- </el-table-column>
- <!-- 设备注册代码 -->
- <el-table-column label="设备注册代码" align="center" prop="equipCode" min-width="140">
- <template #default="{ row }">
- <div>{{ row.equipCode || '-' }}</div>
- </template>
- </el-table-column>
- <el-table-column label="使用证编号" align="center" prop="useRegisterNo" min-width="140">
- <template #default="{ row }">
- <div>{{ row.useRegisterNo || '-' }}</div>
- </template>
- </el-table-column>
- <el-table-column label="型号" align="center" prop="boilerModel" min-width="140">
- <template #default="{ row }">
- <div>{{ row.boilerModel || '-' }}</div>
- </template>
- </el-table-column>
- <el-table-column label="出厂编号" align="center" prop="factoryCode" min-width="140">
- <template #default="{ row }">
- <div>{{ row.factoryCode || '-' }}</div>
- </template>
- </el-table-column>
- <!-- 操作 -->
- <el-table-column label="操作" align="center" width="150" fixed="right">
- <template #default="scope">
- <el-button link type="primary" size="small" @click="handleSchedule(scope.row)">
- 计划排期
- </el-button>
- <!-- <el-button link type="primary" size="small" @click="handleEdit(scope.row)">-->
- <!-- 编辑-->
- <!-- </el-button>-->
- </template>
- </el-table-column>
- </el-table>
- <!-- 分页 -->
- <Pagination
- :total="total"
- v-model:page="queryParams.pageNo"
- v-model:limit="queryParams.pageSize"
- @pagination="handleQuery"
- />
- </ContentWrap>
- <!-- 计划排期弹窗 -->
- <BoilerPlanScheduleDialog
- ref="scheduleDialogRef"
- :selected-rows="selectedRows"
- :source="source"
- @success="handleScheduleSuccess"
- @clear-selected-rows="clearSelectedRows"
- />
- <!-- 详情弹窗 -->
- <Detail :source="source" ref="detailDialogRef" />
- </template>
- <script setup lang="ts">
- import {useUserStore} from "@/store/modules/user";
- import { EquipBoilerSchedulingApi, EquipBoilerSchedulingVO } from '@/api/pressure2/equipboilerscheduling'
- import {DICT_TYPE, getStrDictOptions, StringDictDataType} from "@/utils/dict";
- import DeptSelect from "@/views/pressure2/equipboilerscheduling/components/DeptSelect.vue";
- import AreaSelect from "@/views/system/equipcontainer/components/AreaSelect.vue";
- import StreetSelect from "@/views/system/equipcontainer/components/StreetSelect.vue";
- import dayjs from "dayjs";
- import BoilerPlanScheduleDialog from "@/views/pressure2/equipboilerscheduling/components/BoilerPlanScheduleDialog.vue";
- import Detail from "@/views/pressure2/equipboilerscheduling/detail.vue";
- import download from '@/utils/download'
- /** 锅炉计划排期 列表 */
- defineOptions({ name: 'EquipBoilerScheduling' })
- const message = useMessage() // 消息弹窗
- const userStore = useUserStore()
- const loading = ref(true) // 列表的加载中
- const list = ref<EquipBoilerSchedulingVO[]>([]) // 列表的数据
- const total = ref(0) // 列表的总页数
- const queryParams = ref({
- pageNo: 1,
- pageSize: 10,
- unitName: undefined as string | undefined,
- unitAddress: undefined as string | undefined,
- equipCode: undefined as string | undefined,
- relateDepartment: userStore.user.deptId,
- equipDistrict: undefined as number[] | undefined,
- equipStreet: undefined as number[] | undefined,
- typeList: [] as string[],
- nextDate: [] as string[],
- useStatus: ['100'],
- areaType: 'gz'
- })
- const queryFormRef = ref() // 搜索的表单
- const source = ref<string>('pressure') // 来源:计划约检、前台约检
- const selectedRows = ref<EquipBoilerSchedulingVO[]>([]) // 选中的行
- const scheduleDialogRef = ref() // 计划排期弹窗引用
- const datePickerType = ref<'daterange' | 'month'>('month') // 修改时间选择类型定义
- const daterange = ref<string[]>([]) // 日期选择值
- const month = ref<string>('') // 月份选择值
- const detailDialogRef = ref() // 详情弹窗引用
- // 添加锅炉类型字典选项变量
- const containerTypeOptions = getStrDictOptions(DICT_TYPE.SYSTEM_EQUIP_BOILER_TYPE)
- const selectedTypeList = ref<StringDictDataType[]>([]) // 选中的锅炉归类
- const tableRef = ref() // 表格引用
- /** 查询列表 */
- const getList = async () => {
- loading.value = true
- try {
- const data = await EquipBoilerSchedulingApi.getEquipBoilerSchedulingPage(queryParams.value)
- list.value = data.list
- total.value = data.total
- } finally {
- loading.value = false
- }
- }
- /** 搜索按钮操作 */
- const handleQuery = () => {
- //queryParams.value.pageNo = 1
- getList()
- }
- /** 重置按钮操作 */
- const resetQuery = () => {
- queryFormRef.value.resetFields()
- // 重置日期相关的所有值
- daterange.value = []
- month.value = ''
- datePickerType.value = 'month' // 重置为默认的月份选择
- queryParams.value.nextDate = [] // 重置nextDate参数
- // 重置区域和街道的选择
- queryParams.value.equipDistrict = undefined
- queryParams.value.equipStreet = undefined
- areaStreetMap.value.clear()
- // 重置页码
- queryParams.value.pageNo = 1
- // 清空选中的容器归类对象
- selectedTypeList.value = []
- // 清除表格排序
- tableRef.value?.clearSort()
- handleQuery()
- }
- /** 处理日期变化 */
- const handleDateChange = (val: [string, string] | null) => {
- daterange.value = val || []
- queryParams.value.nextDate = val
- ? [
- dayjs(val[0]).startOf('day').format('YYYY-MM-DD HH:mm:ss'),
- dayjs(val[1]).endOf('day').format('YYYY-MM-DD HH:mm:ss')
- ]
- : []
- }
- /** 处理月份变化 */
- const handleMonthChange = (val: string | null) => {
- if (!val) {
- queryParams.value.nextDate = []
- return
- }
- const date = dayjs(val)
- queryParams.value.nextDate = [
- date.startOf('month').format('YYYY-MM-DD HH:mm:ss'),
- date.endOf('month').format('YYYY-MM-DD HH:mm:ss')
- ]
- month.value = val
- }
- // 记录每个区域下已选择的街道
- const areaStreetMap = ref(new Map<number, number[]>())
- /** 处理区域变化 */
- const handleAreaChange = (areas: number[]) => {
- // 获取移除的区域(通过比较之前的区域列表和现在的区域列表)
- const prevAreas = Array.from(areaStreetMap.value.keys())
- const removedAreas = prevAreas.filter((area) => !areas.includes(area))
- // 移除取消选择的区域下的街道
- if (removedAreas.length > 0) {
- const currentStreets = queryParams.value.equipDistrict || []
- removedAreas.forEach((areaId) => {
- const streetsToRemove = areaStreetMap.value.get(areaId) || []
- // 从当前选中的街道中移除这些街道
- queryParams.value.equipDistrict = currentStreets.filter(
- (streetId) => !streetsToRemove.includes(streetId)
- )
- // 从映射中移除该区域
- areaStreetMap.value.delete(areaId)
- })
- }
- }
- /** 处理区域清空 */
- const handleAreaClear = () => {
- // 清空所有选中的街道
- queryParams.value.equipDistrict = []
- // 清空区域-街道映射
- areaStreetMap.value.clear()
- }
- /** 区域类型的变化 */
- const handleAreaTypeChange = (areaType) => {
- queryParams.value.areaType = areaType
- }
- /** 处理街道变化 */
- const handleStreetChange = (streets: number[], areaId: number) => {
- // 更新区域-街道映射
- if (queryParams.value.equipDistrict?.includes(areaId)) {
- areaStreetMap.value.set(areaId, streets)
- }
- }
- /** 处理街道清空 */
- const handleStreetClear = () => {
- // 清空所有区域下的街道选择
- areaStreetMap.value.clear()
- }
- /** 处理锅炉归类变化 */
- const handleTypeListChange = (values: string[]) => {
- selectedTypeList.value = containerTypeOptions.filter((dict) => values.includes(dict.value))
- }
- /** 表格选择框变化 */
- const handleSelectionChange = (selection: EquipBoilerSchedulingVO[]) => {
- selectedRows.value = selection
- }
- /** 处理表格排序 */
- const handleSortChange = ({ prop, order }) => {
- if (!prop || !order) {
- list.value.sort(() => 0) // 重置排序
- return
- }
- list.value.sort((a, b) => {
- const aValue = a[prop] || ''
- const bValue = b[prop] || ''
- if (order === 'ascending') {
- return aValue > bValue ? 1 : -1
- } else {
- return aValue < bValue ? 1 : -1
- }
- })
- }
- /** 判断是否有已排期的时间 */
- const hasPlanSchedule = (row: EquipBoilerSchedulingVO, type: 'in' | 'out' | 'pressure') => {
- if (type === 'in') {
- return !!row.planInCheckDate
- } else if (type === 'out') {
- return !!row.planOutCheckDate
- } else {
- return !!row.planPressureCheckDate
- }
- }
- /** 获取单元格样式 */
- const getCellStyle = ({ row, column, rowIndex, columnIndex }) => {
- // 检查列是否为检验日期列
- const checkColumns = ['nextInCheckDate', 'nextOutCheckDate', 'nextPressureCheckDate']
- if (checkColumns.includes(column.property)) {
- // 根据不同类型的检验判断是否有排期
- if (column.property === 'nextInCheckDate' && row.planInCheckDate) {
- return { background: '#FFFF99' }
- } else if (column.property === 'nextOutCheckDate' && row.planOutCheckDate) {
- return { background: '#FFFF99' }
- } else if (column.property === 'nextPressureCheckDate' && row.planPressureCheckDate) {
- return { background: '#FFFF99' }
- }
- }
- return {}
- }
- /** 处理单条记录排期 */
- const handleSchedule = (row: EquipBoilerSchedulingVO) => {
- selectedRows.value = [row]
- scheduleDialogRef.value?.open([row])
- }
- //清除选择行
- const clearSelectedRows = () => {
- // 清空表格的多选状态
- nextTick(() => {
- tableRef.value?.clearSelection()
- })
- selectedRows.value = []
- }
- /** 处理编辑操作 */
- const handleEdit = (row: EquipBoilerSchedulingVO) => {
- // 传递当前的查询条件,处理 relateDepartment 类型
- const currentQueryParams = {
- // ...queryParams.value,
- // relateDepartment: queryParams.value.relateDepartment?.toString(),
- // datePickerType: datePickerType.value,
- // month: month.value
- }
- //console.log(currentQueryParams)
- detailDialogRef.value?.open(row, currentQueryParams)
- }
- /** 处理批量排期 */
- const handleBatchSchedule = () => {
- if (selectedRows.value.length === 0) {
- message.warning('请至少选择一条记录')
- return
- }
- scheduleDialogRef.value?.open()
- }
- /** 排期成功处理 */
- const handleScheduleSuccess = () => {
- selectedRows.value = []
- getList()
- }
- //保存查询参数
- const QUERY_PARAMS_CACHE_KEY = 'equip_boiler_scheduling_query_params'
- // 保存查询参数到缓存
- const saveQueryParamsToCache = () => {
- const cacheData = {
- queryParams: unref(queryParams),
- datePickerType: unref(datePickerType),
- dateRange: unref(daterange),
- month: unref(month),
- selectedTypeList: unref(selectedTypeList),
- }
- localStorage.setItem(QUERY_PARAMS_CACHE_KEY, JSON.stringify(cacheData))
- }
- // 从缓存恢复查询参数
- const loadQueryParamsFromCache = () => {
- const cacheData = localStorage.getItem(QUERY_PARAMS_CACHE_KEY)
- if (cacheData) {
- try {
- const parsedData = JSON.parse(cacheData)
- // 排除 useStatus和relateDepartment、pageNo、pageSize 字段
- const { useStatus,relateDepartment, pageNo, pageSize, ...queryParamsWithoutStatus } = parsedData.queryParams
- queryParams.value = {
- ...queryParams.value,
- ...queryParamsWithoutStatus
- }
- datePickerType.value = parsedData.datePickerType
- daterange.value = parsedData.dateRange
- month.value = parsedData.month
- selectedTypeList.value = parsedData.selectedTypeList
- } catch (error) {
- console.error('解析缓存数据失败:', error)
- }
- }
- }
- const exportLoading = ref(false) // 导出的加载中
- /** 导出按钮操作 */
- const handleExport = async () => {
- try {
- // 导出的二次确认
- await message.exportConfirm()
- // 发起导出
- exportLoading.value = true
- console.log(queryParams.value)
- const data = await EquipBoilerSchedulingApi.exportBoilerScheduling(queryParams.value)
- download.excel(data, '锅炉计划排期表单.xls')
- } catch {
- } finally {
- exportLoading.value = false
- }
- }
- /** 初始化 **/
- onMounted(() => {
- loadQueryParamsFromCache()
- getList()
- })
- onUnmounted(()=>{
- saveQueryParamsToCache()
- })
- </script>
- <style lang="scss" scoped>
- .check-number {
- font-size: 18px;
- font-weight: bold;
- }
- .regular-check {
- color: var(--el-color-primary);
- }
- .year-check {
- color: var(--el-color-success);
- }
- .expired-check {
- color: var(--el-color-danger);
- }
- .containerView {
- padding: 10px;
- }
- ::v-deep .el-select__selection.is-near {
- max-height: 200px;
- overflow-y: scroll;
- scrollbar-width: none;
- -ms-overflow-style: none;
- }
- ::v-deep .containerView .el-select__wrapper {
- min-width: 200px;
- }
- </style>
|