Pārlūkot izejas kodu

总后台新增用户信息采集总览功能

cgp 12 stundas atpakaļ
vecāks
revīzija
b7de67ac6f

+ 28 - 0
src/api/company/fsUserInformationCollection.js

@@ -0,0 +1,28 @@
+import request from '@/utils/request'
+
+// 查询用户信息采集列表
+export function listCollection(query) {
+  return request({
+    url: '/hisStore/collection/listOverview',
+    method: 'get',
+    params: query
+  })
+}
+
+// 根据用户ID查询处方列表
+export function getPrescribeListByUserId(query) {
+  return request({
+    url: '/hisStore/collection/getPrescribeListByUserId',
+    method: 'get',
+    params: query
+  })
+}
+
+// 导出用户信息采集
+export function exportCollection(query) {
+  return request({
+    url: '/hisStore/collection/export',
+    method: 'get',
+    params: query
+  })
+}

+ 455 - 0
src/views/company/collection/index.vue

@@ -0,0 +1,455 @@
+<template>
+  <div class="app-container">
+    <el-form :model="queryParams" ref="queryForm" size="small" :inline="true" v-show="showSearch" label-width="68px">
+      <el-form-item label="用户姓名" prop="userName">
+        <el-input
+          v-model="queryParams.userName"
+          placeholder="请输入用户姓名"
+          clearable
+          @keyup.enter.native="handleQuery"
+        />
+      </el-form-item>
+      <el-form-item label="医生姓名" prop="doctorName">
+        <el-input
+          v-model="queryParams.doctorName"
+          placeholder="请输入医生姓名"
+          clearable
+          @keyup.enter.native="handleQuery"
+        />
+      </el-form-item>
+      <el-form-item>
+        <el-button type="primary" icon="el-icon-search" size="mini" @click="handleQuery">搜索</el-button>
+        <el-button icon="el-icon-refresh" size="mini" @click="resetQuery">重置</el-button>
+      </el-form-item>
+    </el-form>
+
+    <el-row :gutter="10" class="mb8">
+      <el-col :span="1.5">
+        <el-button
+          type="warning"
+          plain
+          icon="el-icon-download"
+          size="mini"
+          @click="handleExport"
+          v-hasPermi="['hisStore:collection:export']"
+        >导出
+        </el-button>
+      </el-col>
+      <right-toolbar :showSearch.sync="showSearch" @queryTable="getList"></right-toolbar>
+    </el-row>
+
+<!--    <el-table v-loading="loading" :data="collectionList" @selection-change="handleSelectionChange">-->
+    <el-table v-loading="loading" :data="collectionList">
+      <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">
+        <template #default="{ row }">
+          {{ row.allergy || '无' }}
+        </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">
+        <template slot-scope="scope">
+          <el-button
+            size="mini"
+            type="text"
+            icon="el-icon-view"
+            @click="handleView(scope.row)"
+            v-hasPermi="['hisStore:collection:query']"
+          >详情
+          </el-button>
+          <el-button
+            size="mini"
+            type="text"
+            icon="el-icon-tickets"
+            @click="handlePrescribeList(scope.row)"
+            v-hasPermi="['hisStore:collection:query']"
+          >处方列表
+          </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="open" width="800px" append-to-body>
+      <el-form ref="form" :model="form" label-width="120px">
+        <el-row>
+          <el-col :span="8">
+            <el-form-item label="用户姓名:">{{ form.userName }}</el-form-item>
+          </el-col>
+          <el-col :span="8">
+            <el-form-item label="用户性别:">{{ formatSex(form.sex) }}</el-form-item>
+          </el-col>
+          <el-col :span="8">
+            <el-form-item label="用户年龄:">{{ form.age }}</el-form-item>
+          </el-col>
+          <el-col :span="8">
+            <el-form-item label="电话尾号:">{{ form.userPhoneFour }}</el-form-item>
+          </el-col>
+          <el-col :span="8">
+            <el-form-item label="是否过敏:">{{ form.allergy || '无' }}</el-form-item>
+          </el-col>
+          <el-col :span="8">
+            <el-form-item label="备注:">{{ form.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="cancel">关 闭</el-button>
+      </div>
+    </el-dialog>
+
+    <!-- 处方列表对话框 -->
+    <el-dialog title="用户处方列表" :visible.sync="prescribeDialogVisible" width="80%" append-to-body>
+      <el-table v-loading="prescribeLoading" :data="prescribeList" style="width: 100%">
+        <el-table-column label="序号" type="index" width="60" align="center"/>
+        <el-table-column label="处方图片" align="center">
+          <template #default="{ row }">
+            <el-image
+              v-if="row.prescribeImgUrl"
+              :src="row.prescribeImgUrl"
+              :preview-src-list="[row.prescribeImgUrl]"
+              style="width: 100px; height: 100px;"
+              fit="cover"
+              :preview-teleported="true"
+            >
+              <div slot="error" class="image-slot">
+                <i class="el-icon-picture-outline"></i>
+              </div>
+            </el-image>
+            <span v-else>暂无图片</span>
+          </template>
+        </el-table-column>
+        <el-table-column label="处方编号" prop="prescribeCode" align="center" width="150"/>
+        <el-table-column label="患者姓名" prop="patientName" align="center" width="100"/>
+        <el-table-column label="患者年龄" prop="patientAge" align="center" width="80"/>
+        <el-table-column label="患者性别" align="center" width="80">
+          <template #default="{ row }">
+            <span>{{ formatPatientGender(row.patientGender) }}</span>
+          </template>
+        </el-table-column>
+        <el-table-column label="状态" align="center" width="80">
+          <template #default="{ row }">
+            <el-tag :type="getStatusType(row.status)">{{ getStatusText(row.status) }}</el-tag>
+          </template>
+        </el-table-column>
+        <el-table-column label="创建时间" prop="createTime" align="center" width="160">
+          <template #default="{ row }">
+            <span>{{ parseTime(row.createTime, '{y}-{m}-{d} {h}:{i}:{s}') }}</span>
+          </template>
+        </el-table-column>
+      </el-table>
+
+      <pagination
+        v-show="prescribeTotal > 0"
+        :total="prescribeTotal"
+        :page.sync="prescribeQuery.pageNum"
+        :limit.sync="prescribeQuery.pageSize"
+        @pagination="getPrescribeList"
+      />
+
+      <div slot="footer" class="dialog-footer">
+        <el-button @click="closePrescribeDialog">关 闭</el-button>
+      </div>
+    </el-dialog>
+  </div>
+</template>
+
+<script>
+import {
+  listCollection,
+  exportCollection,
+  getPrescribeListByUserId
+} from "@/api/company/fsUserInformationCollection";
+
+export default {
+  name: "Collection",
+  data() {
+    return {
+      // 遮罩层
+      loading: true,
+      // 选中数组
+      ids: [],
+      // 非单个禁用
+      single: true,
+      // 非多个禁用
+      multiple: true,
+      // 显示搜索条件
+      showSearch: true,
+      // 总条数
+      total: 0,
+      // 用户信息采集表格数据
+      collectionList: [],
+      // 弹出层标题
+      title: "",
+      // 是否显示弹出层
+      open: false,
+      // 查询参数
+      queryParams: {
+        pageNum: 1,
+        pageSize: 10,
+        userName: null,
+        doctorName: null,
+        companyUserName: null,
+      },
+      // 表单参数
+      form: {},
+      // 解析后的问卷信息
+      parsedQuestions: [],
+
+      // 处方列表相关
+      prescribeDialogVisible: false,
+      prescribeLoading: false,
+      prescribeList: [],
+      prescribeTotal: 0,
+      prescribeQuery: {
+        pageNum: 1,
+        pageSize: 10,
+        userId: null
+      }
+    };
+  },
+  created() {
+    this.getList();
+  },
+  methods: {
+    /** 格式化性别显示 */
+    formatSex(sex) {
+      if (sex === 0 || sex === '0') {
+        return '女';
+      } else if (sex === 1 || sex === '1') {
+        return '男';
+      } else {
+        return '未知';
+      }
+    },
+
+    /** 格式化患者性别 */
+    formatPatientGender(gender) {
+      if (gender === '1' || gender === 1) {
+        return '男';
+      } else if (gender === '2' || gender === 2) {
+        return '女';
+      } else {
+        return '未知';
+      }
+    },
+
+    /** 获取状态文本 */
+    getStatusText(status) {
+      if (status === 0) {
+        return '未开';
+      } else if (status === 1) {
+        return '已开';
+      } else {
+        return '未知';
+      }
+    },
+
+    /** 获取状态类型 */
+    getStatusType(status) {
+      if (status === 0) {
+        return 'info';
+      } else if (status === 1) {
+        return 'success';
+      } else {
+        return 'info';
+      }
+    },
+
+    /** 判断选项是否被选中 */
+    isOptionSelected(question, optionValue) {
+      return question.value && question.value.includes(optionValue);
+    },
+
+    /** 解析JSON信息 */
+    parseJsonInfo(jsonInfoStr) {
+      try {
+        if (!jsonInfoStr) {
+          return [];
+        }
+        const parsed = JSON.parse(jsonInfoStr);
+        // 按照sort字段排序
+        return Array.isArray(parsed) ? parsed.sort((a, b) => a.sort - b.sort) : [];
+      } catch (e) {
+        console.error('解析jsonInfo失败:', e);
+        return [];
+      }
+    },
+
+    /** 查询用户信息采集列表 */
+    getList() {
+      this.loading = true;
+      listCollection(this.queryParams).then(response => {
+        this.collectionList = response.rows;
+        this.total = response.total;
+        this.loading = false;
+      });
+    },
+
+    // 取消按钮
+    cancel() {
+      this.open = false;
+      this.reset();
+    },
+    // 表单重置
+    reset() {
+      this.form = {};
+      this.parsedQuestions = [];
+      this.resetForm("form");
+    },
+    /** 搜索按钮操作 */
+    handleQuery() {
+      this.queryParams.pageNum = 1;
+      this.getList();
+    },
+    /** 重置按钮操作 */
+    resetQuery() {
+      this.resetForm("queryForm");
+      this.handleQuery();
+    },
+    // 多选框选中数据
+    handleSelectionChange(selection) {
+      this.ids = selection.map(item => item.id)
+      this.single = selection.length !== 1
+      this.multiple = !selection.length
+    },
+    /** 详情按钮操作 */
+    handleView(row) {
+      this.reset();
+      this.form = {...row};
+      this.parsedQuestions = this.parseJsonInfo(row.jsonInfo);
+      this.open = true;
+      this.title = "用户信息采集详情";
+    },
+    /** 查看处方列表按钮操作 */
+    handlePrescribeList(row) {
+      this.prescribeQuery.userId = row.userId;
+      this.getPrescribeList();
+    },
+    /** 获取处方列表 */
+    getPrescribeList() {
+      this.prescribeLoading = true;
+      this.prescribeQuery.userId = this.prescribeQuery.userId; // 确保userId存在
+
+      getPrescribeListByUserId({
+        userId: this.prescribeQuery.userId,
+        pageNum: this.prescribeQuery.pageNum,
+        pageSize: this.prescribeQuery.pageSize
+      }).then(response => {
+        this.prescribeList = response.rows;
+        this.prescribeTotal = response.total;
+        this.prescribeLoading = false;
+        this.prescribeDialogVisible = true;
+      }).catch(() => {
+        this.prescribeLoading = false;
+        this.prescribeList = [];
+        this.prescribeTotal = 0;
+      });
+    },
+    /** 关闭处方列表对话框 */
+    closePrescribeDialog() {
+      this.prescribeDialogVisible = false;
+      this.prescribeList = [];
+      this.prescribeTotal = 0;
+      this.prescribeQuery = {
+        pageNum: 1,
+        pageSize: 10,
+        userId: null
+      };
+    },
+    /** 导出按钮操作 */
+    handleExport() {
+      this.$confirm('是否确认导出所有用户信息采集数据项?', "警告", {
+        confirmButtonText: "确定",
+        cancelButtonText: "取消",
+        type: "warning"
+      }).then(function() {
+        return exportCollection(this.queryParams);
+      }.bind(this)).then(response => {
+        //调用系统的download方法处理下载
+        this.download(response.msg);
+      }).catch(function() {
+        // 用户取消或错误处理
+      });
+    }
+  }
+};
+</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>