From 35fb4a40571d69b85caede7348101d71789b5fb3 Mon Sep 17 00:00:00 2001
From: chenyao <1219716595@qq.com>
Date: Tue, 04 Aug 2026 11:01:14 +0800
Subject: [PATCH] feat:提交吉安工单和移动端处置数据
---
uniapps/work-app/src/subPackages/workDetail/HandleWorking/index-copy.vue | 602 +++++++++++++++++++++++++++---------------------------
1 files changed, 298 insertions(+), 304 deletions(-)
diff --git a/uniapps/work-app/src/subPackages/workDetail/HandleWorking/index-copy.vue b/uniapps/work-app/src/subPackages/workDetail/HandleWorking/index-copy.vue
index e668b0d..26725c8 100644
--- a/uniapps/work-app/src/subPackages/workDetail/HandleWorking/index-copy.vue
+++ b/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>
--
Gitblit v1.9.3