index.vue 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546
  1. <template>
  2. <div class="app-container">
  3. <el-form
  4. :model="queryParams"
  5. ref="queryForm"
  6. size="small"
  7. :inline="true"
  8. v-show="showSearch"
  9. label-width="100px"
  10. >
  11. <el-form-item label="样本编号" prop="sampleCode">
  12. <el-input
  13. v-model="queryParams.sampleCode"
  14. placeholder="请输入样本编号"
  15. clearable
  16. @keyup.enter.native="handleQuery"
  17. />
  18. </el-form-item>
  19. <el-form-item label="样本类型" prop="sampleTypeId">
  20. <!-- <el-input
  21. v-model="queryParams.sampleTypeId"
  22. placeholder="请输入样本类型"
  23. clearable
  24. @keyup.enter.native="handleQuery"
  25. /> -->
  26. <el-select
  27. v-model="queryParams.sampleTypeId"
  28. placeholder="请选择样本类型"
  29. >
  30. <el-option
  31. v-for="item in options"
  32. :key="item.value"
  33. :label="item.label"
  34. :value="item.value"
  35. >
  36. </el-option>
  37. </el-select>
  38. </el-form-item>
  39. <el-form-item label="送检医院" prop="sampleHospitalId">
  40. <el-select
  41. v-model="queryParams.sampleHospitalId"
  42. placeholder="请选择送检医院"
  43. >
  44. <el-option
  45. v-for="item in options3"
  46. :key="item.value"
  47. :label="item.label"
  48. :value="item.value"
  49. >
  50. </el-option>
  51. </el-select>
  52. </el-form-item>
  53. <el-form-item label="送检科室" prop="sampleDeptId">
  54. <el-select
  55. v-model="queryParams.sampleDeptId"
  56. placeholder="请选择送检科室"
  57. >
  58. <el-option
  59. v-for="item in options2"
  60. :key="item.value"
  61. :label="item.label"
  62. :value="item.value"
  63. >
  64. </el-option>
  65. </el-select>
  66. </el-form-item>
  67. <el-form-item label="医生姓名" prop="doctorName">
  68. <el-input
  69. v-model="queryParams.doctorName"
  70. placeholder="请输入医生姓名"
  71. clearable
  72. @keyup.enter.native="handleQuery"
  73. />
  74. </el-form-item>
  75. <el-form-item>
  76. <el-button
  77. type="primary"
  78. icon="el-icon-search"
  79. size="mini"
  80. @click="handleQuery"
  81. >搜索</el-button
  82. >
  83. <el-button icon="el-icon-refresh" size="mini" @click="resetQuery"
  84. >重置</el-button
  85. >
  86. </el-form-item>
  87. </el-form>
  88. <el-row :gutter="10" class="mb8">
  89. <el-col :span="1.5">
  90. <el-button
  91. type="primary"
  92. plain
  93. icon="el-icon-plus"
  94. size="mini"
  95. @click="handleAdd"
  96. >新增</el-button
  97. >
  98. </el-col>
  99. <el-col :span="1.5">
  100. <el-button
  101. type="success"
  102. plain
  103. icon="el-icon-edit"
  104. size="mini"
  105. :disabled="single"
  106. @click="handleUpdate"
  107. >修改</el-button
  108. >
  109. </el-col>
  110. <el-col :span="1.5">
  111. <el-button
  112. type="danger"
  113. plain
  114. icon="el-icon-delete"
  115. size="mini"
  116. :disabled="multiple"
  117. @click="handleDelete"
  118. >删除</el-button
  119. >
  120. </el-col>
  121. <el-col :span="1.5">
  122. <el-button plain size="mini" @click="handleBack">返回</el-button>
  123. </el-col>
  124. </el-row>
  125. <el-table
  126. v-loading="loading"
  127. :data="sampleInfoList"
  128. @selection-change="handleSelectionChange"
  129. >
  130. <el-table-column type="selection" width="55" align="center" />
  131. <el-table-column label="样本编号" align="center" prop="sampleCode" />
  132. <el-table-column label="患者姓名" align="center" prop="patientName" />
  133. <el-table-column label="患者电话" align="center" prop="patientPhone" />
  134. <el-table-column label="样本类型" align="center" prop="sampleTypeName" />
  135. <el-table-column
  136. label="送检医院"
  137. align="center"
  138. prop="sampleHospitalName"
  139. />
  140. <el-table-column label="送检科室" align="center" prop="sampleDeptName" />
  141. <el-table-column label="医生姓名" align="center" prop="doctorName" />
  142. <el-table-column label="备注" align="center" prop="remark" />
  143. <el-table-column
  144. label="操作"
  145. align="center"
  146. class-name="small-padding fixed-width"
  147. >
  148. <template slot-scope="scope">
  149. <el-button size="mini" type="text" @click="handleUpdate(scope.row)"
  150. >修改</el-button
  151. >
  152. <el-button size="mini" type="text" @click="handleDelete(scope.row)"
  153. >删除</el-button
  154. >
  155. <el-button size="mini" type="text" @click="gojdzx(scope.row)"
  156. >实验解读</el-button
  157. >
  158. </template>
  159. </el-table-column>
  160. </el-table>
  161. <pagination
  162. v-show="total > 0"
  163. :total="total"
  164. :page.sync="queryParams.pageNum"
  165. :limit.sync="queryParams.pageSize"
  166. @pagination="getList"
  167. />
  168. <!-- 添加或修改样本管理对话框 -->
  169. <el-dialog :title="title" :visible.sync="open" width="500px" append-to-body>
  170. <el-form ref="form" :model="form" :rules="rules" label-width="80px">
  171. <el-form-item label="样本编号" prop="sampleCode">
  172. <el-input v-model="form.sampleCode" placeholder="请输入样本编号" />
  173. </el-form-item>
  174. <el-form-item label="样本类型" prop="sampleTypeId">
  175. <el-select
  176. v-model="form.sampleTypeId"
  177. placeholder="请选择样本类型"
  178. style="width: 100%"
  179. >
  180. <el-option
  181. v-for="item in options"
  182. :key="item.value"
  183. :label="item.label"
  184. :value="item.value"
  185. >
  186. </el-option>
  187. </el-select>
  188. </el-form-item>
  189. <el-form-item label="送检医院" prop="sampleHospitalId">
  190. <el-select
  191. v-model="form.sampleHospitalId"
  192. placeholder="请选择送检医院"
  193. >
  194. <el-option
  195. v-for="item in options3"
  196. :key="item.value"
  197. :label="item.label"
  198. :value="item.value"
  199. >
  200. </el-option>
  201. </el-select>
  202. </el-form-item>
  203. <el-form-item label="送检科室" prop="sampleDeptId">
  204. <el-select v-model="form.sampleDeptId" placeholder="请选择送检">
  205. <el-option
  206. v-for="item in options2"
  207. :key="item.value"
  208. :label="item.label"
  209. :value="item.value"
  210. >
  211. </el-option>
  212. </el-select>
  213. </el-form-item>
  214. <el-form-item label="患者身份证号" prop="patientIdCard">
  215. <el-row type="flex" justify="space-between">
  216. <el-col :span="20">
  217. <el-select
  218. v-model="form.patientIdCard"
  219. filterable
  220. remote
  221. reserve-keyword
  222. placeholder="请输入患者身份证号"
  223. :remote-method="queryPatientInfo"
  224. :loading="patientInfoLoading"
  225. @change="handlePatientSelect"
  226. style="width: calc(100% - 20px); "
  227. >
  228. <el-option
  229. v-for="item in patientInfoOptions"
  230. :key="item.id"
  231. :label="item.label"
  232. :value="item.value"
  233. >
  234. </el-option>
  235. </el-select>
  236. </el-col>
  237. <el-col :span="4" style="text-align: right">
  238. <el-button type="primary" size="small" @click="handleAddPatient"
  239. >新增患者</el-button
  240. >
  241. </el-col>
  242. </el-row>
  243. </el-form-item>
  244. <el-form-item label="医生姓名" prop="doctorName">
  245. <el-input v-model="form.doctorName" placeholder="请输入医生姓名" />
  246. </el-form-item>
  247. <el-form-item label="备注" prop="remark">
  248. <el-input
  249. v-model="form.remark"
  250. type="textarea"
  251. placeholder="请输入内容"
  252. />
  253. </el-form-item>
  254. </el-form>
  255. <div slot="footer" class="dialog-footer">
  256. <el-button type="primary" @click="submitForm">确 定</el-button>
  257. <el-button @click="cancel">取 消</el-button>
  258. </div>
  259. </el-dialog>
  260. </div>
  261. </template>
  262. <script>
  263. import {
  264. listSampleInfo,
  265. getSampleInfo,
  266. delSampleInfo,
  267. addSampleInfo,
  268. updateSampleInfo,
  269. getSampleTypeSelect,
  270. getSampleDeptSelect,
  271. getSampleHospitalSelect,
  272. getPatientByIdCard,
  273. } from "@/api/sample/sampleInfo";
  274. export default {
  275. name: "SampleInfo",
  276. data() {
  277. return {
  278. // 遮罩层
  279. loading: true,
  280. // 选中数组
  281. ids: [],
  282. // 非单个禁用
  283. single: true,
  284. // 非多个禁用
  285. multiple: true,
  286. // 显示搜索条件
  287. showSearch: true,
  288. // 总条数
  289. total: 0,
  290. // 样本管理表格数据
  291. sampleInfoList: [],
  292. // 弹出层标题
  293. title: "",
  294. // 是否显示弹出层
  295. open: false,
  296. // 查询参数
  297. queryParams: {
  298. pageNum: 1,
  299. pageSize: 10,
  300. sampleCode: null,
  301. patientId: null,
  302. patientPhone: null,
  303. sampleTypeId: null,
  304. sampleHospitalId: null,
  305. sampleDeptId: null,
  306. doctorName: null,
  307. },
  308. patientId: null,
  309. // 表单参数
  310. form: {
  311. patientIdCard: "",
  312. },
  313. // 表单校验
  314. rules: {},
  315. options: [],
  316. options2: [],
  317. options3: [],
  318. // 患者信息下拉框选项
  319. patientInfoOptions: [],
  320. // 患者信息加载状态
  321. patientInfoLoading: false,
  322. // 防抖定时器
  323. patientInfoTimer: null,
  324. };
  325. },
  326. created() {
  327. this.patientId = this.$route.params && this.$route.params.id;
  328. this.getList();
  329. this.getSampleTypeOptions();
  330. this.getSampleDeptOptions();
  331. this.getSampleHospitalOptions();
  332. },
  333. methods: {
  334. /** 防抖查询患者信息 */
  335. queryPatientInfo(queryString) {
  336. if (this.patientInfoTimer) {
  337. clearTimeout(this.patientInfoTimer);
  338. }
  339. this.patientInfoTimer = setTimeout(() => {
  340. if (queryString.length > 0) {
  341. this.patientInfoLoading = true;
  342. getPatientByIdCard(queryString)
  343. .then((response) => {
  344. if (response.data && response.data.length > 0) {
  345. this.patientInfoOptions = response.data.map((item) => ({
  346. value: item.idCard,
  347. label: `${item.idCard}/${item.name}/${item.bahCode}/${item.createTime}`,
  348. id: item.id,
  349. }));
  350. } else {
  351. this.patientInfoOptions = [];
  352. }
  353. })
  354. .catch((error) => {
  355. console.error("查询患者信息失败:", error);
  356. this.patientInfoOptions = [];
  357. })
  358. .finally(() => {
  359. this.patientInfoLoading = false;
  360. });
  361. } else {
  362. this.patientInfoOptions = [];
  363. }
  364. }, 500);
  365. },
  366. /** 选择患者信息 */
  367. handlePatientSelect(value) {
  368. const selectedItem = this.patientInfoOptions.find(
  369. (item) => item.value === value
  370. );
  371. if (selectedItem && selectedItem.value !== "no-data") {
  372. this.form.patientId = selectedItem.id;
  373. }
  374. },
  375. handleBack() {
  376. const obj = { path: "/sample/samplePatient" };
  377. this.$tab.closeOpenPage(obj);
  378. },
  379. gojdzx(row) {
  380. this.$router.push(
  381. "/read/sampleExperiment?baseid=" + this.patientId + "&id=" + row.id
  382. );
  383. },
  384. /** 查询样本管理列表 */
  385. getList() {
  386. this.loading = true;
  387. this.queryParams.patientId = this.patientId;
  388. listSampleInfo(this.queryParams).then((response) => {
  389. this.sampleInfoList = response.rows;
  390. this.total = response.total;
  391. this.loading = false;
  392. });
  393. },
  394. // 获取样本类型选项
  395. getSampleTypeOptions() {
  396. getSampleTypeSelect().then((response) => {
  397. this.options = response.data.map((item) => ({
  398. value: item.id,
  399. label: item.name,
  400. }));
  401. });
  402. },
  403. // 获取样本类型选项
  404. getSampleDeptOptions() {
  405. getSampleDeptSelect().then((response) => {
  406. this.options2 = response.data.map((item) => ({
  407. value: item.id,
  408. label: item.name,
  409. }));
  410. });
  411. },
  412. // 获取样本类型选项
  413. getSampleHospitalOptions() {
  414. getSampleHospitalSelect().then((response) => {
  415. this.options3 = response.data.map((item) => ({
  416. value: item.id,
  417. label: item.name,
  418. }));
  419. });
  420. },
  421. // 取消按钮
  422. cancel() {
  423. this.open = false;
  424. this.reset();
  425. },
  426. // 表单重置
  427. reset() {
  428. this.form = {
  429. id: null,
  430. sampleCode: null,
  431. patientId: null,
  432. patientPhone: null,
  433. sampleTypeId: null,
  434. sampleHospitalId: null,
  435. sampleDeptId: null,
  436. doctorName: null,
  437. createBy: null,
  438. createTime: null,
  439. updateBy: null,
  440. updateTime: null,
  441. remark: null,
  442. };
  443. this.resetForm("form");
  444. },
  445. /** 搜索按钮操作 */
  446. handleQuery() {
  447. this.queryParams.pageNum = 1;
  448. this.getList();
  449. },
  450. /** 重置按钮操作 */
  451. resetQuery() {
  452. this.resetForm("queryForm");
  453. this.handleQuery();
  454. },
  455. // 多选框选中数据
  456. handleSelectionChange(selection) {
  457. this.ids = selection.map((item) => item.id);
  458. this.single = selection.length !== 1;
  459. this.multiple = !selection.length;
  460. },
  461. /** 新增按钮操作 */
  462. handleAdd() {
  463. this.reset();
  464. this.open = true;
  465. this.title = "添加样本管理";
  466. },
  467. /** 修改按钮操作 */
  468. handleUpdate(row) {
  469. this.reset();
  470. const id = row.id || this.ids;
  471. getSampleInfo(id).then((response) => {
  472. this.form = response.data;
  473. this.open = true;
  474. this.title = "修改样本管理";
  475. });
  476. },
  477. /** 提交按钮 */
  478. submitForm() {
  479. this.$refs["form"].validate((valid) => {
  480. if (valid) {
  481. if (this.form.id != null) {
  482. this.form.patientId = this.patientId;
  483. updateSampleInfo(this.form).then((response) => {
  484. this.$modal.msgSuccess("修改成功");
  485. this.open = false;
  486. this.getList();
  487. });
  488. } else {
  489. this.form.patientId = this.patientId;
  490. addSampleInfo(this.form).then((response) => {
  491. this.$modal.msgSuccess("新增成功");
  492. this.open = false;
  493. this.getList();
  494. });
  495. }
  496. }
  497. });
  498. },
  499. /** 删除按钮操作 */
  500. handleDelete(row) {
  501. const ids = row.id || this.ids;
  502. this.$modal
  503. .confirm('是否确认删除样本管理编号为"' + ids + '"的数据项?')
  504. .then(function () {
  505. return delSampleInfo(ids);
  506. })
  507. .then(() => {
  508. this.getList();
  509. this.$modal.msgSuccess("删除成功");
  510. })
  511. .catch(() => {});
  512. },
  513. /** 导出按钮操作 */
  514. handleExport() {
  515. this.download(
  516. "sample/sampleInfo/export",
  517. {
  518. ...this.queryParams,
  519. },
  520. `sampleInfo_${new Date().getTime()}.xlsx`
  521. );
  522. },
  523. /** 新增患者操作 */
  524. handleAddPatient() {
  525. this.open = false; // 关闭当前对话框
  526. this.$router.push( {
  527. path:"/sample/samplePatient",
  528. query: {
  529. openAdd: "1", // 传递一个标识,表示从样本信息页面跳转
  530. },
  531. });
  532. },
  533. },
  534. };
  535. </script>