|
|
@@ -0,0 +1,223 @@
|
|
|
+<template>
|
|
|
+ <el-dialog
|
|
|
+ title="信息采集表"
|
|
|
+ :visible.sync="dialogVisible"
|
|
|
+ width="1100px"
|
|
|
+ append-to-body
|
|
|
+ :close-on-click-modal="false"
|
|
|
+ @close="handleClose"
|
|
|
+ >
|
|
|
+ <el-table v-loading="loading" :data="collectionList" @selection-change="handleSelectionChange">
|
|
|
+ <el-table-column type="selection" width="55" align="center" />
|
|
|
+ <el-table-column label="用户姓名" align="center" prop="userName" />
|
|
|
+ <el-table-column label="性别" align="center" prop="sex">
|
|
|
+ <template slot-scope="scope">
|
|
|
+ <span>{{ formatSex(scope.row.sex) }}</span>
|
|
|
+ </template>
|
|
|
+ </el-table-column>
|
|
|
+ <el-table-column label="电话尾号" align="center" prop="userPhoneFour" />
|
|
|
+ <el-table-column label="是否过敏" align="center" prop="allergy">
|
|
|
+ <template slot-scope="scope">
|
|
|
+ <span>{{ scope.row.allergy || '无' }}</span>
|
|
|
+ </template>
|
|
|
+ </el-table-column>
|
|
|
+ <el-table-column label="医生" align="center" prop="doctorName" />
|
|
|
+ <el-table-column label="销售" align="center" prop="companyUserName" />
|
|
|
+ <el-table-column label="备注" align="center" prop="remark" show-overflow-tooltip />
|
|
|
+ <el-table-column label="创建时间" align="center" prop="createTime" width="180">
|
|
|
+ <template slot-scope="scope">
|
|
|
+ <span>{{ parseTime(scope.row.createTime, '{y}-{m}-{d} {h}:{i}:{s}') }}</span>
|
|
|
+ </template>
|
|
|
+ </el-table-column>
|
|
|
+ <el-table-column label="操作" align="center" class-name="small-padding fixed-width" width="100">
|
|
|
+ <template slot-scope="scope">
|
|
|
+ <el-button size="mini" type="text" icon="el-icon-view" @click="handleView(scope.row)">详情</el-button>
|
|
|
+ </template>
|
|
|
+ </el-table-column>
|
|
|
+ </el-table>
|
|
|
+
|
|
|
+ <pagination
|
|
|
+ v-show="total > 0"
|
|
|
+ :total="total"
|
|
|
+ :page.sync="queryParams.pageNum"
|
|
|
+ :limit.sync="queryParams.pageSize"
|
|
|
+ @pagination="getList"
|
|
|
+ />
|
|
|
+
|
|
|
+ <!-- 详情对话框 -->
|
|
|
+ <el-dialog title="采集详情" :visible.sync="detailOpen" width="800px" append-to-body>
|
|
|
+ <el-form ref="detailForm" :model="detailForm" label-width="120px" size="small">
|
|
|
+ <el-row>
|
|
|
+ <el-col :span="8">
|
|
|
+ <el-form-item label="用户姓名">{{ detailForm.userName }}</el-form-item>
|
|
|
+ </el-col>
|
|
|
+ <el-col :span="8">
|
|
|
+ <el-form-item label="性别">{{ formatSex(detailForm.sex) }}</el-form-item>
|
|
|
+ </el-col>
|
|
|
+ <el-col :span="8">
|
|
|
+ <el-form-item label="年龄">{{ detailForm.age }}</el-form-item>
|
|
|
+ </el-col>
|
|
|
+ <el-col :span="8">
|
|
|
+ <el-form-item label="电话尾号">{{ detailForm.userPhoneFour }}</el-form-item>
|
|
|
+ </el-col>
|
|
|
+ <el-col :span="8">
|
|
|
+ <el-form-item label="是否过敏">{{ detailForm.allergy || '无' }}</el-form-item>
|
|
|
+ </el-col>
|
|
|
+ <el-col :span="8">
|
|
|
+ <el-form-item label="备注">{{ detailForm.remark }}</el-form-item>
|
|
|
+ </el-col>
|
|
|
+ </el-row>
|
|
|
+ <el-divider content-position="left">采集详情</el-divider>
|
|
|
+ <div v-if="parsedQuestions && parsedQuestions.length > 0">
|
|
|
+ <div v-for="(question, index) in parsedQuestions" :key="index" class="question-item">
|
|
|
+ <h4 class="question-title">{{ index + 1 }}. {{ question.title }}</h4>
|
|
|
+ <div class="options-container">
|
|
|
+ <el-tag
|
|
|
+ v-for="(option, optionIndex) in question.options"
|
|
|
+ :key="optionIndex"
|
|
|
+ :type="isOptionSelected(question, option.value) ? 'primary' : 'info'"
|
|
|
+ :effect="isOptionSelected(question, option.value) ? 'dark' : 'plain'"
|
|
|
+ class="option-tag"
|
|
|
+ >
|
|
|
+ {{ option.name }}
|
|
|
+ </el-tag>
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+ <div v-else class="no-data">暂无采集信息详情</div>
|
|
|
+ </el-form>
|
|
|
+ <div slot="footer" class="dialog-footer">
|
|
|
+ <el-button @click="detailOpen = false">关 闭</el-button>
|
|
|
+ </div>
|
|
|
+ </el-dialog>
|
|
|
+ </el-dialog>
|
|
|
+</template>
|
|
|
+
|
|
|
+<script>
|
|
|
+import { getCollectionInfoListByPhone } from '@/api/patientInfo'
|
|
|
+import { parseTime } from '@/utils/common'
|
|
|
+
|
|
|
+export default {
|
|
|
+ name: 'CollectionInfoDialog',
|
|
|
+ props: {
|
|
|
+ visible: { type: Boolean, default: false },
|
|
|
+ phone: { type: String, default: '' }
|
|
|
+ },
|
|
|
+ data() {
|
|
|
+ return {
|
|
|
+ loading: false,
|
|
|
+ collectionList: [],
|
|
|
+ total: 0,
|
|
|
+ ids: [],
|
|
|
+ single: true,
|
|
|
+ multiple: true,
|
|
|
+ queryParams: { pageNum: 1, pageSize: 10 },
|
|
|
+ detailForm: {},
|
|
|
+ detailOpen: false,
|
|
|
+ parsedQuestions: []
|
|
|
+ }
|
|
|
+ },
|
|
|
+ computed: {
|
|
|
+ dialogVisible: {
|
|
|
+ get() { return this.visible },
|
|
|
+ set(val) { this.$emit('update:visible', val) }
|
|
|
+ }
|
|
|
+ },
|
|
|
+ watch: {
|
|
|
+ visible(newVal) {
|
|
|
+ if (newVal && this.phone) {
|
|
|
+ this.queryParams.pageNum = 1
|
|
|
+ this.getList()
|
|
|
+ }
|
|
|
+ }
|
|
|
+ },
|
|
|
+ methods: {
|
|
|
+ parseTime,
|
|
|
+ formatSex(sex) {
|
|
|
+ if (sex === 0 || sex === '0') return '女'
|
|
|
+ if (sex === 1 || sex === '1') return '男'
|
|
|
+ return '未知'
|
|
|
+ },
|
|
|
+ /** 请求列表数据 */
|
|
|
+ getList() {
|
|
|
+ this.loading = true
|
|
|
+ getCollectionInfoListByPhone({
|
|
|
+ phone: this.phone,
|
|
|
+ pageNum: this.queryParams.pageNum,
|
|
|
+ pageSize: this.queryParams.pageSize
|
|
|
+ }).then(res => {
|
|
|
+ // 兼容多种返回结构:res 可能是完整的后端 JSON,也可能进一步被若依拦截器包裹
|
|
|
+ const inner = res.data || res
|
|
|
+ // 数据可能在 list 或 rows 中
|
|
|
+ const list = inner.list || inner.rows || []
|
|
|
+ this.collectionList = list
|
|
|
+ this.total = inner.total || 0
|
|
|
+ this.loading = false
|
|
|
+ }).catch(err => {
|
|
|
+ console.error('获取信息采集列表失败:', err)
|
|
|
+ this.collectionList = []
|
|
|
+ this.total = 0
|
|
|
+ this.loading = false
|
|
|
+ })
|
|
|
+ },
|
|
|
+ handleSelectionChange(selection) {
|
|
|
+ this.ids = selection.map(item => item.id)
|
|
|
+ this.single = selection.length !== 1
|
|
|
+ this.multiple = !selection.length
|
|
|
+ },
|
|
|
+ handleView(row) {
|
|
|
+ this.detailForm = { ...row }
|
|
|
+ this.parsedQuestions = this.parseJsonInfo(row.jsonInfo)
|
|
|
+ this.detailOpen = true
|
|
|
+ },
|
|
|
+ parseJsonInfo(jsonInfoStr) {
|
|
|
+ try {
|
|
|
+ if (!jsonInfoStr) return []
|
|
|
+ const parsed = JSON.parse(jsonInfoStr)
|
|
|
+ return Array.isArray(parsed) ? parsed.sort((a, b) => a.sort - b.sort) : []
|
|
|
+ } catch (e) {
|
|
|
+ console.error('解析jsonInfo失败:', e)
|
|
|
+ return []
|
|
|
+ }
|
|
|
+ },
|
|
|
+ isOptionSelected(question, optionValue) {
|
|
|
+ return question.value && question.value.includes(optionValue)
|
|
|
+ },
|
|
|
+ handleClose() {
|
|
|
+ this.collectionList = []
|
|
|
+ this.total = 0
|
|
|
+ this.queryParams.pageNum = 1
|
|
|
+ this.$emit('update:visible', false)
|
|
|
+ }
|
|
|
+ }
|
|
|
+}
|
|
|
+</script>
|
|
|
+
|
|
|
+<style scoped>
|
|
|
+.question-item {
|
|
|
+ margin-bottom: 20px;
|
|
|
+ padding: 10px;
|
|
|
+ border: 1px solid #ebeef5;
|
|
|
+ border-radius: 4px;
|
|
|
+ background-color: #fafafa;
|
|
|
+}
|
|
|
+.question-title {
|
|
|
+ margin: 0 0 10px 0;
|
|
|
+ font-size: 16px;
|
|
|
+ font-weight: bold;
|
|
|
+ color: #303133;
|
|
|
+}
|
|
|
+.options-container {
|
|
|
+ display: flex;
|
|
|
+ flex-wrap: wrap;
|
|
|
+ gap: 8px;
|
|
|
+}
|
|
|
+.option-tag {
|
|
|
+ margin-bottom: 5px;
|
|
|
+}
|
|
|
+.no-data {
|
|
|
+ text-align: center;
|
|
|
+ color: #909399;
|
|
|
+ padding: 20px;
|
|
|
+}
|
|
|
+</style>
|