This commit is contained in:
houjunxiang
2025-10-09 18:19:55 +08:00
parent f2ffc65094
commit 386f1e7466
1553 changed files with 284685 additions and 32820 deletions

View File

@@ -0,0 +1,142 @@
<template>
<up-popup :show="visible" mode="right" closeable @close="handleClose" @open="handleOpen">
<uni-section titleFontSize="18px" type="line" title="设备维护保养信息"> </uni-section>
<scroll-view scroll-y="true" style="height: 85vh; width: 90vw">
<view class="content">
<up-row class="flex-wrap pt10 pl10" style="background-color: #f5f7fa">
<up-col class="mb8" :span="gridCol" v-for="(item, index) in detailSchema">
<view style="color: #666"
><span style="color: #333">{{ item.label }}</span>{{ detailInfo[item.value] }}</view
>
</up-col>
</up-row>
<view class="pt5">
<up-row>
<up-col span="6">
<view
>维护保养人
<text style="color: #666">
{{ detailInfo.checkUserName }}
</text>
</view>
<view class="pt5"
>维护保养日期
<text style="color: #666">
{{ detailInfo.checkDate }}
</text>
</view>
</up-col>
<up-col span="6">
<u-album multiple-size="70" single-size="70" :urls="attachment" row-count="4" />
</up-col>
</up-row>
</view>
<view>
<up-row class="p10 font-bold" style="background-color: #f5f5f5">
<up-col span="5">维护保养内容</up-col>
<up-col span="3"> 频次</up-col>
<up-col span="4">维护保养标准</up-col>
</up-row>
<view>
<view v-for="(item, index) in detailInfo.maintainItemList" :key="index">
<up-row class="p10">
<up-col span="5">
<view class="x-f">
<text>
{{ item.itemName }}
</text>
</view>
</up-col>
<up-col span="3">{{ item.frequencyRemark }}</up-col>
<up-col span="4">{{ item.standard }}</up-col>
</up-row>
<up-row class="fill-content">
<up-col span="12"
><view
>维护保养情况:
<text style="color: #666">
{{ item.checkRemark }}
</text>
</view>
</up-col>
</up-row>
</view>
<view class="p10"></view>
</view>
</view>
</view>
</scroll-view>
</up-popup>
</template>
<script setup>
import { ref, reactive, onMounted, watch, computed } from 'vue'
import { useGridCol } from '@/nx/hooks/useGridCol'
import dailyCheckApi from '@/nx/api/dailyCheck'
import { getImgBaseUrl } from '@/defaultBaseUrl'
const { gridCol } = useGridCol([700], [6, 4])
const props = defineProps({
show: {
type: Boolean,
default: false
},
checkInfo: {
type: Object
}
})
const detailSchema = [
{ label: '设备名称', value: 'deviceName' },
{ label: '别名', value: 'alias' },
{ label: '设备型号', value: 'modelNo' },
{ label: '设备编码', value: 'deviceCode' },
{ label: '使用班组', value: 'deptName' }
]
const visible = ref(props.show)
// 监听外部传入的show属性变化
watch(
() => props.show,
newVal => {
visible.value = newVal
}
)
const attachment = computed(() => {
let files = detailInfo.value?.attachment?.split(',') || []
if (files.length > 0) {
return files.map(item => getImgBaseUrl() + item)
} else {
return []
}
})
let detailInfo = ref({})
async function getDetailInfo(id) {
const res = await dailyCheckApi.queryById(id)
detailInfo.value = res
}
const emit = defineEmits(['close', 'open'])
function handleClose() {
emit('close')
}
function handleOpen() {
getDetailInfo(props.checkInfo.id)
}
</script>
<style lang="scss" scoped>
.content {
background-color: #fff;
height: 100%;
padding: 10px;
font-size: 16px;
.fill-content {
font-size: 14px;
border-radius: 3px;
box-shadow: 2px 2px 8px 2px rgba(0, 0, 0, 0.2);
background-color: #fdf6ec;
padding: 10px;
}
}
:deep(.uicon-close) {
font-size: 22px !important;
}
</style>

View File

@@ -0,0 +1,262 @@
<template>
<view>
<up-sticky>
<navbar-back title="维护保养">
<up-button
v-if="detailInfo.id"
type="primary"
:plain="true"
icon="list"
size="small"
text="设备维护保养记录"
@click="handleCheckRecord"
></up-button>
</navbar-back>
</up-sticky>
<view class="container">
<n-scanTemp
v-if="!detailInfo.id"
title="请扫描设备条码进行维护保养"
icon="maintain"
@deviceId="id => getDetailInfo(id)"
/>
<view v-else class="content">
<view>
<uni-section titleFontSize="22px" type="line" title="设备维护保养信息"> </uni-section>
<up-row class="flex-wrap p10" style="background-color: #f5f7fa">
<up-col class="mb10" :span="gridCol" v-for="(item, index) in detailSchema">
<view style="color: #666"
><span style="color: #333">{{ item.label }}</span>{{ detailInfo[item.value] }}</view
>
</up-col>
</up-row>
</view>
<view class="check-header">
<uni-section titleFontSize="22px" type="line" title="维护保养项"> </uni-section>
<up-row class="p10 font-bold border-b" style="background-color: #f5f5f5">
<up-col span="4">维护保养内容</up-col>
<up-col span="4"> 频次</up-col>
<up-col span="4">维护保养标准</up-col>
</up-row>
<view class="pt10">
<view v-for="(item, index) in detailInfo.maintainItemList" :key="index">
<up-row class="p20">
<up-col span="4">
<view class="x-f">
<u-badge type="warning " :value="index + 1"></u-badge>
<text class="pl10">
{{ item.itemName }}
</text>
</view>
</up-col>
<up-col span="4">{{ item.frequencyRemark }}</up-col>
<up-col span="4">{{ item.standard }}</up-col>
</up-row>
<up-row class="fill-content">
<up-col span="12" class="x-f"
><view class="p10"><text class="required-star">*</text>维护保养情况:</view>
<up-input class="bg-w" v-model="item.checkRemark" placeholder="请输入维护保养情况"></up-input
></up-col>
</up-row>
</view>
</view>
</view>
<view>
<view class="p10">附件照片</view>
<n-upload v-model="detailInfo.attachment" />
<view class="p10">维护保养人</view>
<up-input v-model="detailInfo.checkUserName"></up-input>
<view v-if="detailInfo.submitFlag == '1'">
<view class="p10">维护保养日期</view>
<uni-datetime-picker type="date" v-model="detailInfo.checkDate" />
</view>
</view>
<view class="mt40 x-bc" v-if="detailInfo.submitFlag == '0'">
<up-button
style="width: 40%"
loadingText="保存中..."
type="warning"
text="暂存"
@click="handleSubmit('0')"
></up-button>
<up-button
style="width: 40%"
loadingText="提交中..."
type="primary"
text="提交"
@click="handleSubmit('1')"
></up-button>
</view>
</view>
</view>
<up-modal
:show="modalShow"
title="提示"
:content="modalText"
ref="uModal"
:asyncClose="true"
showCancelButton
@confirm="confirm"
@cancel="modalShow = false"
></up-modal>
<up-loading-page :loading="pageLoading"></up-loading-page>
</view>
</template>
<script setup>
import { ref, reactive, onMounted, computed, watch, toRefs } from 'vue'
import { onShow } from '@dcloudio/uni-app'
import dailyCheckApi from '@/nx/api/dailyCheck'
import nx from '@/nx'
import { useScreenOrientation } from '@/nx/hooks/useScreenOrientation'
import { useGridCol } from '@/nx/hooks/useGridCol'
const { gridCol } = useGridCol([700], [6, 4])
const { lockOrientation } = useScreenOrientation()
const pageLoading = ref(false)
const detailSchema = [
{ label: '设备名称', value: 'deviceName' },
{ label: '设备型号', value: 'modelNo' },
{ label: '设备编码', value: 'deviceCode' },
{ label: '使用班组', value: 'deptName' }
]
let detailInfo = ref({})
let checkList = ref([])
const { scanQRInfo } = toRefs(nx.$store('biz'))
watch(scanQRInfo, newVal => {
if (newVal && nx.$router.getCurrentPage().route == 'pages/lims/deviceBusMaintain/index') {
try {
const codeObj = JSON.parse(newVal)
if (!pageLoading.value) {
getDetailInfo(codeObj.id)
}
scanQRInfo.value = ''
} catch (error) {
scanQRInfo.value = ''
uni.showToast({
title: '请扫描设备码',
icon: 'none'
})
}
}
})
onShow(() => {
scanQRInfo.value = ''
})
const modalText = computed(() => {
return `确定${modalType.value == '0' ? '暂存' : '提交'}吗?${modalType.value == '0' ? '' : '提交后不能修改'} `
})
async function getDetailInfo(id) {
pageLoading.value = true
const res = await dailyCheckApi
.getCheckRecord({
deviceId: id,
dataType: 'maintain',
submitFlag: '0',
cancelFlag: '0'
})
.finally(() => {
pageLoading.value = false
})
if (!res.checkUserName) {
res.checkUserName = nx.$store('user').userInfo.realname
res.checkUserId = nx.$store('user').userInfo.id
}
if (!res.checkDate) {
res.checkDate = nx.$dayjs().format('YYYY-MM-DD 00:00:00')
}
detailInfo.value = res
modalType.value = res.submitFlag
lockOrientation('landscape')
}
const modalShow = ref(false)
const modalType = ref('')
function handleSubmit(type) {
if (!detailInfo.value.checkUserName) {
return uni.showToast({
title: '请输入维护保养人',
icon: 'none'
})
}
if (!detailInfo.value.checkDate) {
return uni.showToast({
title: '请选择维护保养日期',
icon: 'none'
})
}
if (type === '1') {
// 新增维护保养项验证
const items = detailInfo.value.maintainItemList || []
for (let i = 0; i < items.length; i++) {
const item = items[i]
const itemNumber = `${i + 1}`
if (!item.checkRemark?.trim()) {
return uni.showToast({ title: `${itemNumber}维护保养情况未填写`, icon: 'none' })
}
}
}
modalType.value = type
modalShow.value = true
console.log(detailInfo.value)
}
const submitLoading = ref(false)
async function confirm() {
if (submitLoading.value) return
submitLoading.value = true
await dailyCheckApi.submit({ ...detailInfo.value, submitFlag: modalType.value }).finally(() => {
submitLoading.value = false
modalShow.value = false
reset()
})
}
function reset() {
detailInfo.value = {}
}
function handleCheckRecord() {
let deviceInfo = {
id: detailInfo.value.deviceId,
deviceName: detailInfo.value.deviceName
}
nx.$store('biz').deviceInfo = deviceInfo
nx.$router.go('/pages/lims/deviceBusMaintain/list')
}
</script>
<style lang="scss" scoped>
.u-sticky {
top: 0 !important;
}
.container {
.required-star {
color: red;
margin-right: 4px;
}
.content {
background-color: #fff;
height: 100%;
padding: 16px;
padding-top: 10px;
font-size: 18px;
.title {
font-size: 22px;
font-weight: bold;
}
.check-header {
.u-sticky {
top: 70px !important;
}
}
.fill-content {
border-radius: 3px;
box-shadow: 2px 2px 8px 2px rgba(0, 0, 0, 0.2);
background-color: #fdf6ec;
padding: 10px;
box-sizing: border-box;
}
}
}
</style>

View File

@@ -0,0 +1,100 @@
<template>
<view>
<up-sticky v-if="!isComponent">
<navbar-back title="维护保养记录"> </navbar-back>
</up-sticky>
<uni-card spacing="0">
<uni-section v-if="!isComponent" titleFontSize="20px" type="line" :title="deviceText"> </uni-section>
<view :style="{ height: isComponent ? '70vh' : '72vh' }">
<zb-table
ref="zbTableRef"
isShowLoadMore
stripe
:fit="false"
:columns="column"
:cellStyle="setCellStyle"
:cellHeaderStyle="setCellHeaderStyle"
:data="listData"
@detail="handleDetail"
@pullUpLoading="pullUpLoadingAction"
></zb-table>
</view>
</uni-card>
<maintain-detail-popup :show="detailShow" :checkInfo="checkInfo" @close="detailShow = false" />
</view>
</template>
<script setup>
import { ref, reactive, onMounted, watch, computed } from 'vue'
import { onLoad } from '@dcloudio/uni-app'
import { setCellHeaderStyle, setCellStyle } from '@/nx/config/zbTable'
import MaintainDetailPopup from './detail.vue'
import dailyCheckApi from '@/nx/api/dailyCheck'
import { useListData } from '@/nx/hooks/usePageListData'
import nx from '@/nx'
let props = defineProps({
isComponent: {
type: Boolean,
default: false
}
})
const column = reactive([
{
label: '维护保养人',
name: 'checkUserName',
width: 160
},
{
label: '维护保养日期',
name: 'checkDate',
width: 300
},
{
name: 'operation',
type: 'operation',
label: '操作',
renders: [{ name: '详情', func: 'detail' }]
}
])
const deviceId = ref('')
const deviceText = ref('')
onMounted(() => {
const { id, deviceName } = nx.$store('biz').deviceInfo
deviceId.value = id
deviceText.value = deviceName
getInitData()
})
const searchParams = computed(() => ({
dataType: 'maintain',
deviceId: deviceId.value
}))
const { listData, loadingData, scrollToLower, loadStatus, getInitData } = useListData({
searchParams,
api: dailyCheckApi.list
})
const zbTableRef = ref()
function pullUpLoadingAction() {
if (loadingData.value) return
if (loadStatus.value === 'nomore') {
zbTableRef.value.pullUpCompleteLoading('ok')
} else {
scrollToLower()
}
}
const detailShow = ref(false)
const checkInfo = ref({})
function handleDetail(row) {
checkInfo.value = row
detailShow.value = true
}
</script>
<style lang="scss" scoped>
.u-sticky {
top: 0 !important;
}
:deep(.zb-table uni-button[type='primary']) {
background-color: $uni-color-primary !important;
}
</style>