yanghao 2 dni temu
rodzic
commit
673c555c6a
2 zmienionych plików z 239 dodań i 0 usunięć
  1. 234 0
      src/views/expert/list/index.vue
  2. 5 0
      src/views/expert/team/index.vue

+ 234 - 0
src/views/expert/list/index.vue

@@ -0,0 +1,234 @@
+<template>
+  <div class="expert-step-table">
+    <div class="table-title">专家梯队示例</div>
+
+    <div class="table-list">
+      <table
+        v-for="row in tableData"
+        :key="row.teamName"
+        class="ladder-row-table"
+        :style="{ width: row.tableWidth }"
+      >
+        <colgroup>
+          <col :style="{ width: row.teamWidth }" />
+          <col
+            v-for="(_, index) in row.columnWidths"
+            :key="index"
+            :style="{ width: `${getColumnPercent(row, index)}%` }"
+          />
+        </colgroup>
+
+        <tbody>
+          <tr>
+            <td class="team-cell">{{ row.teamName }}</td>
+
+            <td v-for="(cell, index) in row.cells" :key="index" class="step-cell">
+              <template v-if="cell.type === 'members'">
+                <button
+                  v-for="member in cell.members"
+                  :key="member"
+                  type="button"
+                  class="member-link"
+                  @click="handleMemberClick(member)"
+                >
+                  {{ member }}
+                </button>
+              </template>
+
+              <span v-else :class="['cell-text', cell.tone === 'danger' ? 'is-danger' : '']">
+                {{ cell.text }}
+              </span>
+            </td>
+          </tr>
+        </tbody>
+      </table>
+    </div>
+
+    <div v-if="selectedMember" class="member-detail"> 当前查看人员:{{ selectedMember }} </div>
+  </div>
+</template>
+
+<script setup lang="ts">
+import { ref } from 'vue'
+
+type CellItem =
+  | {
+      type: 'members'
+      members: string[]
+    }
+  | {
+      type: 'text'
+      text: string
+      tone?: 'normal' | 'danger'
+    }
+
+type TableRow = {
+  teamName: string
+  tableWidth: string
+  teamWidth: string
+  columnWidths: number[]
+  cells: CellItem[]
+}
+
+const tableData: TableRow[] = [
+  {
+    teamName: '第一梯队',
+    tableWidth: '64%',
+    teamWidth: '90px',
+    columnWidths: [1, 1, 1, 1, 1],
+    cells: [
+      { type: 'members', members: ['朱桂林', '孙乐臻', '王军', '钟国伟', '李伟伟', '张伟伟'] },
+      { type: 'text', text: '' },
+      { type: 'text', text: '' },
+
+      { type: 'text', text: '' }
+    ]
+  },
+  {
+    teamName: '第二梯队',
+    tableWidth: '75%',
+    teamWidth: '90px',
+    columnWidths: [1.5, 1.5, 1.5, 1.5, 1.5],
+    cells: [
+      { type: 'members', members: ['朱桂林', '孙乐臻', '王军', '钟国伟', '李伟伟', '张伟伟'] },
+      { type: 'text', text: '' },
+      { type: 'text', text: '' },
+      { type: 'text', text: '' },
+      { type: 'text', text: '' }
+    ]
+  },
+  {
+    teamName: '第三梯队',
+    tableWidth: '100%',
+    teamWidth: '90px',
+    columnWidths: [1.8, 1.8, 1.8, 1.8, 1.8],
+    cells: [
+      {
+        type: 'members',
+        members: [
+          '朱桂林',
+          '孙乐臻',
+          '王军',
+          '钟国伟',
+          '李伟伟',
+          '张伟伟',
+          '张三',
+          '李四',
+          '王五',
+          '赵六',
+          '钱七',
+          '孙八',
+          '周九',
+          '吴十'
+        ]
+      },
+      { type: 'text', text: '' },
+      { type: 'text', text: '' },
+      { type: 'text', text: '' },
+      { type: 'text', text: '' }
+    ]
+  }
+]
+
+const selectedMember = ref('')
+
+const getColumnPercent = (row: TableRow, index: number) => {
+  const total = row.columnWidths.reduce((sum, width) => sum + width, 0)
+
+  return ((row.columnWidths[index] / total) * 100).toFixed(4)
+}
+
+const handleMemberClick = (member: string) => {
+  selectedMember.value = member
+}
+</script>
+
+<style scoped lang="scss">
+.expert-step-table {
+  width: 100%;
+  padding: 24px;
+  overflow: hidden;
+  box-sizing: border-box;
+  background: #f5f7fa;
+}
+
+.table-title {
+  margin-bottom: 16px;
+  font-size: 18px;
+  font-weight: 600;
+  color: #1f2937;
+}
+
+.table-list {
+  width: 100%;
+  overflow: hidden;
+}
+
+.ladder-row-table {
+  max-width: 100%;
+  margin: 0;
+  table-layout: fixed;
+  border-collapse: collapse;
+  border-spacing: 0;
+  background: #fff;
+}
+
+.ladder-row-table + .ladder-row-table {
+  border-top: 0;
+}
+
+.ladder-row-table td {
+  height: 78px;
+  padding: 12px;
+  border: 1px solid #303030;
+  box-sizing: border-box;
+}
+
+.team-cell {
+  text-align: center;
+  font-weight: 600;
+  white-space: nowrap;
+}
+
+.step-cell {
+  text-align: center;
+  vertical-align: middle;
+  overflow-wrap: anywhere;
+  word-break: break-all;
+}
+
+.member-link {
+  display: inline;
+  margin: 0 3px;
+  padding: 0;
+  border: 0;
+  background: transparent;
+  color: #409eff;
+  cursor: pointer;
+  font: inherit;
+  line-height: 1.8;
+}
+
+.member-link:hover {
+  color: #66b1ff;
+  text-decoration: underline;
+}
+
+.cell-text {
+  color: #303133;
+  line-height: 1.7;
+}
+
+.is-danger {
+  color: #f56c6c;
+}
+
+.member-detail {
+  display: inline-block;
+  margin-top: 16px;
+  padding: 8px 12px;
+  border: 1px solid #dcdfe6;
+  background: #fff;
+  color: #606266;
+}
+</style>

+ 5 - 0
src/views/expert/team/index.vue

@@ -0,0 +1,5 @@
+<template>
+  <div class="list"> team </div>
+</template>
+
+<script setup></script>