Commit d8047a86 by pangchong

feat: 新建除冰收费单

parent 326e9d6a
<template>
<!-- 全局下拉框控件 -->
<view class="picker" :style="style">
<view class="picker" :class="{ 'u-border': ps.border }" :style="style">
<global-popup v-model="show" :height="592" :customStyle="{ padding: '28rpx 32rpx' }" v-if="filter" :distance="distance">
<template #top>
<view>
......@@ -61,6 +61,11 @@ const ps = defineProps({
type: Boolean,
default: false
},
//是否有边框
border: {
type: Boolean,
default: false
},
//是否多选(只对filter有效)---待优化
// multiple: {
// type: Boolean,
......@@ -257,7 +262,12 @@ watch(
<style lang="scss" scoped>
.picker {
flex: auto;
height: 100%;
border-radius: 4px;
padding-left: 18rpx;
box-sizing: border-box;
&-content {
height: 100%;
display: flex;
align-items: center;
line-height: 48rpx;
......
......@@ -73,6 +73,7 @@ const switchChange = (value) => {
</script>
<style lang="scss" scoped>
.switch {
flex: 1;
display: flex;
}
</style>
......@@ -70,6 +70,7 @@ import { computed, ref, watch } from 'vue'
import { cloneDeep } from 'lodash'
import { httpInterceptor } from 'mocp/utils/http'
import { onBeforeUnmount } from 'vue'
import { previewFile } from 'mocp/utils/tool'
const es = defineEmits(['update:modelValue', 'change', 'getFileList'])
const ps = defineProps({
......@@ -149,35 +150,6 @@ const confirm = () => {
show.value = false
fileList.value.splice(index.value, 1)
}
//预览图片
const previewFile = (fileUrl) => {
uni.showLoading({
title: '正在打开文件',
mask: true
})
uni.downloadFile({
url: fileUrl,
success: function (res) {
var filePath = res.tempFilePath
uni.openDocument({
filePath: filePath,
showMenu: true,
success: function (res) {
uni.hideLoading()
console.log('打开文件成功')
},
fail: function () {
uni.hideLoading()
uni.$mocpMessage.error('打开文件失败,请重新打开')
}
})
},
fail: function () {
uni.hideLoading()
uni.$mocpMessage.error('打开文件失败,请重新打开')
}
})
}
const isLoading = ref(false)
const onuploadEnd = (e) => {
if (e.type == 'success') {
......
......@@ -7,7 +7,7 @@ export const eb_deicingType = [
{ label: 'FCY-1Bio', value: 'FCY-1Bio' }
]
export const eb_antiicingMix = [
{ label: '30:70', value: '25:75' },
{ label: '25:75', value: '25:75' },
{ label: '30:70', value: '30:70' },
{ label: '40:60', value: '40:60' },
{ label: '50:50', value: '50:50' },
......@@ -29,3 +29,20 @@ export const eb_antiicingType = [
{ label: 'FCY-9311', value: 'FCY-9311' },
{ label: 'FCY-2', value: 'FCY-2' }
]
export const eb_guaranteeUnit = [
{ label: '海技保障', value: '1' },
{ label: '非海技保障', value: '2' }
]
export const eb_weatherToday = [
{ label: '霜', value: '1' },
{ label: '雾', value: '2' },
{ label: '冻雾', value: '3' },
{ label: '结冰', value: '4' },
{ label: '小雪', value: '5' },
{ label: '中雪', value: '6' },
{ label: '大雪', value: '7' }
]
export const eb_modelType = [
{ label: '宽体机', value: '1' },
{ label: '窄体机', value: '2' }
]
......@@ -43,30 +43,55 @@ export const uniqueArray = (arr) => {
return uniqueArr
}
// base64转临时文件
export function base64ToTempFilePath(base64Data) {
return new Promise((resolve, reject) => {
const fs = uni.getFileSystemManager()
// 生成临时文件名,并构建临时文件路径
const fileName = `temp_file_${Date.now()}.png`
const tempFilePath = `${uni.env.USER_DATA_PATH}/${fileName}`
// 移除Base64数据前缀(如果存在)
const base64WithoutPrefix = base64Data.split(',')[1]
// 将Base64字符串转换为ArrayBuffer
const arrayBuffer = uni.base64ToArrayBuffer(base64WithoutPrefix)
// 将ArrayBuffer写入临时文件
fs.writeFile({
filePath: tempFilePath,
data: arrayBuffer,
encoding: 'binary',
success: () => {
// 文件写入成功,返回临时文件路径
resolve(tempFilePath)
},
fail: (err) => {
// 文件写入失败,返回错误信息
reject(err)
}
})
/**
* 文件预览
* @param {*} fileUrl
*/
export const previewFile = (fileUrl) => {
uni.showLoading({
title: '正在打开文件',
mask: true
})
uni.downloadFile({
url: fileUrl,
success: function (res) {
var filePath = res.tempFilePath
uni.openDocument({
filePath: filePath,
showMenu: true,
success: function (res) {
uni.hideLoading()
console.log('打开文件成功')
},
fail: function () {
uni.hideLoading()
uni.$mocpMessage.error('打开文件失败,请重新打开')
}
})
},
fail: function () {
uni.hideLoading()
uni.$mocpMessage.error('打开文件失败,请重新打开')
}
})
}
/**
* 如果至少有一个参数被填写,那么所有参数都必须被填写
* @param {...any} params
* @returns
*/
export const validateParameters = (...params) => {
// 检查参数数组中是否至少有一个非空(非undefined、非null、非空字符串)的值
const anyFilled = params.some((param) => param !== undefined && param !== null && param !== '')
// 如果至少有一个参数被填写,那么检查是否所有的参数都被填写
if (anyFilled) {
// 使用every方法检查所有参数是否都被填写
const allFilled = params.every((param) => param !== undefined && param !== null && param !== '')
return allFilled
}
// 如果没有任何参数被填写,那么也是有效的
return true
}
......@@ -50,7 +50,7 @@
{
"path": "pages/modules/mocp/tab/index",
"style": {
"navigationBarTitleText": "tab页面",
"navigationBarTitleText": "",
"app-plus": {
"bounce": "none"
//关闭窗口回弹效果
......
......@@ -10,6 +10,8 @@ export const formData = reactive({
antiicingDuration: '',
antiicingEndTime: '',
antiicingMix: '',
antiicingMix1: undefined,
antiicingMix2: undefined,
antiicingPersion1: '',
antiicingPersion2: '',
antiicingPersion3: '',
......@@ -33,6 +35,8 @@ export const formData = reactive({
deicingCartNo4: '',
deicingEndTime: '',
deicingMix: '',
deicingMix1: undefined,
deicingMix2: undefined,
deicingPersion1: '',
deicingPersion2: '',
deicingPersion3: '',
......@@ -58,7 +62,11 @@ export const formData = reactive({
nickname: '',
originalAircraftPositionDeicing: 0,
station: '',
username: ''
username: '',
guaranteeUnit: '',
weatherToday: '',
modelType: '',
remark: ''
})
export const rules = reactive({
......@@ -104,5 +112,28 @@ export const rules = reactive({
message: '请选择航班号',
trigger: ['blur', 'change']
}
],
guaranteeUnit: [
{
required: true,
message: '请选择保障单位',
trigger: ['blur', 'change']
}
],
weatherToday: [
{
required: true,
message: '请选择当日天气',
trigger: ['blur', 'change']
}
],
modelType: [
{
required: true,
message: '请选择机型类别',
trigger: ['blur', 'change']
}
]
})
export const formRef = ref()
export const show = ref(false)
import { getAirlineAcregApi } from 'mocp/api/electronicBill'
import { formData } from './add.compositions'
import { formData, formRef, show } from './add.compositions'
import { validateParameters } from 'mocp/utils/tool'
import { showToast } from 'mocp/utils/message'
export const changeAcreg = async (acreg) => {
if (!acreg) return
const res = await getAirlineAcregApi({ acreg }, { loading: true })
if (res.code == 200) {
if (res.data?.aircaraftoperator) {
......@@ -18,3 +21,112 @@ export const changeAcreg = async (acreg) => {
uni.$mocpMessage.error(res.message)
}
}
export const handleFooterClick = async () => {
await formRef.value?.validate()
//验证除冰混合比(Other)
if (formData.deicingMix == 'Other' && (!formData.deicingMix1 || !formData.deicingMix2)) {
return uni.$mocpMessage.warning('请填写除冰自定义混合比')
}
//验证除冰记录完整性
if (!validateParameters(formData.deicingCartNo1, formData.deicingPersion1, formData.deicingQuantity1, formData.deicingUnit1)) {
return uni.$mocpMessage.warning('请完整填写第1条除冰记录')
}
if (!validateParameters(formData.deicingCartNo2, formData.deicingPersion2, formData.deicingQuantity2, formData.deicingUnit2)) {
return uni.$mocpMessage.warning('请完整填写第2条除冰记录')
}
if (!validateParameters(formData.deicingCartNo3, formData.deicingPersion3, formData.deicingQuantity3, formData.deicingUnit3)) {
return uni.$mocpMessage.warning('请完整填写第3条除冰记录')
}
if (!validateParameters(formData.deicingCartNo4, formData.deicingPersion4, formData.deicingQuantity4, formData.deicingUnit4)) {
return uni.$mocpMessage.warning('请完整填写第4条除冰记录')
}
//验证防冰混合比(Other)
if (formData.antiicingMix == 'Other' && (!formData.antiicingMix1 || !formData.antiicingMix2)) {
return uni.$mocpMessage.warning('请填写防冰自定义混合比')
}
//验证防冰记录完整性
if (!validateParameters(formData.antiicingCartNo1, formData.antiicingPersion1, formData.antiicingQuantity1, formData.antiicingUnit1)) {
return uni.$mocpMessage.warning('请完整填写第1条防冰记录')
}
if (!validateParameters(formData.antiicingCartNo2, formData.antiicingPersion2, formData.antiicingQuantity2, formData.antiicingUnit2)) {
return uni.$mocpMessage.warning('请完整填写第2条防冰记录')
}
if (!validateParameters(formData.antiicingCartNo3, formData.antiicingPersion3, formData.antiicingQuantity3, formData.antiicingUnit3)) {
return uni.$mocpMessage.warning('请完整填写第3条防冰记录')
}
if (!validateParameters(formData.antiicingCartNo4, formData.antiicingPersion4, formData.antiicingQuantity4, formData.antiicingUnit4)) {
return uni.$mocpMessage.warning('请完整填写第4条防冰记录')
}
//验证总用量
const limit = getLimit()
let flag = false
if (formData.deicingQuantityTotal && formData.deicingQuantityTotal > 0) {
if (formData.deicingQuantityTotal < limit[0] || formData.deicingQuantityTotal > limit[1]) {
flag = true
}
}
if (formData.antiicingQuantityTotal && formData.antiicingQuantityTotal > 0) {
if (formData.antiicingQuantityTotal < limit[0] || formData.antiicingQuantityTotal > limit[1]) {
flag = true
}
}
if (flag) {
show.value = true
} else {
uni.$mocpJump.navigateTo('/panel/electronicBill/deicing/sign')
}
}
/**
* 对应天气类别 霜/雾 小雪 中雪/冻雾 大雪/结冰
窄体 100-400 400-700 700-1000 1000-2000
宽体 300-700 700-1200 1200-2000 2000-4000
*/
export const getLimit = () => {
if (formData.modelType == '1') {
if (['1', '2'].includes(formData.weatherToday)) {
return [300, 700]
} else if (['5'].includes(formData.weatherToday)) {
return [700, 1200]
} else if (['3', '6'].includes(formData.weatherToday)) {
return [1200, 2000]
} else if (['4', '7'].includes(formData.weatherToday)) {
return [2000, 4000]
}
} else {
if (['1', '2'].includes(formData.weatherToday)) {
return [100, 400]
} else if (['5'].includes(formData.weatherToday)) {
return [400, 700]
} else if (['3', '6'].includes(formData.weatherToday)) {
return [700, 1000]
} else if (['4', '7'].includes(formData.weatherToday)) {
return [1000, 2000]
}
}
return [0, 999999999999999]
}
/**
*
* @param {*} a 用量
* @param {*} b 单位
*/
export const getOneTotal = (a, b) => {
let unit = 0
if (b == 'L' || b == 'KG') {
unit = 1
}
if (b == 'USG') {
unit = 3.7854
}
return (a || 0) * unit
}
export const confirmRemark = () => {
if (!formData.remark) {
showToast('请填写超量使用原因')
} else {
show.value = false
uni.$mocpJump.navigateTo('/panel/electronicBill/deicing/sign')
}
}
......@@ -26,6 +26,15 @@ export const uploadFile = async () => {
}
}
export const addDeicing = async () => {
const params = {
...formData
}
if (formData.deicingMix == 'Other') {
params.deicingMix = formData.deicingMix1 + ':' + formData.deicingMix2
}
if (formData.antiicingMix == 'Other') {
params.antiicingMix = formData.antiicingMix1 + ':' + formData.antiicingMix2
}
const res = await addDeicingApi(formData, { loading: true })
if (res.code == 200) {
uni.$mocpJump.navigateBack()
......@@ -39,6 +48,8 @@ export const addDeicing = async () => {
antiicingDuration: '',
antiicingEndTime: '',
antiicingMix: '',
antiicingMix1: undefined,
antiicingMix2: undefined,
antiicingPersion1: '',
antiicingPersion2: '',
antiicingPersion3: '',
......@@ -62,6 +73,8 @@ export const addDeicing = async () => {
deicingCartNo4: '',
deicingEndTime: '',
deicingMix: '',
deicingMix1: undefined,
deicingMix2: undefined,
deicingPersion1: '',
deicingPersion2: '',
deicingPersion3: '',
......@@ -87,7 +100,11 @@ export const addDeicing = async () => {
nickname: '',
originalAircraftPositionDeicing: 0,
station: '',
username: ''
username: '',
guaranteeUnit: '',
weatherToday: '',
modelType: '',
remark: ''
})
uni.$mocpMessage.success(res.message)
} else {
......
......@@ -24,7 +24,7 @@
</view>
<view class="mocp-title">用户签名预览</view>
<view class="mocp-preview">
<up-image :src="canvasImage" mode="widthFix" :show-loading="true" width="100%" height="100%" v-if="canvasImage"></up-image>
<image :src="canvasImage" mode="widthFix" :show-loading="true" width="100%" height="100%" v-if="canvasImage"></image>
</view>
</global-page>
</template>
......@@ -38,7 +38,6 @@ import { onBeforeUnmount } from 'vue'
const { isSigned, touchStart, touchMove, touchEnd, clear, getPath } = useDrawSignature('canvas')
//保存签名
const handleSave = () => {
console.log(formData)
if (isSigned.value) {
canvasImage.value = ''
getPath('canvas').then((path) => {
......
......@@ -36,71 +36,74 @@
<up-input v-model="formData.flightNo" inputAlign="right" border="none" placeholder="请输入" clearable></up-input>
</up-form-item>
</view>
<view class="mocp-title">非例行工作1</view>
<view class="mocp-title">非例行工作</view>
<view class="mocp-form">
<up-form-item label="非例行工作内容" prop="work1" :borderBottom="true">
<up-input v-model="formData.work1" inputAlign="right" border="none" placeholder="请输入" clearable></up-input>
</up-form-item>
<up-form-item label="人数" prop="number1" :borderBottom="true">
<up-input type="number" v-model="formData.number1" inputAlign="right" border="none" placeholder="请输入" clearable></up-input>
</up-form-item>
<up-form-item label="工时(单位/小时)" prop="workingHours1" :borderBottom="true">
<up-input
type="number"
v-model="formData.workingHours1"
inputAlign="right"
border="none"
placeholder="请输入"
clearable
></up-input>
</up-form-item>
<up-form-item label="材料(液体/气体的补充)" prop="material1" :borderBottom="true">
<up-input v-model="formData.material1" inputAlign="right" border="none" placeholder="请输入" clearable></up-input>
</up-form-item>
</view>
<view class="mocp-title">非例行工作2</view>
<view class="mocp-form">
<up-form-item label="非例行工作内容" prop="work2" :borderBottom="true">
<up-input v-model="formData.work2" inputAlign="right" border="none" placeholder="请输入" clearable></up-input>
</up-form-item>
<up-form-item label="人数" prop="number2" :borderBottom="true">
<up-input type="number" v-model="formData.number2" inputAlign="right" border="none" placeholder="请输入" clearable></up-input>
</up-form-item>
<up-form-item label="工时(单位/小时)" prop="workingHours2" :borderBottom="true">
<up-input
type="number"
v-model="formData.workingHours2"
inputAlign="right"
border="none"
placeholder="请输入"
clearable
></up-input>
</up-form-item>
<up-form-item label="材料(液体/气体的补充)" prop="material2" :borderBottom="true">
<up-input v-model="formData.material2" inputAlign="right" border="none" placeholder="请输入" clearable></up-input>
</up-form-item>
</view>
<view class="mocp-title">非例行工作3</view>
<view class="mocp-form">
<up-form-item label="非例行工作内容" prop="work3" :borderBottom="true">
<up-input v-model="formData.work3" inputAlign="right" border="none" placeholder="请输入" clearable></up-input>
</up-form-item>
<up-form-item label="人数" prop="number3" :borderBottom="true">
<up-input type="number" v-model="formData.number3" inputAlign="right" border="none" placeholder="请输入" clearable></up-input>
</up-form-item>
<up-form-item label="工时(单位/小时)" prop="workingHours3" :borderBottom="true">
<up-input
type="number"
v-model="formData.workingHours3"
inputAlign="right"
border="none"
placeholder="请输入"
clearable
></up-input>
</up-form-item>
<up-form-item label="材料(液体/气体的补充)" prop="material3" :borderBottom="true">
<up-input v-model="formData.material3" inputAlign="right" border="none" placeholder="请输入" clearable></up-input>
</up-form-item>
<view class="sample-table">
<view class="sample-thead">
<view class="sample-thead-th">
<view class="sample-thead-td">非例行工作</view>
<view class="spacer"></view>
<view class="sample-thead-td">人数</view>
<view class="spacer"></view>
<view class="sample-thead-td">工时</view>
<view class="spacer"></view>
<view class="sample-thead-td">材料</view>
</view>
</view>
<view class="sample-tbody">
<view class="sample-tbody-tr">
<view class="sample-tbody-td">
<up-input v-model="formData.work1" placeholder="请输入" clearable></up-input>
</view>
<view class="spacer"></view>
<view class="sample-tbody-td">
<up-input type="number" v-model="formData.number1" placeholder="请输入" clearable></up-input>
</view>
<view class="spacer"></view>
<view class="sample-tbody-td">
<up-input type="number" v-model="formData.workingHours1" placeholder="请输入" clearable></up-input>
</view>
<view class="spacer"></view>
<view class="sample-tbody-td">
<up-input v-model="formData.material1" placeholder="请输入" clearable></up-input>
</view>
</view>
<view class="sample-tbody-tr">
<view class="sample-tbody-td">
<up-input v-model="formData.work2" placeholder="请输入" clearable></up-input>
</view>
<view class="spacer"></view>
<view class="sample-tbody-td">
<up-input type="number" v-model="formData.number2" placeholder="请输入" clearable></up-input>
</view>
<view class="spacer"></view>
<view class="sample-tbody-td">
<up-input type="number" v-model="formData.workingHours2" placeholder="请输入" clearable></up-input>
</view>
<view class="spacer"></view>
<view class="sample-tbody-td">
<up-input v-model="formData.material2" placeholder="请输入" clearable></up-input>
</view>
</view>
<view class="sample-tbody-tr">
<view class="sample-tbody-td">
<up-input v-model="formData.work3" placeholder="请输入" clearable></up-input>
</view>
<view class="spacer"></view>
<view class="sample-tbody-td">
<up-input type="number" v-model="formData.number3" placeholder="请输入" clearable></up-input>
</view>
<view class="spacer"></view>
<view class="sample-tbody-td">
<up-input type="number" v-model="formData.workingHours3" placeholder="请输入" clearable></up-input>
</view>
<view class="spacer"></view>
<view class="sample-tbody-td">
<up-input v-model="formData.material3" placeholder="请输入" clearable></up-input>
</view>
</view>
</view>
</view>
</view>
<view class="mocp-title">特种车辆、设备、工具租用记录</view>
<view class="mocp-form">
......@@ -203,6 +206,7 @@ const handleFooterClick = async () => {
}
</script>
<style lang="scss" scoped>
@import 'mocpStatic/css/table.scss';
.mocp-form {
background: #fff;
margin-bottom: 24rpx;
......
......@@ -2,6 +2,7 @@ import { getAirlineAcregApi } from 'mocp/api/electronicBill'
import { formData } from './add.compositions'
export const changeAcreg = async (acreg) => {
if (!acreg) return
const res = await getAirlineAcregApi({ acreg }, { loading: true })
if (res.code == 200) {
if (res.data?.aircaraftoperator) {
......
......@@ -24,7 +24,7 @@
</view>
<view class="mocp-title">用户签名预览</view>
<view class="mocp-preview">
<up-image :src="canvasImage" mode="widthFix" :show-loading="true" width="100%" height="100%" v-if="canvasImage"></up-image>
<image :src="canvasImage" mode="widthFix" :show-loading="true" width="100%" height="100%" v-if="canvasImage"></image>
</view>
</global-page>
</template>
......
......@@ -2,6 +2,7 @@ import { getAirlineAcregApi } from 'mocp/api/electronicBill'
import { formData } from './add.compositions'
export const changeAcreg = async (acreg) => {
if (!acreg) return
const res = await getAirlineAcregApi({ acreg }, { loading: true })
if (res.code == 200) {
if (res.data?.aircaraftoperator) {
......
......@@ -24,7 +24,7 @@
</view>
<view class="mocp-title">用户签名预览</view>
<view class="mocp-preview">
<up-image :src="canvasImage" mode="widthFix" :show-loading="true" width="100%" height="100%" v-if="canvasImage"></up-image>
<image :src="canvasImage" mode="widthFix" :show-loading="true" width="100%" height="100%" v-if="canvasImage"></image>
</view>
</global-page>
</template>
......
import { downuploadApi } from 'mocp/api/fileList'
import { base64ToTempFilePath } from 'mocp/utils/tool'
import { previewFile } from 'mocp/utils/tool'
export const transformData = (data) => {
return data.map((item) => {
......@@ -17,37 +16,6 @@ export const handleClick = (item) => {
if (item.directory) {
uni.$mocpJump.navigateTo(`${'/panel/fileList/index?path=' + item.path}`)
} else {
downupload(item.path)
}
}
export const downupload = async (path) => {
uni.showLoading({
title: '正在打开文件',
mask: true
})
const res = await downuploadApi({ path })
if (res.code == 200) {
base64ToTempFilePath(res.data)
.then((filePath) => {
uni.openDocument({
filePath,
showMenu: true,
success: function () {
uni.hideLoading()
console.log('文件打开成功')
},
fail: function () {
uni.hideLoading()
uni.$mocpMessage.error('打开文件失败,请重新打开')
}
})
})
.catch(() => {
uni.hideLoading()
uni.$mocpMessage.error('打开文件失败,请重新打开')
})
} else {
uni.hideLoading()
uni.$mocpMessage.error(res.message)
previewFile(item.url)
}
}
.sample-table {
padding-bottom: 24rpx;
.spacer {
width: 12rpx;
}
.sample-thead {
padding: 24rpx 0;
border-bottom: 1rpx solid #d6d7d9;
color: $mocp-text-5;
&-th {
display: flex;
}
&-td {
flex: 1;
text-align: center;
}
}
.sample-tbody {
padding-top: 24rpx;
&-tr {
display: flex;
margin-bottom: 24rpx;
&:last-child {
margin-bottom: 0;
}
}
&-td {
flex: 1;
text-align: center;
}
}
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment