From 46d143d1d6fe8f286399f4d027c9a86adf7cd7fc Mon Sep 17 00:00:00 2001 From: baoshiwei <baoshiwei@shlanbao.cn> Date: 星期三, 09 七月 2025 08:50:01 +0800 Subject: [PATCH] feat(inspection,maintenance): - 实现保养工单批量确认功能 - 在点检记录确认时增加时间限制,距离上次更新时间两小时内不允许确认 --- eims-ui-mobile/src/pages/inspect/insp-record.vue | 311 +++++++++++++++++++++++++++++++++++++++++++-------- 1 files changed, 263 insertions(+), 48 deletions(-) diff --git a/eims-ui-mobile/src/pages/inspect/insp-record.vue b/eims-ui-mobile/src/pages/inspect/insp-record.vue index f0b128d..aa5832a 100644 --- a/eims-ui-mobile/src/pages/inspect/insp-record.vue +++ b/eims-ui-mobile/src/pages/inspect/insp-record.vue @@ -1,14 +1,19 @@ <route lang="json5"> { - style: { - navigationBarTitleText: '鐐规璁板綍', - navigationStyle: 'custom', - navigationBarBackgroundColor: '#4D80F0', - }, + layout: 'default', + needLogin: true, + style: { navigationBarTitleText: '鐐规璁板綍', navigationStyle: 'custom' }, } </route> <template> - <z-paging ref="paging" v-model="dataList" @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="鐐规璁板綍" @@ -18,15 +23,21 @@ @click-right="handleClickRight" custom-style="background: #4D80F0;" safeAreaInsetTop - ></wd-navbar> - + > + <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"> @@ -34,32 +45,37 @@ </view> </view> </template> - <view class="flex h-[100rpx]" 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">姝e父: {{ 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"> - <wd-icon class="icon-color-success" name="check-outline" size="40rpx"></wd-icon> + <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> @@ -69,17 +85,22 @@ <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> @@ -103,13 +124,48 @@ </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-[1rpx] bg-base"></view> + <!-- <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" @@ -120,15 +176,26 @@ 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 { getInspStRecordList, updateInspectSt, updateInspRecordBatch } from '@/service/inspect' +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() @@ -136,6 +203,7 @@ const collapseRef = ref<CollapseInstance>() const isAllExpanded = ref(false) +const viewMode = ref<string>('Day') // 瀹氫箟鎺ュ彛 interface QueryParams { @@ -151,16 +219,22 @@ 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<string[]>([]) +const collSelects = ref('') +const selectedItems = ref([]) // 鐐规姹囨�绘暟鎹�(涓婁釜椤甸潰浼犲��) const inspSt = reactive<InspSt>({ @@ -169,27 +243,28 @@ equName: '', assetNo: '', planTimeStr: '', + createTime: '', status: '', inspUser: '', specialNote: '', + runTimes: undefined, + faultTimes: undefined, }) const paging = ref(null) const dataList = ref([]) -const queryList = (pageNum?: number, pageSize?: number) => { +const queryList = () => { // 杩欓噷鐨刾ageNo鍜宲ageSize浼氳嚜鍔ㄨ绠楀ソ锛岀洿鎺ヤ紶缁欐湇鍔″櫒鍗冲彲 // 杩欓噷鐨勮姹傚彧鏄紨绀猴紝璇锋浛鎹㈡垚鑷繁鐨勯」鐩殑缃戠粶璇锋眰锛屽苟鍦ㄧ綉缁滆姹傚洖璋冧腑閫氳繃paging.value.complete(璇锋眰鍥炴潵鐨勬暟缁�)灏嗚姹傜粨鏋滀紶缁檢-paging const params: QueryParams = { - pageNum, - pageSize, inspCode: inspSt.inspCode, } getInspStRecordList(params) .then((res: any) => { // 璇峰嬁鍦ㄧ綉缁滆姹傚洖璋冧腑缁檇ataList璧嬪�硷紒锛佸彧闇�瑕佽皟鐢╟omplete灏卞彲浠ヤ簡 - paging.value.complete(res.rows) + paging.value.complete(res.rows, res.total) }) .catch((res) => { // 濡傛灉璇锋眰澶辫触鍐檖aging.value.complete(false)锛屼細鑷姩灞曠ず閿欒椤甸潰 @@ -200,14 +275,25 @@ } 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() } + function handleClickRight() { - handleConfirm() + + if (inspSt.status === '0') { + handleConfirm() + } else if (inspSt.status === '1') { + handleComplete() + } } const toggleCollapse = () => { @@ -216,10 +302,31 @@ } 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: '纭畾鎻愪氦锛�', @@ -228,15 +335,18 @@ 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) @@ -245,19 +355,76 @@ }) .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('鎿嶄綔澶辫触') }) } @@ -267,8 +434,17 @@ */ 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 @@ -277,15 +453,40 @@ { 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.specialNote = options?.specialNote - inspSt.inspUser = userStore?.userInfo?.userId + // 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) @@ -304,7 +505,7 @@ margin-right: 24rpx; } .text-mini { - font-size: 22rpx; + font-size: 24rpx; } .menu-indicator { @@ -323,12 +524,26 @@ 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: 34rpx; +} + +// 鏂板鏍峰紡锛氱偣妫�椤硅儗鏅壊 +.status-normal { + background-color: #e6f7ff; // 姝e父鐘舵�佽儗鏅壊锛堢豢鑹诧級 +} + +.status-abnormal { + background-color: #fffbe6; // 寮傚父鐘舵�佽儗鏅壊锛堥粍鑹诧級 +} +:deep(.wd-radio-group) { + // 鏀逛负鏃犺儗鏅壊 + background-color: transparent; } </style> -- Gitblit v1.9.3