| | |
| | | </view> |
| | | <view class="info-item"> |
| | | <view class="label">任务类型</view> |
| | | <view class="value">{{ getTaskTypeText(taskDetail.taskType) }}</view> |
| | | <view class="value">{{ displayTaskType }}</view> |
| | | </view> |
| | | <view class="info-item"> |
| | | <view class="label">任务状态</view> |
| | | <view class="value status" :class="taskDetail.taskStatus === 'PENDING' ? 'pending' : taskDetail.taskStatus === 'DEPARTING' ? 'in_progress' : taskDetail.taskStatus === 'ARRIVED' ? 'in_progress' : taskDetail.taskStatus === 'RETURNING' ? 'in_progress' : taskDetail.taskStatus === 'IN_PROGRESS' ? 'in_progress' : taskDetail.taskStatus === 'COMPLETED' ? 'completed' : taskDetail.taskStatus === 'CANCELLED' ? 'cancelled' : ''"> |
| | | {{ getStatusText(taskDetail.taskStatus) }} |
| | | <view class="value status" :class="statusClass"> |
| | | {{ displayTaskStatus }} |
| | | </view> |
| | | </view> |
| | | <view class="info-item"> |
| | |
| | | <view class="section-title">时间信息</view> |
| | | <view class="info-item"> |
| | | <view class="label">计划开始时间</view> |
| | | <view class="value">{{ formatDateTime(taskDetail.plannedStartTime) }}</view> |
| | | <view class="value">{{ displayPlannedStartTime }}</view> |
| | | </view> |
| | | <view class="info-item"> |
| | | <view class="label">计划结束时间</view> |
| | | <view class="value">{{ formatDateTime(taskDetail.plannedEndTime) }}</view> |
| | | <view class="value">{{ displayPlannedEndTime }}</view> |
| | | </view> |
| | | <view class="info-item" v-if="taskDetail.actualStartTime"> |
| | | <view class="label">实际开始时间</view> |
| | | <view class="value">{{ formatDateTime(taskDetail.actualStartTime) }}</view> |
| | | <view class="value">{{ displayActualStartTime }}</view> |
| | | </view> |
| | | <view class="info-item" v-if="taskDetail.actualEndTime"> |
| | | <view class="label">实际结束时间</view> |
| | | <view class="value">{{ formatDateTime(taskDetail.actualEndTime) }}</view> |
| | | <view class="value">{{ displayActualEndTime }}</view> |
| | | </view> |
| | | </view> |
| | | |
| | | <view class="detail-section"> |
| | | <view class="section-title">位置信息</view> |
| | | <!-- 急救转运任务:显示转出/转入医院地址 --> |
| | | <!-- 转运任务:显示转出/转入医院地址 --> |
| | | <template v-if="taskDetail.taskType === 'EMERGENCY_TRANSFER' && taskDetail.emergencyInfo"> |
| | | <view class="info-item" v-if="taskDetail.emergencyInfo.hospitalOutAddress"> |
| | | <view class="label">转出医院</view> |
| | |
| | | <view class="description">{{ taskDetail.remark }}</view> |
| | | </view> |
| | | |
| | | <!-- 急救转运任务特有信息 --> |
| | | <!-- 转运任务特有信息 --> |
| | | <view class="detail-section" v-if="taskDetail.taskType === 'EMERGENCY_TRANSFER' && taskDetail.emergencyInfo"> |
| | | <view class="section-title">患者信息</view> |
| | | <view class="info-item" v-if="taskDetail.emergencyInfo.patientName"> |
| | | <view class="label">患者姓名</view> |
| | | <view class="value">{{ taskDetail.emergencyInfo.patientName }}</view> |
| | | <view class="info-item"> |
| | | <view class="label">联系人</view> |
| | | <view class="value">{{ taskDetail.emergencyInfo.patientContact || '未设置' }}</view> |
| | | </view> |
| | | <view class="info-item" v-if="taskDetail.emergencyInfo.patientPhone"> |
| | | <view class="info-item"> |
| | | <view class="label">患者姓名</view> |
| | | <view class="value">{{ taskDetail.emergencyInfo.patientName || '未设置' }}</view> |
| | | </view> |
| | | <view class="info-item"> |
| | | <view class="label">联系电话</view> |
| | | <view class="value">{{ taskDetail.emergencyInfo.patientPhone }}</view> |
| | | <view class="value">{{ taskDetail.emergencyInfo.patientPhone || '未设置' }}</view> |
| | | </view> |
| | | <view class="info-item" v-if="taskDetail.emergencyInfo.patientGender"> |
| | | <view class="label">性别</view> |
| | |
| | | </view> |
| | | </view> |
| | | |
| | | <!-- 急救转运 - 转出医院信息 --> |
| | | <!-- 转运 - 转出医院信息 --> |
| | | <view class="detail-section" v-if="taskDetail.taskType === 'EMERGENCY_TRANSFER' && taskDetail.emergencyInfo"> |
| | | <view class="section-title">转出医院信息</view> |
| | | <view class="info-item" v-if="taskDetail.emergencyInfo.hospitalOutName"> |
| | |
| | | </view> |
| | | </view> |
| | | |
| | | <!-- 急救转运 - 转入医院信息 --> |
| | | <!-- 转运 - 转入医院信息 --> |
| | | <view class="detail-section" v-if="taskDetail.taskType === 'EMERGENCY_TRANSFER' && taskDetail.emergencyInfo"> |
| | | <view class="section-title">转入医院信息</view> |
| | | <view class="info-item" v-if="taskDetail.emergencyInfo.hospitalInName"> |
| | |
| | | </view> |
| | | </view> |
| | | |
| | | <!-- 急救转运 - 费用信息 --> |
| | | <!-- 转运 - 费用信息 --> |
| | | <view class="detail-section" v-if="taskDetail.taskType === 'EMERGENCY_TRANSFER' && taskDetail.emergencyInfo"> |
| | | <view class="section-title">费用信息</view> |
| | | <view class="info-item" v-if="taskDetail.emergencyInfo.transferDistance"> |
| | |
| | | <view class="info-item" v-if="taskDetail.emergencyInfo.transferPrice"> |
| | | <view class="label">转运费用</view> |
| | | <view class="value">¥{{ taskDetail.emergencyInfo.transferPrice }}</view> |
| | | </view> |
| | | </view> |
| | | |
| | | <!-- 附件信息 --> |
| | | <view class="detail-section"> |
| | | <view class="section-title"> |
| | | 任务附件 |
| | | <button class="upload-btn" @click="showUploadDialog">上传附件</button> |
| | | </view> |
| | | <view v-if="attachmentList && attachmentList.length > 0"> |
| | | <view class="attachment-item" v-for="(item, index) in attachmentList" :key="item.attachmentId"> |
| | | <view class="attachment-info"> |
| | | <view class="attachment-category"> |
| | | <text class="category-tag">{{ getCategoryName(item.attachmentCategory) }}</text> |
| | | </view> |
| | | <view class="attachment-name">{{ item.fileName }}</view> |
| | | <view class="attachment-meta"> |
| | | <text class="upload-time">{{ formatTime(item.uploadTime) }}</text> |
| | | <text class="file-size">{{ formatFileSize(item.fileSize) }}</text> |
| | | </view> |
| | | </view> |
| | | <view class="attachment-actions"> |
| | | <button class="action-btn view-btn" @click="viewAttachment(item)">查看</button> |
| | | <button class="action-btn delete-btn" @click="deleteAttachment(item.attachmentId, index)">删除</button> |
| | | </view> |
| | | </view> |
| | | </view> |
| | | <view v-else class="no-attachment"> |
| | | <text>暂无附件</text> |
| | | </view> |
| | | </view> |
| | | |
| | |
| | | |
| | | <!-- 已完成/已取消: 不显示按钮 --> |
| | | </view> |
| | | |
| | | <!-- 附件上传对话框 --> |
| | | <uni-popup ref="uploadPopup" type="bottom"> |
| | | <view class="upload-dialog"> |
| | | <view class="dialog-header"> |
| | | <text class="dialog-title">上传附件</text> |
| | | <uni-icons type="closeempty" size="24" @click="closeUploadDialog"></uni-icons> |
| | | </view> |
| | | <view class="dialog-content"> |
| | | <view class="form-item"> |
| | | <view class="form-label">附件分类</view> |
| | | <picker @change="onCategoryChange" :value="selectedCategoryIndex" :range="categoryList" range-key="label"> |
| | | <view class="picker-value"> |
| | | {{ categoryList[selectedCategoryIndex].label }} |
| | | <uni-icons type="arrowdown" size="16"></uni-icons> |
| | | </view> |
| | | </picker> |
| | | </view> |
| | | <view class="form-item"> |
| | | <view class="form-label">选择图片</view> |
| | | <button class="choose-image-btn" @click="chooseImage"> |
| | | <uni-icons type="image" size="20"></uni-icons> |
| | | <text>点击选择</text> |
| | | </button> |
| | | </view> |
| | | <view class="preview-area" v-if="tempImagePath"> |
| | | <image :src="tempImagePath" mode="aspectFit" class="preview-image"></image> |
| | | </view> |
| | | </view> |
| | | <view class="dialog-footer"> |
| | | <button class="cancel-btn" @click="closeUploadDialog">取消</button> |
| | | <button class="confirm-btn" @click="confirmUpload" :disabled="!tempImagePath">确定上传</button> |
| | | </view> |
| | | </view> |
| | | </uni-popup> |
| | | </view> |
| | | </template> |
| | | |
| | | <script> |
| | | import { getTask, changeTaskStatus } from '@/api/task' |
| | | import { getAttachmentList, uploadAttachmentFromWechat, deleteAttachment, getWechatAccessToken } from '@/api/task' |
| | | import { formatDateTime } from '@/utils/common' |
| | | |
| | | export default { |
| | | data() { |
| | | return { |
| | | taskDetail: null, |
| | | taskId: null |
| | | taskId: null, |
| | | attachmentList: [], |
| | | categoryList: [ |
| | | { label: '知情同意书', value: '1' }, |
| | | { label: '病人资料', value: '2' }, |
| | | { label: '操作记录', value: '3' }, |
| | | { label: '出车前', value: '4' }, |
| | | { label: '出车后', value: '5' }, |
| | | { label: '系安全带', value: '6' } |
| | | ], |
| | | selectedCategoryIndex: 0, |
| | | tempImagePath: null, |
| | | isWechatMiniProgram: false // 是否是微信小程序环境 |
| | | } |
| | | }, |
| | | computed: { |
| | | // 显示任务类型 |
| | | displayTaskType() { |
| | | if (!this.taskDetail || !this.taskDetail.taskType) { |
| | | return '未设置' |
| | | } |
| | | return this.getTaskTypeText(this.taskDetail.taskType) |
| | | }, |
| | | // 显示任务状态 |
| | | displayTaskStatus() { |
| | | if (!this.taskDetail || !this.taskDetail.taskStatus) { |
| | | return '未设置' |
| | | } |
| | | return this.getStatusText(this.taskDetail.taskStatus) |
| | | }, |
| | | // 状态样式类 |
| | | statusClass() { |
| | | if (!this.taskDetail || !this.taskDetail.taskStatus) { |
| | | return '' |
| | | } |
| | | const status = this.taskDetail.taskStatus |
| | | if (status === 'PENDING') return 'pending' |
| | | if (['DEPARTING', 'ARRIVED', 'RETURNING', 'IN_PROGRESS'].includes(status)) return 'in_progress' |
| | | if (status === 'COMPLETED') return 'completed' |
| | | if (status === 'CANCELLED') return 'cancelled' |
| | | return '' |
| | | }, |
| | | // 显示计划开始时间 |
| | | displayPlannedStartTime() { |
| | | if (!this.taskDetail || !this.taskDetail.plannedStartTime) { |
| | | return '未设置' |
| | | } |
| | | return formatDateTime(this.taskDetail.plannedStartTime, 'YYYY-MM-DD HH:mm') |
| | | }, |
| | | // 显示计划结束时间 |
| | | displayPlannedEndTime() { |
| | | if (!this.taskDetail || !this.taskDetail.plannedEndTime) { |
| | | return '未设置' |
| | | } |
| | | return formatDateTime(this.taskDetail.plannedEndTime, 'YYYY-MM-DD HH:mm') |
| | | }, |
| | | // 显示实际开始时间 |
| | | displayActualStartTime() { |
| | | if (!this.taskDetail || !this.taskDetail.actualStartTime) { |
| | | return '未设置' |
| | | } |
| | | return formatDateTime(this.taskDetail.actualStartTime, 'YYYY-MM-DD HH:mm') |
| | | }, |
| | | // 显示实际结束时间 |
| | | displayActualEndTime() { |
| | | if (!this.taskDetail || !this.taskDetail.actualEndTime) { |
| | | return '未设置' |
| | | } |
| | | return formatDateTime(this.taskDetail.actualEndTime, 'YYYY-MM-DD HH:mm') |
| | | } |
| | | }, |
| | | onLoad(options) { |
| | | this.taskId = options.id |
| | | this.loadTaskDetail() |
| | | this.loadAttachmentList() |
| | | |
| | | // 检测是否是微信小程序环境 |
| | | // #ifdef MP-WEIXIN |
| | | this.isWechatMiniProgram = true |
| | | // #endif |
| | | }, |
| | | methods: { |
| | | // 加载任务详情 |
| | |
| | | getTask(this.taskId).then(response => { |
| | | this.taskDetail = response.data || response |
| | | // 调试:打印返回的数据 |
| | | console.log('任务详情数据:', this.taskDetail) |
| | | console.log('出发地址:', this.taskDetail.departureAddress) |
| | | console.log('目的地址:', this.taskDetail.destinationAddress) |
| | | // console.log('任务详情完整数据:', JSON.stringify(this.taskDetail, null, 2)) |
| | | // console.log('任务类型字段值:', this.taskDetail.taskType) |
| | | // console.log('任务状态字段值:', this.taskDetail.taskStatus) |
| | | // console.log('出发地址:', this.taskDetail.departureAddress) |
| | | // console.log('目的地址:', this.taskDetail.destinationAddress) |
| | | }).catch(error => { |
| | | console.error('加载任务详情失败:', error) |
| | | this.$modal.showToast('加载任务详情失败') |
| | |
| | | |
| | | // 获取距离信息:根据任务类型返回不同字段 |
| | | getDistanceInfo(task) { |
| | | // 急救转运:优先使用transferDistance |
| | | // 转运:优先使用transferDistance |
| | | if (task.taskType === 'EMERGENCY_TRANSFER' && task.emergencyInfo && task.emergencyInfo.transferDistance) { |
| | | return task.emergencyInfo.transferDistance |
| | | } |
| | |
| | | // 返回上一页 |
| | | goBack() { |
| | | uni.navigateBack() |
| | | }, |
| | | |
| | | // 格式化日期时间 |
| | | formatDateTime(dateTime) { |
| | | if (!dateTime) return '未设置' |
| | | const date = new Date(dateTime) |
| | | return date.toLocaleString('zh-CN', { |
| | | year: 'numeric', |
| | | month: '2-digit', |
| | | day: '2-digit', |
| | | hour: '2-digit', |
| | | minute: '2-digit' |
| | | }) |
| | | }, |
| | | |
| | | // 获取状态文本 |
| | |
| | | 'MAINTENANCE': '维修保养', |
| | | 'FUEL': '加油', |
| | | 'OTHER': '其他', |
| | | 'EMERGENCY_TRANSFER': '急救转运', |
| | | 'EMERGENCY_TRANSFER': '转运任务', |
| | | 'WELFARE': '福祉车' |
| | | } |
| | | return typeMap[type] || '未知类型' |
| | |
| | | }) |
| | | } |
| | | }) |
| | | }, |
| | | |
| | | // 加载附件列表 |
| | | loadAttachmentList() { |
| | | if (!this.taskId) { |
| | | return |
| | | } |
| | | |
| | | getAttachmentList(this.taskId).then(response => { |
| | | this.attachmentList = response.data || response || [] |
| | | }).catch(error => { |
| | | console.error('加载附件列表失败:', error) |
| | | }) |
| | | }, |
| | | |
| | | // 显示上传对话框 |
| | | showUploadDialog() { |
| | | this.selectedCategoryIndex = 0 |
| | | this.tempImagePath = null |
| | | this.$refs.uploadPopup.open() |
| | | }, |
| | | |
| | | // 关闭上传对话框 |
| | | closeUploadDialog() { |
| | | this.$refs.uploadPopup.close() |
| | | }, |
| | | |
| | | // 分类选择变化 |
| | | onCategoryChange(e) { |
| | | this.selectedCategoryIndex = e.detail.value |
| | | }, |
| | | |
| | | // 选择图片 |
| | | chooseImage() { |
| | | const that = this |
| | | uni.chooseImage({ |
| | | count: 1, |
| | | sizeType: ['compressed'], |
| | | sourceType: ['album', 'camera'], |
| | | success: function(res) { |
| | | that.tempImagePath = res.tempFilePaths[0] |
| | | }, |
| | | fail: function(err) { |
| | | console.error('选择图片失败:', err) |
| | | that.$modal.showToast('选择图片失败') |
| | | } |
| | | }) |
| | | }, |
| | | |
| | | // 确认上传 |
| | | confirmUpload() { |
| | | if (!this.tempImagePath) { |
| | | this.$modal.showToast('请先选择图片') |
| | | return |
| | | } |
| | | |
| | | const that = this |
| | | const category = this.categoryList[this.selectedCategoryIndex].value |
| | | |
| | | // 微信小程序环境:先获取AccessToken,再上传到微信服务器,最后提交mediaId到后端 |
| | | // #ifdef MP-WEIXIN |
| | | if (this.isWechatMiniProgram) { |
| | | uni.showLoading({ |
| | | title: '上传中...' |
| | | }) |
| | | |
| | | // 第一步:从后端获取AccessToken |
| | | getWechatAccessToken().then(tokenResponse => { |
| | | // 接口返回格式:{"msg":"token值","code":200} |
| | | console.log('获取AccessToken成功:', tokenResponse) |
| | | const accessToken = tokenResponse.msg || tokenResponse.data || tokenResponse |
| | | if (!accessToken) { |
| | | uni.hideLoading() |
| | | that.$modal.showToast('获取AccessToken失败') |
| | | console.error('获取AccessToken失败,响应数据:', tokenResponse) |
| | | return |
| | | } |
| | | |
| | | console.log('获取到AccessToken:', accessToken) |
| | | |
| | | // 第二步:上传到微信服务器 |
| | | const uploadUrl = `https://api.weixin.qq.com/cgi-bin/media/upload?access_token=${accessToken}&type=image` |
| | | |
| | | uni.uploadFile({ |
| | | url: uploadUrl, |
| | | filePath: that.tempImagePath, |
| | | name: 'media', |
| | | success: function(res) { |
| | | console.log('微信上传响应:', res) |
| | | try { |
| | | const data = JSON.parse(res.data) |
| | | if (data.media_id) { |
| | | // 第三步:提交mediaId到后端 |
| | | uploadAttachmentFromWechat(that.taskId, data.media_id, category).then(response => { |
| | | uni.hideLoading() |
| | | that.$modal.showToast('上传成功') |
| | | that.closeUploadDialog() |
| | | that.loadAttachmentList() |
| | | }).catch(error => { |
| | | uni.hideLoading() |
| | | console.error('提交mediaId失败:', error) |
| | | that.$modal.showToast('上传失败:' + (error.msg || '请重试')) |
| | | }) |
| | | } else { |
| | | uni.hideLoading() |
| | | const errMsg = data.errmsg || '未知错误' |
| | | console.error('微信返回错误:', data) |
| | | that.$modal.showToast('微信上传失败:' + errMsg) |
| | | } |
| | | } catch (e) { |
| | | uni.hideLoading() |
| | | console.error('解析微信响应失败:', e, res.data) |
| | | that.$modal.showToast('上传失败:响应解析错误') |
| | | } |
| | | }, |
| | | fail: function(err) { |
| | | uni.hideLoading() |
| | | console.error('上传到微信失败:', err) |
| | | that.$modal.showToast('上传失败:' + (err.errMsg || '请检查网络')) |
| | | } |
| | | }) |
| | | }).catch(error => { |
| | | uni.hideLoading() |
| | | console.error('获取AccessToken失败:', error) |
| | | that.$modal.showToast('获取AccessToken失败') |
| | | }) |
| | | return |
| | | } |
| | | // #endif |
| | | |
| | | // 非微信小程序环境:直接上传到后端服务器 |
| | | uni.showLoading({ |
| | | title: '上传中...' |
| | | }) |
| | | |
| | | uni.uploadFile({ |
| | | url: that.$baseUrl + '/task/attachment/upload/' + that.taskId, |
| | | filePath: that.tempImagePath, |
| | | name: 'file', |
| | | formData: { |
| | | 'category': category |
| | | }, |
| | | header: { |
| | | 'Authorization': 'Bearer ' + uni.getStorageSync('token') |
| | | }, |
| | | success: function(uploadRes) { |
| | | uni.hideLoading() |
| | | |
| | | if (uploadRes.statusCode === 200) { |
| | | const result = JSON.parse(uploadRes.data) |
| | | if (result.code === 200) { |
| | | that.$modal.showToast('上传成功') |
| | | that.closeUploadDialog() |
| | | that.loadAttachmentList() |
| | | } else { |
| | | that.$modal.showToast(result.msg || '上传失败') |
| | | } |
| | | } else { |
| | | that.$modal.showToast('上传失败') |
| | | } |
| | | }, |
| | | fail: function(err) { |
| | | uni.hideLoading() |
| | | console.error('上传失败:', err) |
| | | that.$modal.showToast('上传失败') |
| | | } |
| | | }) |
| | | }, |
| | | |
| | | // 查看附件 |
| | | viewAttachment(item) { |
| | | // 如果是图片,使用图片预览 |
| | | const imageTypes = ['jpg', 'jpeg', 'png', 'gif', 'bmp'] |
| | | const fileExt = item.fileName.split('.').pop().toLowerCase() |
| | | |
| | | if (imageTypes.includes(fileExt)) { |
| | | // 构建图片访问地址 |
| | | // 如果是filePath是完整路径,需要通过下载接口访问 |
| | | const imageUrl = this.$baseUrl + '/task/attachment/download/' + item.attachmentId |
| | | |
| | | // 微信小程序中预览图片 |
| | | // #ifdef MP-WEIXIN |
| | | // 微信小程序需要先下载到本地再预览 |
| | | uni.showLoading({ title: '加载中...' }) |
| | | uni.downloadFile({ |
| | | url: imageUrl, |
| | | success: function(res) { |
| | | uni.hideLoading() |
| | | if (res.statusCode === 200) { |
| | | uni.previewImage({ |
| | | urls: [res.tempFilePath], |
| | | current: res.tempFilePath |
| | | }) |
| | | } else { |
| | | uni.showToast({ title: '加载图片失败', icon: 'none' }) |
| | | } |
| | | }, |
| | | fail: function() { |
| | | uni.hideLoading() |
| | | uni.showToast({ title: '下载失败', icon: 'none' }) |
| | | } |
| | | }) |
| | | // #endif |
| | | |
| | | // 非微信小程序环境,直接预览 |
| | | // #ifndef MP-WEIXIN |
| | | uni.previewImage({ |
| | | urls: [imageUrl], |
| | | current: imageUrl |
| | | }) |
| | | // #endif |
| | | } else { |
| | | this.$modal.showToast('仅支持预览图片') |
| | | } |
| | | }, |
| | | |
| | | // 删除附件 |
| | | deleteAttachment(attachmentId, index) { |
| | | const that = this |
| | | this.$modal.confirm('确定要删除该附件吗?').then(() => { |
| | | deleteAttachment(attachmentId).then(response => { |
| | | that.$modal.showToast('删除成功') |
| | | that.attachmentList.splice(index, 1) |
| | | }).catch(error => { |
| | | console.error('删除附件失败:', error) |
| | | that.$modal.showToast('删除失败') |
| | | }) |
| | | }).catch(() => {}) |
| | | }, |
| | | |
| | | // 获取分类名称 |
| | | getCategoryName(category) { |
| | | const item = this.categoryList.find(c => c.value === category) |
| | | return item ? item.label : '未分类' |
| | | }, |
| | | |
| | | // 格式化时间 |
| | | formatTime(time) { |
| | | if (!time) return '' |
| | | return formatDateTime(time, 'YYYY-MM-DD HH:mm') |
| | | }, |
| | | |
| | | // 格式化文件大小 |
| | | formatFileSize(size) { |
| | | if (!size) return '0B' |
| | | if (size < 1024) return size + 'B' |
| | | if (size < 1024 * 1024) return (size / 1024).toFixed(2) + 'KB' |
| | | return (size / 1024 / 1024).toFixed(2) + 'MB' |
| | | } |
| | | } |
| | | } |
| | |
| | | color: #333; |
| | | border-bottom: 1rpx solid #f0f0f0; |
| | | padding-bottom: 10rpx; |
| | | display: flex; |
| | | justify-content: space-between; |
| | | align-items: center; |
| | | |
| | | .upload-btn { |
| | | font-size: 24rpx; |
| | | padding: 8rpx 20rpx; |
| | | background-color: #007AFF; |
| | | color: white; |
| | | border-radius: 8rpx; |
| | | border: none; |
| | | } |
| | | } |
| | | |
| | | .info-item { |
| | |
| | | background-color: #f9f9f9; |
| | | padding: 20rpx; |
| | | border-radius: 10rpx; |
| | | } |
| | | |
| | | .no-attachment { |
| | | text-align: center; |
| | | padding: 40rpx 0; |
| | | color: #999; |
| | | font-size: 28rpx; |
| | | } |
| | | |
| | | .attachment-item { |
| | | display: flex; |
| | | justify-content: space-between; |
| | | align-items: center; |
| | | padding: 20rpx; |
| | | margin-bottom: 15rpx; |
| | | background-color: #f9f9f9; |
| | | border-radius: 10rpx; |
| | | |
| | | &:last-child { |
| | | margin-bottom: 0; |
| | | } |
| | | |
| | | .attachment-info { |
| | | flex: 1; |
| | | margin-right: 20rpx; |
| | | |
| | | .attachment-category { |
| | | margin-bottom: 8rpx; |
| | | |
| | | .category-tag { |
| | | display: inline-block; |
| | | padding: 4rpx 12rpx; |
| | | background-color: #007AFF; |
| | | color: white; |
| | | font-size: 22rpx; |
| | | border-radius: 4rpx; |
| | | } |
| | | } |
| | | |
| | | .attachment-name { |
| | | font-size: 28rpx; |
| | | color: #333; |
| | | margin-bottom: 8rpx; |
| | | word-break: break-all; |
| | | } |
| | | |
| | | .attachment-meta { |
| | | font-size: 24rpx; |
| | | color: #999; |
| | | |
| | | .upload-time { |
| | | margin-right: 20rpx; |
| | | } |
| | | } |
| | | } |
| | | |
| | | .attachment-actions { |
| | | display: flex; |
| | | flex-direction: column; |
| | | gap: 10rpx; |
| | | |
| | | .action-btn { |
| | | padding: 8rpx 20rpx; |
| | | font-size: 24rpx; |
| | | border-radius: 6rpx; |
| | | border: none; |
| | | |
| | | &.view-btn { |
| | | background-color: #007AFF; |
| | | color: white; |
| | | } |
| | | |
| | | &.delete-btn { |
| | | background-color: #ff3b30; |
| | | color: white; |
| | | } |
| | | } |
| | | } |
| | | } |
| | | } |
| | | |
| | |
| | | } |
| | | } |
| | | } |
| | | |
| | | .upload-dialog { |
| | | background-color: white; |
| | | border-radius: 20rpx 20rpx 0 0; |
| | | padding: 30rpx; |
| | | |
| | | .dialog-header { |
| | | display: flex; |
| | | justify-content: space-between; |
| | | align-items: center; |
| | | margin-bottom: 30rpx; |
| | | |
| | | .dialog-title { |
| | | font-size: 32rpx; |
| | | font-weight: bold; |
| | | color: #333; |
| | | } |
| | | } |
| | | |
| | | .dialog-content { |
| | | .form-item { |
| | | margin-bottom: 30rpx; |
| | | |
| | | .form-label { |
| | | font-size: 28rpx; |
| | | color: #333; |
| | | margin-bottom: 15rpx; |
| | | } |
| | | |
| | | .picker-value { |
| | | display: flex; |
| | | justify-content: space-between; |
| | | align-items: center; |
| | | padding: 20rpx; |
| | | background-color: #f5f5f5; |
| | | border-radius: 10rpx; |
| | | font-size: 28rpx; |
| | | color: #333; |
| | | } |
| | | |
| | | .choose-image-btn { |
| | | display: flex; |
| | | align-items: center; |
| | | justify-content: center; |
| | | padding: 30rpx; |
| | | background-color: #f5f5f5; |
| | | border-radius: 10rpx; |
| | | border: 2rpx dashed #ccc; |
| | | color: #666; |
| | | font-size: 28rpx; |
| | | |
| | | text { |
| | | margin-left: 10rpx; |
| | | } |
| | | } |
| | | } |
| | | |
| | | .preview-area { |
| | | margin-top: 20rpx; |
| | | |
| | | .preview-image { |
| | | width: 100%; |
| | | height: 400rpx; |
| | | border-radius: 10rpx; |
| | | } |
| | | } |
| | | } |
| | | |
| | | .dialog-footer { |
| | | display: flex; |
| | | gap: 20rpx; |
| | | margin-top: 30rpx; |
| | | |
| | | button { |
| | | flex: 1; |
| | | height: 80rpx; |
| | | border-radius: 10rpx; |
| | | font-size: 30rpx; |
| | | border: none; |
| | | } |
| | | |
| | | .cancel-btn { |
| | | background-color: #f5f5f5; |
| | | color: #666; |
| | | } |
| | | |
| | | .confirm-btn { |
| | | background-color: #007AFF; |
| | | color: white; |
| | | |
| | | &:disabled { |
| | | background-color: #ccc; |
| | | } |
| | | } |
| | | } |
| | | } |
| | | } |
| | | </style> |