| | |
| | | { |
| | | layout: 'default', |
| | | needLogin: true, |
| | | style: { |
| | | navigationBarTitleText: '点检记录', |
| | | 'app-plus': { |
| | | titleNView: { |
| | | buttons: [ |
| | | { |
| | | text: '提交', |
| | | fontSize: '14px', |
| | | color: '#FFFFFF', |
| | | }, |
| | | { |
| | | text: '', |
| | | fontSize: '24px', |
| | | color: '#FFFFFF', |
| | | }, |
| | | ], |
| | | }, |
| | | }, |
| | | }, |
| | | style: { navigationBarTitleText: '点检记录', navigationStyle: 'custom' }, |
| | | } |
| | | </route> |
| | | <template> |
| | | <z-paging ref="paging" v-model="dataList" :auto="false" @query="queryList" show-refresher-update-time> |
| | | <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"> |
| | | <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-sm align-center">{{ inspSt.equName }}</view> |
| | | <view class="text-color-gray ml-2 text-mini">{{ inspSt.assetNo }}</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"> |
| | |
| | | <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-xs mt-1 flex"> |
| | | <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-xs mt-2 flex"> |
| | | <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-xs mt-2 flex"> |
| | | <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> |
| | | <text class="ml-1">进行中</text> |
| | | </template> |
| | | </view> |
| | | <view class="text-color-gray text-xs mt-2 flex">创建时间: {{ inspSt.createTime }}</view> |
| | | <view class="text-color-gray text-sm mt-2 flex">创建时间: {{ inspSt.createTime }}</view> |
| | | </view> |
| | | </view> |
| | | </wd-card> |
| | |
| | | <view class="w-full h-[24rpx]"></view> |
| | | <wd-cell> |
| | | <template #title> |
| | | <text class="text-color-gray">点检项</text> |
| | | <text class="text-color-gray text-sm">点检项</text> |
| | | </template> |
| | | <wd-button size="small" type="text" @click.stop="toggleCollapse"> |
| | | {{ isAllExpanded ? '全部折叠' : '全部展开' }} |
| | | </wd-button> |
| | | <!-- <wd-button size="small" type="text" @click.stop="toggleCollapse">--> |
| | | <!-- {{ isAllExpanded ? '全部折叠' : '全部展开' }}--> |
| | | <!-- </wd-button>--> |
| | | </wd-cell> |
| | | <wd-collapse v-model="collSelects" title="点检项" ref="collapseRef"> |
| | | <wd-collapse-item :name="item.id" v-for="(item, index) in dataList"> |
| | | <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"> |
| | | <view class="flex justify-center items-center" style="max-width: 60%"> |
| | | <text class="text-sm">{{ item.inspName }}</text> |
| | | </view> |
| | | |
| | |
| | | </view> |
| | | </view> |
| | | </template> |
| | | <view class="text-color-gray text-xs flex justify-between"> |
| | | |
| | | <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-[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" |
| | |
| | | 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 { ref } from 'vue' |
| | | import { useUserStore, useAccessStore, useSystemConfigStore } from '@/store' |
| | | import { isLeader, isLineOrRepair } from '@/utils/RoleUtils' |
| | | import { |
| | | getInspStRecordList, |
| | | getInspSt, |
| | |
| | | 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<string[]>([]) |
| | | const collSelects = ref('') |
| | | const selectedItems = ref([]) |
| | | |
| | | // 点检汇总数据(上个页面传值) |
| | | const inspSt = reactive<InspSt>({ |
| | |
| | | status: '', |
| | | inspUser: '', |
| | | specialNote: '', |
| | | runTimes: undefined, |
| | | faultTimes: undefined, |
| | | }) |
| | | |
| | | const paging = ref(null) |
| | | const dataList = ref([]) |
| | | |
| | | const queryList = (pageNum?: number, pageSize?: number) => { |
| | | const queryList = () => { |
| | | // 这里的pageNo和pageSize会自动计算好,直接传给服务器即可 |
| | | // 这里的请求只是演示,请替换成自己的项目的网络请求,并在网络请求回调中通过paging.value.complete(请求回来的数组)将请求结果传给z-paging |
| | | const params: QueryParams = { |
| | | pageNum, |
| | | pageSize, |
| | | inspCode: inspSt.inspCode, |
| | | } |
| | | |
| | | getInspStRecordList(params) |
| | | .then((res: any) => { |
| | | // 请勿在网络请求回调中给dataList赋值!!只需要调用complete就可以了 |
| | | paging.value.completeByTotal(res.rows, res.total) |
| | | paging.value.complete(res.rows, res.total) |
| | | }) |
| | | .catch((res) => { |
| | | // 如果请求失败写paging.value.complete(false),会自动展示错误页面 |
| | |
| | | } |
| | | |
| | | function inspResultClick(item: any) { |
| | | // userStore?.userInfo?.userId |
| | | 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() |
| | | } |
| | | onNavigationBarButtonTap((e) => { |
| | | if (e.index === 0) { |
| | | |
| | | function handleClickRight() { |
| | | |
| | | if (inspSt.status === '0') { |
| | | handleConfirm() |
| | | } else if (inspSt.status === '1') { |
| | | handleComplete() |
| | | } |
| | | }) |
| | | } |
| | | |
| | | const toggleCollapse = () => { |
| | | isAllExpanded.value = !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: '确定提交?', |
| | |
| | | updateData(resolve) |
| | | }, |
| | | }) |
| | | .then(() => {}) |
| | | .then(() => { |
| | | goBack() |
| | | }) |
| | | .catch((error) => { |
| | | console.log(error) |
| | | }) |
| | | } |
| | | |
| | | function updateData(resolve: any) { |
| | | console.log('updateData', selectedItems.value) |
| | | const params = { |
| | | inspRecordList: dataList.value, |
| | | inspRecordList: selectedItems.value, |
| | | } |
| | | // 更新点检记录 |
| | | updateInspRecordBatch(params) |
| | | .then((res: any) => { |
| | | updateInspSt(resolve) |
| | | toast.success('操作成功') |
| | | }) |
| | | .catch((res) => { |
| | | console.error(res) |
| | | toast.error('操作失败') |
| | | }) |
| | | } |
| | | function updateInspSt(resolve: any) { |
| | | // 更新点检汇总 |
| | | inspSt.status = '1' |
| | | 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('操作失败') |
| | | }) |
| | | } |
| | | |
| | |
| | | */ |
| | | 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], // 使用扩展运算符创建新数组以触发监听 |
| | | () => [...dataList.value, inspSt], // 使用扩展运算符创建新数组以触发监听 |
| | | (newVal, oldVal) => { |
| | | if (oldVal.length > 0) { |
| | | dataChange.value = true |
| | |
| | | margin-right: 24rpx; |
| | | } |
| | | .text-mini { |
| | | font-size: 22rpx; |
| | | font-size: 24rpx; |
| | | } |
| | | |
| | | .menu-indicator { |
| | |
| | | background: $uni-color-primary; |
| | | } |
| | | :deep(.wd-navbar__text) { |
| | | font-size: 26rpx; |
| | | font-size: 28rpx; |
| | | color: white; |
| | | } |
| | | :deep(.wd-icon-arrow-left:before), |
| | | :deep(.wd-navbar__title) { |
| | | color: white; |
| | | font-weight: 0; |
| | | font-size: 32rpx; |
| | | font-size: 34rpx; |
| | | } |
| | | |
| | | // 新增样式:点检项背景色 |
| | | .status-normal { |
| | | background-color: #e6f7ff; // 正常状态背景色(绿色) |
| | | } |
| | | |
| | | .status-abnormal { |
| | | background-color: #fffbe6; // 异常状态背景色(黄色) |
| | | } |
| | | :deep(.wd-radio-group) { |
| | | // 改为无背景色 |
| | | background-color: transparent; |
| | | } |
| | | </style> |