xinli/xinlidsj/pages/interventionTask/detail.vue
2026-02-24 16:49:05 +08:00

297 lines
8.1 KiB
Vue

<template>
<view class="page" :class="{ big: isH5 }">
<view class="panel">
<view class="title">任务详情</view>
<view class="subtitle">任务ID {{ taskId || '-' }}</view>
</view>
<view class="panel" v-if="task">
<view class="kv">
<view class="kv-item"><text class="k">类型</text><text class="v">{{ task.interventionType || '—' }}</text></view>
<view class="kv-item"><text class="k">负责人</text><text class="v">{{ task.ownerName || task.ownerId || '—' }}</text></view>
<view class="kv-item"><text class="k">状态</text><text class="v">{{ statusText(task.status) }}</text></view>
<view class="kv-item"><text class="k">截止</text><text class="v">{{ formatTime(task.dueTime) }}</text></view>
</view>
<view class="btn-row">
<button class="btn ghost" @click="goAddRecord">新增记录</button>
<button class="btn primary" v-if="String(task.status) !== '2'" @click="markDone">标记完成</button>
</view>
</view>
<view class="panel">
<view class="section-title">过程记录</view>
<view v-if="loadingRecords" class="empty">加载中...</view>
<view v-else>
<view v-if="records.length === 0" class="empty">暂无记录</view>
<view v-else class="list">
<view class="item" v-for="r in records" :key="r.recordId">
<view class="item-head">{{ formatTime(r.recordTime) }}</view>
<view class="item-content">{{ r.content }}</view>
<view class="attach" v-if="(r.attachments || []).length">
<view class="attach-title">附件</view>
<view class="attach-item" v-for="(a, idx) in r.attachments" :key="idx" @tap="copyUrl(a.url)">
{{ a.originalFilename || a.newFileName || a.fileName || a.url }}
</view>
</view>
</view>
</view>
</view>
<view v-if="errorMsg" class="error">{{ errorMsg }}</view>
</view>
</view>
</template>
<script>
import { getInterventionTask, updateInterventionTaskStatus } from '../../api/psychology/interventionTask'
import { listInterventionRecords } from '../../api/psychology/interventionRecord'
export default {
data() {
return {
isH5: false,
taskId: '',
task: null,
records: [],
loading: false,
loadingRecords: false,
errorMsg: ''
}
},
onLoad(options) {
try {
const info = uni.getSystemInfoSync()
const p = info ? (info.uniPlatform || info.platform) : ''
this.isH5 = p === 'web' || p === 'h5'
} catch (e) {
this.isH5 = false
}
this.taskId = options && options.taskId ? options.taskId : ''
this.refresh()
},
onShow() {
this.refreshRecords()
},
methods: {
formatTime(val) {
if (!val) return '—'
try {
const d = new Date(val)
const pad = (n) => String(n).padStart(2, '0')
return `${d.getFullYear()}-${pad(d.getMonth() + 1)}-${pad(d.getDate())} ${pad(d.getHours())}:${pad(d.getMinutes())}`
} catch (e) {
return String(val)
}
},
statusText(status) {
const map = { '0': '待分配', '1': '处理中', '2': '已完成' }
return map[String(status)] || '未知'
},
refresh() {
this.refreshTask()
this.refreshRecords()
},
refreshTask() {
this.errorMsg = ''
if (!this.taskId) return
this.loading = true
getInterventionTask(this.taskId).then((res) => {
this.loading = false
const data = res && res.data ? res.data : null
if (!data || data.code !== 200) {
this.errorMsg = (data && data.msg) ? data.msg : '加载任务失败'
return
}
this.task = data.data || null
}).catch((e) => {
this.loading = false
this.errorMsg = e && e.message ? e.message : '网络错误'
})
},
refreshRecords() {
this.errorMsg = ''
if (!this.taskId) return
this.loadingRecords = true
listInterventionRecords(this.taskId).then((res) => {
this.loadingRecords = false
const data = res && res.data ? res.data : null
if (!data || data.code !== 200) {
this.errorMsg = (data && data.msg) ? data.msg : '加载记录失败'
return
}
this.records = data.data || []
}).catch((e) => {
this.loadingRecords = false
this.errorMsg = e && e.message ? e.message : '网络错误'
})
},
goAddRecord() {
if (!this.taskId) return
uni.navigateTo({ url: '/pages/interventionTask/addRecord?taskId=' + encodeURIComponent(this.taskId) })
},
markDone() {
if (!this.taskId) return
uni.showModal({
title: '标记完成',
content: '确认将该任务标记为已完成?',
success: (r) => {
if (!r.confirm) return
updateInterventionTaskStatus({ taskId: Number(this.taskId), status: '2' }).then((res) => {
const data = res && res.data ? res.data : null
if (!data || data.code !== 200) {
uni.showToast({ title: (data && data.msg) ? data.msg : '更新失败', icon: 'none' })
return
}
uni.showToast({ title: '已完成', icon: 'success' })
this.refreshTask()
}).catch((e) => {
uni.showToast({ title: e && e.message ? e.message : '网络错误', icon: 'none' })
})
}
})
},
copyUrl(url) {
if (!url) return
uni.setClipboardData({ data: url })
}
}
}
</script>
<style>
.page {
min-height: 100vh;
padding: 32rpx;
box-sizing: border-box;
background: #f6f7fb;
}
.page.big {
padding: 14rpx 14rpx 120rpx;
background-image:
radial-gradient(1100rpx 520rpx at 50% 14%, rgba(43, 107, 255, 0.30) 0%, rgba(6, 16, 40, 0.0) 65%),
linear-gradient(180deg, rgba(5, 11, 24, 0.90) 0%, rgba(8, 20, 45, 0.85) 42%, rgba(6, 16, 40, 0.92) 100%),
url('/static/bg.png');
background-size: auto, auto, cover;
background-position: center, center, center;
background-repeat: no-repeat, no-repeat, no-repeat;
}
.panel {
background: #ffffff;
border-radius: 20rpx;
padding: 24rpx;
border: 1px solid rgba(0, 0, 0, 0.05);
margin-bottom: 24rpx;
}
.title {
font-size: 36rpx;
font-weight: 700;
color: #1f2329;
}
.subtitle {
margin-top: 10rpx;
font-size: 24rpx;
color: #646a73;
line-height: 36rpx;
}
.section-title {
font-size: 28rpx;
font-weight: 700;
color: #1f2329;
margin-bottom: 14rpx;
}
.kv {
display: flex;
flex-wrap: wrap;
}
.kv-item {
width: 50%;
margin-top: 10rpx;
}
.k {
color: #8f959e;
font-size: 24rpx;
}
.v {
color: #1f2329;
font-size: 26rpx;
margin-left: 10rpx;
}
.btn-row {
display: flex;
justify-content: space-between;
margin-top: 18rpx;
}
.btn {
width: 48%;
border-radius: 16rpx;
}
.btn.primary {
background: #1677ff;
color: #fff;
}
.btn.ghost {
background: rgba(22, 119, 255, 0.12);
color: #1677ff;
}
.empty {
padding: 20rpx 0;
color: #8f959e;
font-size: 24rpx;
text-align: center;
}
.list .item {
border: 1px solid rgba(0, 0, 0, 0.05);
border-radius: 18rpx;
padding: 18rpx;
margin-bottom: 14rpx;
}
.item-head {
font-size: 24rpx;
color: #8f959e;
}
.item-content {
margin-top: 10rpx;
font-size: 26rpx;
color: #1f2329;
line-height: 38rpx;
}
.attach {
margin-top: 12rpx;
padding-top: 10rpx;
border-top: 1px dashed rgba(0, 0, 0, 0.12);
}
.attach-title {
font-size: 24rpx;
color: #8f959e;
margin-bottom: 8rpx;
}
.attach-item {
font-size: 24rpx;
color: #1677ff;
line-height: 38rpx;
}
.error {
margin-top: 14rpx;
font-size: 24rpx;
color: #ff4d4f;
line-height: 36rpx;
}
.page.big .panel,
.page.big .list .item {
border: 1px solid rgba(116, 216, 255, 0.22);
background: linear-gradient(180deg, rgba(10, 18, 38, 0.75) 0%, rgba(5, 10, 22, 0.55) 100%);
box-shadow: 0 12rpx 24rpx rgba(0, 0, 0, 0.35);
}
.page.big .title,
.page.big .section-title,
.page.big .v { color: rgba(235, 248, 255, 0.92); }
.page.big .subtitle,
.page.big .k,
.page.big .empty,
.page.big .item-head { color: rgba(201, 242, 255, 0.65); }
.page.big .item-content { color: rgba(235, 248, 255, 0.88); }
.page.big .btn.primary { background: linear-gradient(90deg, rgba(116, 216, 255, 0.95) 0%, rgba(43, 107, 255, 0.92) 100%); color: #0b1226; }
.page.big .btn.ghost { background: rgba(7, 13, 28, 0.35); border: 1px solid rgba(116, 216, 255, 0.18); color: rgba(201, 242, 255, 0.86); }
.page.big .kv-item { border-bottom-color: rgba(116, 216, 255, 0.12); }
.page.big .attach { border-top-color: rgba(116, 216, 255, 0.16); }
</style>