<route lang="json5">
|
{
|
layout: 'default',
|
needLogin: true,
|
style: { navigationBarTitleText: '点检记录', navigationStyle: 'custom' },
|
}
|
</route>
|
<template>
|
<z-paging
|
ref="paging"
|
v-model="dataList"
|
:auto="false"
|
@query="queryList"
|
refresher-only
|
show-refresher-update-time
|
>
|
<template #top>
|
<wd-navbar
|
title="点检记录"
|
left-arrow
|
@click-left="goBack"
|
right-text="提交"
|
@click-right="handleClickRight"
|
custom-style="background: #4D80F0;"
|
safeAreaInsetTop
|
>
|
<template #right>
|
<text v-if="inspSt.status === '0'" class="text-white">提交</text>
|
</template>
|
</wd-navbar>
|
<wd-card type="rectangle">
|
<template #title>
|
<view class="flex justify-between">
|
<view
|
class="flex items-center menu-title-box center"
|
style="align-content: center; flex-wrap: wrap"
|
>
|
<view class="menu-indicator"></view>
|
<view class="ml-1 text-lg align-center">{{ inspSt.equName }}</view>
|
<view class="text-color-gray ml-2 text-sm">{{ inspSt.assetNo }}</view>
|
</view>
|
|
<view class="flex items-center">
|
<text class="text-color-gray text-mini">{{ inspSt.planTimeStr }}</text>
|
</view>
|
</view>
|
</template>
|
<view class="flex h-[140rpx]" 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">
|
<text class="mr-3">点检总数: {{ dataCount }}</text>
|
|
|
<text class="mx-3">已点检: {{ checkCount }}</text>
|
|
|
<text class="ml-3">未点检: {{ dataCount - checkCount }}</text>
|
</view>
|
<view class="text-color-gray text-sm mt-2 flex">
|
<text class="mr-3">正常: {{ normalNum }}</text>
|
|
|
<text class="mx-3">异常: {{ abNormalNum }}</text>
|
</view>
|
<view class="text-color-gray text-sm mt-2 flex">
|
<text>状态:</text>
|
<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>
|
<text class="ml-1">进行中</text>
|
</template>
|
</view>
|
<view class="text-color-gray text-sm mt-2 flex">创建时间: {{ inspSt.createTime }}</view>
|
</view>
|
</view>
|
</wd-card>
|
</template>
|
|
<view class="bg-base">
|
<view class="w-full h-[24rpx]"></view>
|
<wd-cell>
|
<template #title>
|
<text class="text-color-gray text-sm">点检项</text>
|
</template>
|
<!-- <wd-button size="small" type="text" @click.stop="toggleCollapse">-->
|
<!-- {{ isAllExpanded ? '全部折叠' : '全部展开' }}-->
|
<!-- </wd-button>-->
|
</wd-cell>
|
<wd-collapse v-model="collSelects" title="点检项" ref="collapseRef" accordion>
|
<wd-collapse-item
|
:name="item.id"
|
v-for="(item, index) in dataList"
|
:key="item.id"
|
:class="getItemClass(item)"
|
>
|
<template #title="{ expanded, disabled, isFirst }">
|
<view class="flex justify-between">
|
<view class="flex justify-center items-center" style="max-width: 60%">
|
<text class="text-sm">{{ item.inspName }}</text>
|
</view>
|
|
<view class="flex items-center">
|
<wd-radio-group
|
v-model="item.inspResult"
|
inline
|
shape="dot"
|
@change="inspResultClick(item)"
|
>
|
<wd-radio value="1">正常</wd-radio>
|
<wd-radio value="2">异常</wd-radio>
|
</wd-radio-group>
|
<wd-icon
|
v-if="expanded"
|
name="arrow-up"
|
size="30rpx"
|
class="icon-color-gray"
|
></wd-icon>
|
<wd-icon v-else name="arrow-down" size="30rpx" class="icon-color-gray"></wd-icon>
|
</view>
|
</view>
|
</template>
|
|
<view v-if="item.inspResult === '2'" class="mt-2">
|
<wd-input
|
v-model="item.inspDesc"
|
placeholder="请输入异常描述"
|
clearable
|
:maxlength="200"
|
/>
|
</view>
|
<view class="text-color-gray text-sm flex justify-between">
|
<text class="mr-3">点检人: {{ item.inspUserName }}</text>
|
<text class="mx-3">点检时间: {{ item.inspTime }}</text>
|
</view>
|
</wd-collapse-item>
|
</wd-collapse>
|
<!-- <view class="w-full h-[24rpx]"></view>-->
|
<!-- <wd-cell>-->
|
<!--<!– <template #title>–>-->
|
<!--<!– <text class="text-color-gray">其他</text>–>-->
|
<!--<!– </template>–>-->
|
<!-- </wd-cell>-->
|
<view class="w-full h-[1px] bg-base"></view>
|
<wd-input
|
v-if="inspSt.status !== '0'"
|
label="运行时间"
|
label-width="200rpx"
|
clearable
|
v-model="inspSt.runTimes"
|
placeholder="请输入运行时间(h)"
|
inputmode="numeric"
|
size="large"
|
/>
|
<wd-input
|
v-if="inspSt.status !== '0'"
|
label="故障时间"
|
label-width="200rpx"
|
clearable
|
v-model="inspSt.faultTimes"
|
placeholder="请输入故障时间(h)"
|
inputmode="numeric"
|
size="large"
|
/>
|
<wd-textarea
|
label="特记事项"
|
label-width="200rpx"
|
type="textarea"
|
v-model="inspSt.specialNote"
|
auto-height
|
:maxlength="200"
|
show-word-limit
|
placeholder="请输入特记事项"
|
clearable
|
size="large"
|
/>
|
<!-- 新增提交按钮 -->
|
<view class="flex justify-around">
|
<wd-button type="primary" style="margin: 20px" block v-if="inspSt.status === '0' || inspSt.status === '1'" @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>
|
</template>
|
|
<script setup lang="ts">
|
import { useUserStore, useAccessStore, useSystemConfigStore } from '@/store'
|
import { isLeader, isLineOrRepair } from '@/utils/RoleUtils'
|
import {
|
getInspStRecordList,
|
getInspSt,
|
updateInspectSt,
|
updateInspRecordBatch,
|
} from '@/service/inspect'
|
import { useToast, useMessage } from 'wot-design-uni'
|
import type { CollapseInstance } from 'wot-design-uni/components/wd-collapse/types'
|
const message = useMessage()
|
const toast = useToast()
|
|
const collapseRef = ref<CollapseInstance>()
|
const isAllExpanded = ref(false)
|
const viewMode = ref<string>('Day')
|
|
// 定义接口
|
interface QueryParams {
|
pageNum: number
|
pageSize: number
|
inspCode: string
|
status?: string
|
}
|
|
interface InspSt {
|
id: string
|
inspCode: string
|
equName: string
|
assetNo: string
|
planTimeStr?: string
|
createTime?: string
|
status: string
|
inspUser: number | string
|
specialNote: string
|
runTimes: number
|
faultTimes: number
|
verifyUser?: number | string
|
verifyTime?: string
|
}
|
|
const dataChange = ref(false)
|
|
const userStore = useUserStore()
|
|
const collSelects = ref('')
|
const selectedItems = ref([])
|
|
// 点检汇总数据(上个页面传值)
|
const inspSt = reactive<InspSt>({
|
id: '',
|
inspCode: '',
|
equName: '',
|
assetNo: '',
|
planTimeStr: '',
|
createTime: '',
|
status: '',
|
inspUser: '',
|
specialNote: '',
|
runTimes: undefined,
|
faultTimes: undefined,
|
})
|
|
const paging = ref(null)
|
const dataList = ref([])
|
|
const queryList = () => {
|
// 这里的pageNo和pageSize会自动计算好,直接传给服务器即可
|
// 这里的请求只是演示,请替换成自己的项目的网络请求,并在网络请求回调中通过paging.value.complete(请求回来的数组)将请求结果传给z-paging
|
const params: QueryParams = {
|
inspCode: inspSt.inspCode,
|
}
|
|
getInspStRecordList(params)
|
.then((res: any) => {
|
// 请勿在网络请求回调中给dataList赋值!!只需要调用complete就可以了
|
paging.value.complete(res.rows, res.total)
|
})
|
.catch((res) => {
|
// 如果请求失败写paging.value.complete(false),会自动展示错误页面
|
// 注意,每次都需要在catch中写这句话很麻烦,z-paging提供了方案可以全局统一处理
|
// 在底层的网络请求抛出异常时,写uni.$emit('z-paging-error-emit');即可
|
paging.value.complete(false)
|
})
|
}
|
|
function inspResultClick(item: any) {
|
console.log('inspResultClick', userStore.userInfo)
|
// 自动填充点检人和时间
|
item.inspUserName = userStore?.userInfo?.realName || ''
|
// 修改时间格式为 YYYY-MM-DD HH:mm:ss
|
const now = new Date()
|
item.inspTime = `${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')}`
|
}
|
|
const goBack = () => {
|
uni.navigateBack()
|
}
|
|
function handleClickRight() {
|
|
if (inspSt.status === '0') {
|
handleConfirm()
|
} else if (inspSt.status === '1') {
|
handleComplete()
|
}
|
}
|
|
const toggleCollapse = () => {
|
isAllExpanded.value = !isAllExpanded.value
|
collapseRef.value.toggleAll(isAllExpanded.value)
|
}
|
|
function handleConfirm() {
|
console.log('handleConfirm')
|
if (!dataChange.value) {
|
message.alert('请操作后提交!')
|
return false
|
}
|
|
// 检查是否有异常项未填写描述
|
const invalidItems = dataList.value.filter(
|
(item) => item.inspResult === '2' && !item.inspDesc?.trim(),
|
)
|
if (invalidItems.length > 0) {
|
message.alert('请填写所有异常项的异常描述!')
|
return false
|
}
|
|
// 过滤出已选择的项目
|
selectedItems.value = dataList.value.filter(
|
(item) => item.inspResult === '1' || item.inspResult === '2',
|
)
|
|
if (selectedItems.value.length === 0) {
|
message.alert('请至少选择一个点检项!')
|
return false
|
}
|
|
message
|
.confirm({
|
msg: '确定提交?',
|
title: '提示',
|
beforeConfirm: ({ resolve }) => {
|
updateData(resolve)
|
},
|
})
|
.then(() => {
|
goBack()
|
})
|
.catch((error) => {
|
console.log(error)
|
})
|
}
|
|
function updateData(resolve: any) {
|
console.log('updateData', selectedItems.value)
|
const params = {
|
inspRecordList: selectedItems.value,
|
}
|
// 更新点检记录
|
updateInspRecordBatch(params)
|
.then((res: any) => {
|
updateInspSt(resolve)
|
})
|
.catch((res) => {
|
console.error(res)
|
toast.error('操作失败')
|
})
|
}
|
function updateInspSt(resolve: any) {
|
// 更新点检汇总
|
if (dataCount.value === selectedItems.value.length) {
|
inspSt.status = '1'
|
} else {
|
inspSt.status = '0'
|
}
|
|
updateInspectSt(inspSt)
|
.then((res: any) => {
|
toast.success('操作成功')
|
paging.value.reload()
|
uni.$emit('insp-st-refresh')
|
resolve(true)
|
})
|
.catch((res) => {
|
console.error(res)
|
toast.error('操作失败')
|
})
|
}
|
|
/**
|
* 确认完成按钮点击事件
|
*/
|
function handleComplete() {
|
console.log('handleComplete', inspSt)
|
if (!inspSt.runTimes || !inspSt.faultTimes) {
|
message.alert('请填写运行次数和故障次数!')
|
return false
|
}
|
// 如果当前时间距上次新时间两小时以内则不允许确认
|
console.log('inspSt.updateTime', inspSt.updateTime)
|
console.log('new Date().getTime()', new Date().getTime())
|
console.log('inspSt.updateTime', new Date(inspSt.updateTime).getTime())
|
console.log('new Date().getTime() - new Date(inspSt.updateTime).getTime()', new Date().getTime() - new Date(inspSt.updateTime).getTime())
|
console.log("2 * 60 * 60 * 1000", 2 * 60 * 60 * 1000)
|
console.log('new Date().getTime() - new Date(inspSt.updateTime).getTime() < 2 * 60 * 60 * 1000', new Date().getTime() - new Date(inspSt.updateTime).getTime() < 2 * 60 * 60 * 1000)
|
if (
|
new Date().getTime() - new Date(inspSt.updateTime).getTime() < 2 * 60 * 60 * 1000
|
) {
|
console.log("new Date().getTime() - new Date(inspSt.updateTime).getTime() < 2 * 60 * 60 * 1000",new Date().getTime() - new Date(inspSt.updateTime).getTime() < 2 * 60 * 60 * 1000)
|
message.alert('点检两小时以内不允许确认!')
|
return false
|
}
|
const now = new Date();
|
const data: any = Object.assign(
|
{},
|
{
|
id: inspSt.id,
|
runTimes: inspSt.runTimes,
|
faultTimes: inspSt.faultTimes,
|
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
|
*/
|
function itemClick(item: any) {}
|
|
function getItemClass(item: any) {
|
if (item.inspResult === '1') {
|
return 'status-normal'
|
} else if (item.inspResult === '2') {
|
return 'status-abnormal'
|
}
|
return ''
|
}
|
|
watch(
|
() => [...dataList.value, inspSt], // 使用扩展运算符创建新数组以触发监听
|
(newVal, oldVal) => {
|
if (oldVal.length > 0) {
|
dataChange.value = true
|
}
|
},
|
{ deep: true },
|
)
|
onLoad((options) => {
|
// inspSt.id = options.id
|
// inspSt.inspCode = options.inspCode
|
// inspSt.equName = options.equName
|
// inspSt.assetNo = options.assetNo
|
// inspSt.planTimeStr = options.planTimeStr
|
// inspSt.createTime = options.createTime
|
// inspSt.specialNote = options?.specialNote
|
// inspSt.inspUser = userStore?.userInfo?.userId
|
viewMode.value = options.viewMode
|
initData(options.id)
|
})
|
|
function initData(id: any) {
|
getInspSt(id)
|
.then((res: any) => {
|
if (res?.id) {
|
const inspCode = `${res?.equId}_${res?.planTime}_${viewMode.value}`
|
inspSt.inspCode = inspCode
|
Object.assign(inspSt, res)
|
reloadData()
|
} else {
|
uni.showToast({
|
title: '数据查询失败,请联系管理员',
|
icon: 'none',
|
})
|
}
|
})
|
.catch((res) => {
|
console.error(res)
|
})
|
}
|
function reloadData() {
|
paging.value.reload()
|
}
|
const dataCount = computed(() => dataList.value.length)
|
const checkCount = computed(() => dataList.value.filter((item) => item.status === '1').length)
|
const normalNum = computed(() => dataList.value.filter((item) => item.inspResult === '1').length)
|
const abNormalNum = computed(() => dataList.value.filter((item) => item.inspResult === '2').length)
|
</script>
|
|
<style scoped lang="scss">
|
.menu-title-box {
|
height: 30rpx;
|
line-height: 30rpx;
|
}
|
|
.slot-img {
|
width: 72rpx;
|
height: 72rpx;
|
margin-right: 24rpx;
|
}
|
.text-mini {
|
font-size: 24rpx;
|
}
|
|
.menu-indicator {
|
width: 6rpx;
|
height: 22rpx;
|
border-radius: 10rpx;
|
background-color: $uni-color-primary;
|
}
|
:deep(.wd-card__footer) {
|
padding: 10rpx !important;
|
}
|
|
.col-title-box {
|
}
|
.bg-primary {
|
background: $uni-color-primary;
|
}
|
:deep(.wd-navbar__text) {
|
font-size: 28rpx;
|
color: white;
|
}
|
:deep(.wd-icon-arrow-left:before),
|
:deep(.wd-navbar__title) {
|
color: white;
|
font-weight: 0;
|
font-size: 34rpx;
|
}
|
|
// 新增样式:点检项背景色
|
.status-normal {
|
background-color: #e6f7ff; // 正常状态背景色(绿色)
|
}
|
|
.status-abnormal {
|
background-color: #fffbe6; // 异常状态背景色(黄色)
|
}
|
:deep(.wd-radio-group) {
|
// 改为无背景色
|
background-color: transparent;
|
}
|
</style>
|