回访打印

master
xy 1 year ago
parent 3a17c47217
commit a9dc72aab4

@ -0,0 +1,481 @@
<template>
<div>
<xy-dialog ref="dialog"
:is-show.sync="isShow"
type="form"
:title="type === 'add' ? '新增长护险回访' : '编辑长护险回访'"
:form="form"
:rules="rules"
@submit="submit">
<template v-slot:satisfy>
<div class="xy-table-item">
<div class="xy-table-item-label">
服务满意度
</div>
<div class="xy-table-item-content">
<el-select v-model="form.satisfy"
clearable
placeholder="请选择服务满意度"
style="width: 300px;">
<el-option v-for="item in satisfys"
:key="item.value"
:label="item.label"
:value="item.value"></el-option>
</el-select>
</div>
</div>
</template>
<template v-slot:nurse_investigate>
<div class="xy-table-item">
<div class="xy-table-item-label">
护理员护理情况调查
</div>
<div class="xy-table-item-content">
<el-select v-model="form.nurse_investigate"
clearable
placeholder="请选择护理员护理情况调查"
style="width: 300px;">
<el-option v-for="item in nurse_investigates"
:key="item.value"
:label="item.label"
:value="item.value"></el-option>
</el-select>
</div>
</div>
</template>
<template v-slot:is_work>
<div class="xy-table-item">
<div class="xy-table-item-label">
是否在岗
</div>
<div class="xy-table-item-content">
<el-switch v-model="form.is_work"
:active-value="1"
:inactive-value="0"
></el-switch>
</div>
</div>
</template>
<template v-slot:is_on_time>
<div class="xy-table-item">
<div class="xy-table-item-label">
按照排班时间上门服务
</div>
<div class="xy-table-item-content">
<el-switch v-model="form.is_on_time"
:active-value="1"
:inactive-value="0"
></el-switch>
</div>
</div>
</template>
<template v-slot:tools>
<div class="xy-table-item">
<div class="xy-table-item-label">
护理工具携带
</div>
<div class="xy-table-item-content">
<el-input v-model="form.tools"
clearable
placeholder="请输入护理工具携带"
style="width: 300px;"
></el-input>
</div>
</div>
</template>
<template v-slot:accessory>
<div class="xy-table-item">
<div class="xy-table-item-label">
工作服和工作证
</div>
<div class="xy-table-item-content">
<el-input v-model="form.accessory"
clearable
placeholder="请输入工作服和工作证"
style="width: 300px;"
></el-input>
</div>
</div>
</template>
<template v-slot:serve>
<div class="xy-table-item">
<div class="xy-table-item-label">
服务内容
</div>
<div class="xy-table-item-content">
<el-input v-model="form.serve"
clearable
placeholder="请输入服务内容"
style="width: 300px;"
></el-input>
</div>
</div>
</template>
<template v-slot:other>
<div class="xy-table-item">
<div class="xy-table-item-label">
其他需求
</div>
<div class="xy-table-item-content">
<el-input v-model="form.other"
clearable
placeholder="请输入其他需求"
style="width: 300px;"
></el-input>
</div>
</div>
</template>
<template v-slot:tip>
<div class="xy-table-item">
<div class="xy-table-item-label">
建议
</div>
<div class="xy-table-item-content">
<el-input type="textarea"
:autosize="{minRows:2}"
v-model="form.tip"
clearable
placeholder="请输入建议"
style="width: 300px;"
></el-input>
</div>
</div>
</template>
<template v-slot:file_ids>
<div class="xy-table-item">
<div class="xy-table-item-label">
回访图片
</div>
<div class="xy-table-item-content">
<el-upload
style="width: 300px;"
class="upload-demo"
:action="action"
:on-success="(response, file, fileList) => successHandle(response, file, fileList, 'file_ids')"
:before-upload="uploadBefore"
:file-list="file_ids"
:on-remove="(file, fileList) => removeHande(file, fileList, 'file_ids')"
list-type="picture-card">
<i slot="default" class="el-icon-plus"></i>
<div slot="tip" class="el-upload__tip">只能上传jpg/png文件且不超过500kb</div>
</el-upload>
</div>
</div>
</template>
<template v-slot:sign_image_id>
<div class="xy-table-item">
<div class="xy-table-item-label">
服务对象/家属签名
</div>
<div class="xy-table-item-content">
<el-upload
style="width: 300px;"
class="upload-demo"
:action="action"
:limit="1"
:on-success="(response, file, fileList) => successHandle(response, file, fileList, 'sign_image_id')"
:before-upload="uploadBefore"
:file-list="sign_image_id"
:on-remove="(file, fileList) => removeHande(file, fileList, 'sign_image_id')"
list-type="picture-card">
<i slot="default" class="el-icon-plus"></i>
<div slot="tip" class="el-upload__tip">只能上传jpg/png文件且不超过500kb</div>
</el-upload>
</div>
</div>
</template>
<template v-slot:admin_sign_image_id>
<div class="xy-table-item">
<div class="xy-table-item-label">
调查人员签名
</div>
<div class="xy-table-item-content">
<el-upload
style="width: 300px;"
class="upload-demo"
:action="action"
:on-success="(response, file, fileList) => successHandle(response, file, fileList, 'admin_sign_image_id')"
:before-upload="uploadBefore"
:limit="1"
:file-list="admin_sign_image_id"
:on-remove="(file, fileList) => removeHande(file, fileList, 'admin_sign_image_id')"
list-type="picture-card">
<i slot="default" class="el-icon-plus"></i>
<div slot="tip" class="el-upload__tip">只能上传jpg/png文件且不超过500kb</div>
</el-upload>
</div>
</div>
</template>
<template v-slot:remark>
<div class="xy-table-item">
<div class="xy-table-item-label">
备注
</div>
<div class="xy-table-item-content">
<el-input type="textarea"
:autosize="{minRows:2}"
v-model="form.remark"
clearable
placeholder="请输入备注"
style="width: 300px;"
></el-input>
</div>
</div>
</template>
<template v-slot:lat>
<div class="xy-table-item">
<div class="xy-table-item-label">
纬度
</div>
<div class="xy-table-item-content">
<el-input v-model="form.lat"
clearable
placeholder="请输入纬度"
style="width: 300px;"
></el-input>
</div>
</div>
</template>
<template v-slot:lng>
<div class="xy-table-item">
<div class="xy-table-item-label">
经度
</div>
<div class="xy-table-item-content">
<el-input v-model="form.lng"
clearable
placeholder="请输入经度"
style="width: 300px;"
></el-input>
</div>
</div>
</template>
<template v-slot:address>
<div class="xy-table-item">
<div class="xy-table-item-label">
地址
</div>
<div class="xy-table-item-content">
<el-input v-model="form.address"
clearable
placeholder="请输入地址"
style="width: 300px;"
></el-input>
</div>
</div>
</template>
<template v-slot:customer_id>
<div class="xy-table-item">
<div class="xy-table-item-label">
客户
</div>
<div class="xy-table-item-content">
<el-select v-model="form.customer_id"
clearable
placeholder="请选择客户"
style="width: 300px;">
<el-option v-for="item in customer_ids"
:key="item.id"
:label="item.value"
:value="item.id"></el-option>
</el-select>
</div>
</div>
</template>
</xy-dialog>
</div>
</template>
<script>
import {
getForm,
save
} from '@/api/longInsurance';
export default {
props:{
satisfys: {
type:Array,
default:()=>[]
},
nurse_investigates: {
type:Array,
default:()=>[]
},
customer_ids: {
type:Array,
default:()=>[]
},
},
data() {
return {
isShow: false,
id: '',
type: '',
action: process.env.VUE_APP_UPLOAD_API,
file_ids: [],
sign_image_id: [],
admin_sign_image_id: [],
form: {
satisfy: "",
nurse_investigate: "",
is_work: "",
is_on_time: "",
tools: "",
accessory: "",
serve: "",
other: "",
tip: "",
file_ids: "",
sign_image_id: "",
admin_sign_image_id: "",
remark: "",
lat: "",
lng: "",
address: "",
customer_id: "",
},
rules: {
}
}
},
methods: {
show(){
this.isShow = true;
},
hidden(){
this.isShow = false;
},
init(){
for (let key in this.form) {
if (this.form[key] instanceof Array) {
this.form[key] = [];
} else {
this.form[key] = "";
}
}
this.$refs["dialog"].clearValidate();
},
setId(id) {
if(typeof id == "number") {
this.id = id;
}else {
console.error("error typeof id: " + typeof id)
}
},
getId() {
return this.id;
},
setType(type = 'add') {
let types = ['add','editor']
if(types.includes(type)) {
this.type = type;
}else{
console.warn("Unknown type: " + type)
}
},
setForm(key = [], value = []) {
if(key instanceof Array) {
key.forEach((key,index) => {
this.form[key] = value[index] ?? "";
})
}
if(typeof key === "string"){
this.form[key] = value
}
if(!key){
this.init()
}
},
//
successHandle(response, file, fileList, key) {
this[key] = fileList;
},
removeHande(file, fileList, key) {
this[key] = fileList;
},
uploadBefore(file) {
console.log(file);
if (file.size / 1000 > 20 * 1024) {
this.$message({
type: "warning",
message: "上传图片大小超过20MB",
});
return false;
}
},
async getDetail() {
const res = await getForm(this.id)
this.$integrateData(this.form, res)
this.file_ids = res.files?.map(i => ({
url: i.url,
name: i.original_name,
response: i
}))
this.admin_sign_image_id = [{
url: res.admin_sign_image?.url,
name: res.admin_sign_image?.name,
response: res.admin_sign_image
}]
this.sign_image_id = [{
url: res.sign_image?.url,
name: res.sign_image?.name,
response: res.sign_image
}]
},
submit() {
if(this.type === 'add'){
if(this.form.hasOwnProperty('id')){
delete this.form.id
}
}
if (this.type === 'editor') {
Object.defineProperty(this.form, 'id', {
value: this.id,
enumerable: true,
configurable: true,
writable: true
})
}
save(this.form).then(res => {
this.$message({
type: 'success',
message: this.type === 'add' ? '新增长护险回访' : '编辑长护险回访' + '成功'
});
this.isShow = false
this.$emit('refresh')
})
}
},
watch: {
isShow(val) {
if (val) {
if (this.type === 'editor') {
this.getDetail()
}
} else {
this.id = ''
this.type = ''
this.init();
this.$refs['dialog'].clearValidate();
delete this.form.id
}
},
}
}
</script>
<style scoped lang="scss">
::v-deep .el-input__inner {
text-align: left;
}
.xy-table-item-label {
width: 160px;
}
</style>

@ -0,0 +1,352 @@
<template>
<div>
<div ref="lxHeader">
<lx-header icon="md-apps" style="margin-bottom: 10px; border: 0px; margin-top: 15px" text="长护险回访明细">
<div slot="content"></div>
<slot>
<div class="select">
<div>
<span>被护理人</span>
<el-select
v-load-more="getCustomers"
:loading="customerLoading"
remote
:remote-method="customerRemote"
filterable
size="small"
v-model="select.customer_id"
placeholder="选择被护理人"
clearable
style="width: 160px;"
>
<el-option
v-for="item in customers"
:value="item.id"
:label="item.name"
:key="item.id"
></el-option>
</el-select>
</div>
<div>
<span>关键词</span>
<el-input size="small" style="width: 160px;" v-model="select.keyword" clearable placeholder="请输入关键词"></el-input>
</div>
<div>
<Button type="primary" @click="total = 0,select.page = 1,getList()">查询</Button>
</div>
<div>
<Button type="primary" @click="exportExcel"></Button>
</div>
</div>
</slot>
</lx-header>
</div>
<xy-table
:total="total"
:list="list"
:table-item="table"
@editor="editor"
@delete="destroy"
@pageSizeChange="e => select.page_size = e"
@pageIndexChange="e => {select.page = e;getList()}">
<template v-slot:btns>
<el-table-column label="操作" fixed="right" header-align="center" align="left" width="200">
<template v-slot:default="scope">
<Button
size="small"
type="primary"
style="margin-right: 6px"
@click="_ => {
$refs['longInsuranceDetail'].setId(scope.row.id)
$refs['longInsuranceDetail'].show()
}"
>查看</Button>
<Poptip
transfer
confirm
title="确认要删除?"
@on-ok="destroy(scope.row)"
>
<Button size="small" type="error" ghost style="margin-right: 6px"
>删除</Button
>
</Poptip>
<Button size="small"
ghost
type="primary"
@click="editor(scope.row)">编辑</Button>
</template>
</el-table-column>
</template>
</xy-table>
<add ref="add" :customer_ids="customers" :satisfys="satisfy" :nurse_investigates="nurse_investigate" @refresh="getList"></add>
<longInsuranceDetail ref="longInsuranceDetail"></longInsuranceDetail>
</div>
</template>
<script>
import {getList,destroy} from '@/api/longInsurance'
import {getList as customerIndex} from "@/api/customer";
import {getList as nurseList} from "@/api/worker";
import * as XLSX from "xlsx";
import { saveAs } from "file-saver";
import longInsuranceDetail from "@/views/customer/component/longInsuranceDetail.vue"
import add from "./component/addLongInsurance.vue"
export default {
components:{
add,
longInsuranceDetail
},
data() {
return {
satisfy: [
{
label: "90分以上",
value: 1
},
{
label: "80-90分",
value: 2
},
{
label: "80分以下",
value: 3
},
],
nurse_investigate: [
{
label: "护理中回访",
value: 1
},
{
label: "日常回访",
value: 2
},
],
customers:[],
customerLoading: false,
customerTotal: 0,
customerSelect: {
page: 1,
page_size: 20,
keyword: ""
},
select:{
page:1,
page_size:10,
customer_id: "",
keyword: "",
},
total:0,
list:[],
table:[
{
type: 'index',
width: 50
},
{
prop: "customer.name",
label: "服务对象",
width: 140
},
{
prop: 'created_at',
label: '回访日期',
align: 'center',
width: 160
},
{
prop: 'satisfy',
label: '服务满意度',
width: 180,
align: 'center',
formatter: (data,row,val) => {
return this.satisfy.find(i => i.value === val)?.label
}
},
{
prop: 'nurse_investigate',
label: '护理员护理情况调查',
width: 180,
formatter: (data,row,val) => {
return this.nurse_investigate.find(i => i.value === val)?.label
}
},
{
prop: 'is_work',
label: '是否在岗',
width: 120,
align: 'center',
formatter: (data, row, val) => {
return val ? '是' : '否'
}
},
{
prop: 'is_on_time',
label: '按照排班时间上门服务',
width: 154,
align: 'center',
formatter: (data, row, val) => {
return val ? '是' : '否'
}
},
{
prop: 'accessory',
label: '是否有工作证、工作服',
width: 160,
align: 'center',
},
{
prop: 'tools',
label: '护理工具携带',
width: 180,
align: 'left',
},
{
prop: 'serve',
label: '服务内容',
width: 180,
align: 'left',
},
{
prop: 'other',
label: '其他需求',
align: 'left',
width: 180
},
{
prop: 'tip',
label: '建议',
align: 'left',
minWidth: 180
},
]
}
},
methods: {
async getCustomers(){
if ((this.customers.length >= this.customerTotal) && this.customers.length !== 0) return;
this.customerLoading = true;
try {
const res = await customerIndex(this.customerSelect,false)
this.customers.push(...res.data.data);
this.customerTotal = res.data.total;
this.customerSelect.page++;
this.customerLoading = false;
} catch (err) {
this.customerLoading = false;
}
},
customerRemote (query) {
let keyword = query ? query.trim() : "";
this.customers = [];
this.customerTotal = 0;
this.customerSelect.page = 1;
this.customerSelect.keyword = keyword;
this.getCustomers();
},
async getList(){
const res = await getList(this.select)
this.total = res.total
this.list = res.data
console.log(this.list)
},
editor(row){
this.$refs['add'].setId(row.id)
this.$refs['add'].setType('editor')
this.$refs['add'].show()
},
destroy(row){
destroy(row.id).then(res => {
this.$successMessage('destroy','')
this.getList()
})
},
async exportExcel () {
const res = await getList({
...this.select,
page: 1,
page_size: 9999
})
const handlerValue = (key, obj) => {
try {
if (key.includes(".")) {
let splitKey = key.split(".")
let temp = obj;
for (let i of splitKey) {
if (i && typeof i === 'string' && typeof temp === 'object') {
temp = temp[i]
}
}
return temp
} else {
return obj[key]
}
} catch (err) {
console.error(err)
}
}
if (res.data) {
let header = this.table.slice(1).map(i => i.label)
let data = res.data.map(i => {
let temp = [];
this.table.slice(1).forEach(row => {
if (row.hasOwnProperty("formatter")) {
temp.push(row.formatter(false, false, handlerValue(row.prop, i)))
} else {
temp.push(handlerValue(row.prop, i))
}
})
return temp;
})
data.unshift(header)
const wb = XLSX.utils.book_new();
const ws = XLSX.utils.aoa_to_sheet(data);
XLSX.utils.book_append_sheet(wb, ws, "长护险回访明细");
const wbout = XLSX.write(wb, {
bookType: "xlsx",
bookSST: true,
type: "array",
});
saveAs(
new Blob([wbout], { type: "application/octet-stream" }),
`回访明细${this.$moment().format('YYYY-MM-DD')}.xlsx`
);
}
}
},
created() {
this.getCustomers()
this.getList()
}
}
</script>
<style scoped lang="scss">
.select {
display: flex;
flex-wrap: wrap;
align-items: center;
& > div {
margin: 2px 6px;
& > span {
padding-right: 12px;
font-weight: 600;
}
}
}
</style>
Loading…
Cancel
Save