flyzto 4 semanas atrás
pai
commit
cedfd7457e

+ 24 - 3
web/apps/web-antd/src/views/match/components/match_card.vue

@@ -42,6 +42,10 @@ defineProps({
     type: Array,
     required: false
   },
+  iorGroups: {
+    type: Array,
+    required: false
+  },
 })
 </script>
 
@@ -58,15 +62,27 @@ defineProps({
           <tr v-for="item in events">
             <th>{{ parseEventKey(item[0]) }}</th>
             <td>
-              <span :class="{'selected': selected.includes(item[1]?.key), 'strikethrough': item[1]?.qualified === 0}">{{ item[1]?.value ? item[1].value : '-' }}</span>
+              <span :class="{
+                'selected': selected.includes(item[1]?.key),
+                'highlight': iorGroups?.includes(item[1]?.key),
+                'strikethrough': item[1]?.qualified === 0
+              }">{{ item[1]?.value ? item[1].value : '-' }}</span>
               <em v-if="item[1]?.origin">{{ item[1].origin }}</em>
             </td>
             <td>
-              <span :class="{'selected': selected.includes(item[2]?.key), 'strikethrough': item[2]?.qualified === 0}">{{ item[2]?.value ? item[2].value : '-' }}</span>
+              <span :class="{
+                'selected': selected.includes(item[2]?.key),
+                'highlight': iorGroups?.includes(item[2]?.key),
+                'strikethrough': item[2]?.qualified === 0
+              }">{{ item[2]?.value ? item[2].value : '-' }}</span>
               <em v-if="item[2]?.origin">{{ item[2].origin }}</em>
             </td>
             <td>
-              <span :class="{'selected': selected.includes(item[3]?.key), 'strikethrough': item[3]?.qualified === 0}">{{ item[3]?.value ? item[3].value : '-' }}</span>
+              <span :class="{
+                'selected': selected.includes(item[3]?.key),
+                'highlight': iorGroups?.includes(item[3]?.key),
+                'strikethrough': item[3]?.qualified === 0
+              }">{{ item[3]?.value ? item[3].value : '-' }}</span>
               <em v-if="item[3]?.origin">{{ item[3].origin }}</em>
             </td>
           </tr>
@@ -152,6 +168,11 @@ defineProps({
         text-decoration: line-through;
         color: hsl(var(--foreground) / 0.35);
       }
+      &.highlight {
+        border-radius: 4px;
+        background-color: hsl(var(--primary) / 0.15);
+        color: hsl(var(--primary));
+      }
       &.selected {
         border-radius: 4px;
         background-color: hsl(var(--primary));

+ 92 - 61
web/apps/web-antd/src/views/match/components/solution_item.vue

@@ -35,30 +35,52 @@ const emit = defineEmits(['toggle']);
 
 const selectedIndex = ref(0);
 
-const PS_IOR_KEYS = [
-  ['0', 'ior_mh', 'ior_mn', 'ior_mc'],
-  ['-1', 'ior_rh_15', 'ior_wmh_1', 'ior_rac_05'],
-  ['-2', 'ior_rh_25', 'ior_wmh_2', 'ior_rac_15'],
-  ['-3', 'ior_rh_35', 'ior_wmh_3', 'ior_rac_25'],
-  // ['-4', 'ior_rh_45', 'ior_wmh_4', 'ior_rac_35'],
-  // ['-5', 'ior_rh_55', 'ior_wmh_5', 'ior_rac_45'],
-  ['+1', 'ior_rah_05', 'ior_wmc_1', 'ior_rc_15'],
-  ['+2', 'ior_rah_15', 'ior_wmc_2', 'ior_rc_25'],
-  ['+3', 'ior_rah_25', 'ior_wmc_3', 'ior_rc_35'],
-  // ['+4', 'ior_rah_35', 'ior_wmc_4', 'ior_rc_45'],
-  // ['+5', 'ior_rah_45', 'ior_wmc_5', 'ior_rc_55'],
-  ['ou_05', 'ior_ouc_05', '-', 'ior_ouh_05'],
-  ['ou_15', 'ior_ouc_15', '-', 'ior_ouh_15'],
-  ['ou_25', 'ior_ouc_25', '-', 'ior_ouh_25'],
-  ['ou_35', 'ior_ouc_35', '-', 'ior_ouh_35'],
-  ['ot_1', '-', 'ior_ot_1', '-'],
-  ['ot_2', '-', 'ior_ot_2', '-'],
-  ['ot_3', '-', 'ior_ot_3', '-'],
-  ['ot_4', '-', 'ior_ot_4', '-'],
-  ['ot_5', '-', 'ior_ot_5', '-'],
-  // ['ot_6', '-', 'ior_ot_6', '-'],
-  // ['ot_7', '-', 'ior_ot_7', '-'],
-];
+// const PS_IOR_KEYS = [
+//   ['0', 'ior_mh', 'ior_mn', 'ior_mc'],
+//   ['-1', 'ior_rh_15', 'ior_wmh_1', 'ior_rac_05'],
+//   ['-2', 'ior_rh_25', 'ior_wmh_2', 'ior_rac_15'],
+//   ['-3', 'ior_rh_35', 'ior_wmh_3', 'ior_rac_25'],
+//   // ['-4', 'ior_rh_45', 'ior_wmh_4', 'ior_rac_35'],
+//   // ['-5', 'ior_rh_55', 'ior_wmh_5', 'ior_rac_45'],
+//   ['+1', 'ior_rah_05', 'ior_wmc_1', 'ior_rc_15'],
+//   ['+2', 'ior_rah_15', 'ior_wmc_2', 'ior_rc_25'],
+//   ['+3', 'ior_rah_25', 'ior_wmc_3', 'ior_rc_35'],
+//   // ['+4', 'ior_rah_35', 'ior_wmc_4', 'ior_rc_45'],
+//   // ['+5', 'ior_rah_45', 'ior_wmc_5', 'ior_rc_55'],
+//   ['ou_05', 'ior_ouc_05', '-', 'ior_ouh_05'],
+//   ['ou_15', 'ior_ouc_15', '-', 'ior_ouh_15'],
+//   ['ou_25', 'ior_ouc_25', '-', 'ior_ouh_25'],
+//   ['ou_35', 'ior_ouc_35', '-', 'ior_ouh_35'],
+//   ['ot_1', '-', 'ior_ot_1', '-'],
+//   ['ot_2', '-', 'ior_ot_2', '-'],
+//   ['ot_3', '-', 'ior_ot_3', '-'],
+//   ['ot_4', '-', 'ior_ot_4', '-'],
+//   ['ot_5', '-', 'ior_ot_5', '-'],
+//   // ['ot_6', '-', 'ior_ot_6', '-'],
+//   // ['ot_7', '-', 'ior_ot_7', '-'],
+// ];
+
+const fixFloat = (number, x = 2) => {
+  return parseFloat(number.toFixed(x));
+}
+
+const IOR_ORDER = {
+  'm': 0,
+  '0': 1,
+  '-': 2,
+  '+': 3,
+  'ou': 4,
+  'wm': 5,
+  'ot': 6,
+}
+
+const getIorPrefix = (ior) => {
+  const iorParts = ior.split('_');
+  if (iorParts.length === 1) {
+    return iorParts[0][0];
+  }
+  return iorParts[0];
+}
 
 const parseRatio = (ratioString) => {
   return parseFloat(`${ratioString[0]}.${ratioString.slice(1)}`);
@@ -81,31 +103,27 @@ const parseIorKey = (iorKey) => {
   return { type, side, ratio };
 }
 
-const fixFloat = (number, x = 2) => {
-  return parseFloat(number.toFixed(x));
-}
-
-const formatPsEvents = (events) => {
-  return PS_IOR_KEYS.map(([label, ...keys]) => {
-    const labelParts = label.split('_');
-    const labelType = labelParts[0];
-    if (labelType === 'ou') {
-      const labelRatio = parseRatio(labelParts[1]);
-      label = `ou_${labelRatio}`;
-    }
-    const match = keys.map(key => ({
-      key,
-      value: events[key]?.v ?? 0,
-      origin: events[key]?.r
-    }));
-    return {
-      label,
-      match
-    };
-  })
-  // .filter(item => item.match.every(entry => entry.value !== 0))
-  .map(({label, match}) => [label, ...match]);
-}
+// const formatPsEvents = (events) => {
+//   return PS_IOR_KEYS.map(([label, ...keys]) => {
+//     const labelParts = label.split('_');
+//     const labelType = labelParts[0];
+//     if (labelType === 'ou') {
+//       const labelRatio = parseRatio(labelParts[1]);
+//       label = `ou_${labelRatio}`;
+//     }
+//     const match = keys.map(key => ({
+//       key,
+//       value: events[key]?.v ?? 0,
+//       origin: events[key]?.r
+//     }));
+//     return {
+//       label,
+//       match
+//     };
+//   })
+//   // .filter(item => item.match.every(entry => entry.value !== 0))
+//   .map(({label, match}) => [label, ...match]);
+// }
 
 const formatEvents = (events) => {
   const eventsMap = {};
@@ -182,7 +200,14 @@ const formatEvents = (events) => {
     eventsMap[ratioKey][index] = { key, value, origin, qualified };
   });
 
-  return Object.keys(eventsMap).sort((a, b) => a.localeCompare(b)).map(key => {
+  return Object.keys(eventsMap).sort((a, b) => {
+    const aPrefix = getIorPrefix(a);
+    const bPrefix = getIorPrefix(b);
+    if (aPrefix !== bPrefix) {
+      return IOR_ORDER[aPrefix] - IOR_ORDER[bPrefix];
+    }
+    return a.localeCompare(b);
+  }).map(key => {
     return [key, ...eventsMap[key]];
   });
 }
@@ -228,7 +253,8 @@ const currentRelation = computed(() => {
       relation.rel = {};
     }
     const mergedEvents = { ...events, ...special };
-    const formattedEvents = platform === 'ps' ? formatPsEvents(mergedEvents) : formatEvents(mergedEvents);
+    // const formattedEvents = platform === 'ps' ? formatPsEvents(mergedEvents) : formatEvents(mergedEvents);
+    const formattedEvents = formatEvents(mergedEvents);
     relation.rel[platform] = {
       eventId: eventId ?? 0,
       teamHomeName: teamHomeName ?? '主队',
@@ -243,6 +269,12 @@ const currentRelation = computed(() => {
     }
     relation.rel[p]['selected'].push(k);
   });
+  const iorGroups = props.solutions.map(solution => {
+    const { group } = solution;
+    const idx = group.indexOf('_');
+    return group.slice(idx + 1);
+  });
+  relation.iorGroups = [...new Set(iorGroups)];
   return relation;
 });
 
@@ -262,15 +294,15 @@ const ob = computed(() => {
   return currentRelation.value.rel.ob;
 });
 
-const im = computed(() => {
-  return currentRelation.value.rel.im;
-});
+// const im = computed(() => {
+//   return currentRelation.value.rel.im;
+// });
 
 </script>
 
 <template>
 <div class="solution-item" :class="{ 'selected': selected }">
-  <div class="solution-header">
+  <div class="solution-header" @click.self="toggleSolution">
     <div class="serial-number" v-if="serial">{{ serial }}.</div>
     <div class="stage" v-if="currentRelation.stage">[{{ currentRelation.stage }}{{ currentRelation.retime ? ` ${currentRelation.retime}` : '' }}]</div>
     <div class="score" v-if="currentRelation.stage">[{{ currentRelation.score }}]</div>
@@ -282,13 +314,13 @@ const im = computed(() => {
       class="switch-btn-item"
       :class="{ 'selected': index === currentIndex }"
       :title="`${sol.win_profit_rate}% (${sol.cross_type})`"
-      @click="switchSolution(index)">{{ sol.win_average_rate }}</Tooltip>
+      @click.stop="switchSolution(index)">{{ sol.win_average_rate }}</Tooltip>
     </div>
   </div>
   <div class="solution-content">
     <MatchCard platform="ps" :eventId="ps.eventId" :teamHomeName="ps.teamHomeName"
     :teamAwayName="ps.teamAwayName" :events="ps.events ?? []"
-    :selected="ps.selected ?? []" />
+    :selected="ps.selected ?? []" :iorGroups="currentRelation.iorGroups" />
 
     <MatchCard platform="ob" :eventId="ob.eventId" :teamHomeName="ob.teamHomeName"
       :teamAwayName="ob.teamAwayName" :events="ob.events ?? []"
@@ -298,9 +330,9 @@ const im = computed(() => {
       :teamAwayName="hg.teamAwayName" :events="hg.events ?? []"
       :selected="hg.selected ?? []" />
 
-    <MatchCard platform="im" :eventId="im.eventId" :teamHomeName="im.teamHomeName"
+    <!-- <MatchCard platform="im" :eventId="im.eventId" :teamHomeName="im.teamHomeName"
       :teamAwayName="im.teamAwayName" :events="im.events ?? []"
-      :selected="im.selected ?? []" />
+      :selected="im.selected ?? []" /> -->
 
     <!-- <div class="solution-profit" @click="toggleSolution()">
       <p>{{ currentSolution.sol.win_average_rate }}%</p>
@@ -369,8 +401,7 @@ const im = computed(() => {
 .switch-btns {
   display: flex;
   align-items: center;
-  justify-content: flex-end;
-  flex: 1;
+  margin-left: auto;
   :deep(.switch-btn-item) {
     display: block;
     height: 20px;

+ 1 - 1
web/apps/web-antd/src/views/match/solutions/index.vue

@@ -264,7 +264,7 @@ onUnmounted(() => {
         <span>PS</span>
         <span>OB</span>
         <span>HG</span>
-        <span>IM</span>
+        <!-- <span>IM</span> -->
         <!-- <em>利润</em> -->
       </div>
     </div>