车间能级提升-智能设备管理系统
baoshiwei
2025-06-09 2ab727eb8a56077d9ad52112a9c8e97010b84b6d
feat(eims): 优化保养计划和点检记录功能

-移除保养人和保养部门的必填验证
- 修改计划时间格式为年月日
-调整工单生成逻辑,提前10天生成
-优化点检记录和保养计划的状态处理
- 添加确认完成功能- 实现工单卡片根据不同状态显示不同背景颜色
-调整筛选条件为标签页形式
已修改8个文件
261 ■■■■ 文件已修改
eims-ui-mobile/src/pages/inspect/insp-record.vue 51 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
eims-ui-mobile/src/pages/inspect/insp-st.vue 48 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
eims-ui-mobile/src/pages/maint/maint-order.vue 60 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
eims-ui-mobile/src/pages/maint/maint-st.vue 89 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
eims-ui-mobile/src/utils/RoleUtils.ts 5 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
eims/ruoyi-modules/lb-eims/src/main/java/org/dromara/eims/domain/bo/EimsMaintPlanBo.java 4 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
eims/ruoyi-modules/lb-eims/src/main/java/org/dromara/eims/domain/vo/EimsMaintStVo.java 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
eims/ruoyi-modules/lb-eims/src/main/java/org/dromara/eims/job/MaintPlanToOrderJob.java 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
eims-ui-mobile/src/pages/inspect/insp-record.vue
@@ -24,7 +24,7 @@
        safeAreaInsetTop
      >
        <template #right>
          <text v-if="isOperatorOrRepair()" class="text-white">提交</text>
          <text v-if="inspSt.status === '0'" class="text-white">提交</text>
        </template>
      </wd-navbar>
      <wd-card type="rectangle">
@@ -61,9 +61,13 @@
            </view>
            <view class="text-color-gray text-sm mt-2 flex">
              <text>状态:</text>
              <template v-if="dataCount > 0 && dataCount === checkCount">
              <template v-if="inspSt.status === '1'">
                <wd-icon class="icon-color-success" name="check-outline" size="34rpx"></wd-icon>
                <text class="ml-1">已完成</text>
              </template>
              <template v-else-if="inspSt.status === '2'">
                <wd-icon class="icon-color-warning" name="check-outline" size="34rpx"></wd-icon>
                <text class="ml-1">已确认</text>
              </template>
              <template v-else>
                <wd-icon class="icon-color-base" name="detection" size="40rpx"></wd-icon>
@@ -172,8 +176,9 @@
        size="large"
      />
      <!-- 新增提交按钮 -->
      <view class="flex justify-center mt-4">
        <wd-button type="primary" block size="large" @click="handleClickRight">提交</wd-button>
      <view class="flex justify-around mt-4">
        <wd-button type="primary" block size="large" v-if="inspSt.status === '0'" @click="handleClickRight">提交</wd-button>
        <wd-button type="success" block size="large" v-if="isLeader() && inspSt.status === '1'" @click="handleComplete">确认完成</wd-button>
      </view>
    </view>
  </z-paging>
@@ -217,6 +222,8 @@
  specialNote: string
  runTimes: number
  faultTimes: number
  verifyUser?: number | string
  verifyTime?: string
}
const dataChange = ref(false)
@@ -356,7 +363,11 @@
}
function updateInspSt(resolve: any) {
  // 更新点检汇总
  if (dataCount.value === selectedItems.value.length) {
  inspSt.status = '1'
  } else {
    inspSt.status = '0'
  }
  updateInspectSt(inspSt)
    .then((res: any) => {
      toast.success('操作成功')
@@ -371,6 +382,38 @@
}
/**
 * 确认完成按钮点击事件
 */
function handleComplete() {
  if (!isLeader()) {
    toast.info('无权限操作');
    return;
  }
  const now = new Date();
  const data: any = Object.assign(
    {},
    {
      id: inspSt.id,
      status: '2',
      verifyUser: userStore?.userInfo?.userId,
      verifyTime: `${now.getFullYear()}-${String(now.getMonth() + 1).padStart(2, '0')}-${String(now.getDate()).padStart(2, '0')} ${String(now.getHours()).padStart(2, '0')}:${String(now.getMinutes()).padStart(2, '0')}:${String(now.getSeconds()).padStart(2, '0')}`
    },
  )
  updateInspectSt(data)
    .then((res: any) => {
      if (res?.code === 200) {
        uni.$emit('insp-st-refresh')
        goBack()
        toast.success('操作成功')
      }
    })
    .catch((res) => {
      console.error(res)
      toast.error('操作失败')
    })
}
/**
 * 点检记录条目点击事件
 * @param item
 */
eims-ui-mobile/src/pages/inspect/insp-st.vue
@@ -11,15 +11,11 @@
<template>
  <z-paging ref="paging" v-model="dataList" @query="queryList" show-refresher-update-time>
    <template #top>
      <wd-drop-menu>
        <wd-drop-menu-item v-model="viewMode" :options="viewModeList" @change="handleViewMode" />
        <wd-drop-menu-item
          v-model="filterDate"
          :options="filterDateList"
          @change="handleFilterDate"
        />
        <wd-drop-menu-item v-model="equName" :options="equList" @change="handleEquName" />
      </wd-drop-menu>
      <wd-tabs v-model="activeTab" @change="handleTabChange">
        <wd-tab title="待点检"></wd-tab>
        <wd-tab title="待确认"></wd-tab>
        <wd-tab title="已完成"></wd-tab>
      </wd-tabs>
    </template>
    <view class="bg-base">
      <wd-card type="rectangle" v-for="(item, index) in dataList" :key="item.id">
@@ -40,7 +36,7 @@
            </view>
          </view>
        </template>
        <view class="flex h-[140rpx]" items-center>
        <view class="flex h-[200rpx]" items-center>
          <image class="slot-img text-center" src="/static/images/camera.png" />
          <view class="flex-1">
            <view class="text-color-gray text-sm mt-1 flex">
@@ -57,9 +53,13 @@
            </view>
            <view class="text-color-gray text-sm mt-2 flex">
              <text>状态:</text>
              <template v-if="item.recordCount === item.checkCount">
              <template v-if="item.status === '1'">
                <wd-icon class="icon-color-success" name="check-outline" size="34rpx"></wd-icon>
                <text class="ml-1">已完成</text>
              </template>
              <template v-else-if="item.status === '2'">
                <wd-icon class="icon-color-warning" name="check-outline" size="34rpx"></wd-icon>
                <text class="ml-1">已确认</text>
              </template>
              <template v-else>
                <wd-icon class="icon-color-base" name="detection" size="40rpx"></wd-icon>
@@ -76,13 +76,17 @@
</template>
<script setup lang="ts">
import { ref } from 'vue'
import { getInspStList } from '@/service/inspect'
import dayjs from 'dayjs'
// 标签页相关
const activeTab = ref(0) // 默认选中第一个标签页(待点检)
// 原有变量
const viewMode = ref<string>('Day')
const equName = ref<string>('所有设备')
const filterDate = ref<string>('1')
const status = ref<string>('0') // 默认为待点检状态
const viewModeList = ref<Record<string, any>[]>([
  { label: '日视图', value: 'Day' },
@@ -94,6 +98,25 @@
])
const equList = ref<Record<string, any>[]>([{ label: '所有设备', value: '所有设备' }])
// 标签页切换处理函数
function handleTabChange({ index }) {
  // 根据标签页索引设置对应的状态值
  if (index === 0) {
    // 待点检
    status.value = '0'
  } else if (index === 1) {
    // 待确认
    status.value = '1'
  } else if (index === 2) {
    // 已完成
    status.value = '2'
  }
  // 重新加载数据
  reloadData()
}
// 原有函数
function handleViewMode({ value }) {
  reloadData()
}
@@ -112,6 +135,7 @@
    pageNum,
    pageSize,
    viewMode: viewMode.value,
    status: status.value, // 添加状态筛选
  }
  if (filterDate.value === '1') {
    params.planTime = dayjs().format('YYYY-MM-DD')
eims-ui-mobile/src/pages/maint/maint-order.vue
@@ -25,7 +25,7 @@
        safeAreaInsetTop
      >
        <template #right>
          <text v-if="isOperatorOrRepair()" class="text-white">提交</text>
          <text v-if="maintSt.status === '0'" class="text-white">提交</text>
        </template>
      </wd-navbar>
      <wd-cell>
@@ -48,7 +48,7 @@
            </view>
          </view>
        </template>
        <view class="flex h-[140rpx]" items-center>
        <view class="flex" items-center>
          <image class="slot-img text-center" src="/static/images/camera.png" />
          <view class="flex-1">
            <view class="text-color-gray text-sm mt-1 flex">
@@ -60,14 +60,18 @@
              <text class="mr-3">待保养: {{ maintSt.dbyCount }}</text>
              |
              <text class="mx-3">保养中: {{ maintSt.byCount }}</text>
              |
              <text class="ml-3">待验证: {{ maintSt.dyzCount }}</text>
<!--              |-->
<!--              <text class="ml-3">待验证: {{ maintSt.dyzCount }}</text>-->
            </view>
            <view class="text-color-gray text-sm mt-2 flex">
              <text>状态:</text>
              <template v-if="maintSt.status === '1'">
                <wd-icon class="icon-color-success" name="check-outline" size="34rpx"></wd-icon>
                <text class="ml-1">已完成</text>
              </template>
              <template v-else-if="maintSt.status === '2'">
                <wd-icon class="icon-color-warning" name="check-outline" size="34rpx"></wd-icon>
                <text class="ml-1">已确认</text>
              </template>
              <template v-else>
                <wd-icon class="icon-color-base" name="detection" size="40rpx"></wd-icon>
@@ -205,11 +209,16 @@
        placeholder="请输入特记事项"
        clearable
      />
      <!-- 新增确认完成按钮 -->
      <view class="flex justify-around mt-4">
        <wd-button type="primary" block size="large" v-if="maintSt.status === '0'" @click="handleClickRight">提交</wd-button>
        <wd-button type="success" block size="large" v-if="isLeader() && maintSt.status === '1'" @click="handleComplete">确认完成</wd-button>
      </view>
    </view>
    <!-- 新增提交按钮 -->
    <view class="flex justify-center mt-4">
      <wd-button type="primary" block size="large" @click="handleClickRight">提交</wd-button>
    </view>
<!--    <view class="flex justify-center mt-4">-->
<!--      <wd-button type="primary" block size="large" @click="handleClickRight">提交</wd-button>-->
<!--    </view>-->
  </z-paging>
  <!-- 备件选择弹出层 -->
@@ -340,7 +349,7 @@
}
function loadSpareParts(value?: string) {
  getSpareList({ name: value }).then((res: any) => {
  getSpareList({ name: value, pageNum: 1, pageSize: 10 }).then((res: any) => {
    sparePartsList.value = res.rows
  })
@@ -498,7 +507,8 @@
          .then((res: any) => {
            resolve(true)
            if (res?.code === 200) {
              reloadData()
              uni.$emit('maint-st-refresh')
              goBack()
              toastSucces()
            }
          })
@@ -604,6 +614,38 @@
    });
}
/**
 * 确认完成按钮点击事件
 */
function handleComplete() {
  if (!isLeader()) {
    toast.info('无权限操作');
    return;
  }
  const now = new Date();
  const data: any = Object.assign(
    {},
    {
      id: maintSt.id,
      status: '2',
      verifyUser: userStore?.userInfo?.userId ,
      verifyTime: `${now.getFullYear()}-${String(now.getMonth() + 1).padStart(2, '0')}-${String(now.getDate()).padStart(2, '0')} ${String(now.getHours()).padStart(2, '0')}:${String(now.getMinutes()).padStart(2, '0')}:${String(now.getSeconds()).padStart(2, '0')}`
    },
  )
  updateMaintSt(data)
    .then((res: any) => {
      if (res?.code === 200) {
        uni.$emit('maint-st-refresh')
        goBack()
        toastSucces()
      }
    })
    .catch((res) => {
      console.error(res)
    })
}
// 新增方法:获取状态文本
function getStatusText(maintFun: string): string {
  switch (maintFun) {
eims-ui-mobile/src/pages/maint/maint-st.vue
@@ -11,18 +11,19 @@
<template>
  <z-paging ref="paging" v-model="dataList" @query="queryList" show-refresher-update-time>
    <template #top>
      <wd-drop-menu>
        <wd-drop-menu-item v-model="equName" :options="equList" @change="handleEquName" />
        <wd-drop-menu-item
          v-model="filterDate"
          :options="filterDateList"
          @change="handleFilterDate"
        />
        <wd-drop-menu-item v-model="status" :options="statusList" @change="handleStatus" />
      </wd-drop-menu>
      <wd-tabs v-model="activeTab" @change="handleTabChange">
        <wd-tab title="待保养"></wd-tab>
        <wd-tab title="待确认"></wd-tab>
        <wd-tab title="已完成"></wd-tab>
      </wd-tabs>
    </template>
    <view class="bg-base">
      <wd-card type="rectangle" v-for="(item, index) in dataList" :key="item.id">
      <wd-card
        type="rectangle"
        v-for="(item, index) in dataList"
        :key="item.id"
        :class="[getCardColorClass(item.planTime)]"
      >
        <template #title>
          <view class="flex justify-between">
            <view class="flex items-center menu-title-box">
@@ -40,7 +41,7 @@
            </view>
          </view>
        </template>
        <view class="flex h-[140rpx]" items-center>
        <view class="flex" items-center>
          <image class="slot-img text-center" src="/static/images/camera.png" />
          <view class="flex-1">
            <view class="text-color-gray text-sm mt-1 flex">
@@ -52,14 +53,18 @@
              <text class="mr-3">待保养: {{ item.dbyCount }}</text>
              |
              <text class="mx-3">保养中: {{ item.byCount }}</text>
              |
              <text class="ml-3">待验证: {{ item.dyzCount }}</text>
<!--              |-->
<!--              <text class="ml-3">待验证: {{ item.dyzCount }}</text>-->
            </view>
            <view class="text-color-gray text-sm mt-2 flex">
              <text>状态:</text>
              <template v-if="item.status === '1'">
                <wd-icon class="icon-color-success" name="check-outline" size="34rpx"></wd-icon>
                <text class="ml-1">已完成</text>
              </template>
              <template v-else-if="item.status === '2'">
                <wd-icon class="icon-color-warning" name="check-outline" size="34rpx"></wd-icon>
                <text class="ml-1">已确认</text>
              </template>
              <template v-else>
                <wd-icon class="icon-color-base" name="detection" size="40rpx"></wd-icon>
@@ -76,7 +81,7 @@
</template>
<script setup lang="ts">
import { ref } from 'vue'
import { ref, computed } from 'vue'
import { getMaintStList } from '@/service/maint'
import dayjs from 'dayjs'
@@ -99,12 +104,37 @@
  params?: NonNullable<unknown>
}
// 计算工单卡片的背景颜色类
function getCardColorClass(planTime) {
  if (!planTime) return ''
  const now = dayjs()
  const planDate = dayjs(planTime)
  const diffDays = planDate.diff(now, 'day')
  if (diffDays < 0) {
    // 超过计划时间,红色背景
    return 'card-overdue'
  } else if (diffDays <= 3) {
    // 距离计划时间三天以内,黄色背景
    return 'card-urgent'
  } else {
    // 正常状态,背景颜色不变
    return ''
  }
}
// 页面参数,上个页面传递过来的参数
const option = reactive<PageParams>({
  assetNo: '',
  from: '',
})
const status = ref<string>('-1')
// 标签页相关
const activeTab = ref(0) // 默认选中第一个标签页(待保养)
// 原有状态
const status = ref<string>('0') // 默认为待保养状态
const equName = ref<string>('-1')
const filterDate = ref<string>('1')
@@ -121,6 +151,25 @@
  { label: '已完成', value: '3' },
])
const equList = ref<Record<string, any>[]>([{ label: '所有设备', value: '-1' }])
// 标签页切换处理函数
function handleTabChange({ index }) {
  // 根据标签页索引设置对应的状态值
  if (index === 0) {
    // 待保养
    status.value = '0'
  } else if (index === 1) {
    // 待确认
    status.value = '1'
  } else if (index === 2) {
    // 已完成
    status.value = '2'
  }
  // 重新加载数据
  reloadData()
}
// 原有函数
function handleStatus({ value }) {}
function handleEquName({ value }) {
  console.log(value)
@@ -185,6 +234,8 @@
function reloadData() {
  paging.value.reload()
}
onLoad((options) => {
  Object.assign(option, options)
  uni.$on('maint-st-refresh', reloadData)
@@ -223,4 +274,12 @@
:deep(.wd-card__title-content) {
  padding: 24rpx 0 !important;
}
/* 工单卡片背景颜色 */
.card-urgent {
  background-color: rgba(255, 204, 0, 0.1); /* 黄色背景 */
}
.card-overdue {
  background-color: rgba(255, 0, 0, 0.1); /* 红色背景 */
}
</style>
eims-ui-mobile/src/utils/RoleUtils.ts
@@ -26,8 +26,9 @@
 * 登录角色是操作工或维修工
 */
export const isOperatorOrRepair = () => {
  const roles = useUserStore()?.userInfo?.roles || []
  return roles.includes(ROLE_OPERATOR) || roles.includes(ROLE_REPAIR)
  // const roles = useUserStore()?.userInfo?.roles || []
  // return roles.includes(ROLE_OPERATOR) || roles.includes(ROLE_REPAIR)
  return true
}
/**
eims/ruoyi-modules/lb-eims/src/main/java/org/dromara/eims/domain/bo/EimsMaintPlanBo.java
@@ -79,13 +79,13 @@
    /**
     * 保养人
     */
    @NotNull(message = "保养人不能为空", groups = { AddGroup.class, EditGroup.class })
//    @NotNull(message = "保养人不能为空", groups = { AddGroup.class, EditGroup.class })
    private Long maintUser;
    /**
     * 保养部门
     */
    @NotNull(message = "保养部门不能为空", groups = { AddGroup.class, EditGroup.class })
//    @NotNull(message = "保养部门不能为空", groups = { AddGroup.class, EditGroup.class })
    private Long maintDept;
    /**
eims/ruoyi-modules/lb-eims/src/main/java/org/dromara/eims/domain/vo/EimsMaintStVo.java
@@ -57,7 +57,7 @@
     *
     */
    @ExcelProperty(value = "")
    @JsonFormat(pattern = "yyyy-MM")
    @JsonFormat(pattern = "yyyy-MM-dd")
    private Date planTime;
    /**
     *稽查日期
eims/ruoyi-modules/lb-eims/src/main/java/org/dromara/eims/job/MaintPlanToOrderJob.java
@@ -57,7 +57,7 @@
            Date oldNext = planVo.getMaintNextTime();
            int day = DateUtils.differentDays(today, oldNext);
            // 如果计划生成工单日期大于今天则不生成工单
            if (day >= 1) {
            if (day >= 10) {
                continue;
            }