index.vue 22 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640
  1. <template>
  2. <div class="p-2">
  3. <!-- 赛事信息展示区域 -->
  4. <div v-if="tournamentInfo" class="mb-[20px] bg-light-white p-[10px] rounded">
  5. <div>
  6. <span style="font-size: 1.2rem; font-weight: bold">{{ tournamentInfo.name }}</span>
  7. <!-- 大字体 -->
  8. <span style="font-size: 0.9rem; margin-left: 5px">({{ tournamentInfo.tournamentsBiId }})</span>
  9. <!-- 小字体,带括号 -->
  10. </div>
  11. <div>比赛时间:{{ tournamentInfo.startTime }} ~ {{ tournamentInfo.endTime }}</div>
  12. <div>参加人数:{{ tournamentInfo.signNum }}人</div>
  13. </div>
  14. <!-- 桌次信息展示区域 -->
  15. <div v-if="tableData.length > 0" class="mb-[20px]">
  16. <div class="section-title">桌次:</div>
  17. <el-scrollbar>
  18. <div class="card-container">
  19. <div
  20. v-for="(table, index) in tableData.slice(0, showMore ? tableData.length : 6)"
  21. :key="index"
  22. class="table-card"
  23. :class="{ 'selected': selectedTableId === table.tableId }"
  24. @click="handleTableClick(table)"
  25. >
  26. {{ table.tableId }}
  27. </div>
  28. </div>
  29. <div v-if="tableData.length > 6" class="more-button-container">
  30. <el-button @click="showMore = !showMore" size="small">
  31. {{ showMore ? '收起' : '更多' }}
  32. </el-button>
  33. </div>
  34. </el-scrollbar>
  35. <div class="section-title">局数:</div>
  36. <el-scrollbar>
  37. <div class="card-container">
  38. <div
  39. v-for="(table, index) in tableNumberData.slice(0, showMoreNumber ? tableNumberData.length : 6)"
  40. :key="index"
  41. class="table-card2"
  42. :class="{ 'selected': selectedTableHandNumberId === table.handNumber }"
  43. @click="handleTableNumberClick(table)"
  44. >
  45. {{ table.handNumber }}
  46. </div>
  47. </div>
  48. <div v-if="tableNumberData.length > 6" class="more-button-container">
  49. <el-button @click="showMoreNumber = !showMoreNumber" size="small">
  50. {{ showMoreNumber ? '收起' : '更多' }}
  51. </el-button>
  52. </div>
  53. </el-scrollbar>
  54. </div>
  55. <!-- <transition :enter-active-class="proxy?.animate.searchAnimate.enter" :leave-active-class="proxy?.animate.searchAnimate.leave">
  56. <div v-show="showSearch" class="mb-[10px]">
  57. <el-card shadow="hover">
  58. <el-form ref="queryFormRef" :model="queryParams" :inline="true">
  59. <el-form-item label="" prop="handId">
  60. <el-input v-model="queryParams.handId" placeholder="请输入" clearable @keyup.enter="handleQuery" />
  61. </el-form-item>
  62. <el-form-item label="" prop="tournamentId">
  63. <el-input v-model="queryParams.tournamentId" placeholder="请输入" clearable @keyup.enter="handleQuery" />
  64. </el-form-item>
  65. <el-form-item label="" prop="handNumber">
  66. <el-input v-model="queryParams.handNumber" placeholder="请输入" clearable @keyup.enter="handleQuery" />
  67. </el-form-item>
  68. <el-form-item label="" prop="boardCards">
  69. <el-input v-model="queryParams.boardCards" placeholder="请输入" clearable @keyup.enter="handleQuery" />
  70. </el-form-item>
  71. <el-form-item label="" prop="totalPot">
  72. <el-input v-model="queryParams.totalPot" placeholder="请输入" clearable @keyup.enter="handleQuery" />
  73. </el-form-item>
  74. <el-form-item label="" prop="handStartTime">
  75. <el-date-picker clearable v-model="queryParams.handStartTime" type="date" value-format="YYYY-MM-DD" placeholder="请选择" />
  76. </el-form-item>
  77. <el-form-item label="" prop="handEndTime">
  78. <el-date-picker clearable v-model="queryParams.handEndTime" type="date" value-format="YYYY-MM-DD" placeholder="请选择" />
  79. </el-form-item>
  80. <el-form-item label="" prop="createdAt">
  81. <el-date-picker clearable v-model="queryParams.createdAt" type="date" value-format="YYYY-MM-DD" placeholder="请选择" />
  82. </el-form-item>
  83. <el-form-item>
  84. <el-button type="primary" icon="Search" @click="handleQuery">搜索</el-button>
  85. <el-button icon="Refresh" @click="resetQuery">重置</el-button>
  86. </el-form-item>
  87. </el-form>
  88. </el-card>
  89. </div>
  90. </transition>-->
  91. <el-card shadow="never">
  92. <template #header>
  93. <el-row :gutter="10" class="mb8">
  94. <!-- 发牌信息显示 -->
  95. <!-- <el-col :span="24" style="font-size: 14px; color: #333; margin-bottom: 6px;">
  96. <strong>发牌信息:</strong>
  97. <span v-html="blindsInfoText"></span>
  98. </el-col>-->
  99. <el-col :span="24" style="font-size: 14px; color: #333; margin-bottom: 6px">
  100. <strong>公共牌:</strong>
  101. <span v-html="publicInfoText"></span>
  102. </el-col>
  103. <!-- <el-col :span="1.5">
  104. <el-button type="primary" plain icon="Plus" @click="handleAdd" v-hasPermi="['system:history:add']">新增</el-button>
  105. </el-col>
  106. <el-col :span="1.5">
  107. <el-button type="success" plain icon="Edit" :disabled="single" @click="handleUpdate()" v-hasPermi="['system:history:edit']"
  108. >修改</el-button
  109. >
  110. </el-col>
  111. <el-col :span="1.5">
  112. <el-button type="danger" plain icon="Delete" :disabled="multiple" @click="handleDelete()" v-hasPermi="['system:history:remove']"
  113. >删除</el-button
  114. >
  115. </el-col>
  116. <el-col :span="1.5">
  117. <el-button type="warning" plain icon="Download" @click="handleExport" v-hasPermi="['system:history:export']">导出</el-button>
  118. </el-col>-->
  119. <right-toolbar v-model:showSearch="showSearch" @queryTable="getList"></right-toolbar>
  120. </el-row>
  121. </template>
  122. <el-table v-loading="loading" border :data="historyList" @selection-change="handleSelectionChange">
  123. <!-- <el-table-column type="selection" width="55" align="center" />-->
  124. <el-table-column label="" align="center" prop="id" v-if="false" />
  125. <!-- 事件列:自定义渲染,高亮“小盲”和“大盲” -->
  126. <el-table-column label="事件" align="left">
  127. <template #default="scope">
  128. <span v-html="highlightBlinds(scope.row.operateText)"></span>
  129. </template>
  130. </el-table-column>
  131. <!-- <el-table-column label="公共牌" align="center" prop="publicBrand" />-->
  132. <!-- <el-table-column label="操作" align="center" class-name="small-padding fixed-width">
  133. &lt;!&ndash; <template #default="scope">
  134. <el-tooltip content="修改" placement="top">
  135. <el-button link type="primary" icon="Edit" @click="handleUpdate(scope.row)" v-hasPermi="['system:history:edit']"></el-button>
  136. </el-tooltip>
  137. <el-tooltip content="删除" placement="top">
  138. <el-button link type="primary" icon="Delete" @click="handleDelete(scope.row)" v-hasPermi="['system:history:remove']"></el-button>
  139. </el-tooltip>
  140. </template>&ndash;&gt;
  141. </el-table-column>-->
  142. </el-table>
  143. <pagination v-show="total > 0" :total="total" v-model:page="queryParams.pageNum" v-model:limit="queryParams.pageSize" @pagination="getList" />
  144. </el-card>
  145. <!-- 添加或修改【请填写功能名称】对话框 -->
  146. <el-dialog :title="dialog.title" v-model="dialog.visible" width="500px" append-to-body>
  147. <el-form ref="historyFormRef" :model="form" :rules="rules" label-width="80px">
  148. <el-form-item label="" prop="handId">
  149. <el-input v-model="form.handId" placeholder="请输入" />
  150. </el-form-item>
  151. <el-form-item label="" prop="tournamentId">
  152. <el-input v-model="form.tournamentId" placeholder="请输入" />
  153. </el-form-item>
  154. <el-form-item label="" prop="handNumber">
  155. <el-input v-model="form.handNumber" placeholder="请输入" />
  156. </el-form-item>
  157. <el-form-item label="" prop="boardCards">
  158. <el-input v-model="form.boardCards" placeholder="请输入" />
  159. </el-form-item>
  160. <el-form-item label="" prop="totalPot">
  161. <el-input v-model="form.totalPot" placeholder="请输入" />
  162. </el-form-item>
  163. <el-form-item label="" prop="handStartTime">
  164. <el-date-picker clearable v-model="form.handStartTime" type="datetime" value-format="YYYY-MM-DD HH:mm:ss" placeholder="请选择">
  165. </el-date-picker>
  166. </el-form-item>
  167. <el-form-item label="" prop="handEndTime">
  168. <el-date-picker clearable v-model="form.handEndTime" type="datetime" value-format="YYYY-MM-DD HH:mm:ss" placeholder="请选择">
  169. </el-date-picker>
  170. </el-form-item>
  171. <el-form-item label="" prop="createdAt">
  172. <el-date-picker clearable v-model="form.createdAt" type="datetime" value-format="YYYY-MM-DD HH:mm:ss" placeholder="请选择">
  173. </el-date-picker>
  174. </el-form-item>
  175. </el-form>
  176. <template #footer>
  177. <div class="dialog-footer">
  178. <el-button :loading="buttonLoading" type="primary" @click="submitForm">确 定</el-button>
  179. <el-button @click="cancel">取 消</el-button>
  180. </div>
  181. </template>
  182. </el-dialog>
  183. </div>
  184. </template>
  185. <script setup name="History" lang="ts">
  186. import {
  187. listHistory,
  188. getHistory,
  189. delHistory,
  190. addHistory,
  191. updateHistory,
  192. listHistory2,
  193. selectAllHandZhuoCi2,
  194. selectAllHandNumber
  195. } from '@/api/system/business/history';
  196. import { getTournaments } from '@/api/system/business/tournaments';
  197. import { HistoryVO, HistoryQuery, HistoryForm } from '@/api/system/business/history/types';
  198. const { proxy } = getCurrentInstance() as ComponentInternalInstance;
  199. const historyList = ref<HistoryVO[]>([]);
  200. const buttonLoading = ref(false);
  201. const loading = ref(true);
  202. const showSearch = ref(true);
  203. const ids = ref<Array<string | number>>([]);
  204. const single = ref(true);
  205. const multiple = ref(true);
  206. const total = ref(0);
  207. const queryFormRef = ref<ElFormInstance>();
  208. const historyFormRef = ref<ElFormInstance>();
  209. const showMore = ref(false); // 定义 showMore 状态
  210. const showMoreNumber = ref(false); // 定义 showMore 状态
  211. // 响应式变量
  212. const blindsInfoText = ref<string>('');
  213. //公共牌
  214. const publicInfoText = ref<string>('');
  215. const dialog = reactive<DialogOption>({
  216. visible: false,
  217. title: ''
  218. });
  219. const initFormData: HistoryForm = {
  220. id: undefined,
  221. handId: undefined,
  222. tournamentId: undefined,
  223. involvedPlayers: undefined,
  224. handNumber: undefined,
  225. boardCards: undefined,
  226. totalPot: undefined,
  227. handStartTime: undefined,
  228. handEndTime: undefined,
  229. handDetails: undefined,
  230. createdAt: undefined
  231. };
  232. const data = reactive<PageData<HistoryForm, HistoryQuery>>({
  233. form: { ...initFormData },
  234. queryParams: {
  235. pageNum: 1,
  236. pageSize: 10,
  237. handId: undefined,
  238. tournamentId: undefined,
  239. involvedPlayers: undefined,
  240. handNumber: undefined,
  241. boardCards: undefined,
  242. totalPot: undefined,
  243. handStartTime: undefined,
  244. handEndTime: undefined,
  245. handDetails: undefined,
  246. createdAt: undefined,
  247. historyId: undefined,
  248. params: {}
  249. },
  250. rules: {
  251. id: [{ required: true, message: '不能为空', trigger: 'blur' }],
  252. handId: [{ required: true, message: '不能为空', trigger: 'blur' }],
  253. tournamentId: [{ required: true, message: '不能为空', trigger: 'blur' }],
  254. involvedPlayers: [{ required: true, message: '不能为空', trigger: 'blur' }],
  255. handNumber: [{ required: true, message: '不能为空', trigger: 'blur' }],
  256. totalPot: [{ required: true, message: '不能为空', trigger: 'blur' }],
  257. handStartTime: [{ required: true, message: '不能为空', trigger: 'blur' }],
  258. handDetails: [{ required: true, message: '不能为空', trigger: 'blur' }],
  259. createdAt: [{ required: true, message: '不能为空', trigger: 'blur' }]
  260. }
  261. });
  262. const { queryParams, form, rules } = toRefs(data);
  263. import { useRoute } from 'vue-router';
  264. import { ref } from 'vue';
  265. import { TournamentsVO } from '@/api/system/business/tournaments/types';
  266. const route = useRoute();
  267. /** 查询【请填写功能名称】列表 */
  268. const getList = async () => {
  269. // 从 URL 参数中获取 tournamentId 和 playerId
  270. const { tournamentId, playerId } = route.query;
  271. // 设置到 queryParams 中
  272. if (tournamentId) {
  273. queryParams.value.tournamentId = String(tournamentId);
  274. }
  275. if (playerId) {
  276. //queryParams.value.playerId = String(playerId);
  277. }
  278. loading.value = true;
  279. /* queryParams.value.tournamentId = 5147;
  280. queryParams.value.historyId = 46569;*/
  281. const res = await listHistory2(queryParams.value);
  282. // ✅ 提取第一条数据的 parseBlindsInfo
  283. if (res.rows && res.rows.length > 0 && res.rows[0]?.parseBlindsInfo) {
  284. blindsInfoText.value = highlightBlinds(res.rows[0].parseBlindsInfo);
  285. } else {
  286. blindsInfoText.value = '';
  287. }
  288. if (res.rows && res.rows.length > 0 && res.rows[0]?.publicBrand) {
  289. publicInfoText.value = highlightBlinds(res.rows[0].publicBrand);
  290. } else {
  291. publicInfoText.value = '';
  292. }
  293. historyList.value = res.rows;
  294. total.value = res.total;
  295. loading.value = false;
  296. };
  297. /** 取消按钮 */
  298. const cancel = () => {
  299. reset();
  300. dialog.visible = false;
  301. };
  302. /** 表单重置 */
  303. const reset = () => {
  304. form.value = { ...initFormData };
  305. historyFormRef.value?.resetFields();
  306. };
  307. /** 搜索按钮操作 */
  308. const handleQuery = () => {
  309. queryParams.value.pageNum = 1;
  310. getList();
  311. };
  312. /** 重置按钮操作 */
  313. const resetQuery = () => {
  314. queryFormRef.value?.resetFields();
  315. handleQuery();
  316. };
  317. /** 多选框选中数据 */
  318. const handleSelectionChange = (selection: HistoryVO[]) => {
  319. ids.value = selection.map((item) => item.id);
  320. single.value = selection.length != 1;
  321. multiple.value = !selection.length;
  322. };
  323. /** 新增按钮操作 */
  324. const handleAdd = () => {
  325. reset();
  326. dialog.visible = true;
  327. dialog.title = '添加【请填写功能名称】';
  328. };
  329. /** 修改按钮操作 */
  330. const handleUpdate = async (row?: HistoryVO) => {
  331. reset();
  332. const _id = row?.id || ids.value[0];
  333. const res = await getHistory(_id);
  334. Object.assign(form.value, res.data);
  335. dialog.visible = true;
  336. dialog.title = '修改【请填写功能名称】';
  337. };
  338. /** 提交按钮 */
  339. const submitForm = () => {
  340. historyFormRef.value?.validate(async (valid: boolean) => {
  341. if (valid) {
  342. buttonLoading.value = true;
  343. if (form.value.id) {
  344. await updateHistory(form.value).finally(() => (buttonLoading.value = false));
  345. } else {
  346. await addHistory(form.value).finally(() => (buttonLoading.value = false));
  347. }
  348. proxy?.$modal.msgSuccess('操作成功');
  349. dialog.visible = false;
  350. await getList();
  351. }
  352. });
  353. };
  354. /** 删除按钮操作 */
  355. const handleDelete = async (row?: HistoryVO) => {
  356. const _ids = row?.id || ids.value;
  357. await proxy?.$modal.confirm('是否确认删除【请填写功能名称】编号为"' + _ids + '"的数据项?').finally(() => (loading.value = false));
  358. await delHistory(_ids);
  359. proxy?.$modal.msgSuccess('删除成功');
  360. await getList();
  361. };
  362. /** 导出按钮操作 */
  363. const handleExport = () => {
  364. proxy?.download(
  365. 'system/history/export',
  366. {
  367. ...queryParams.value
  368. },
  369. `history_${new Date().getTime()}.xlsx`
  370. );
  371. };
  372. const tableData = ref<any[]>([]);
  373. const tableNumberData = ref<any[]>([]);
  374. const getTableData = async (playerId: string | number, tournamentId: string | number) => {
  375. try {
  376. // 确保 playerId 和 tournamentId 为 number 类型
  377. const playerIdNum = Number(playerId);
  378. const tournamentIdNum = Number(tournamentId);
  379. if (!isNaN(playerIdNum) && !isNaN(tournamentIdNum)) {
  380. queryParams.value.tournamentId = tournamentIdNum;
  381. queryParams.value.playerId = playerIdNum;
  382. const res = await selectAllHandZhuoCi2(queryParams.value);
  383. if (res.code === 200) {
  384. tableData.value = res.data;
  385. // ✅ 默认选中第一个桌次
  386. if (tableData.value.length > 0) {
  387. const firstTable = tableData.value[0];
  388. selectedTableId.value = firstTable.tableId;
  389. //默认加载这桌下面的局数
  390. queryParams.value.tournamentId = tournamentIdNum;
  391. queryParams.value.tableId = firstTable.tableId;
  392. const res = await selectAllHandNumber(queryParams.value);
  393. tableNumberData.value = res.data;
  394. const firstHandTable = tableNumberData.value[0];
  395. selectedTableHandNumberId.value = firstHandTable.handNumber;
  396. queryParams.value.historyId = firstHandTable.id;
  397. queryParams.value.tournamentId = String(tournamentId);
  398. }
  399. }
  400. } else {
  401. console.error('Invalid playerId or tournamentId');
  402. }
  403. } catch (error) {
  404. console.error('获取桌次数据失败', error);
  405. }
  406. };
  407. const tournamentInfo = ref<Partial<TournamentsVO>>({
  408. id: '',
  409. startTime: '',
  410. endTime: '',
  411. itemsNum: 0,
  412. itemsName: '',
  413. blindStructureId: 0,
  414. blindStructuresName: '',
  415. lateRegistrationLevel: 0,
  416. tournamentsBiId: '',
  417. signNum: 0
  418. });
  419. /*onMounted(async () => {
  420. // 将回调函数定义为 async 函数
  421. // 获取 URL 参数中的 tournamentId
  422. // 获取 URL 参数中的 tournamentId 和 playerId
  423. const { tournamentId, playerId } = route.query;
  424. if (tournamentId && playerId) {
  425. // 确保 tournamentId 和 playerId 为 number 类型
  426. const playerIdNum = Number(playerId);
  427. const tournamentIdNum = Number(tournamentId);
  428. if (!isNaN(playerIdNum) && !isNaN(tournamentIdNum)) {
  429. // 调用 getTableData 方法获取桌次数据
  430. await getTableData(playerIdNum, tournamentIdNum);
  431. } else {
  432. console.error('Invalid playerId or tournamentId in URL params');
  433. }
  434. }
  435. // 确保 tournamentId 是字符串类型
  436. if (tournamentId) {
  437. let id: string | number = '';
  438. if (Array.isArray(tournamentId)) {
  439. // 如果是数组,取第一个元素
  440. id = tournamentId[0];useRoute
  441. } else {
  442. // 否则直接赋值
  443. id = tournamentId;
  444. }
  445. try {
  446. const res = await getTournaments(id);
  447. if (res.code === 200) {
  448. tournamentInfo.value = res.data;
  449. }
  450. } catch (error) {
  451. console.error('获取数据失败', error);
  452. }
  453. }
  454. // 初始化列表数据
  455. await getList(); // 如果 getList 也是异步函数,这里也使用 await
  456. });*/
  457. watch(
  458. () => route.query,
  459. async (newQuery) => {
  460. const { tournamentId, playerId } = newQuery;
  461. if (tournamentId && playerId) {
  462. const playerIdNum = Number(playerId);
  463. const tournamentIdNum = Number(tournamentId);
  464. if (!isNaN(playerIdNum) && !isNaN(tournamentIdNum)) {
  465. await getTableData(playerIdNum, tournamentIdNum);
  466. }
  467. }
  468. if (tournamentId) {
  469. const id = Array.isArray(tournamentId) ? tournamentId[0] : tournamentId;
  470. try {
  471. const res = await getTournaments(id);
  472. if (res.code === 200) {
  473. tournamentInfo.value = res.data;
  474. }
  475. } catch (error) {
  476. console.error('获取赛事信息失败', error);
  477. }
  478. }
  479. await getList();
  480. },
  481. { deep: true, immediate: true }
  482. );
  483. const selectedTableId = ref<number | null>(null);
  484. const handleTableClick = async (table: any) => {
  485. // ✅ 加上 async
  486. selectedTableId.value = table.tableId;
  487. //queryParams.value.historyId = table.id;
  488. queryParams.value.tableId = table.tableId;
  489. const tournamentId = tournamentInfo.value.id;
  490. queryParams.value.tournamentId = tournamentId;
  491. try {
  492. const res = await selectAllHandNumber(queryParams.value);
  493. console.log('请求成功', res);
  494. tableNumberData.value = [];
  495. tableNumberData.value = res.data;
  496. //加载列表
  497. const firstHandTable = tableNumberData.value[0];
  498. //选中对应的变颜色底部
  499. selectedTableHandNumberId.value = firstHandTable.handNumber; // 添加这行代码
  500. queryParams.value.historyId = firstHandTable.id;
  501. } catch (error) {
  502. console.error('请求失败:', error);
  503. // 可选:清空数据或提示用户
  504. tableNumberData.value = [];
  505. }
  506. // 如果 getList 也需要异步等待,也应加上 async/await
  507. await getList();
  508. };
  509. const selectedTableHandNumberId = ref<number | null>(null);
  510. const handleTableNumberClick = async (table: any) => {
  511. // ✅ 加上 async
  512. selectedTableId.value = table.tableId;
  513. selectedTableHandNumberId.value = table.handNumber; // 添加这行代码
  514. queryParams.value.historyId = table.id;
  515. const tournamentId = tournamentInfo.value.id;
  516. queryParams.value.tournamentId = tournamentId;
  517. try {
  518. // 如果 getList 也需要异步等待,也应加上 async/await
  519. await getList();
  520. } catch (error) {
  521. console.error('请求失败:', error);
  522. // 可选:清空数据或提示用户
  523. tableNumberData.value = [];
  524. }
  525. };
  526. // 高亮小盲、大盲
  527. function highlightBlinds(text: string): string {
  528. if (!text) return '';
  529. return text
  530. .replace(/小盲/g, '<span style="color: blue; font-weight: bold;">小盲</span>')
  531. .replace(/大盲/g, '<span style="color: red; font-weight: bold;">大盲</span>');
  532. }
  533. </script>
  534. <style scoped>
  535. .section-title {
  536. font-size: 14px;
  537. color: #333;
  538. margin-bottom: 10px;
  539. font-weight: bold;
  540. }
  541. .card-container {
  542. display: flex;
  543. flex-wrap: nowrap; /* 不换行 */
  544. gap: 8px;
  545. margin-bottom: 10px;
  546. overflow-x: auto; /* 横向滚动 */
  547. padding: 5px 0;
  548. }
  549. .table-card,
  550. .table-card2 {
  551. cursor: pointer;
  552. transition: all 0.3s ease;
  553. width: 40px;
  554. height: 40px;
  555. min-width: 40px; /* 防止压缩 */
  556. display: flex;
  557. align-items: center;
  558. justify-content: center;
  559. border-radius: 6px;
  560. box-sizing: border-box;
  561. background-color: #f5f7fa;
  562. border: 1px solid #dcdfe6;
  563. font-size: 14px;
  564. flex-shrink: 0; /* 防止压缩 */
  565. }
  566. .table-card:hover,
  567. .table-card2:hover {
  568. transform: scale(1.05);
  569. box-shadow: 0 2px 12px 0 rgba(0, 0, 0, 0.1);
  570. }
  571. .table-card.selected,
  572. .table-card2.selected {
  573. background-color: #409eff;
  574. color: white;
  575. border-color: #409eff;
  576. box-shadow: 0 2px 8px rgba(64, 158, 255, 0.3);
  577. }
  578. .more-button-container {
  579. display: flex;
  580. justify-content: center;
  581. margin-top: 5px;
  582. }
  583. /* 滚动条样式优化 */
  584. :deep(.el-scrollbar) {
  585. margin-bottom: 15px;
  586. }
  587. :deep(.el-scrollbar .el-scrollbar__wrap) {
  588. overflow-x: hidden; /* 隐藏横向滚动条,因为我们自己实现了 */
  589. }
  590. </style>