Files
zgty-mas-m/pages/analysis/sample/sample-print.vue
houjunxiang 386f1e7466 1
2025-10-09 18:19:55 +08:00

319 lines
8.2 KiB
Vue
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
<template>
<view>
<navbar-back :autoBack="false" title="单据补打" @leftClick="customBack"></navbar-back>
<u-row class="content-title" gutter="16">
<u-col span="4">
<view class="content-title-name">
<text>任务列表</text>
</view>
<u-gap height="5" bg-color="#0055A2"></u-gap>
</u-col>
<u-col span="8">
<view class="content-title-name">
<text>样品列表</text>
</view>
<u-gap height="5" bg-color="#0055A2"></u-gap>
</u-col>
</u-row>
<u-row class="content-main-height" gutter="16" align="top">
<!-- 左侧任务列表 -->
<u-col span="4">
<scroll-view
scroll-y
scroll-with-animation
class="content-main-height content-main-left"
:scroll-top="scrollTop"
ref="menuScrollView"
>
<view
v-for="(task, index) in taskList"
:key="index"
class="u-tab-item"
:class="{ 'u-tab-item-active': current === index }"
@tap.stop="switchTask(index)"
>
<u-row style="width: 100%">
<u-col span="2" style="text-align: center">
<u-icon :color="taskStyle(task)" name="tags-fill" size="34"></u-icon>
</u-col>
<u-col span="10">
<view>
<text style="font-size: 18px">{{ task.taskNo }}</text>
</view>
<view style="margin-top: 10px">
<text>{{ task.taskName }} {{ task.assayOper }}</text>
</view>
<view class="x-f" style="margin-top: 10px">
<u-icon name="clock"></u-icon>
<text style="margin-left: 5px">{{ task.taskOperTime }}</text>
</view>
</u-col>
</u-row>
</view>
</scroll-view>
</u-col>
<!-- 右侧样品列表 -->
<u-col span="8">
<view class="content-main-height">
<scroll-view scroll-y scroll-with-animation class="content-main-right">
<block v-for="(sample, index) in sampleList" :key="index">
<view style="padding: 5px; font-size: 16px">
<u-row>
<u-col span="2" style="text-align: center">
<view>
<text>{{ sample.sort }}</text>
</view>
</u-col>
<u-col span="5">
<view>
<text style="padding-left: 10px">{{ sample.sampleCode }}</text>
</view>
<view>
<text style="padding-left: 10px">{{ sample.sampleName }}</text>
</view>
</u-col>
</u-row>
<u-line style="padding: 10rpx" color="#bbb" />
</view>
</block>
</scroll-view>
<!-- 操作按钮 -->
<view class="content-main-right-operation">
<u-row>
<u-col span="6"></u-col>
<u-col span="3">
<u-button class="btn-operation" type="primary" @click="previewPDF" v-if="currentTaskId">
预览任务单
</u-button>
</u-col>
<u-col span="3">
<u-button class="btn-operation" :disabled="taskList.length <= 0" type="success" @click="printTask">
打印任务单
</u-button>
</u-col>
</u-row>
</view>
</view>
</u-col>
</u-row>
</view>
</template>
<script setup>
import { ref, onMounted } from 'vue'
import nx from '@/nx'
// refs
const scrollTop = ref(0)
const current = ref(0)
const menuHeight = ref(0)
const menuItemHeight = ref(0)
const currentTask = ref({})
const currentTaskId = ref('')
const currentTaskNo = ref('')
const conAssayTask = ref(null)
const taskList = ref([])
const sampleList = ref([])
const menuScrollView = ref(null)
// 生命周期
onMounted(() => {
getAssayTask()
})
checkPrintConfig()
// 方法
function customBack() {
uni.reLaunch({
url: '/pages/analysis/index/index'
})
}
function taskStyle(task) {
return task.weightTaskStatus === 3 ? 'green' : ''
}
// 切换任务
async function switchTask(index) {
if (index === current.value) return
current.value = index
// 初始化高度
if (menuHeight.value === 0 || menuItemHeight.value === 0) {
await getElRect('menu-scroll-view', 'menuHeight')
await getElRect('.u-tab-item', 'menuItemHeight')
}
// 滚动居中
scrollTop.value = index * menuItemHeight.value + menuItemHeight.value / 2 - menuHeight.value / 2
// 更新当前任务
const task = taskList.value[index]
currentTask.value = task
currentTaskNo.value = task.taskNo
currentTaskId.value = task.id
getAssayTaskDetail(currentTaskNo.value)
}
// 获取元素尺寸
function getElRect(selector, targetRef) {
return new Promise(resolve => {
const query = uni.createSelectorQuery().in(getCurrentInstance().proxy)
query
.select(selector)
.fields({ size: true }, res => {
if (!res) {
// 如果未获取到,稍后重试(可选)
setTimeout(() => resolve(getElRect(selector, targetRef)), 10)
return
}
if (targetRef === 'menuHeight') {
menuHeight.value = res.height
} else if (targetRef === 'menuItemHeight') {
menuItemHeight.value = res.height
}
resolve(res)
})
.exec()
})
}
// 获取任务列表
function getAssayTask() {
const param = {
operateType: 'print',
finishStatus: 'submited,finished'
}
nx.$api.auncel.getAssayTaskList(param).then(res => {
taskList.value = res || []
if (taskList.value.length > 0) {
const first = taskList.value[0]
currentTask.value = first
currentTaskNo.value = first.taskNo
currentTaskId.value = first.id
getAssayTaskDetail(currentTaskNo.value)
} else {
currentTask.value = {}
currentTaskNo.value = ''
currentTaskId.value = ''
}
})
}
// 获取任务详情
function getAssayTaskDetail(taskNo) {
if (!taskNo) return
nx.$api.assayTask.getAssayTaskDetailListByTaskNo({ taskNo }).then(res => {
sampleList.value = res.result || []
if (res.additionalProperties?.conAssayTask) {
conAssayTask.value = res.additionalProperties.conAssayTask
}
})
}
// 打印任务
function printTask() {
const task = currentTask.value
uni.showModal({
title: '提示',
content: `确定补打“${task.taskNo}的原始记录单”?`,
cancelColor: '#0055A2',
confirmColor: '#0055A2',
success: res => {
if (res.confirm) {
nx.$print.getPrintTemplateAndPrint(currentTask.value)
}
}
})
}
// 预览 PDF
function previewPDF() {
const url = `/pages/analysis/sample/pdf-preview?taskId=${currentTaskId.value}&reportKey=${conAssayTask.value?.assayTaskTemplateKey}&hideResultFlag=true`
uni.navigateTo({ url })
}
// 检查打印服务配置(模拟 onShow
function checkPrintConfig() {
const printList = uni.getStorageSync('KEY_PRINT_LIST')
if (!printList || printList.length <= 0) {
uni.showToast({
title: '打印服务未配置,请在系统设置中配置打印服务!',
icon: 'none'
})
}
}
</script>
<style lang="scss" scoped>
.content-title {
height: 50px;
width: 100%;
font-size: 20px;
font-weight: 300;
}
.content-title-name {
padding: 10px;
text-align: center;
}
.content-main-height {
height: calc(100vh - 125px);
}
.content-main-left {
background-color: #f6f6f6;
}
.u-tab-item {
padding: 5px;
height: 100px;
background: #f6f6f6;
box-sizing: border-box;
display: flex;
align-items: center;
justify-content: center;
font-size: 16px;
color: #444;
line-height: 1;
border-width: 2px;
border-bottom: dotted;
}
.u-tab-item-active {
position: relative;
color: #0055a2;
font-weight: 600;
background: #fff;
}
.u-tab-item-active::before {
content: '';
position: absolute;
height: 16px;
left: 0;
top: 20px;
}
.content-main-right {
height: calc(100vh - 205px);
}
.content-main-right-operation {
height: 80px;
padding-top: 15px;
padding-right: 15px;
}
.btn-operation {
width: 95%;
}
</style>