index.vue 32 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973
  1. <template>
  2. <div class="midd-page">
  3. <div class="header">
  4. <div class="h_left">
  5. <p class="current-doc">
  6. <strong>当前文献</strong>:
  7. <span style="color: #97a8be">{{ firstForm.currentDocument }}</span>
  8. </p>
  9. <div class="search-box">
  10. <p>
  11. <strong>所属标签</strong>:
  12. <el-tag
  13. v-for="(item, index) in firstForm.tag"
  14. :key="index"
  15. type=""
  16. :style="index !== 0 ? 'margin-left: 5px;' : ''"
  17. >
  18. {{ item }} </el-tag
  19. ><!-- <span style="color: #97a8be">{{
  20. firstForm.tag || '暂无标签'
  21. }}</span> -->
  22. </p>
  23. </div>
  24. </div>
  25. </div>
  26. <el-table :data="firstTableData" style="width: 100%">
  27. <!-- <el-table-column
  28. label="工作类型"
  29. prop="workType"
  30. :filters="firstForm.workTypeFilters"
  31. :filter-method="firstFilterWorkType"
  32. filter-placement="bottom-end"
  33. width="140"
  34. >
  35. <template #default="scope">
  36. <el-select
  37. v-model="scope.row.workType"
  38. placeholder="请选择"
  39. v-if="scope.row.isEdit"
  40. >
  41. <el-option label="类型1" value="type1"></el-option>
  42. <el-option label="类型2" value="type2"></el-option>
  43. <el-option label="类型3" value="type3"></el-option>
  44. </el-select>
  45. <span v-else>{{ scope.row.workType }}</span>
  46. </template>
  47. </el-table-column> -->
  48. <el-table-column
  49. label="项目"
  50. prop=""
  51. :filters="firstForm.projectFilters"
  52. :filter-method="firstFilterProject"
  53. filter-placement="bottom-end"
  54. width="140"
  55. ><!-- name -->
  56. <template #default="scope">
  57. <el-input
  58. v-model="scope.row.project_name"
  59. v-if="scope.row.isEdit"
  60. ></el-input>
  61. <span v-else>{{ scope.row.project_name }}</span>
  62. </template>
  63. </el-table-column>
  64. <el-table-column label="说明" prop="project_description"
  65. ><!-- description -->
  66. <template #default="scope">
  67. <el-input
  68. v-model="scope.row.project_description"
  69. v-if="scope.row.isEdit"
  70. ></el-input>
  71. <span v-else>{{ scope.row.project_description }}</span>
  72. </template>
  73. </el-table-column>
  74. <el-table-column label="范例" prop="project_example"
  75. ><!-- example -->
  76. <template #default="scope">
  77. <el-input
  78. v-model="scope.row.project_example"
  79. v-if="scope.row.isEdit"
  80. ></el-input>
  81. <span v-else>
  82. {{ scope.row.project_example }}
  83. <i
  84. class="el-icon-edit"
  85. @click="openExampleDialog(scope.row)"
  86. style="cursor: pointer; margin-left: 5px"
  87. ></i>
  88. </span>
  89. </template>
  90. </el-table-column>
  91. <el-table-column
  92. label="模型生成1"
  93. prop="generation_1"
  94. class-name="model-gen-1"
  95. >
  96. <template #default="scope">
  97. <el-input
  98. v-model="scope.row.generation_1"
  99. v-if="scope.row.isEdit"
  100. ></el-input>
  101. <span v-else>
  102. {{ scope.row.generation_1 }}
  103. <!-- <i
  104. class="el-icon-refresh"
  105. @click="openModel1Dialog(scope.row)"
  106. style="cursor: pointer; margin-left: 5px"
  107. ></i> -->
  108. </span>
  109. </template>
  110. </el-table-column>
  111. <el-table-column
  112. label="模型生成2"
  113. prop="generation_2"
  114. class-name="model-gen-2"
  115. >
  116. <template #default="scope">
  117. <el-input
  118. v-model="scope.row.generation_2"
  119. v-if="scope.row.isEdit"
  120. ></el-input>
  121. <span v-else>
  122. {{ scope.row.generation_2 }}
  123. <!-- <i
  124. class="el-icon-refresh"
  125. @click="openModel2Dialog(scope.row)"
  126. style="cursor: pointer; margin-left: 5px"
  127. ></i> -->
  128. </span>
  129. </template>
  130. </el-table-column>
  131. <el-table-column label="操作" width="100">
  132. <template #default="scope">
  133. <el-dropdown trigger="click">
  134. <el-button
  135. type="text"
  136. size="small"
  137. circle
  138. class="operation-button"
  139. style="font-size: 15px; margin-left: 10px"
  140. icon="el-icon-more"
  141. ></el-button>
  142. <template #dropdown>
  143. <el-dropdown-menu>
  144. <el-dropdown-item
  145. @click.native="firstHandleEdit(scope.$index, scope.row)"
  146. v-if="!scope.row.isEdit"
  147. >
  148. <i class="el-icon-edit"></i> 编辑
  149. </el-dropdown-item>
  150. <el-dropdown-item
  151. @click.native="firstHandleSave(scope.$index, scope.row)"
  152. v-if="scope.row.isEdit"
  153. >
  154. <i class="el-icon-check"></i> 保存
  155. </el-dropdown-item>
  156. <el-dropdown-item
  157. @click.native="firstHandleConfig(scope.$index, scope.row)"
  158. >
  159. <i class="el-icon-refresh"></i> 配置模型
  160. </el-dropdown-item>
  161. <!-- <el-dropdown-item
  162. @click.native="firstHandleUpload(scope.$index, scope.row)"
  163. >
  164. <i class="el-icon-refresh"></i> 更新内容
  165. </el-dropdown-item> -->
  166. <el-dropdown-item
  167. @click.native="firstHandleDelete(scope.$index, scope.row)"
  168. >
  169. <i class="el-icon-delete"></i> 删除
  170. </el-dropdown-item>
  171. </el-dropdown-menu>
  172. </template>
  173. </el-dropdown>
  174. </template>
  175. </el-table-column>
  176. </el-table>
  177. <el-dialog :visible.sync="dialogVisible" title="编辑范例" width="30%">
  178. <el-input v-model="currentExample" type="textarea" :rows="4"></el-input>
  179. <template #footer>
  180. <span class="dialog-footer">
  181. <el-button @click="dialogVisible = false">取消</el-button>
  182. <el-button type="primary" @click="saveExample">确定</el-button>
  183. </span>
  184. </template>
  185. </el-dialog>
  186. <el-dialog
  187. :visible.sync="firstForm.dialogVisible"
  188. title="内容更新"
  189. width="40%"
  190. >
  191. <!-- 应用选择 -->
  192. <el-form :model="firstForm.firstAiForm" label-width="120px">
  193. <el-form-item label="应用">
  194. <el-select
  195. v-model="firstForm.firstAiForm.application"
  196. placeholder="请选择应用"
  197. disabled
  198. >
  199. <el-option
  200. v-for="(item, index) in configArr"
  201. :key="index"
  202. :label="item.chat_name"
  203. :value="item.id"
  204. ></el-option>
  205. </el-select>
  206. </el-form-item>
  207. <!-- 字数限制 -->
  208. <el-form-item label="MAX-token数">
  209. <el-input-number
  210. v-model="firstForm.firstAiForm.wordCount"
  211. :min="1"
  212. :max="9999"
  213. placeholder="请输入字数限制"
  214. >
  215. </el-input-number>
  216. </el-form-item>
  217. <!-- 说明 -->
  218. <el-form-item label="说明">
  219. <el-input
  220. v-model="firstForm.firstAiForm.description"
  221. type="textarea"
  222. :rows="2"
  223. placeholder="请输入说明"
  224. >
  225. </el-input>
  226. </el-form-item>
  227. <!-- 提示词 -->
  228. <el-form-item label="提示词">
  229. <el-input
  230. v-model="firstForm.firstAiForm.prompt"
  231. type="textarea"
  232. :rows="3"
  233. placeholder="请输入提示词"
  234. >
  235. </el-input>
  236. </el-form-item>
  237. <!-- 生成的内容 -->
  238. <el-form-item label="生成内容">
  239. <el-input
  240. v-model="firstForm.firstAiForm.modelValue"
  241. type="textarea"
  242. :rows="4"
  243. readonly
  244. >
  245. </el-input>
  246. </el-form-item>
  247. </el-form>
  248. <template #footer>
  249. <span class="dialog-footer">
  250. <el-button @click="saveConfig">保存配置</el-button>
  251. <el-button @click="generateContent">生成内容</el-button>
  252. <el-button @click="firstForm.dialogVisible = false">取消</el-button>
  253. <el-button type="primary" @click="firstSaveExample">确定</el-button>
  254. </span>
  255. </template>
  256. </el-dialog>
  257. <!-- 配置生成 -->
  258. <el-dialog
  259. :visible.sync="firstForm.configVisible"
  260. title="配置模型"
  261. width="40%"
  262. >
  263. <el-form :model="firstForm.configForm" label-width="120px">
  264. <el-form-item label="模型1">
  265. <el-select
  266. v-model="firstForm.configForm.model_a_config"
  267. placeholder="请选择应用"
  268. >
  269. <el-option
  270. v-for="(item, index) in configArr"
  271. :key="index"
  272. :label="item.chat_name"
  273. :value="item.id"
  274. ></el-option>
  275. </el-select>
  276. </el-form-item>
  277. <el-form-item label="模型2">
  278. <el-select
  279. v-model="firstForm.configForm.model_b_config"
  280. placeholder="请选择应用"
  281. >
  282. <el-option
  283. v-for="(item, index) in configArr"
  284. :key="index"
  285. :label="item.chat_name"
  286. :value="item.id"
  287. ></el-option>
  288. </el-select>
  289. </el-form-item>
  290. <!-- 字数限制 -->
  291. <el-form-item label="MAX-token数">
  292. <el-input-number
  293. v-model="firstForm.configForm.max_tokens"
  294. :min="1"
  295. :max="2048"
  296. placeholder="请输入字数限制"
  297. >
  298. </el-input-number>
  299. </el-form-item>
  300. <!-- 说明 -->
  301. <el-form-item label="说明">
  302. <el-input
  303. v-model="firstForm.configForm.project_description"
  304. type="textarea"
  305. :rows="2"
  306. placeholder="请输入说明"
  307. >
  308. </el-input>
  309. </el-form-item>
  310. <!-- 提示词 -->
  311. <el-form-item label="提示词">
  312. <el-input
  313. v-model="firstForm.configForm.project_name"
  314. type="textarea"
  315. :rows="3"
  316. placeholder="请输入提示词"
  317. >
  318. </el-input>
  319. </el-form-item>
  320. <!-- 生成方法 -->
  321. <el-form-item label="生成方法">
  322. <el-input
  323. v-model="firstForm.configForm.generation_method"
  324. type="textarea"
  325. :rows="3"
  326. placeholder="请输入生成方法"
  327. >
  328. </el-input>
  329. </el-form-item>
  330. </el-form>
  331. <template #footer>
  332. <span class="dialog-footer">
  333. <el-button @click="firstForm.dialogVisible = false">取消</el-button>
  334. <el-button @click="saveConfig" type="primary">保存配置</el-button>
  335. </span>
  336. </template>
  337. </el-dialog>
  338. </div>
  339. </template>
  340. <script>
  341. import {
  342. getDetail,
  343. saveConfig,
  344. configList,
  345. listProConfig,
  346. updateConfig,
  347. deleteConfig,
  348. } from "@/api/knowledge";
  349. export default {
  350. name: "MiddPage",
  351. data() {
  352. return {
  353. activeName: "first",
  354. firstForm: {
  355. tableData: [
  356. /* {
  357. workType: "复制",
  358. project: "indication",
  359. description:
  360. "器械在文献中使用的适应症,按照器械分析,也需要添加器械使用部位以区分",
  361. example: "t1d: n=191;",
  362. model1: "t1d: n=191;",
  363. model2: "t1d: n=191;",
  364. isEdit: false,
  365. },
  366. {
  367. workType: "总结",
  368. project: "Study Design/ Method",
  369. description:
  370. "患者/试验者的人种,国家地区,以查阅是否存在数据上人种差异",
  371. example:
  372. "white non-hispanic: n=247;african american:n=25;hispanic or latino: n=34",
  373. model1:
  374. "white non-hispanic: n=247;african american:n=25;hispanic or latino: n=34",
  375. model2:
  376. "white non-hispanic: n=247;african american:n=25;hispanic or latino: n=34",
  377. isEdit: false,
  378. },
  379. {
  380. workType: "总结和数据提取;",
  381. project: "Alternative device(treatment)",
  382. description:
  383. "Device name + model name如无,可写疗法(以评价的器械的替代疗法)",
  384. example:
  385. "Capillary blood by BMG;Venous blood by YSI(此处为CGM的替代疗法)",
  386. model1:
  387. "Capillary blood by BMG;Venous blood by YSI(此处为CGM的替代疗法)",
  388. model2:
  389. "Capillary blood by BMG;Venous blood by YSI(此处为CGM的替代疗法)",
  390. isEdit: false,
  391. }, */
  392. ],
  393. workTypeFilters: [
  394. { text: "类型1", value: "type1" },
  395. { text: "类型2", value: "type2" },
  396. { text: "类型3", value: "type3" },
  397. ],
  398. projectFilters: [],
  399. activeFilters: {
  400. workType: [],
  401. project: [],
  402. },
  403. dialogVisible: false,
  404. configVisible: false,
  405. firstAiForm: {
  406. application: "",
  407. wordCount: 100,
  408. description: "",
  409. prompt: "",
  410. modelValue: "",
  411. },
  412. /* 配置应用表单 */
  413. configForm: {
  414. id: "",
  415. project_name: "提取第一作者",
  416. max_tokens: 1024,
  417. project_description: "从文献中提取第一作者信息,并进行格式化处理",
  418. generation_method: "extract_first_author",
  419. model_a_config: 20,
  420. model_b_config: 22,
  421. project_example: "",
  422. },
  423. currentDocument: "AED数据表", // 当前文档名称
  424. tag: [],
  425. searchQuery: "", // 搜索关键词
  426. currentPage: 1, // 当前页码
  427. pageSize: 10, // 每页显示条数
  428. total: 3, // 总条数
  429. },
  430. /* secondForm: {
  431. tableData: [
  432. {
  433. workType: "SOTA-E1-01",
  434. project: "Ultrasounic knife",
  435. description: "Pain: VAS (day3)",
  436. example: "37",
  437. isEdit: false,
  438. },
  439. {
  440. workType: "SOTA-E1-02",
  441. project: "EqMD",
  442. description: "Quality of life: xx scale (week 2)",
  443. example: "66",
  444. isEdit: false,
  445. },
  446. {
  447. workType: "SOTA-E1-03",
  448. project: "EqMD",
  449. description: "Pain: VAS (day7)",
  450. example: "35",
  451. isEdit: false,
  452. },
  453. ],
  454. workTypeFilters: [
  455. { text: "类型1", value: "type1" },
  456. { text: "类型2", value: "type2" },
  457. { text: "类型3", value: "type3" },
  458. ],
  459. projectFilters: [],
  460. activeFilters: {
  461. workType: [],
  462. project: [],
  463. },
  464. },
  465. thirdForm: {
  466. tableData: [
  467. {
  468. workType: "SOTA-E1-01",
  469. project: "EqMD",
  470. description: "Pain: VAS (day3)",
  471. example: "t1d: n=191;",
  472. isEdit: false,
  473. },
  474. {
  475. workType: "SOTA-E1-02",
  476. project: "EqMD",
  477. description: "Pain: VAS (day3)",
  478. example:
  479. "white non-hispanic: n=247;african american:n=25;hispanic or latino: n=34",
  480. isEdit: false,
  481. },
  482. ],
  483. workTypeFilters: [
  484. { text: "类型1", value: "type1" },
  485. { text: "类型2", value: "type2" },
  486. { text: "类型3", value: "type3" },
  487. ],
  488. projectFilters: [],
  489. activeFilters: {
  490. workType: [],
  491. project: [],
  492. },
  493. }, */
  494. configArr: [],
  495. dialogVisible: false,
  496. currentExample: "",
  497. currentRow: null,
  498. };
  499. },
  500. computed: {
  501. firstTableData() {
  502. return this.firstForm.tableData.filter((data) => {
  503. return (
  504. (!this.firstForm.activeFilters.workType.length ||
  505. this.firstForm.activeFilters.workType.includes(data.workType)) &&
  506. (!this.firstForm.activeFilters.project.length ||
  507. this.firstForm.activeFilters.project.includes(data.project))
  508. );
  509. });
  510. },
  511. },
  512. mounted() {
  513. this.firstForm.currentDocument = this.$route.query.name;
  514. this.firstForm.tag = JSON.parse(this.$route.query.tag);
  515. this.firstInit();
  516. this.updateProjectFilters();
  517. },
  518. methods: {
  519. /* 配置模型 */
  520. firstHandleConfig(index, row) {
  521. this.firstForm.configForm = row;
  522. this.firstForm.configForm.model_a_config = row.model_a_config.id;
  523. this.firstForm.configForm.model_b_config = row.model_b_config.id;
  524. /* this.firstForm.configForm.id=row.id
  525. this.firstForm.configForm.project_description = row.description; */
  526. this.firstForm.configVisible = true;
  527. },
  528. /* 保存配置JSON.stringify() */
  529. saveConfig() {
  530. if (!this.firstForm.configForm.id) {
  531. saveConfig(this.firstForm.configForm).then((res) => {
  532. if (res.status !== 200) return;
  533. this.firstForm.configVisible = false;
  534. });
  535. } else {
  536. updateConfig(this.firstForm.configForm).then((res) => {
  537. if (res.status !== 200) return;
  538. this.firstForm.configVisible = false;
  539. this.$message.success("修改成功!");
  540. });
  541. }
  542. },
  543. /* AED数据表(第一) 操作事件*/
  544. openExampleDialog(row) {
  545. this.dialogVisible = true;
  546. this.currentRow = row;
  547. this.currentExample = row.project_example; // 将当前行的范例赋值给弹窗输入框
  548. },
  549. saveExample() {
  550. if (this.currentRow && this.currentExample) {
  551. // 更新当前行的范例内容
  552. this.currentRow.project_example = this.currentExample;
  553. // 如果需要同步更新到后端,可以调用更新API
  554. updateConfig({
  555. ...this.currentRow,
  556. project_example: this.currentExample,
  557. }).then((res) => {
  558. if (res.status === 200) {
  559. this.$message.success("范例更新成功");
  560. this.firstInit();
  561. }
  562. });
  563. }
  564. this.dialogVisible = false;
  565. this.currentRow = null;
  566. this.currentExample = "";
  567. },
  568. /* 生成内容 */
  569. // 更新内容处理方法
  570. firstHandleUpload(index, row) {
  571. // 这里假设你有一个获取更新内容的API
  572. const updatedContent = this.getUpdatedContent(row);
  573. // 更新两个模型的内容
  574. this.$set(row, "model1", updatedContent.model1);
  575. this.$set(row, "model2", updatedContent.model2);
  576. // 可以添加提示
  577. this.$message({
  578. type: "success",
  579. message: "内容已更新",
  580. });
  581. },
  582. // 打开模型1对话框
  583. openModel1Dialog(row) {
  584. this.firstForm.firstAiForm.application = "app1";
  585. this.firstForm.firstAiForm.description = row.description;
  586. this.firstForm.dialogVisible = true;
  587. },
  588. // 打开模型2对话框
  589. openModel2Dialog(row) {
  590. this.firstForm.firstAiForm.application = "app2";
  591. this.firstForm.firstAiForm.description = row.description;
  592. this.firstForm.dialogVisible = true;
  593. },
  594. // 获取更新内容的方法(需要根据实际API进行修改)
  595. getUpdatedContent(row) {
  596. // 这里应该调用实际的API
  597. return {
  598. model1: "更新后的模型1内容",
  599. model2: "更新后的模型2内容",
  600. };
  601. },
  602. async generateContent() {
  603. try {
  604. // 这里替换为实际的API调用
  605. const response = await this.yourApiCall({
  606. application: this.firstForm.firstAiForm.application,
  607. wordCount: this.firstForm.firstAiForm.wordCount,
  608. description: this.firstForm.firstAiForm.description,
  609. prompt: this.firstForm.firstAiForm.prompt,
  610. });
  611. // 将获取的内容更新到modelValue
  612. this.firstForm.firstAiForm.modelValue = response.data;
  613. // 注意这里不关闭弹窗
  614. } catch (error) {
  615. this.$message.error("生成内容失败");
  616. }
  617. },
  618. /* 内容更新确定 */
  619. firstSaveExample() {
  620. this.firstForm.dialogVisible = false;
  621. },
  622. firstHandleUpload(index, row) {
  623. this.firstForm.dialogVisible = true;
  624. },
  625. firstHandleEdit(index, row) {
  626. this.firstForm.configForm = row;
  627. this.firstForm.configForm.model_a_config = row.model_a_config.id;
  628. this.firstForm.configForm.model_b_config = row.model_b_config.id;
  629. row.isEdit = true;
  630. },
  631. firstHandleSave(index, row) {
  632. row.isEdit = false;
  633. updateConfig(this.firstForm.configForm).then((res) => {
  634. if (res.status !== 200) return;
  635. this.$message.success("修改成功!");
  636. this.firstInit();
  637. });
  638. // 在这里可以添加保存到后端的逻辑
  639. },
  640. // 修改删除方法
  641. async firstHandleDelete(index, row) {
  642. try {
  643. await this.$confirm("确认删除该记录?", "提示", {
  644. confirmButtonText: "确定",
  645. cancelButtonText: "取消",
  646. type: "warning",
  647. });
  648. const res = await deleteConfig({ id: row.id });
  649. if (res.status === 200) {
  650. this.$message.success("删除成功");
  651. this.firstInit(); // 重新加载数据
  652. }
  653. } catch (error) {
  654. if (error !== "cancel") {
  655. this.$message.error("删除失败");
  656. }
  657. }
  658. },
  659. firstHandleAdd() {
  660. this.firstForm.tableData.push({
  661. workType: "",
  662. project: "",
  663. description: "",
  664. example: "",
  665. isEdit: true,
  666. });
  667. },
  668. firstFilterWorkType(value, row) {
  669. return row.workType === value;
  670. },
  671. firstFilterProject(value, row) {
  672. return row.project === value;
  673. },
  674. updateProjectFilters() {
  675. const projects = [
  676. ...new Set(this.firstForm.tableData.map((item) => item.project)),
  677. ];
  678. this.projectFilters = projects.map((project) => ({
  679. text: project,
  680. value: project,
  681. }));
  682. },
  683. /* 搜索逻辑 */
  684. handleSearch() {
  685. // 实现搜索逻辑
  686. const query = this.firstForm.searchQuery.toLowerCase();
  687. const filteredData = this.firstForm.tableData.filter((item) => {
  688. return Object.values(item).some((value) =>
  689. String(value).toLowerCase().includes(query)
  690. );
  691. });
  692. this.total = filteredData.length;
  693. // 更新表格数据
  694. },
  695. handleSearchClear() {
  696. this.firstForm.searchQuery = "";
  697. this.handleSearch();
  698. },
  699. handleSizeChange(val) {
  700. this.firstForm.pageSize = val;
  701. this.handleSearch();
  702. },
  703. handleCurrentChange(val) {
  704. this.firstForm.currentPage = val;
  705. this.handleSearch();
  706. },
  707. handleClick() {},
  708. /* 获取详细信息 */
  709. async firstInit() {
  710. /* 获取配置信息 */
  711. listProConfig().then((res) => {
  712. if (res.status !== 200) return;
  713. res.data.data.map((el) => {
  714. el.isEdit = false;
  715. });
  716. this.firstForm.tableData = res.data.data;
  717. });
  718. /* 应用列表 */
  719. configList().then((res) => {
  720. if (res.status !== 200) return;
  721. this.configArr = res.data;
  722. });
  723. /* const res = await getDetail({ id: this.$route.query.id });
  724. // 定义字段映射关系
  725. const fieldMappings = {
  726. identifier: {
  727. description: "SOTA-Xx-Xx",
  728. example: "文献唯一标识符",
  729. },
  730. literature_type: {
  731. description:
  732. "1-Meta-Analysis 2-Systematic Review(Systematic Review有非常严格的检索、选择、评价标准)3-Review 4-Randomized Controlled Trials 5-Cohort Study 6-Case-Report 7-Background Information/Expert Opinion 8-Animal Research/Lab Studies 可以从文献的:标题(1,2在标题出现的概率高),abstract,method中识别文献类型",
  733. example: "4-Randomized Controlled Trials",
  734. },
  735. first_author: {
  736. description: "第一作者",
  737. example: "",
  738. },
  739. study_design: {
  740. description:
  741. "可以从文献的method部分提取实验设计/方法可以是Randomized controlled方式.文献搜索,数据库提取文献,干预分组……",
  742. example:
  743. "searched Medline, Embase, the Web of Science, and the Cochrane Library for randomized trials and observational studies",
  744. },
  745. population: {
  746. description:
  747. "Population information; including: patient quantify(N, N of male/female); age(mean,range) Adult/children eg:60 adults with T1D (mean age 38years), 20 male",
  748. example:
  749. "Type II Diabetes: n=10282 Age: ≥18 years; Naive to CGM; Between 2017 to 2019",
  750. },
  751. region_country: {
  752. description:
  753. "患者/试验者的人种,国家地区,以查阅是否存在数据上人种差异",
  754. example:
  755. "white non-hispanic: n=247; african american:n=25; hispanic or latino: n=34",
  756. },
  757. indication: {
  758. description:
  759. "器械在文献中使用的适应症,按照器械分析,也需要添加器械使用部位以区分",
  760. example: "t1d: n=191;t2d: n=152;",
  761. },
  762. intervention: {
  763. description:
  764. "Group 1: xx; Group 2: xx 写清对照组和实验组分组的情况,如:有无干预,分适应症,分部位……",
  765. example:
  766. "CGM(N=XX) vs. SMBG(N=XX); CGM (N=XX) vs. venous blood glucose test(N=XX); CGM+SMBG(N=XX) vs. SMBG(N=XX)",
  767. },
  768. subject_device: {
  769. description:
  770. "Device name + model name 如无,可写疗法(以评价的器械所用疗法为主)",
  771. example: "Dexcom G6(此处为CGM器械名字)",
  772. },
  773. alternative_device: {
  774. description:
  775. "Device name + model name 如无,可写疗法(以评价的器械的替代疗法)",
  776. example:
  777. "Capillary blood by BMG; Venous blood by YSI (此处为CGM的替代疗法)",
  778. },
  779. outcomes: {
  780. description: "Scope: tools (follow-up); such as 'Pain: VAS (day 3)'",
  781. example: "a1c;tir;tbr;tar",
  782. },
  783. risk_adverse_event: {
  784. description: "Type of side effect",
  785. example: "Serious Hypoglycemia (SH);Diabetic Ketoacidosis (DKA)",
  786. },
  787. follow_up: {
  788. description: "随访时间",
  789. example: "8 weeks",
  790. },
  791. clinical_benefit: {
  792. description:
  793. "临床收益(文献中提到研究器械的好处,或者可以达到什么效果,可以摘抄过来可以从result,discussion中提取detailed can be refer to MEDDEV 2.7.1 rev4,b. Evaluation of the device’s benefits to the patient",
  794. example:
  795. "the pediatric age span who used a CGM have improved glycemic control compared with patients who did patients who use insulin pumps along with CGM did achieve a lower HbA1c and better CGM metrics compared with the reference groups.",
  796. },
  797. disadvantage: {
  798. description:
  799. "临床劣势(文献中提到研究器械的劣势,比如在什么情况下疗效不好)eg:导致出血,导致uncomfortable,导致预后不好……可以从result,discussion中提取",
  800. example: "/",
  801. },
  802. conclusion: {
  803. description: "结论",
  804. example:
  805. "CGM use was associated with a lower HbA1c in both MDI and pump users. Pump use was only associated with a lower HbA1c if used with CGM. HCL was associated with the lowest HbA1c. Spanish language and minority race/ethnicity were associated with lower rates of pump and CGM use, highlighting the need to reduce disparities.",
  806. },
  807. clinical_guidelines: {
  808. description: "识别文献中提到的临床实践指南",
  809. example: "",
  810. },
  811. clinical_background: {
  812. description: "描述有关器械的临床背景,包括发展的概述等",
  813. example: "",
  814. },
  815. medical_field: {
  816. description:
  817. "识别该器械是用于哪个医疗领域?例如骨科,外科,牙科,放射诊断等,包括已确定的医疗领域的历史方面的概述",
  818. example: "",
  819. },
  820. associated_conditions: {
  821. description:
  822. "1 讨论该设备拟治疗的疾病的所有方面,包括但不限于流行病学、发病机制、临床表现和共病2 临床条件的描述,如:2.1 自然病程和结果。2.2 医疗条件是否有不同的临床方式、阶段和严重性。2.3 总体人群中的频率,通过年龄、性别、种族划分,熟悉的诱因、遗传方面等。",
  823. example: "",
  824. },
  825. suitability_criteria: {
  826. description:
  827. "D1 Actual device D2 Equivalent device D3 Other device A1 Same use A2 Minor deviation A3 Major deviation P1 Applicable P2 Limited P3 Different population R1 High quality R2 Minor deficiencies R3 Insufficient information",
  828. example: "D2,A1,P1,R1",
  829. },
  830. contribution_criteria: {
  831. description:
  832. "1 Yes; 2 No T:Was the design of the study appropriate? O:Do the outcome measures reported reflect the intended purpose of the device? F:Is the duration of the follow-up long enough to access whether duration of treatment effects and identify complications? S:Has a statistical analysis of the data been provided and is it appropriate? C:Was the magnitude of the treatment effect observed clinically significant? ",
  833. example: "T1,O1,F1,S1,C1",
  834. },
  835. oxford_evidence: {
  836. description:
  837. "根据Literature type,对照Oxford Centre for Evidence-Based Medicine, Levels of Evidence (2011)填写基本level 1:Systematic review of randomized trials level 2:Randomized trial or observational study level 3:Non-randomized controlled cohort/follow-upstudy (PMS) level 4:Case report level 5:Mechanism-based reasoning",
  838. example: "level 2",
  839. },
  840. overall_quality: {
  841. description:
  842. "将前面数字加起来的总和 9-14 Accepted and Pivotal 15-23 Accepted but not Pivotal 24-27 Excluded",
  843. example: "12",
  844. },
  845. };
  846. // Transform data into array of objects with name property
  847. const processedData = Object.entries(res.data.data.datalist)
  848. .filter(([key]) => !["id", "create_time", "update_time"].includes(key))
  849. .map(([key]) => ({
  850. name: key,
  851. isEdit: false,
  852. description: fieldMappings[key]?.description || "",
  853. example: fieldMappings[key]?.example || "",
  854. generation_1: "", // 为模型生成1预留空间
  855. generation_2: "", // 为模型生成2预留空间
  856. }));
  857. this.firstForm.tableData = processedData; */
  858. },
  859. },
  860. watch: {
  861. tableData: {
  862. handler() {
  863. this.updateProjectFilters();
  864. },
  865. deep: true,
  866. },
  867. },
  868. };
  869. </script>
  870. <style scoped>
  871. .midd-page {
  872. padding: 20px;
  873. }
  874. .el-icon-edit {
  875. font-size: 14px;
  876. color: #409eff;
  877. }
  878. /* 浅蓝色背景 */
  879. ::v-deep .model-gen-1 {
  880. background-color: #e6f3ff !important;
  881. }
  882. ::v-deep .model-gen-1.el-table__cell {
  883. background-color: #e6f3ff !important;
  884. color: #333333 !important; /* 深色文字确保可读性 */
  885. }
  886. /* 浅紫色背景 */
  887. ::v-deep .model-gen-2 {
  888. background-color: #f0e6ff !important;
  889. }
  890. ::v-deep .model-gen-2.el-table__cell {
  891. background-color: #f0e6ff !important;
  892. color: #333333 !important; /* 深色文字确保可读性 */
  893. }
  894. .header {
  895. display: flex;
  896. justify-content: space-between;
  897. align-items: center;
  898. margin: 15px 0;
  899. }
  900. .h_left p {
  901. margin-top: 0px;
  902. }
  903. .search-container {
  904. display: flex;
  905. justify-content: center;
  906. align-items: center;
  907. }
  908. .search-box {
  909. width: 350px; /* 可以根据需要调整宽度 */
  910. }
  911. /* 自定义输入框样式 */
  912. .custom-search-input :deep(.el-input__inner) {
  913. height: 40px;
  914. line-height: 40px;
  915. border-right: none;
  916. border-radius: 4px 0 0 4px;
  917. }
  918. /* 自定义搜索按钮样式 */
  919. .custom-search-input :deep(.el-input-group__append) {
  920. padding: 0;
  921. border: none;
  922. background-color: transparent;
  923. }
  924. .custom-search-input :deep(.el-input-group__append .el-button) {
  925. height: 40px;
  926. padding: 0 20px;
  927. border-radius: 0 4px 4px 0;
  928. margin: 0;
  929. }
  930. /* 悬停效果 */
  931. .custom-search-input :deep(.el-input__inner:hover) {
  932. border-color: #dcdfe6;
  933. }
  934. .custom-search-input :deep(.el-input__inner:focus) {
  935. border-color: #409eff;
  936. }
  937. </style>