Files
zgty-mas-m/pages/analysis/sample/sample-work-list.vue
2025-11-26 18:11:13 +08:00

299 lines
9.1 KiB
Vue

<template>
<view>
<navbar-back :autoBack="false" title="样品分析" @leftClick="customBack"></navbar-back>
<u-row class="content-title">
<u-col span="4">
<view class="content-title-name">
<text>任务列表</text>
<up-badge v-if="taskList.length > 0" class="ml5" :value="taskList.length" type="warning"></up-badge>
</view>
<u-gap height="5" bg-color="#0055A2"></u-gap>
<scroll-view style="height: 82vh" scroll-y scroll-with-animation class="content-main-left">
<template v-if="taskList.length > 0">
<TaskItem
v-for="(task, index) in taskList"
:key="index"
:task="task"
:seq="index + 1"
:active="current === index"
@click="switchTask(index)"
/>
</template>
<up-empty v-else text="暂无数据" mode="list"> </up-empty>
</scroll-view>
</u-col>
<u-col span="8">
<view class="pl16">
<view class="content-title-name">
<text>样品列表</text>
<up-badge v-if="sampleList.length > 0" class="ml5" :value="sampleList.length" type="warning"></up-badge>
</view>
<u-gap height="5" bg-color="#0055A2"></u-gap>
<scroll-view scroll-y scroll-with-animation style="height: calc(82vh - 60px)">
<u-checkbox-group placement="column" v-model="checkedSampleCodes">
<block v-for="(sample, index) in sampleList" :key="index">
<view v-if="currentTask.reviewCount === sample.reviewCount" class="sample-item">
<u-row>
<u-col span="2" class="text-center">
<u-row>
<u-col span="4" class="text-center">
<u-checkbox :disabled="sampleDisabled(sample.rollbackStatus)" :name="sample.id"></u-checkbox>
</u-col>
<u-col span="8" class="text-center">
<view
><text>{{ index + 1 }}</text></view
>
</u-col>
</u-row>
</u-col>
<u-col span="10">
<u-row>
<u-col span="4">
<view>
{{ sample.sampleAssayCode }}
</view>
<view class="mt10">
{{ sample.sampleName }}
</view>
</u-col>
<u-col span="6">
<view>
<rich-text :nodes="sample.assayProject"> </rich-text>
</view>
</u-col>
</u-row>
</u-col>
</u-row>
<u-icon
v-if="sample.rollbackStatus"
class="sample-status"
:name="`/static/images/status/${sampleReturnIcon(sample.rollbackStatus)}.png`"
size="45"
/>
</view>
</block>
</u-checkbox-group>
</scroll-view>
<view class="content-main-right-operation">
<u-row>
<u-col span="4"></u-col>
<u-col span="4">
<u-button class="btn-operation" type="warning" @click="showRollbackModal">申请退回样品</u-button>
</u-col>
<u-col span="4">
<u-button class="btn-operation" :disabled="taskList.length === 0" type="success" @click="startWork">
开始分析
</u-button>
</u-col>
</u-row>
</view>
</view>
</u-col>
</u-row>
<!-- 退回样品弹窗 -->
<up-modal
:show="showRollbackModalFlag"
showCancelButton
@confirm="applyRollbackSample"
@cancel="showRollbackModalFlag = false"
title="退回说明"
width="500px"
>
<u--textarea v-model="rollbackContent" placeholder="请输入退回原因或说明"></u--textarea>
</up-modal>
</view>
</template>
<script setup>
import { ref, computed, getCurrentInstance } from 'vue'
import { onLoad, onBackPress, onPullDownRefresh } from '@dcloudio/uni-app'
import nx from '@/nx'
import { useScreenOrientation } from '@/nx/hooks/useScreenOrientation'
import { getDataSourceTypeShow } from '../common'
import TaskItem from './components/task-item.vue'
// 响应式数据
const currentNode = ref('F31')
const dicSampleProcessCodeList = ref([])
const showRollbackModalFlag = ref(false)
const rollbackContent = ref('')
const current = ref(0)
const currentTask = ref({})
const taskList = ref([])
const sampleList = ref([])
const checkedSampleCodes = ref([])
const sampleReturnIcon = rollbackStatus => {
switch (rollbackStatus) {
case 'returned':
return 'return_returned'
case 'rejected':
return 'return_rejected'
case 'in_progress':
return 'return_in_progress'
default:
return ''
}
}
const sampleDisabled = rollbackStatus => {
return rollbackStatus === 'returned' || rollbackStatus === 'in_progress'
}
// 计算属性
const userInfo = computed(() => nx.$store('user').userInfo)
// 方法
const customBack = () => {
uni.reLaunch({ url: '/pages/analysis/index/index' })
}
onPullDownRefresh(() => {
getAssayTask().finally(() => {
uni.stopPullDownRefresh()
uni.showToast({ title: '刷新成功', icon: 'none' })
})
})
const showRollbackModal = () => {
if (checkedSampleCodes.value.length === 0) {
uni.showToast({ title: '请选择要退回的样品!', icon: 'none' })
return
}
showRollbackModalFlag.value = true
}
const applyRollbackSample = () => {
if (!rollbackContent.value.trim()) {
uni.showToast({ title: '请输入退回说明!', icon: 'none' })
return
}
const data = {
backDesc: rollbackContent.value,
idList: checkedSampleCodes.value
}
nx.$api.assayTask.rollbackAssayTask(data).then(() => {
getAssayTaskDetail(currentTask.value.id)
showRollbackModalFlag.value = false
checkedSampleCodes.value = []
})
}
const checkWork = () => {
let checkedSampleList = sampleList.value.filter(
item => item.rollbackStatus === 'running' || item.rollbackStatus === 'finished'
)
if (checkedSampleList.length > 0) {
uni.showToast({ title: '存在未处理的退回申请,请处理后再分析!', icon: 'none' })
return false
}
checkedSampleList = sampleList.value.filter(item => item.sampleProcessNo !== currentNode.value)
if (checkedSampleList.length > 0) {
uni.showToast({ title: '部分样品状态异常,请联系管理员处理!', icon: 'none', duration: 2300 })
return false
}
return true
}
const startWork = () => {
// if (!checkWork()) return
uni.navigateTo({
url: `/pages/analysis/sample/sample-work-detail?currentTaskId=${currentTask.value.id}&configReportTemplateKey=${currentTask.value.configReportTemplateKey}`
})
}
const switchTask = async index => {
if (index === current.value) return
current.value = index
rollbackContent.value = ''
const task = taskList.value[index]
currentTask.value = task
getAssayTaskDetail(task.id)
checkedSampleCodes.value = []
}
const getAssayTask = async () => {
rollbackContent.value = ''
const param = {
taskAssignStatus: 'submitted',
taskAssayStatusList: ['not_start', 'saved'],
assayOperator: userInfo.value.nickname
}
const res = await nx.$api.assayTask.getAssayTaskList(param)
if (res) {
taskList.value = res
if (taskList.value.length > 0) {
currentTask.value = taskList.value[0]
getAssayTaskDetail(currentTask.value.id)
}
}
}
const getAssayTaskDetail = businessAssayTaskId => {
sampleList.value = []
nx.$api.assayTask.getAssayTaskDetailList({ businessAssayTaskId }).then(res => {
const list = res || []
list.forEach(item => (item.checked = false))
sampleList.value = list
})
}
const getDicSampleProcessCodeList = () => {
nx.$api.assayTask.queryQmsDicSampleProcessCodeList().then(res => {
dicSampleProcessCodeList.value = res.records || []
})
}
const getProcessNameShow = val => {
const item = dicSampleProcessCodeList.value.find(i => i.processCode === val)
return item ? item.processName : val
}
// 生命周期
onLoad(() => {
const { lockOrientation } = useScreenOrientation()
lockOrientation('landscape')
// getDicSampleProcessCodeList()
getAssayTask()
})
onBackPress(() => {
customBack()
return true
})
</script>
<style lang="scss" scoped>
.content-title-name {
height: 60px;
box-sizing: border-box;
font-size: 22px;
padding: 10px;
text-align: center;
display: flex;
justify-content: center;
align-items: center;
}
.content-main-left {
background-color: #f6f6f6;
}
.sample-item {
position: relative;
border-bottom: 1px solid #eee;
padding: 4px;
.sample-status {
position: absolute;
top: 0;
right: 0;
}
}
.content-main-right-operation {
height: 50px;
padding-top: 10px;
padding-right: 10px;
}
.btn-operation {
font-size: 18px;
width: 95%;
}
</style>