吉安感知网项目-前端
chenyao
5 hours ago 35fb4a40571d69b85caede7348101d71789b5fb3
feat:提交吉安工单和移动端处置数据
8 files modified
719 ■■■■■ changed files
applications/task-work-order/src/styles/common/cockpit.scss 3 ●●●● patch | view | raw | blame | history
applications/task-work-order/src/views/orderView/orderManage/clueEvents/DistributeDiaLog.vue 2 ●●● patch | view | raw | blame | history
applications/task-work-order/src/views/orderView/orderManage/clueEvents/ViewDiaLog.vue 15 ●●●● patch | view | raw | blame | history
applications/task-work-order/src/views/orderView/orderManage/eventManage/ViewDiaLog.vue 87 ●●●●● patch | view | raw | blame | history
uniapps/work-app/src/subPackages/workDetail/HandleWork/index.vue 6 ●●●● patch | view | raw | blame | history
uniapps/work-app/src/subPackages/workDetail/HandleWorking/index-copy.vue 602 ●●●● patch | view | raw | blame | history
uniapps/work-app/src/subPackages/workDetail/HandleWorking/index.vue 2 ●●● patch | view | raw | blame | history
uniapps/work-app/src/subPackages/workDetail/index.vue 2 ●●● patch | view | raw | blame | history
applications/task-work-order/src/styles/common/cockpit.scss
@@ -686,7 +686,8 @@
  th.el-table__cell:not(.fixed-column),
  td.el-table__cell:not(.fixed-column) {
    background: transparent !important;
    // background: transparent !important;
    background: white !important;
  }
  .el-checkbox {
applications/task-work-order/src/views/orderView/orderManage/clueEvents/DistributeDiaLog.vue
@@ -146,7 +146,7 @@
// 打开弹框
async function open({ row, workOrderId: orderId } = {}) {
    console.log('333',row)
    console.log('33399',row)
    currentRow.value = row
    workOrderId.value = orderId
    formData.value = initForm()
applications/task-work-order/src/views/orderView/orderManage/clueEvents/ViewDiaLog.vue
@@ -180,8 +180,19 @@
.gd-dialog-table {
    flex: 1;
    :deep(.el-table__body-wrapper) {
        overflow-y: auto !important;
    .el-table__body-wrapper {
        flex: none;
        overflow: visible;
    }
    .el-table__body-wrapper .el-scrollbar,
    .el-table__body-wrapper .el-scrollbar__wrap {
        height: auto;
        overflow: visible;
    }
    .el-table__body-wrapper .el-scrollbar__bar.is-vertical {
        display: none;
    }
}
</style>
applications/task-work-order/src/views/orderView/orderManage/eventManage/ViewDiaLog.vue
@@ -72,12 +72,17 @@
                </div>
                <div class="img_flow">
                    <div class="imgurl">
                        <el-image
                        <el-image v-if="eventInfo.attachmentType === 1"
                            :src="eventInfo.eventImageUrl"
                            :preview-src-list="[eventInfo.eventImageUrl]"
                            fit="cover"
                            preview-teleported
                        />
                        <div class="video-btn" v-if="eventInfo.attachmentType === 3" @click="videoClick(eventInfo)">
                            <el-icon :size="30" color="#fff">
                                <VideoPlay />
                            </el-icon>
                        </div>
                    </div>
                    <div class="flow">
                        <div v-if="disposeRecords.length === 0">
@@ -86,7 +91,7 @@
                        <div v-else class="flow-card" v-for="item in disposeRecords" :key="item.id">
                            <div class="flow-row1">
                                <span class="flow-name">{{ item.disposeUserName }}</span>
                                <span class="flow-status">{{ item.disposeStatusName }}</span>
                                <span class="flow-status card-status" :class="statusClass(item.disposeStatus)">{{ item.disposeStatusName }}</span>
                            </div>
                            <div class="flow-row2">{{ item.disposeContent }}</div>
                            <div class="flow-row3" v-if="item.attachUrl?.length">
@@ -114,6 +119,7 @@
            </div>
        </div>
    </el-dialog>
    <VideoPlayDialog ref="videoPlayDialogRef" v-if="VideoShow" v-model="VideoShow" :playUrl="eventInfo.eventImageUrl" />
</template>
<script setup>
@@ -121,11 +127,15 @@
import { getDetailFull } from './eventManageApi'
import OrderStepBar from './OrderStepBar.vue'
import { ref } from 'vue'
import { VideoPlay } from '@element-plus/icons-vue'
import VideoPlayDialog from '@/components/VideoPlayDialog.vue'
const visible = defineModel()
const eventInfo = ref({})
const disposeRecords = ref([])
const statusFlows = ref([])
const VideoShow = ref(false)
const videoPlayDialogRef = ref(null)
// 获取状态文本
const getStatusLabel = status => {
@@ -137,6 +147,14 @@
        4: '已完成',
    }
    return map[status] || '未知'
}
// 状态样式类名
const statusClass = status => {
    if (status === 1) return 'status-processing'
    if (status === 3) return 'status-handled'
    if (status === 4) return 'status-completed'
    return ''
}
// 兼容事件记录接口中不同版本的字段名称
@@ -152,9 +170,15 @@
    }
}
function videoClick(eventInfo) {
    // currentVideo.value = eventInfo
    VideoShow.value = true
}
// 打开弹框
async function open({ row } = {}) {
    if (!row?.id) return
    console.log(row, '9098')
    const res = await getDetailFull({ id: row.id })
    const detail = res?.data?.data || {}
    eventInfo.value = detail.eventInfo || {}
@@ -216,6 +240,44 @@
                    width: 100%;
                }
            }
            .video-btn {
        width: 100%;
        height:100%;
        position: relative;
        overflow: hidden;
        border-radius: 4px;
        background: linear-gradient(135deg, rgba(76, 52, 255, 0.14), rgba(76, 52, 255, 0) 48%),
            linear-gradient(180deg, #f4f5ff 0%, #e9ecff 100%);
        box-shadow: inset 0 0 0 1px rgba(255, 255, 255, 0.7);
        display: flex;
        align-items: center;
        justify-content: center;
        cursor: pointer;
        &::before {
            content: '';
            position: absolute;
            inset: 0;
            background-image: linear-gradient(
                90deg,
                rgba(76, 52, 255, 0.05) 0,
                rgba(76, 52, 255, 0.05) 1px,
                transparent 1px,
                transparent 12px
            );
            opacity: 0.42;
        }
        .el-icon {
            position: relative;
            z-index: 1;
            width: 42px;
            height: 42px;
            border-radius: 50%;
            background: rgba(76, 52, 255, 0.72);
            box-shadow: 0 4px 12px rgba(76, 52, 255, 0.2);
        }
    }
            .flow {
                margin-left: 10px;
                flex: 1;
@@ -265,6 +327,25 @@
                        font-size: 12px;
                        color: #999;
                    }
                    .card-status {
                        font-family: Source Han Sans CN, Source Han Sans CN;
                        font-weight: 400;
                        font-size: 14px;
                        padding: 2px 6px;
                        border-radius: 4px;
                        color: #ffffff;
                        background: #999;
                        &.status-processing {
                            background: #1d6fe9;
                        }
                        &.status-handled {
                            background: #e6a23c;
                        }
                        &.status-completed {
                            background: #00b578;
                        }
                    }
                }
            }
        }
@@ -291,6 +372,8 @@
    .processBox {
        display: flex;
        flex-direction: column;
        height: 650px;
        overflow: auto;
        .process {
            height: 100%;
uniapps/work-app/src/subPackages/workDetail/HandleWork/index.vue
@@ -225,9 +225,9 @@
.card-status {
    font-family: Source Han Sans CN, Source Han Sans CN;
    font-weight: 400;
    font-size: 24rpx;
    padding: 4rpx 16rpx;
    border-radius: 6rpx;
    // font-size: 44px;
    padding: 4px 16px;
    border-radius: 6px;
    color: #ffffff;
    background: #999;
uniapps/work-app/src/subPackages/workDetail/HandleWorking/index-copy.vue
@@ -1,58 +1,55 @@
<template>
    <view class="handle-page">
        <u-navbar title="待办处置" :is-back="true" back-text="" :back-icon-size="40" @left-click="onBackClick"></u-navbar>
  <view class="handle-page">
    <u-navbar title="待办处置" :is-back="true" back-text="" :back-icon-size="40" @left-click="onBackClick"></u-navbar>
        <scroll-view class="form-scroll" scroll-y>
            <view class="form-section description-section">
                <view class="section-header">
                    <text class="section-title">处置描述</text>
                </view>
                <view class="description-wrapper">
    <scroll-view class="form-scroll" scroll-y>
      <view class="form-section description-section">
        <view class="section-header">
          <text class="section-title">处置描述</text>
        </view>
        <view class="description-wrapper">
                    <textarea
                        v-model="formData.disposeContent"
                        class="description-input"
                        maxlength="140"
                        placeholder="请输入"
                        placeholder-class="description-placeholder"
                        :show-confirm-bar="false"
                    />
                    <text class="word-count">{{ descriptionLength }}/140</text>
                </view>
            </view>
            v-model="formData.disposeContent"
            class="description-input"
            maxlength="140"
            placeholder="请输入"
            placeholder-class="description-placeholder"
            :show-confirm-bar="false"
          />
          <text class="word-count">{{ descriptionLength }}/140</text>
        </view>
      </view>
            <!--            <view class="form-section status-section">-->
            <!--                <text class="section-title">处置中</text>-->
            <!--                <switch class="status-switch" :checked="formData.isHandling" color="#00b578" @change="handleStatusChange" />-->
            <!--            </view>-->
      <!--            <view class="form-section status-section">-->
      <!--                <text class="section-title">处置中</text>-->
      <!--                <switch class="status-switch" :checked="formData.isHandling" color="#00b578" @change="handleStatusChange" />-->
      <!--            </view>-->
            <view class="form-section upload-section">
                <view class="section-header upload-header">
                    <text class="section-title">附件上传</text>
                </view>
                <!--                <button class="select-file-btn" @click="handleChooseFile">选择文件</button>-->
                <u-button color="#1D6FE9" class="select-file-btn" :disabled="uploading" @click="handleChooseFile">
                    {{ uploading ? '上传中...' : '选择文件' }}
                </u-button>
      <view class="form-section upload-section">
        <view class="section-header upload-header">
          <text class="section-title">附件上传</text>
        </view>
        <!--                <button class="select-file-btn" @click="handleChooseFile">选择文件</button>-->
        <u-button color="#1D6FE9" class="select-file-btn" :disabled="uploading" @click="handleChooseFile">
          {{ uploading ? '上传中...' : '选择文件' }}
        </u-button>
                <view v-if="attachmentList.length" class="attachment-list">
                    <view v-for="(file, index) in attachmentList" :key="`${file.path}-${index}`" class="attachment-item">
                        <view class="file-info">
                            <text class="file-name">{{ file.name }}</text>
                            <text v-if="file.size" class="file-size">{{ formatFileSize(file.size) }}</text>
                        </view>
                        <text class="remove-file-btn" @click.stop="handleRemoveFile(index)">×</text>
                    </view>
                </view>
            </view>
        </scroll-view>
        <view v-if="attachmentList.length" class="attachment-list">
          <view v-for="(file, index) in attachmentList" :key="`${file.path}-${index}`" class="attachment-item">
            <image class="attachment-image" :src="file.path" mode="aspectFill" @click="handlePreviewImage(index)" />
            <text class="remove-file-btn" @click.stop="handleRemoveFile(index)">×</text>
          </view>
        </view>
      </view>
    </scroll-view>
        <view class="action-footer">
            <u-button color="#AEAEAE" class="custom-style" @click="handleCancel">取消</u-button>
            <u-button color="#1D6FE9" class="custom-style" :disabled="submitting || uploading" @click="handleSubmit">
                {{ submitting ? '提交中...' : '确定' }}
            </u-button>
        </view>
    </view>
    <view class="action-footer">
      <u-button color="#AEAEAE" class="custom-style" @click="handleCancel">取消</u-button>
      <u-button color="#1D6FE9" class="custom-style" :disabled="submitting || uploading" @click="handleSubmit">
        {{ submitting ? '提交中...' : '确定' }}
      </u-button>
    </view>
  </view>
</template>
<script setup>
@@ -67,13 +64,13 @@
const uploading = ref(false)
const attachmentList = ref([])
const formData = ref({
    disposeContent: '',
    isHandling: true,
  disposeContent: '',
  isHandling: true,
})
const navbarTitleStyle = {
    color: '#ffffff',
    fontSize: '34rpx',
    fontWeight: '500',
  color: '#ffffff',
  fontSize: '34rpx',
  fontWeight: '500',
}
// 计算处置描述字数
@@ -81,12 +78,12 @@
// 读取当前工单标识
onLoad(options => {
    eventId.value = options?.id ?? ''
  eventId.value = options?.id ?? ''
})
// 返回上一页
function handleBack() {
    uni.navigateBack()
  uni.navigateBack()
}
// 切换处置状态
@@ -96,375 +93,372 @@
// 提取文件名称
function getFileName(filePath = '') {
    const normalizedPath = filePath.replace(/\\/g, '/')
    return decodeURIComponent(normalizedPath.split('/').pop() || '未命名文件')
  const normalizedPath = filePath.replace(/\\/g, '/')
  return decodeURIComponent(normalizedPath.split('/').pop() || '未命名文件')
}
// 上传单个已选择文件
async function uploadSelectedFile(file) {
    const response = await uploadFileAPI(file.path)
    const link = response?.data?.link || response?.data?.url || response?.link
    if (!link) throw new Error('上传接口未返回文件地址')
    return { ...file, link }
  const response = await uploadFileAPI(file.path)
  const link = response?.data?.link || response?.data?.url || response?.link
  if (!link) throw new Error('上传接口未返回文件地址')
  return { ...file, link }
}
// 处理已选择文件
async function handleChooseSuccess(result) {
    const selectedFiles = result.tempFiles?.length
        ? result.tempFiles
        : (result.tempFilePaths ?? []).map(path => ({ path }))
    const availableCount = MAX_FILE_COUNT - attachmentList.value.length
    const normalizedFiles = selectedFiles
        .slice(0, availableCount)
        .map(file => {
            const path = file.path || file.tempFilePath || ''
            return {
                name: file.name || getFileName(path),
                path,
                size: Number(file.size) || 0,
            }
        })
        .filter(file => file.path)
    if (!normalizedFiles.length) return
  const selectedFiles = result.tempFiles?.length
    ? result.tempFiles
    : (result.tempFilePaths ?? []).map(path => ({ path }))
  const availableCount = MAX_FILE_COUNT - attachmentList.value.length
  const normalizedFiles = selectedFiles
    .slice(0, availableCount)
    .map(file => {
      const path = file.path || file.tempFilePath || ''
      return {
        name: file.name || getFileName(path),
        path,
        size: Number(file.size) || 0,
      }
    })
    .filter(file => file.path)
  if (!normalizedFiles.length) return
    uploading.value = true
    uni.showLoading({ title: '上传中...', mask: true })
    let failedCount = 0
    try {
        const uploadResults = await Promise.all(
            normalizedFiles.map(async file => {
                try {
                    return { success: true, file: await uploadSelectedFile(file) }
                } catch {
                    return { success: false, file }
                }
            })
        )
        const uploadedFiles = uploadResults.filter(item => item.success).map(item => item.file)
        failedCount = uploadResults.length - uploadedFiles.length
        attachmentList.value.push(...uploadedFiles)
    } finally {
        uni.hideLoading()
        uploading.value = false
    }
    uni.showToast({
        title: failedCount ? `${failedCount}个文件上传失败` : '上传成功',
        icon: failedCount ? 'none' : 'success',
    })
  uploading.value = true
  uni.showLoading({ title: '上传中...', mask: true })
  let failedCount = 0
  try {
    const uploadResults = await Promise.all(
      normalizedFiles.map(async file => {
        try {
          return { success: true, file: await uploadSelectedFile(file) }
        } catch {
          return { success: false, file }
        }
      })
    )
    const uploadedFiles = uploadResults.filter(item => item.success).map(item => item.file)
    failedCount = uploadResults.length - uploadedFiles.length
    attachmentList.value.push(...uploadedFiles)
  } finally {
    uni.hideLoading()
    uploading.value = false
  }
  uni.showToast({
    title: failedCount ? `${failedCount}个文件上传失败` : '上传成功',
    icon: failedCount ? 'none' : 'success',
  })
}
// 处理选择文件失败
function handleChooseFail(error) {
    if (error?.errMsg?.includes('cancel')) return
    uni.showToast({ title: '选择文件失败', icon: 'none' })
  if (error?.errMsg?.includes('cancel')) return
  uni.showToast({ title: '取消选择文件', icon: 'none' })
}
// 选择附件
function handleChooseFile() {
    if (uploading.value) return
    const availableCount = MAX_FILE_COUNT - attachmentList.value.length
    if (availableCount <= 0) {
        uni.showToast({ title: `最多选择${MAX_FILE_COUNT}个附件`, icon: 'none' })
        return
    }
    const options = {
        count: availableCount,
        type: 'all',
        success: handleChooseSuccess,
        fail: handleChooseFail,
    }
  if (uploading.value) return
  const availableCount = MAX_FILE_COUNT - attachmentList.value.length
  if (availableCount <= 0) {
    uni.showToast({ title: `最多选择${MAX_FILE_COUNT}个附件`, icon: 'none' })
    return
  }
  const options = {
    count: availableCount,
    type: 'image',
    success: handleChooseSuccess,
    fail: handleChooseFail,
  }
    // #ifdef H5
    uni.chooseFile(options)
    // #endif
  // #ifdef H5
  uni.chooseFile(options)
  // #endif
    // #ifdef MP-WEIXIN
    uni.chooseMessageFile(options)
    // #endif
  // #ifdef MP-WEIXIN
  uni.chooseMessageFile(options)
  // #endif
    // #ifdef APP-PLUS
    uni.chooseImage({ ...options, sourceType: ['album', 'camera'] })
    // #endif
  // #ifdef APP-PLUS
  uni.chooseImage({ ...options, sourceType: ['album', 'camera'] })
  // #endif
}
// 移除附件
function handleRemoveFile(index) {
    attachmentList.value.splice(index, 1)
  attachmentList.value.splice(index, 1)
}
// 格式化文件大小
function formatFileSize(size) {
    if (size < 1024) return `${size} B`
    if (size < 1024 * 1024) return `${(size / 1024).toFixed(1)} KB`
    return `${(size / 1024 / 1024).toFixed(1)} MB`
// 预览已选择图片
function handlePreviewImage(index) {
  uni.previewImage({
    current: index,
    urls: attachmentList.value.map(file => file.path),
  })
}
// 取消处置
function handleCancel() {
    uni.navigateBack()
  uni.navigateBack()
}
// 提交处置信息
async function handleSubmit() {
    if (uploading.value) {
        uni.showToast({ title: '请等待附件上传完成', icon: 'none' })
        return
    }
    const disposeContent = formData.value.disposeContent.trim()
    if (!disposeContent) {
        uni.showToast({ title: '请输入处置描述', icon: 'none' })
        return
    }
    if (!eventId.value) {
        uni.showToast({ title: '工单信息缺失', icon: 'none' })
        return
    }
  if (uploading.value) {
    uni.showToast({ title: '请等待附件上传完成', icon: 'none' })
    return
  }
  const disposeContent = formData.value.disposeContent.trim()
  if (!disposeContent) {
    uni.showToast({ title: '请输入处置描述', icon: 'none' })
    return
  }
  if (!eventId.value) {
    uni.showToast({ title: '工单信息缺失', icon: 'none' })
    return
  }
    submitting.value = true
    try {
        await addDisposeRecord({
            eventId: eventId.value,
            recordType: 1,
            disposeContent: formData.value.disposeContent,
            targetEventStatus: eventStatus.value == 1 ? 3 : eventStatus.value,
            updateEventStatus: true,
            attachUrl: attachmentList.value.map(file => file.link),
            // operateTime: '2026-07-30 14:00:00',
            // eventStatus: formData.value.isHandling ? '1' : '3',
            // handleDesc,
            // attachmentList: attachmentList.value.map(file => ({
            //     attachName: file.name,
            //     filePath: file.path,
            // })),
        })
        uni.showToast({ title: '提交成功', icon: 'success' })
        setTimeout(() => {
            submitting.value = false
            uni.navigateBack()
            // uni.navigateTo({
            //     url: `/subPackages/workDetail/HandleWork/index?id=${eventId.value}`,
            // })
        }, 1200)
    } catch {
        submitting.value = false
        uni.showToast({ title: '提交失败,请重试', icon: 'none' })
    }
  submitting.value = true
  try {
    await addDisposeRecord({
      eventId: eventId.value,
      recordType: 1,
      disposeContent: formData.value.disposeContent,
      targetEventStatus: eventStatus.value == 1 ? 3 : eventStatus.value,
      updateEventStatus: true,
      attachUrl: attachmentList.value.map(file => file.link),
      // operateTime: '2026-07-30 14:00:00',
      // eventStatus: formData.value.isHandling ? '1' : '3',
      // handleDesc,
      // attachmentList: attachmentList.value.map(file => ({
      //     attachName: file.name,
      //     filePath: file.path,
      // })),
    })
    uni.showToast({ title: '提交成功', icon: 'success' })
    setTimeout(() => {
      submitting.value = false
      uni.navigateBack()
      // uni.navigateTo({
      //     url: `/subPackages/workDetail/HandleWork/index?id=${eventId.value}`,
      // })
    }, 1200)
  } catch {
    submitting.value = false
    uni.showToast({ title: '提交失败,请重试', icon: 'none' })
  }
}
// 返回按钮点击事件
const onBackClick = () => {
    uni.navigateBack()
  uni.navigateBack()
}
onLoad(options => {
    console.log(options, '9090')
    eventId.value = options?.id || ''
    eventStatus.value = options?.eventStatus || ''
  console.log(options, '9090')
  eventId.value = options?.id || ''
  eventStatus.value = options?.eventStatus || ''
})
</script>
<style scoped lang="scss">
.handle-page {
    padding-top: 88rpx;
    :deep() {
        .u-navbar__content {
            background: url('https://wrj.shuixiongit.com/aiskyminio/cloud-bucket/ztzf_app_assets/images/user/bg.png')
                no-repeat !important;
            background-size: 100% !important;
            height: 88rpx !important;
        }
    }
  padding-top: 88rpx;
  :deep() {
    .u-navbar__content {
      background: url('https://wrj.shuixiongit.com/aiskyminio/cloud-bucket/ztzf_app_assets/images/user/bg.png')
      no-repeat !important;
      background-size: 100% !important;
      height: 88rpx !important;
    }
  }
    display: flex;
    flex-direction: column;
    box-sizing: border-box;
    height: calc(100vh);
    //padding-top: 88rpx;
    //background: #111827;
    //color: #f5f7fa;
  display: flex;
  flex-direction: column;
  box-sizing: border-box;
  height: calc(100vh);
  //padding-top: 88rpx;
  //background: #111827;
  //color: #f5f7fa;
    //:deep(.u-navbar__content) {
    //    height: 88rpx !important;
    //    background: #151c29 !important;
    //}
  //:deep(.u-navbar__content) {
  //    height: 88rpx !important;
  //    background: #151c29 !important;
  //}
}
.form-scroll {
    box-sizing: border-box;
    height: 0;
    flex: 1;
    padding: 60rpx 24rpx 24rpx;
    // #ifdef APP-PLUS
    padding-top: 60rpx;
    // #endif
  box-sizing: border-box;
  height: 0;
  flex: 1;
  padding: 0 24rpx 24rpx;
}
.form-section {
    box-sizing: border-box;
    margin-bottom: 20rpx;
    background: #ffffff;
    border: 1rpx solid rgba(255, 255, 255, 0.03);
  box-sizing: border-box;
  margin-bottom: 20rpx;
  background: #ffffff;
  border: 1rpx solid rgba(255, 255, 255, 0.03);
}
.section-header {
    display: flex;
    align-items: center;
    justify-content: space-between;
    height: 82rpx;
    padding: 0 22rpx;
    border-bottom: 1rpx solid #eeeeee;
  display: flex;
  align-items: center;
  justify-content: space-between;
  height: 82rpx;
  padding: 0 22rpx;
  border-bottom: 1rpx solid #eeeeee;
}
.section-title {
    font-size: 30rpx;
    font-weight: 400;
    color: #222324;
  font-size: 30rpx;
  font-weight: 400;
  color: #222324;
}
.description-wrapper {
    position: relative;
  position: relative;
}
.word-count {
    position: absolute;
    right: 22rpx;
    bottom: 16rpx;
    font-size: 24rpx;
    color: #999;
  position: absolute;
  right: 22rpx;
  bottom: 16rpx;
  font-size: 24rpx;
  color: #999;
}
.description-input {
    display: block;
    box-sizing: border-box;
    width: 100%;
    height: 350rpx;
    padding: 24rpx 22rpx;
    font-size: 30rpx;
    line-height: 1.6;
    color: #222324;
    background: transparent;
  display: block;
  box-sizing: border-box;
  width: 100%;
  height: 350rpx;
  padding: 24rpx 22rpx;
  font-size: 30rpx;
  line-height: 1.6;
  color: #222324;
  background: transparent;
}
:deep(.description-placeholder) {
    color: #999;
  color: #999;
}
.status-section {
    display: flex;
    align-items: center;
    justify-content: space-between;
    height: 104rpx;
    padding: 0 20rpx 0 22rpx;
  display: flex;
  align-items: center;
  justify-content: space-between;
  height: 104rpx;
  padding: 0 20rpx 0 22rpx;
}
.status-switch {
    transform: scale(0.84);
    transform-origin: right center;
  transform: scale(0.84);
  transform-origin: right center;
}
.upload-section {
    padding-bottom: 22rpx;
  padding-bottom: 22rpx;
}
.upload-header {
    margin-bottom: 0;
  margin-bottom: 0;
}
.select-file-btn {
    width: 210rpx;
    height: 70rpx;
    margin: 0;
    font-size: 28rpx;
    line-height: 70rpx;
    //color: #ffffff;
    //background: #409eff;
    //border-radius: 4rpx;
  width: 210rpx;
  height: 70rpx;
  margin: 0;
  font-size: 28rpx;
  line-height: 70rpx;
  //color: #ffffff;
  //background: #409eff;
  //border-radius: 4rpx;
}
.select-file-btn::after,
.action-btn::after {
    border: 0;
  border: 0;
}
.custom-style {
    width: 276rpx;
    height: 76rpx;
    font-family: 'Source Han Sans CN';
    font-weight: 400;
    font-size: 28rpx;
  width: 276rpx;
  height: 76rpx;
  font-family: 'Source Han Sans CN';
  font-weight: 400;
  font-size: 28rpx;
}
.attachment-list {
    padding: 10rpx 22rpx 0;
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 16rpx;
  padding: 10rpx 22rpx 0;
}
.attachment-item {
    display: flex;
    align-items: center;
    justify-content: space-between;
    min-height: 70rpx;
    border-bottom: 1rpx solid #eeeeee;
  position: relative;
  width: 100%;
  aspect-ratio: 1;
  overflow: hidden;
  border-radius: 8rpx;
}
.file-info {
    display: flex;
    align-items: center;
    width: 0;
    flex: 1;
}
.file-name {
    overflow: hidden;
    font-size: 26rpx;
    color: #222324;
    text-overflow: ellipsis;
    white-space: nowrap;
}
.file-size {
    margin-left: 14rpx;
    font-size: 22rpx;
    color: #999;
    white-space: nowrap;
.attachment-image {
  display: block;
  width: 100%;
  height: 100%;
}
.remove-file-btn {
    width: 56rpx;
    font-size: 42rpx;
    line-height: 56rpx;
    color: #999;
    text-align: right;
  position: absolute;
  top: 6rpx;
  right: 6rpx;
  width: 40rpx;
  height: 40rpx;
  font-size: 32rpx;
  line-height: 36rpx;
  color: #ffffff;
  text-align: center;
  background: rgba(0, 0, 0, 0.55);
  border-radius: 50%;
}
.action-footer {
    display: flex;
    align-items: center;
    gap: 28rpx;
    box-sizing: border-box;
    padding: 22rpx 28rpx calc(22rpx + env(safe-area-inset-bottom));
    //background: #111827;
  display: flex;
  align-items: center;
  gap: 28rpx;
  box-sizing: border-box;
  padding: 22rpx 28rpx calc(22rpx + env(safe-area-inset-bottom));
  //background: #111827;
}
.action-btn {
    height: 82rpx;
    margin: 0;
    flex: 1;
    font-size: 30rpx;
    line-height: 80rpx;
    color: #ffffff;
    border-radius: 6rpx;
  height: 82rpx;
  margin: 0;
  flex: 1;
  font-size: 30rpx;
  line-height: 80rpx;
  color: #ffffff;
  border-radius: 6rpx;
}
.cancel-btn {
    color: #00b578;
    background: transparent;
    border: 2rpx solid #00b578;
  color: #00b578;
  background: transparent;
  border: 2rpx solid #00b578;
}
.confirm-btn {
    background: #00b578;
    border: 2rpx solid #00b578;
  background: #00b578;
  border: 2rpx solid #00b578;
}
.confirm-btn[disabled] {
    color: rgba(255, 255, 255, 0.72);
    background: #087b58;
  color: rgba(255, 255, 255, 0.72);
  background: #087b58;
}
</style>
uniapps/work-app/src/subPackages/workDetail/HandleWorking/index.vue
@@ -227,7 +227,7 @@
      recordType: 1,
      disposeContent: formData.value.disposeContent,
      targetEventStatus: eventStatus.value == 1 ? 3 : eventStatus.value,
      updateEventStatus: true,
      updateEventStatus: Number(eventStatus.value) == 1 ? true : false,
      attachUrl: attachmentList.value.map(file => file.link),
      // operateTime: '2026-07-30 14:00:00',
      // eventStatus: formData.value.isHandling ? '1' : '3',
uniapps/work-app/src/subPackages/workDetail/index.vue
@@ -241,7 +241,7 @@
    if (workDetailData.value.eventStatus === 1 && selectedOption.value === 3) {
        // 跳转上传处置页面
        uni.navigateTo({
            url: `/subPackages/workDetail/HandleWorking/index?id=${workDetailData.value.id}&eventStatus=${selectedOption.value}`,
            url: `/subPackages/workDetail/HandleWorking/index?id=${workDetailData.value.id}&eventStatus=${workDetailData.value.eventStatus}`,
        })
    }