feat(WorkOrderEdit): 新增工作票组件并调整样式

添加WorkNote组件用于工作票信息填写,包含风险类型选择、安全措施配置等功能
调整GatePassInfo组件样式,优化文件上传列表的显示
This commit is contained in:
liangbin 2026-01-19 10:58:07 +08:00
parent 6a66ff4422
commit 485f35157b
3 changed files with 418 additions and 1 deletions

View File

@ -269,6 +269,7 @@ const HandleDeleteCar = (carId) => {
.UpFileListBox { .UpFileListBox {
margin-top: 20rpx; margin-top: 20rpx;
height: auto; height: auto;
.UpFileItem { .UpFileItem {
border: 1rpx solid #e4e7ed; border: 1rpx solid #e4e7ed;
padding: 20rpx; padding: 20rpx;
@ -276,11 +277,13 @@ const HandleDeleteCar = (carId) => {
display: flex; display: flex;
flex-direction: column; flex-direction: column;
gap: 20rpx; gap: 20rpx;
.UpFileName { .UpFileName {
font-size: 30rpx; font-size: 30rpx;
font-weight: bold; font-weight: bold;
color: #333; color: #333;
} }
.UpFileSize { .UpFileSize {
font-size: 24rpx; font-size: 24rpx;
color: #666; color: #666;

View File

@ -0,0 +1,411 @@
<!-- 工作票 -->
<template>
<view class="MainBox">
<view class="FormBox">
<view class="FormItem">
<view class="FormLableBox mustBox">票证编号</view>
<view class="FormValueBox">
<u-input v-model="formData.serialNumber" placeholder="请输入票证编号" readonly></u-input>
</view>
</view>
<view class="FormItem">
<view class="FormLableBox mustBox">所属项目</view>
<view class="FormValueBox">
<u-input v-model="formData.projectName" placeholder="请输入所属项目" readonly></u-input>
</view>
</view>
<view class="FormItem">
<view class="FormLableBox mustBox">作业地点</view>
<view class="FormValueBox">
<u-input v-model="formData.workLocation" placeholder="请输入作业地点" readonly></u-input>
</view>
</view>
<view class="FormItem">
<view class="FormLableBox mustBox">作业负责人</view>
<view class="FormValueBox">
<u-input v-model="formData.workResponsible" placeholder="请输入作业负责人" readonly></u-input>
</view>
</view>
<view class="H2Box">核心信息</view>
<view class="FormItem">
<view class="FormLableBox mustBox">作业内容</view>
<view class="FormValueBox">
<u-textarea v-model="formData.workContent" placeholder="请输入作业内容" readonly></u-textarea>
</view>
</view>
<view class="FormItem">
<view class="FormLableBox FlexBox">
<view class="mustBox">风险类型</view>
<view class="addBtn" @click="showPicker = true">选择</view>
</view>
<view class="FormValueBox">
<view class="BorderBox">{{ formData.riskType }}</view>
<u-picker v-model="formData.riskType" :columns="[riskTypeList]" :show="showPicker" keyName="name"
@confirm="confirmRiskTypePicker" @cancel="showPicker = false"></u-picker>
</view>
</view>
<view class="FormItem">
<view class="FormLableBox mustBox">作业起止时间</view>
<view class="FormValueBox">
<view class="date-range-box">
<view class="date-item">
<u-input v-model="startDateText" placeholder="开始日期" readonly>
<template #suffix>
<u-button type="primary" size="small"
@click="showStartDatePicker = true">选择日期</u-button>
</template>
</u-input>
<up-datetime-picker :show="showStartDatePicker" v-model="startDate" mode="date"
:minDate="minTimestamp" @confirm="HandleStartDateConfirm"
@cancel="showStartDatePicker = false"></up-datetime-picker>
</view>
<view class="date-separator"></view>
<view class="date-item">
<u-input v-model="endDateText" placeholder="结束日期" readonly>
<template #suffix>
<u-button type="primary" size="small"
@click="showEndDatePicker = true">选择日期</u-button>
</template>
</u-input>
<up-datetime-picker :show="showEndDatePicker" v-model="endDate" mode="date"
:minDate="minTimestamp" @confirm="HandleEndDateConfirm"
@cancel="showEndDatePicker = false"></up-datetime-picker>
</view>
</view>
</view>
</view>
<view class="H2Box">安全措施</view>
<view class="FormItem">
<view class="FormLableBox mustBox">通用安全措施</view>
<view class="FormValueBox">
<up-checkbox-group v-model="checkboxValue1" placement="column" @change="checkboxChange">
<up-checkbox :customStyle="{ marginBottom: '8px' }" v-for="(item, index) in safeMeasureList"
:key="item.id" :label="item.name" :name="item.name">
</up-checkbox>
</up-checkbox-group>
</view>
<view class="FlexBox" v-if="showMeasureBox">
<u-input v-model="customSafeMeasure" placeholder="请输入自定义安全措施"></u-input>
<view class="FlexBox">
<u-button type="info" size="small" @click="showMeasureBox = false">取消</u-button>
<u-button type="primary" size="small" @click="addCustomSafeMeasure">确认</u-button>
</view>
</view>
<view class="BlueTxt" @click="showMeasureBox = true">添加自定义措施</view>
</view>
<view class="FormItem">
<view class="FormLableBox mustBox">作业班成员资质确认</view>
<view class="FormValueBox">
<view class="MemberBox">
<view class="MemberItem" v-for="(item, index) in memberList" :key="item.id">
<view class="FlexBox">
<view class="MemberName">{{ item.name }}</view>
<view class="">
<u-tag type="primary" v-if="item.status == '持证'">{{ item.status }}</u-tag>
<u-tag type="warning" plain v-else>{{ item.status }}</u-tag>
</view>
</view>
<view class="FlexBox">
<u-checkbox v-model="checkedList" label="已经确认特种作业资格"></u-checkbox>
</view>
</view>
</view>
</view>
</view>
<view class="H2Box">高风险作业专项</view>
<view class="FormItem">
<view class="FormLableBox FlexBox">
<view >是否需要申领移动球机</view>
<view class="FlexBox">
<span></span>
<up-switch v-model="needApplyBallMachine" @change="change"></up-switch>
<span></span>
</view>
</view>
<view class="FormValueBox">
<u-button type="primary" :disabled="!needApplyBallMachine">申领移动球机</u-button>
</view>
</view>
</view>
</view>
</template>·
<script setup>
import { generateGuid } from '@/utils/index.js';
import dayjs from 'dayjs';
import { ref, defineExpose } from 'vue'
//
const riskTypeList = ref([
{
id: 1,
name: '电气作业-低等风险',
value: '1',
},
{
id: 2,
name: '电气作业-中等风险',
value: '2',
},
{
id: 3,
name: '电气作业-高等风险',
value: '3',
},
])
//
const safeMeasureList = ref([
{
id: 1,
name: '断电并挂牌上锁',
},
{
id: 2,
name: '验电确认无电压',
},
{
id: 3,
name: '设置临时接地线',
},
{
id: 4,
name: '穿戴绝缘手套和防护服',
},
{
id: 5,
name: '安排专人监护',
},
])
const showMeasureBox = ref(false); //
const customSafeMeasure = ref(''); //
//
const memberList = ref([
{
id: 1,
name: '张三',
status: '持证',
},
{
id: 2,
name: '李四',
status: '未持证',
},
{
id: 3,
name: '王五',
status: '持证',
},
])
//
const needApplyBallMachine = ref(false);
//
const formData = ref({
serialNumber: '', //
projectName: '', //
workLocation: '', //
workResponsible: '', //
workContent: '', //
riskType: '', //
})
//
const showPicker = ref(false);
const showStartDatePicker = ref(false); //
const showEndDatePicker = ref(false); //
const startDate = ref(null); //
const endDate = ref(null); //
const startDateText = ref(''); //
const endDateText = ref(''); //
const minTimestamp = ref(dayjs('2020-01-01').valueOf()); //
//
defineExpose({
getFormData() {
return formData.value;
}
})
//
const confirmRiskTypePicker = (e) => {
formData.value.riskType = e.value[0].name;
showPicker.value = false;
}
//
const HandleStartDateConfirm = (e) => {
console.log('选中的开始日期:', e);
// 使
const selectedDate = (e.value && dayjs(e.value).isValid()) ? e.value : minTimestamp.value;
startDateText.value = dayjs(selectedDate).format('YYYY-MM-DD');
startDate.value = selectedDate;
endDateText.value = '';
endDate.value = null;
showStartDatePicker.value = false;
UpdatePeriod();
};
//
const HandleEndDateConfirm = (e) => {
console.log('选中的结束日期:', e);
// 使
const selectedDate = (e.value && dayjs(e.value).isValid()) ? e.value : minTimestamp.value;
//
if (startDate.value && dayjs(selectedDate).isBefore(dayjs(startDate.value))) {
uni.showToast({
title: '结束日期不能小于开始日期',
icon: 'none',
duration: 2000
});
return;
}
endDateText.value = dayjs(selectedDate).format('YYYY-MM-DD');
endDate.value = selectedDate;
showEndDatePicker.value = false;
UpdatePeriod();
};
//
const UpdatePeriod = () => {
if (startDateText.value && endDateText.value) {
formData.value.period = [startDateText.value, endDateText.value];
} else if (startDateText.value) {
formData.value.period = [startDateText.value, ''];
} else if (endDateText.value) {
formData.value.period = ['', endDateText.value];
} else {
formData.value.period = [];
}
console.log('作业周期:', formData.value.period);
};
//
const addCustomSafeMeasure = () => {
if (customSafeMeasure.value.trim() !== '') {
safeMeasureList.value.push({
id: generateGuid(8),
name: customSafeMeasure.value,
});
customSafeMeasure.value = '';
showMeasureBox.value = false;
}
}
</script>
<style lang="scss" scoped>
.BlueTxt {
font-size: 28rpx;
color: #2979ff;
margin: 10rpx 0;
}
.addBtn {
font-size: 30rpx;
color: #2979ff;
font-weight: bold;
}
.BorderBox {
border: 1rpx solid #e4e7ed;
padding: 20rpx;
border-radius: 10rpx;
}
.FlexBox {
display: flex;
align-items: center;
justify-content: space-between;
gap: 20rpx;
}
.MainBox {
padding: 20rpx;
background-color: #fff;
height: 100%;
overflow: auto;
}
.mustBox::after {
content: "*";
color: red;
font-size: 30rpx;
margin-left: 10rpx;
}
.FormBox {
background-color: #f5f5f5;
height: 100%;
.FormItem {
padding: 20rpx;
background-color: #fff;
.FormLableBox {
font-size: 30rpx;
font-weight: bold;
margin-bottom: 20rpx;
}
.FormValueBox {
font-size: 30rpx;
margin-top: 20rpx;
}
}
}
.MemberBox{
display: flex;
flex-direction: column;
gap: 20rpx;
.MemberItem{
border: 1rpx solid #e4e7ed;
padding: 20rpx;
border-radius: 10rpx;
.MemberName{
font-size: 30rpx;
}
}
}
.date-range-box {
display: flex;
align-items: center;
gap: 20rpx;
flex: 1;
.date-item {
flex: 1;
}
.date-separator {
color: #999;
font-size: 28rpx;
}
}
.H2Box {
font-size: 34rpx;
font-weight: bold;
margin-top: 20rpx;
}
</style>

View File

@ -17,6 +17,7 @@
<view class="ContentBox"> <view class="ContentBox">
<BasicsInfo ref="basicsInfoRef" :allData="allData" v-if="currentStep == 1"></BasicsInfo> <BasicsInfo ref="basicsInfoRef" :allData="allData" v-if="currentStep == 1"></BasicsInfo>
<GatePassInfo ref="gatePassInfoRef" :allData="allData" v-if="currentStep == 2"></GatePassInfo> <GatePassInfo ref="gatePassInfoRef" :allData="allData" v-if="currentStep == 2"></GatePassInfo>
<WorkNote ref="workNoteRef" :allData="allData" v-if="currentStep == 3"></WorkNote>
</view> </view>
<view class="FootBox" v-for="item in stepList" :key="item.id"> <view class="FootBox" v-for="item in stepList" :key="item.id">
<u-button :text="item.PrevBtnName" type="info"></u-button> <u-button :text="item.PrevBtnName" type="info"></u-button>
@ -28,6 +29,8 @@
import { ref } from 'vue' import { ref } from 'vue'
import BasicsInfo from './compoents/BasicsInfo.vue' import BasicsInfo from './compoents/BasicsInfo.vue'
import GatePassInfo from './compoents/GatePassInfo.vue' import GatePassInfo from './compoents/GatePassInfo.vue'
import WorkNote from './compoents/WorkNote.vue'
const currentStep = ref(1)// const currentStep = ref(1)//
const basicsInfoRef = ref(null); // const basicsInfoRef = ref(null); //
const gatePassInfoRef = ref(null); // const gatePassInfoRef = ref(null); //