| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421 |
- <template>
- <view class="form-page">
- <!-- 可滚动内容区域 -->
- <scroll-view class="form-scroll" scroll-y="true">
- <view class="form-container">
- <!-- 站点类型 -->
- <form-item label="站点类型" :required="formConfig.siteType.required" :error="formConfig.siteType.error">
- <select-picker v-model="formData.siteType" placeholder="请选择站点类型" title="选择站点类型" :options="siteTypeOptions" :showLabel="false" />
- </form-item>
- <!-- 站点名称 -->
- <form-item label="站点名称" :required="formConfig.siteName.required" :error="formConfig.siteName.error">
- <select-picker v-model="formData.siteName" placeholder="请选择站点名称" title="选择站点名称" :options="siteNameOptions" :showLabel="false" />
- </form-item>
- <!-- 对比参数 -->
- <form-item label="对比参数" :required="formConfig.parameter.required" :error="formConfig.parameter.error">
- <select-picker v-model="formData.parameter" placeholder="请选择对比参数" title="选择对比参数" :options="parameterOptions" :showLabel="false" />
- </form-item>
- <!-- 单行文本 -->
- <form-item label="单行文本" :required="formConfig.remark.required" :error="formConfig.remark.error">
- <l-input
- class="form-input"
- v-model="formData.remark"
- placeholder="请输入单行文本"
- :maxlength="100"
- :clearable="true"
- :bordered="false"
- placeholderStyle="font-size: 14px;"
- />
- </form-item>
- <!-- 多行文本 -->
- <form-item label="多行文本" :required="formConfig.multilineText.required" :error="formConfig.multilineText.error" layout="vertical">
- <l-textarea
- class="form-textarea"
- v-model="formData.multilineText"
- placeholder="请输入多行文本"
- :maxlength="500"
- :indicator="true"
- :bordered="false"
- :autosize="true"
- placeholderStyle="font-size: 14px;"
- />
- </form-item>
- <!-- 采集日期 -->
- <form-item label="采集日期" :required="formConfig.collectDate.required" :error="formConfig.collectDate.error">
- <date-picker v-model="formData.collectDate" placeholder="请选择采集日期" title="选择采集日期" :start="datePickerStart" :end="datePickerEnd" :showLabel="false" />
- </form-item>
- <!-- 日期范围 -->
- <form-item label="日期范围" :required="formConfig.dateRange.required" :error="formConfig.dateRange.error">
- <date-range-picker
- v-model:startValue="formData.dateRange2Start"
- v-model:endValue="formData.dateRange2End"
- placeholder="请选择日期范围"
- startTitle="选择开始日期"
- endTitle="选择结束日期"
- :start="datePickerStart"
- :end="datePickerEnd"
- :showLabel="false"
- />
- </form-item>
- <!-- 上传图片 -->
- <form-item label="上传图片" :required="formConfig.images.required" :error="formConfig.images.error" layout="vertical">
- <upload-image
- :modelValue="formData.images"
- @update:modelValue="handleImagesUpdate"
- :maxCount="imageMaxCount"
- businessType="image"
- ></upload-image>
- </form-item>
- <!-- 上传视频 -->
- <form-item label="上传视频" :required="formConfig.videos.required" :error="formConfig.videos.error" layout="vertical">
- <upload-video
- :modelValue="formData.videos"
- @update:modelValue="handleVideosUpdate"
- :maxCount="videoMaxCount"
- businessType="video"
- ></upload-video>
- </form-item>
- </view>
- </scroll-view>
- <!-- 固定底部按钮 -->
- <view class="footer">
- <button class="submit-btn" :disabled="submitting" @click="handleSubmit">
- <text class="submit-btn-text">{{ submitting ? "提交中..." : "提交" }}</text>
- </button>
- </view>
- </view>
- </template>
- <script setup lang="uts">
- import { ref } from 'vue'
- import type { PickerColumn } from '@/uni_modules/lime-picker'
- import type { UploadResponse, VideoItem } from '../../../types/workbench'
- // 表单 label 宽度统一配置
- const labelWidth = '140rpx'
-
- // 上传组件配置
- const imageMaxCount: number = 9
- const videoMaxCount: number = 3
- // 计算日期范围:当前时间前后100年
- const now = new Date()
- const currentYear = now.getFullYear()
- const startYear = currentYear - 100
- const endYear = currentYear + 100
- // 格式化日期为 YYYY-MM-DD
- const formatDate = (year: number, month: number, day: number): string => {
- const m = month < 10 ? `0${month}` : `${month}`
- const d = day < 10 ? `0${day}` : `${day}`
- return `${year}-${m}-${d}`
- }
- // 日期选择器的开始和结束日期
- const datePickerStart = ref<string>(formatDate(startYear, 1, 1))
- const datePickerEnd = ref<string>(formatDate(endYear, 12, 31))
- // 表单数据类型
- type FormDataType = {
- siteType: string
- siteName: string
- parameter: string
- remark: string
- multilineText: string
- images: UploadResponse[]
- videos: VideoItem[]
- collectDate: string
- dateRange2Start: string
- dateRange2End: string
- }
- // 表单数据
- const formData = ref<FormDataType>({
- siteType: '',
- siteName: '',
- parameter: '',
- remark: '',
- multilineText: '',
- images: [],
- videos: [],
- collectDate: '',
- dateRange2Start: '',
- dateRange2End: ''
- })
- const submitting = ref<boolean>(false)
- // 表单字段配置类型
- type FormFieldConfig = {
- required: boolean
- error: string
- errorMsg: string
- }
- // 表单字段配置
- type FormFieldsConfig = {
- siteType: FormFieldConfig
- siteName: FormFieldConfig
- parameter: FormFieldConfig
- remark: FormFieldConfig
- multilineText: FormFieldConfig
- images: FormFieldConfig
- videos: FormFieldConfig
- collectDate: FormFieldConfig
- dateRange: FormFieldConfig
- }
- // 表单配置
- const formConfig = ref<FormFieldsConfig>({
- siteType: {
- required: true,
- error: '',
- errorMsg: '请选择站点类型'
- },
- siteName: {
- required: true,
- error: '',
- errorMsg: '请选择站点名称'
- },
- parameter: {
- required: false,
- error: '',
- errorMsg: '请选择对比参数'
- },
- remark: {
- required: false,
- error: '',
- errorMsg: '请输入单行文本'
- },
- multilineText: {
- required: false,
- error: '',
- errorMsg: '请输入多行文本'
- },
- images: {
- required: false,
- error: '',
- errorMsg: '请上传图片'
- },
- videos: {
- required: false,
- error: '',
- errorMsg: '请上传视频'
- },
- collectDate: {
- required: false,
- error: '',
- errorMsg: '请选择采集日期'
- },
- dateRange: {
- required: false,
- error: '',
- errorMsg: '请选择完整的日期范围'
- }
- })
- // 清空所有错误信息
- const clearErrors = (): void => {
- formConfig.value.siteType.error = ''
- formConfig.value.siteName.error = ''
- formConfig.value.parameter.error = ''
- formConfig.value.remark.error = ''
- formConfig.value.multilineText.error = ''
- formConfig.value.images.error = ''
- formConfig.value.videos.error = ''
- formConfig.value.collectDate.error = ''
- formConfig.value.dateRange.error = ''
- }
- // 站点类型选项
- const siteTypeOptions = [
- { label: '人工站', value: '人工站' },
- { label: '自动站', value: '自动站' },
- { label: '水文站', value: '水文站' },
- { label: '气象站', value: '气象站' }
- ] as PickerColumn
- // 站点名称选项
- const siteNameOptions = [
- { label: '肖川-龙口', value: '肖川-龙口' },
- { label: '北京-朝阳', value: '北京-朝阳' },
- { label: '上海-浦东', value: '上海-浦东' },
- { label: '深圳-南山', value: '深圳-南山' }
- ] as PickerColumn
- // 对比参数选项
- const parameterOptions = [
- { label: '水温(℃)', value: '水温(℃)' },
- { label: '水位(m)', value: '水位(m)' },
- { label: '流量(m³/s)', value: '流量(m³/s)' },
- { label: '降雨量(mm)', value: '降雨量(mm)' }
- ] as PickerColumn
- // 表单验证
- const validateForm = (): boolean => {
- // 清空之前的错误信息
- clearErrors()
- let isValid = true
- // 站点类型验证
- if (formConfig.value.siteType.required && formData.value.siteType.length == 0) {
- formConfig.value.siteType.error = formConfig.value.siteType.errorMsg
- isValid = false
- }
- // 站点名称验证
- if (formConfig.value.siteName.required && formData.value.siteName.length == 0) {
- formConfig.value.siteName.error = formConfig.value.siteName.errorMsg
- isValid = false
- }
- // 对比参数验证
- if (formConfig.value.parameter.required && formData.value.parameter.length == 0) {
- formConfig.value.parameter.error = formConfig.value.parameter.errorMsg
- isValid = false
- }
- // 单行文本验证
- if (formConfig.value.remark.required && formData.value.remark.length == 0) {
- formConfig.value.remark.error = formConfig.value.remark.errorMsg
- isValid = false
- }
- // 多行文本验证
- if (formConfig.value.multilineText.required && formData.value.multilineText.length == 0) {
- formConfig.value.multilineText.error = formConfig.value.multilineText.errorMsg
- isValid = false
- }
- // 图片验证
- if (formConfig.value.images.required && formData.value.images.length == 0) {
- formConfig.value.images.error = formConfig.value.images.errorMsg
- isValid = false
- }
- // 视频验证
- if (formConfig.value.videos.required && formData.value.videos.length == 0) {
- formConfig.value.videos.error = formConfig.value.videos.errorMsg
- isValid = false
- }
- // 采集日期验证
- if (formConfig.value.collectDate.required && formData.value.collectDate.length == 0) {
- formConfig.value.collectDate.error = formConfig.value.collectDate.errorMsg
- isValid = false
- }
- // 日期范围验证
- if (formConfig.value.dateRange.required && (formData.value.dateRange2Start.length == 0 || formData.value.dateRange2End.length == 0)) {
- formConfig.value.dateRange.error = formConfig.value.dateRange.errorMsg
- isValid = false
- }
- return isValid
- }
- // 处理图片更新
- const handleImagesUpdate = (images: UploadResponse[]): void => {
- formData.value.images = images
- }
- // 处理视频更新
- const handleVideosUpdate = (videos: VideoItem[]): void => {
- formData.value.videos = videos
- }
- // 提交表单
- const handleSubmit = async (): Promise<void> => {
- if (!validateForm()) {
- return
- }
- try {
- submitting.value = true
- // 打印表单数据
- console.log('表单数据:', formData.value)
- // 模拟提交
- await new Promise<void>((resolve) => {
- setTimeout(() => {
- resolve()
- }, 1500)
- })
- uni.showToast({
- title: '提交成功',
- icon: 'success'
- })
- // 延迟返回
- // setTimeout(() => {
- // uni.navigateBack()
- // }, 1000)
- } catch (e: any) {
- uni.showToast({
- title: e.message ?? '提交失败',
- icon: 'none'
- })
- } finally {
- submitting.value = false
- }
- }
- </script>
- <style lang="scss">
- @import "@/static/css/form.scss";
- .form-page {
- flex: 1;
- background-color: #e8f0f9;
- flex-direction: column;
- .form-scroll {
- flex: 1;
- padding: 30rpx;
- padding-bottom: 20rpx;
- .form-container {
- background-color: #ffffff;
- border-radius: 16rpx;
- padding: 30rpx;
- }
- }
- .footer {
- padding: 20rpx 30rpx;
- padding-bottom: 40rpx;
- .submit-btn {
- width: 100%;
- height: 88rpx;
- background-color: #007aff;
- border-radius: 12rpx;
- color: #ffffff !important;
-
- &:disabled {
- background-color: #cccccc;
- }
- .submit-btn-text {
- font-size: 32rpx;
- color: #ffffff !important;
- font-weight: bold;
- }
- }
- }
- }
- </style>
|