质控打印

master
lion 2 weeks ago
parent b557c8c771
commit df9813eb87

@ -211,6 +211,14 @@
</div>
</td>
</tr>
<tr>
<th>调查地址</th>
<td colspan="5">
<div style="text-align: center; letter-spacing: 1px">
{{ detail.address }}
</div>
</td>
</tr>
</tbody>
</table>

@ -0,0 +1,363 @@
<template>
<div>
<Modal v-model="isShow" width="800" title="质控管理">
<table id="print-table">
<thead style="border: none">
<tr style="visibility: hidden">
<th class="border-none" style="width: calc(100% / 6)" />
<th class="border-none" style="width: calc(100% / 6)" />
<th class="border-none" style="width: calc(100% / 6)" />
<th class="border-none" style="width: calc(100% / 6)" />
<th class="border-none" style="width: calc(100% / 6)" />
<th class="border-none" style="width: calc(100% / 6)" />
</tr>
<tr>
<th colspan="6">
<p style="font-size: 17px; letter-spacing: 1px">
四世同堂质控考评表
</p>
</th>
</tr>
</thead>
<tbody>
<tr>
<td colspan="2">
<span style="font-weight: 600">回访日期</span>
{{ $moment(detail.created_at).format("YYYY年MM月DD日") }}
</td>
<td colspan="4">
<span style="font-weight: 600">护理员</span>
{{ detail.nurse_name }}
</td>
</tr>
<tr>
<td colspan="2">
<span style="font-weight: 600">姓名</span>
{{ detail.customer ? detail.customer.name : "" }}
</td>
<td colspan="4">
<span style="font-weight: 600">性别</span>
{{ detail.customer ? detail.customer.sex : "" }}
</td>
</tr>
<tr>
<td colspan="2">
<span style="font-weight: 600">联系电话</span>
{{ detail.customer ? detail.customer.phone : "" }}
</td>
<td colspan="4">
<span style="font-weight: 600">身份证号</span>
{{ detail.customer ? detail.customer.idcard : "" }}
</td>
</tr>
<tr>
<td colspan="2">
<span style="font-weight: 600">紧急联系人</span>
{{ detail.customer ? detail.customer.contact_name : "" }}
</td>
<td colspan="4">
<span style="font-weight: 600">紧急联系电话</span>
{{ detail.customer ? detail.customer.contact_phone : "" }}
</td>
</tr>
<tr>
<td colspan="6">
<span style="font-weight: 600">服务对象住址</span>
{{ detail.customer ? detail.customer.idcard_address : "" }}
</td>
</tr>
<tr>
<th
rowspan="2"
colspan="1"
style="
writing-mode: vertical-rl;
text-align: center;
letter-spacing: 2px;
"
>
考评详情
</th>
</tr>
<tr>
<td colspan="5">
<div v-if="detail.forms && detail.forms.length > 0" style="margin-top: 10px;">
<div
v-for="(form, index) in detail.forms"
:key="index"
style="margin-bottom: 5px;"
>
<span style="font-weight: 500;">{{ index + 1 }}. {{ form.ask }}</span>
<span v-if="form.type === 'checkbox'">
{{ joinSelectedOptions(form.options || []) }}
</span>
<span v-else>
{{ form.score !== '' ? form.score : '-' }}
</span>
</div>
</div>
<div v-else style="color: #999;">暂无考评数据</div>
</td>
</tr>
<tr>
<td colspan="1">
<span style="font-weight: 600">总分</span>
</td>
<td colspan="5">
{{ detail.total_score }}
</td>
</tr>
<tr>
<td colspan="6">
<div style="font-weight: 600">对护理员哪些方面要求改进</div>
<div>{{ detail.tip }}</div>
</td>
</tr>
<tr>
<td colspan="6">
<div style="font-weight: 600">对护理员有哪些方面肯定</div>
<div>{{ detail.sure }}</div>
</td>
</tr>
<tr>
<td colspan="6">
<div style="font-weight: 600">备注</div>
<div>{{ detail.remark }}</div>
</td>
</tr>
<tr>
<th>服务对象/家属签字</th>
<td colspan="2">
<div style="position: relative; height: 100px">
<img
style="
width: 100px;
object-fit: contain;
transform: rotate(270deg) translateY(-50px);
position: absolute;
top: -50px;
transform-origin: center;
left: 50%;
"
:src="detail.sign_image ? detail.sign_image.url : ''"
alt=""
/>
</div>
</td>
<th rowspan="2">
回访图片
</th>
<td colspan="3" rowspan="2">
<img
v-for="img in detail.files"
:key="img.id"
:src="img.url"
:alt="img.original_name"
style="max-height: 100px;margin-right: 4px;"
/>
</td>
</tr>
<tr>
<th>调查人员签字</th>
<td colspan="2">
<div style="position: relative; height: 100px">
<img
style="
width: 100px;
object-fit: contain;
transform: rotate(270deg) translateY(-50px);
position: absolute;
top: -50px;
transform-origin: center;
left: 50%;
"
:src="
detail.admin_sign_image ? detail.admin_sign_image.url : ''
"
alt=""
/>
</div>
</td>
</tr>
<tr>
<th>调查日期</th>
<td colspan="5">
<div style="text-align: center; letter-spacing: 1px">
{{ $moment(detail.created_at).format("YYYY年MM月DD日") }}
</div>
</td>
</tr>
<tr>
<th>回访地址</th>
<td colspan="5">
<div style="text-align: center; letter-spacing: 1px">
{{ detail.address }}
</div>
</td>
</tr>
</tbody>
</table>
<template #footer>
<div>
<Button type="text" @click="hide"></Button>
<Button type="primary" @click="exportPrint"></Button>
</div>
</template>
</Modal>
</div>
</template>
<script>
import { getForm } from '@/api/quality'
export default {
data() {
return {
isShow: false,
id: '',
detail: {}
}
},
computed: {
isMark() {
return function(markName, str) {
const arr = str?.split('|') || []
return arr.indexOf(markName) !== -1 ? '✓' : ''
}
},
otherVal() {
return function(options, str) {
const arr = str?.split('|') || []
return (
arr.filter((i) => options.findIndex((j) => j === i) === -1)[0] || ' '
)
}
},
joinSelectedOptions() {
return function(options) {
// checked true
const selectedOptions = options.filter(option => option.checked === true)
// name 使
return selectedOptions.map(option => option.name).join('')
}
}
},
watch: {
isShow(newVal) {
if (newVal) {
this.getDetail()
}
}
},
methods: {
show() {
this.isShow = true
},
hide() {
this.isShow = false
},
setId(id) {
this.id = id
},
async getDetail() {
const res = await getForm(this.id)
console.log(res)
this.detail = res
},
exportPrint() {
const table = document.getElementById('print-table').outerHTML
const printWindow = window.open('', '_blank')
printWindow.document.write('<html><head><title>打印表格</title>')
printWindow.document.write(`
</head><style>
table {
width: 100%;
border-collapse: collapse;
margin: 20px 0;
}
th, td {
border: 1px solid #ddd;
padding: 8px;
text-align: left;
}
thead {
background-color: #f2f2f2;
}
th {
word-break: keep-all;
text-align: center;
height: 40px;
}
.border-none {
border: none;
}
.border-bottom-none {
border-top: none;
border-bottom: none;
}</style><body>`)
printWindow.document.write(table)
printWindow.document.write('</body></html>')
printWindow.document.close()
const imgEl = printWindow.document.querySelectorAll('img')
let temp = 0
imgEl.forEach((el) => {
el.addEventListener('load', (_) => {
temp++
if (temp === imgEl.length) {
printWindow.print()
}
})
})
}
}
}
</script>
<style scoped lang="scss">
table {
width: 100%;
border-collapse: collapse;
margin: 20px 0;
}
th,
td {
border: 1px solid #ddd;
padding: 8px;
text-align: left;
}
thead {
background-color: #f2f2f2;
}
th {
word-break: keep-all;
text-align: center;
height: 40px;
}
.border-none {
border: none;
}
.border-bottom-none {
border-top: none;
border-bottom: none;
}
</style>

@ -24,98 +24,97 @@
<!-- 表格 -->
<xy-table :list="list" :table-item="tableItem" :total="total" @delete="destroy" @editor="editor"
@pageSizeChange="e => select.page_size = e" @pageIndexChange="e => {select.page = e;getWorkers()}">
<template v-slot:forms>
<!-- 遍历列配置 forms每个列对应一个配置项 -->
<el-table-column
v-for="(colConfig, index) in forms"
:key="index"
width="200"
header-align="center"
align="center"
:label="colConfig.ask"
>
<template v-slot:default="scope">
<!-- 找到当前列对应的行实际数据通过索引匹配 -->
<!-- 假设 forms scope.row.forms 顺序一致索引相同 -->
<template v-if="scope.row.forms && scope.row.forms[index]">
<!-- 当前行的实际数据项 -->
<!-- 处理 checkbox 类型 -->
<template v-if="colConfig.type === 'checkbox'">
<div>
{{ joinSelectedOptions(scope.row.forms[index].options || []) }}
</div>
</template>
<!-- 处理普通分数类型 -->
<template v-else>
<div>
{{ scope.row.forms[index].score !== '' ? scope.row.forms[index].score : '-' }} <!-- 空值显示 - -->
</div>
</template>
</template>
<!-- 行数据不存在时显示默认值 -->
<template v-else>
<div>-</div>
</template>
</template>
</el-table-column>
</template>
<template v-slot:files>
<el-table-column
width="200"
header-align="center"
align="center"
label="回访图片"
>
<template v-slot:default="scope">
<template v-if="scope.row.files">
<div style="display:flex">
<el-image
v-for="item in scope.row.files"
style="width: 60px; height: 60px;margin:5px"
:src="item.url"
:preview-src-list="scope.row.files.map(item=>item.url)"></el-image>
</div>
</template>
</template>
</el-table-column>
</template>
<template v-slot:sign_image>
<el-table-column
width="200"
header-align="center"
align="center"
label="服务对象/家属签名"
>
<template v-slot:default="scope">
<el-image
v-if="scope.row.sign_image"
style="width: 100px; height: 100px"
:src="scope.row.sign_image.url"
:preview-src-list="[scope.row.sign_image.url]"></el-image>
</template>
</el-table-column>
</template>
<template v-slot:admin_sign_image>
<el-table-column
width="200"
header-align="center"
align="center"
label="调查人员签名"
>
<template v-slot:default="scope">
<el-image
v-if="scope.row.admin_sign_image"
style="width: 100px; height: 100px"
:src="scope.row.admin_sign_image.url"
:preview-src-list="[scope.row.admin_sign_image.url]"></el-image>
</template>
</el-table-column>
<template v-slot:forms>
<!-- 遍历列配置 forms每个列对应一个配置项 -->
<el-table-column
v-for="(colConfig, index) in forms"
:key="index"
width="200"
header-align="center"
align="center"
:label="colConfig.ask"
>
<template v-slot:default="scope">
<!-- 找到当前列对应的行实际数据通过索引匹配 -->
<!-- 假设 forms scope.row.forms 顺序一致索引相同 -->
<template v-if="scope.row.forms && scope.row.forms[index]">
<!-- 当前行的实际数据项 -->
<!-- 处理 checkbox 类型 -->
<template v-if="colConfig.type === 'checkbox'">
<div>
{{ joinSelectedOptions(scope.row.forms[index].options || []) }}
</div>
</template>
<!-- 处理普通分数类型 -->
<template v-else>
<div>
{{ scope.row.forms[index].score !== '' ? scope.row.forms[index].score : '-' }} <!-- 空值显示 - -->
</div>
</template>
</template>
<!-- 行数据不存在时显示默认值 -->
<template v-else>
<div>-</div>
</template>
</template>
</el-table-column>
</template>
<template v-slot:files>
<el-table-column
width="200"
header-align="center"
align="center"
label="回访图片"
>
<template v-slot:default="scope">
<template v-if="scope.row.files">
<div style="display:flex">
<el-image
v-for="item in scope.row.files"
style="width: 60px; height: 60px;margin:5px"
:src="item.url"
:preview-src-list="scope.row.files.map(item=>item.url)"></el-image>
</div>
</template>
</template>
</el-table-column>
</template>
<template v-slot:sign_image>
<el-table-column
width="200"
header-align="center"
align="center"
label="服务对象/家属签名"
>
<template v-slot:default="scope">
<el-image
v-if="scope.row.sign_image"
style="width: 100px; height: 100px"
:src="scope.row.sign_image.url"
:preview-src-list="[scope.row.sign_image.url]"></el-image>
</template>
</el-table-column>
</template>
<template v-slot:admin_sign_image>
<el-table-column
width="200"
header-align="center"
align="center"
label="调查人员签名"
>
<template v-slot:default="scope">
<el-image
v-if="scope.row.admin_sign_image"
style="width: 100px; height: 100px"
:src="scope.row.admin_sign_image.url"
:preview-src-list="[scope.row.admin_sign_image.url]"></el-image>
</template>
</el-table-column>
</template>
<template v-slot:btns>
<div></div>
<!-- <el-table-column
<el-table-column
fixed="right"
width="200"
header-align="center"
@ -123,35 +122,18 @@
label="操作"
>
<template v-slot:default="scope">
<Poptip
v-if="!$store.getters.myRoles.find(i => i.name === '质控员')"
transfer
confirm
title="确认要删除?"
@on-ok="destroy(scope.row)"
>
<Button size="small" type="error" ghost style="margin-right: 6px"
>删除</Button
>
</Poptip>
<Button
v-if="!$store.getters.myRoles.find(i => i.name === '质控员')"
size="small"
ghost
type="primary"
@click="editor(scope.row)"
style="margin-right: 6px"
>编辑</Button
>
<Button size="small" type="primary" @click="openShowQuality(scope.row)"></Button>
</template>
</el-table-column> -->
</el-table-column>
</template>
</xy-table>
<!-- <add-worker
ref="addWorker"
@refresh="getWorkers"></add-worker> -->
</div>
<show-quality
ref="showQuality"></show-quality>
</div>
</template>
<script>
@ -160,11 +142,13 @@
destroy
} from '@/api/quality'
import { download } from "@/utils/downloadRequest"
import showQuality from "@/views/quality/components/showQuality"
// import addWorker from "@/views/worker/component/addWorker";
export default {
components: {
// addWorker
showQuality
},
data() {
return {
@ -243,21 +227,21 @@ import { download } from "@/utils/downloadRequest"
label: '回访地址',
width: 180,
align: 'left'
},{
prop: 'files',
label: '回访图片',
width: 180,
align: 'left'
},{
prop: 'sign_image',
label: '服务对象/家属签名',
width: 180,
align: 'left',
},{
prop: 'admin_sign_image',
label: '调查人员签名',
width: 180,
align: 'left'
},{
prop: 'files',
label: '回访图片',
width: 180,
align: 'left'
},{
prop: 'sign_image',
label: '服务对象/家属签名',
width: 180,
align: 'left',
},{
prop: 'admin_sign_image',
label: '调查人员签名',
width: 180,
align: 'left'
}
],
forms: [{
@ -383,6 +367,10 @@ import { download } from "@/utils/downloadRequest"
this.list = res.data
this.total = res.total
},
openShowQuality(row) {
this.$refs['showQuality'].setId(row.id)
this.$refs['showQuality'].show()
},
joinSelectedOptions(options) {
console.log("options", options)
// checked true
@ -399,11 +387,11 @@ import { download } from "@/utils/downloadRequest"
background: "rgba(0,0,0,0.4)",
text: "正在导出..."
})
download('/api/admin/quality-callbacks/get-list','get',{
...this.select,
page: 1,
page_size: 9999,
is_export:1
download('/api/admin/quality-callbacks/get-list','get',{
...this.select,
page: 1,
page_size: 9999,
is_export:1
},`质控回访.xlsx`)
loading.close()
} catch (err) {
@ -429,4 +417,4 @@ import { download } from "@/utils/downloadRequest"
</script>
<style lang="scss" scoped>
</style>
</style>

@ -25,7 +25,7 @@ module.exports = {
* Detail: https://cli.vuejs.org/config/#publicpath
*/
publicPath: process.env.ENV === 'staging' ? '/admin_test' : '/admin/',
// outputDir: '/Users/mac/Documents/朗业/2025/s-四世同堂-护工/sstt/public', //测试
// outputDir: '/Users/mac/Documents/朗业/2025/s-四世同堂-护工/sstt/public/admin', //测试
outputDir: '/Users/mac/Documents/朗业/2025/s-四世同堂-护工/正式/sstt/public/admin',
assetsDir: 'static',
css: {

Loading…
Cancel
Save