From 4442c8e908d8ff01ed26fdd4ad0c68a29088e3e4 Mon Sep 17 00:00:00 2001
From: zhanghx <2014227881@qq.com>
Date: Fri, 31 Jul 2026 17:46:25 +0800
Subject: [PATCH] feat:设置记录

---
 uniapps/work-app/src/subPackages/workDetail/HandleWorking/index.vue |  786 +++++++++++++++++++++++++++++++------------------------
 1 files changed, 439 insertions(+), 347 deletions(-)

diff --git a/uniapps/work-app/src/subPackages/workDetail/HandleWorking/index.vue b/uniapps/work-app/src/subPackages/workDetail/HandleWorking/index.vue
index 61781f5..3b95707 100644
--- a/uniapps/work-app/src/subPackages/workDetail/HandleWorking/index.vue
+++ b/uniapps/work-app/src/subPackages/workDetail/HandleWorking/index.vue
@@ -1,381 +1,473 @@
-<script setup>
-import { onLoad } from '@dcloudio/uni-app'
-
-onLoad(options => {
-	console.log(options, '9090')
-	// eventId.value = options?.id || ''
-	// eventStatus.value = options?.eventStatus || ''
-})
-</script>
 <template>
-	<div class="workDetailContainer">
-		<!-- 自定义导航栏 -->
-		<u-navbar title="工单详情" :is-back="true" back-text="" :back-icon-size="40" @left-click="onBackClick">
-			<template #right>
-				<div v-if="isH5" class="tapShare-icon"><img src="/static/images/work/share.svg" @click="onShareClick" /></div>
-				<div v-else class="share-btn" @click="onShareClick"></div>
-			</template>
-		</u-navbar>
-		<div class="detailTop">打发打发打发打发</div>
-	</div>
+  <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">
+					<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>
+
+      <!--			<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 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 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>
 
-<style lang="scss" scoped>
-	.workDetailContainer {
-		// 添加导航栏高度的padding-top,避免内容被遮挡
-		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;
-			}
-		} // 分享按钮样式
-		.share-btn {
-			// #ifdef APP-PLUS
-			width: 40rpx;
-			height: 40rpx;
-			background-image: url('/static/images/work/share.svg');
-			background-size: contain;
-			background-repeat: no-repeat;
-			background-position: center;
-			// #endif
-		}
-		.tapShare-icon {
-			width: 40rpx;
-			height: 40rpx;
-			img {
-				width: 40rpx;
-				height: 40rpx;
-			}
-		}
-		.detailTop {
-			// #ifdef APP-PLUS
-			padding-top: 60rpx;
-			// #endif
-			.image-container {
-				position: relative;
-				width: 100%;
-				height: 410rpx;
+<script setup>
+import { computed, ref } from 'vue'
+import { onLoad } from '@dcloudio/uni-app'
+import { backGdApi, addDisposeRecord, uploadFileAPI } from '@/api/work/index.js'
 
-				.detailImage {
-					width: 100%;
-					height: 100%;
-					display: block;
-					object-fit: cover;
-				}
-				// 轮播图容器
-				:deep(.u-swiper) {
-					// 指示器容器 - 修改为居中对齐
-					.u-swiper__indicator {
-						position: absolute;
-						left: 50%;
-						transform: translateX(-50%);
-						bottom: 20rpx;
-						display: flex;
-						justify-content: center;
-						align-items: center;
-						z-index: 10;
-					}
-					.u-swiper-indicator__wrapper__dot--active {
-						width: 5px !important;
-					}
-				}
-			}
-		}
+const MAX_FILE_COUNT = 9
+const eventId = ref('')
+const eventStatus = ref(null)
+const submitting = ref(false)
+const uploading = ref(false)
+const attachmentList = ref([])
+const formData = ref({
+  disposeContent: '',
+  isHandling: true,
+})
+const navbarTitleStyle = {
+  color: '#ffffff',
+  fontSize: '34rpx',
+  fontWeight: '500',
+}
 
-		.worderContainer {
-			padding: 0 24rpx;
-			padding-bottom: 4rpx;
-			background: #f6f6f6;
-			margin-top: 20rpx;
-			height: calc(100vh - 530rpx);
-			overflow: auto;
-		}
-		.workOrderContent {
-			margin-top: 30epx;
-			background-color: #fff;
-			border-radius: 12rpx;
-			padding: 20rpx;
-			margin-bottom: 34rpx;
-			.workOrderTitle {
-				font-family: Source Han Sans CN, Source Han Sans CN;
-				font-weight: bold;
-				font-size: 32rpx;
-				color: #222324;
-			}
-			.workOrderContainer {
-				.orderRow {
-					display: flex;
-					justify-content: space-between;
-					align-items: center;
-					min-height: 96rpx;
-					border-bottom: 1px solid #f5f5f5;
-					color: #7b7b7b;
-					.rowTitle {
-						font-family: Source Han Sans CN, Source Han Sans CN;
-						font-weight: 400;
-						font-size: 30rpx;
-						color: #222324;
-						white-space: nowrap;
-					}
-					.rowAddress {
-						font-family: Source Han Sans CN, Source Han Sans CN;
-						font-weight: 400;
-						font-size: 28rpx;
-						color: #1d6fe9;
-						text-decoration: underline;
-						text-align: right;
+// 计算处置描述字数
+const descriptionLength = computed(() => formData.value.disposeContent.length)
 
-						padding-top: 1px;
-						padding-left: 5px;
-						padding-right: 2px;
-					}
-					.status-picker {
-						.picker-value {
-							font-family: Source Han Sans CN, Source Han Sans CN;
-							font-weight: 400;
-							font-size: 28rpx;
-							color: #1d6fe9;
-							display: flex;
-							align-items: center;
-							gap: 8rpx;
-						}
-						.picker-arrow {
-							font-size: 20rpx;
-							color: #999;
-						}
-					}
-				}
-			}
-		}
+// 读取当前工单标识
+onLoad(options => {
+  eventId.value = options?.id ?? ''
+})
 
-		.actionButton {
-			display: flex;
-			justify-content: center;
-			align-items: center;
-			box-sizing: border-box;
-			width: 100%;
-			height: 61px;
-			padding: 0 24rpx;
+// 返回上一页
+function handleBack() {
+  uni.navigateBack()
+}
 
-			border-radius: 6px 6px 6px 6px;
+// 切换处置状态
+// function handleStatusChange(event) {
+// 	formData.value.isHandling = event.detail.value
+// }
 
-			.btngroups {
-				display: flex;
-				align-items: center;
-				width: 100%;
-				min-width: 0;
-				:deep(.u-button) {
-					width: 0 !important;
-					min-width: 0;
-					margin: 0 !important;
-					flex: 1;
-					height: 76rpx !important;
-				}
-				&:not(.three-actions) {
-					:deep(.u-button + .u-button) {
-						margin-left: 20rpx !important;
-					}
-				}
-				&.three-actions {
-					justify-content: center;
-					:deep(.u-button) {
-						width: 210rpx !important;
-						flex: 0 0 210rpx;
-					}
-					:deep(.u-button:last-child) {
-						margin-left: 20rpx !important;
-					}
-				}
-			}
-		}
-	}
+// 提取文件名称
+function getFileName(filePath = '') {
+  const normalizedPath = filePath.replace(/\\/g, '/')
+  return decodeURIComponent(normalizedPath.split('/').pop() || '未命名文件')
+}
 
-	.complete-modal-overlay {
-		position: fixed;
-		top: 0;
-		right: 0;
-		bottom: 0;
-		left: 0;
-		z-index: 10000;
-		display: flex;
-		align-items: center;
-		justify-content: center;
-		box-sizing: border-box;
-		padding: 40rpx;
-		background: rgba(0, 0, 0, 0.55);
-	}
+// 上传单个已选择文件
+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 }
+}
 
-	.complete-modal {
-		box-sizing: border-box;
-		width: 620rpx;
-		max-width: 100%;
-		padding: 32rpx;
-		background: #ffffff;
-		border-radius: 12rpx;
-	}
+// 处理已选择文件
+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
 
-	.complete-modal-title {
-		margin-bottom: 28rpx;
-		font-size: 32rpx;
-		font-weight: 500;
-		color: #222324;
-		text-align: center;
-	}
+  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',
+  })
+}
 
-	.complete-input-wrapper {
-		position: relative;
-		box-sizing: border-box;
-		height: 220rpx;
-		padding-bottom: 38rpx;
-		background: #f6f7f9;
-		border: 1rpx solid #e5e7eb;
-		border-radius: 6rpx;
-	}
+// 处理选择文件失败
+function handleChooseFail(error) {
+  if (error?.errMsg?.includes('cancel')) return
+  uni.showToast({ title: '取消选择文件', icon: 'none' })
+}
 
-	.complete-input {
-		box-sizing: border-box;
-		width: 100%;
-		height: 100%;
-		padding: 20rpx;
-		font-size: 28rpx;
-		line-height: 1.5;
-		color: #222324;
-	}
+// 选择附件
+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,
+  }
 
-	.complete-word-count {
-		position: absolute;
-		right: 16rpx;
-		bottom: 10rpx;
-		font-size: 22rpx;
-		color: #999999;
-	}
+  // #ifdef H5
+  uni.chooseFile(options)
+  // #endif
 
-	.complete-modal-actions {
-		display: flex;
-		gap: 24rpx;
-		margin-top: 30rpx;
-	}
+  // #ifdef MP-WEIXIN
+  uni.chooseMessageFile(options)
+  // #endif
 
-	.complete-action-btn {
-		height: 76rpx;
-		margin: 0;
-		flex: 1;
-		font-size: 28rpx;
-		line-height: 76rpx;
-		border-radius: 6rpx;
-	}
+  // #ifdef APP-PLUS
+  uni.chooseImage({ ...options, sourceType: ['album', 'camera'] })
+  // #endif
+}
 
-	.complete-action-btn::after {
-		border: 0;
-	}
+// 移除附件
+function handleRemoveFile(index) {
+  attachmentList.value.splice(index, 1)
+}
 
-	.complete-cancel-btn {
-		color: #666666;
-		background: #f1f2f4;
-	}
+// 格式化文件大小
+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`
+}
 
-	.complete-confirm-btn {
-		color: #ffffff;
-		background: #1d6fe9;
-	}
+// 取消处置
+function handleCancel() {
+  uni.navigateBack()
+}
 
-	.complete-action-btn[disabled] {
-		opacity: 0.65;
-	}
+// 提交处置信息
+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
+  }
 
-	/* 分享弹出层样式 */
-	.share-modal-overlay {
-		position: fixed;
-		top: 0;
-		left: 0;
-		right: 0;
-		bottom: 0;
-		background-color: rgba(0, 0, 0, 0.6);
-		display: flex;
-		justify-content: flex-end;
-		align-items: flex-end;
-		z-index: 9999;
-	}
+  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' })
+  }
+}
 
-	.share-modal-content {
-		background-color: #fff;
-		border-radius: 20rpx 20rpx 0 0;
-		padding: 30rpx;
-		width: 100%;
-		max-height: 80vh;
-		overflow-y: auto;
-	}
+// 返回按钮点击事件
+const onBackClick = () => {
+  uni.navigateBack()
+}
 
-	.share-modal-header {
-		display: flex;
-		justify-content: space-between;
-		align-items: center;
-		margin-bottom: 30rpx;
-	}
+onLoad(options => {
+  console.log(options, '9090')
+  eventId.value = options?.id || ''
+  eventStatus.value = options?.eventStatus || ''
+})
+</script>
 
-	.share-modal-title {
-		font-size: 36rpx;
-		font-weight: bold;
-		color: #222324;
-		text-align: center;
-		flex: 1;
-	}
+<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;
+    }
+  }
 
-	.share-modal-close {
-		font-size: 60rpx;
-		color: #999;
-		line-height: 40rpx;
-	}
+  display: flex;
+  flex-direction: column;
+  box-sizing: border-box;
+  height: calc(100vh);
+  //padding-top: 88rpx;
+  //background: #111827;
+  //color: #f5f7fa;
 
-	.share-modal-body {
-		display: flex;
-		flex-wrap: wrap;
-		justify-content: space-around;
-		padding-bottom: 30rpx;
-	}
+  //:deep(.u-navbar__content) {
+  //	height: 88rpx !important;
+  //	background: #151c29 !important;
+  //}
+}
 
-	.share-modal-footer {
-		display: flex;
-		justify-content: space-around;
-		padding-top: 30rpx;
-		border-top: 1px solid #f0f0f0;
-	}
+.form-scroll {
+	// #ifdef APP-PLUS
+	padding-top: 60rpx;
+	// #endif
+  box-sizing: border-box;
+  height: 0;
+  flex: 1;
+  padding: 0 24rpx 24rpx;
+}
 
-	.share-item {
-		display: flex;
-		flex-direction: column;
-		align-items: center;
-		margin: 20rpx;
-		width: 120rpx;
-	}
+.form-section {
+  box-sizing: border-box;
+  margin-bottom: 20rpx;
+  background: #ffffff;
+  border: 1rpx solid rgba(255, 255, 255, 0.03);
+}
 
-	.share-icon {
-		width: 90rpx;
-		height: 90rpx;
-		border-radius: 50%;
-		margin-bottom: 15rpx;
-		background-size: contain;
-		background-repeat: no-repeat;
-		background-position: center;
-	}
+.section-header {
+  display: flex;
+  align-items: center;
+  justify-content: space-between;
+  height: 82rpx;
+  padding: 0 22rpx;
+  border-bottom: 1rpx solid #eeeeee;
+}
 
-	.share-icon.wechat {
-		background-image: url('@/static/images/work/wechat.svg');
-	}
+.section-title {
+  font-size: 30rpx;
+  font-weight: 400;
+  color: #222324;
+}
 
-	.share-icon.moments {
-		background-image: url('@/static/images/work/moments.svg');
-	}
+.description-wrapper {
+  position: relative;
+}
 
-	.share-icon.link {
-		background-image: url('@/static/images/work/link.svg');
-	}
-	.share-name {
-		font-size: 24rpx;
-		color: #666;
-		margin-top: 10rpx;
-	}
+.word-count {
+  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;
+}
+
+:deep(.description-placeholder) {
+  color: #999;
+}
+
+.status-section {
+  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;
+}
+
+.upload-section {
+  padding-bottom: 22rpx;
+}
+
+.upload-header {
+  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;
+}
+
+.select-file-btn::after,
+.action-btn::after {
+  border: 0;
+}
+
+.custom-style {
+  width: 276rpx;
+  height: 76rpx;
+  font-family: 'Source Han Sans CN';
+  font-weight: 400;
+  font-size: 28rpx;
+}
+
+.attachment-list {
+  padding: 10rpx 22rpx 0;
+}
+
+.attachment-item {
+  display: flex;
+  align-items: center;
+  justify-content: space-between;
+  min-height: 70rpx;
+  border-bottom: 1rpx solid #eeeeee;
+}
+
+.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;
+}
+
+.remove-file-btn {
+  width: 56rpx;
+  font-size: 42rpx;
+  line-height: 56rpx;
+  color: #999;
+  text-align: right;
+}
+
+.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;
+}
+
+.action-btn {
+  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;
+}
+
+.confirm-btn {
+  background: #00b578;
+  border: 2rpx solid #00b578;
+}
+
+.confirm-btn[disabled] {
+  color: rgba(255, 255, 255, 0.72);
+  background: #087b58;
+}
 </style>

--
Gitblit v1.9.3