|  | @@ -1,141 +1,172 @@
 | 
	
		
			
				|  |  |  <template>
 | 
	
		
			
				|  |  |    <div class="metrics-cards">
 | 
	
		
			
				|  |  |      <MCard
 | 
	
		
			
				|  |  | -     v-model="info.metric"
 | 
	
		
			
				|  |  | -     :metric-items="props.metricItems"
 | 
	
		
			
				|  |  | -     :color="info.color"
 | 
	
		
			
				|  |  | -     v-for="info in displayMetrics"
 | 
	
		
			
				|  |  | -     @change-metric="changedMetric"
 | 
	
		
			
				|  |  | -     @click="clickCard(info.metric)"/>
 | 
	
		
			
				|  |  | +        v-for="info in displayMetrics"
 | 
	
		
			
				|  |  | +        :key="info.metric"
 | 
	
		
			
				|  |  | +        v-model="info.metric"
 | 
	
		
			
				|  |  | +        :color="info.color"
 | 
	
		
			
				|  |  | +        :metric-items="props.metricItems"
 | 
	
		
			
				|  |  | +        @click="clickCard(info.metric)"
 | 
	
		
			
				|  |  | +        @change-metric="changedMetric" />
 | 
	
		
			
				|  |  |    </div>
 | 
	
		
			
				|  |  |  </template>
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |  <script lang="ts" setup>
 | 
	
		
			
				|  |  | -import { ref, Ref, onBeforeMount, watch, onMounted, computed } from 'vue'
 | 
	
		
			
				|  |  | -import MCard from './mCard.vue'
 | 
	
		
			
				|  |  | +import { computed, onBeforeMount, ref, Ref, watch } from 'vue';
 | 
	
		
			
				|  |  | +import MCard from './mCard.vue';
 | 
	
		
			
				|  |  |  import XEUtils from 'xe-utils';
 | 
	
		
			
				|  |  | +import { initData, weekInitData } from '/@/views/reportManage/dataCenter/utils/enum';
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |  interface Props {
 | 
	
		
			
				|  |  |    modelValue: ShowMetric[],
 | 
	
		
			
				|  |  |    metricItems: MetricData[],
 | 
	
		
			
				|  |  |  }
 | 
	
		
			
				|  |  | -const colorsMap: { [key: string]: boolean } = {}
 | 
	
		
			
				|  |  | -const props = defineProps<Props>()
 | 
	
		
			
				|  |  | -const emits = defineEmits(['change', 'update:modelValue'])
 | 
	
		
			
				|  |  | -// const allMetricItems = ref(props.metricItems)
 | 
	
		
			
				|  |  | -const selectedMetric = ref(props.modelValue)
 | 
	
		
			
				|  |  | -const displayMetrics: Ref<{metric:string, color?: string}[]> = ref([])
 | 
	
		
			
				|  |  | -
 | 
	
		
			
				|  |  | -const metricMap = computed(():{[key: string]: string} => {
 | 
	
		
			
				|  |  | -  const tmp:{[key: string]: string} = {}
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +const dateType = inject<Ref>('statDim');
 | 
	
		
			
				|  |  | +const colorsMap: { [key: string]: boolean } = {};
 | 
	
		
			
				|  |  | +const props = defineProps<Props>();
 | 
	
		
			
				|  |  | +const emits = defineEmits(['change', 'update:modelValue']);
 | 
	
		
			
				|  |  | +const selectedMetric = ref(props.modelValue);
 | 
	
		
			
				|  |  | +const displayMetrics: Ref<{ metric: string, color?: string }[]> = ref([]);
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +const metricMap = computed(() => {
 | 
	
		
			
				|  |  | +  const tmp: { [key: string]: string } = {};
 | 
	
		
			
				|  |  |    for (const info of props.metricItems) {
 | 
	
		
			
				|  |  | -    tmp[info.value] = info.label
 | 
	
		
			
				|  |  | +    tmp[info.value] = info.label;
 | 
	
		
			
				|  |  | +  }
 | 
	
		
			
				|  |  | +  return tmp;
 | 
	
		
			
				|  |  | +});
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +const initializeMetrics = () => {
 | 
	
		
			
				|  |  | +  selectedMetric.value = [];
 | 
	
		
			
				|  |  | +  displayMetrics.value = [];
 | 
	
		
			
				|  |  | +  //console.log('初始化', selectedMetric.value);
 | 
	
		
			
				|  |  | +  Object.keys(colorsMap).forEach(key => delete colorsMap[key]);
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +  if (dateType.value === 'day' || dateType.value === 'month') {
 | 
	
		
			
				|  |  | +    // 不要改成initData,不然会动态变化
 | 
	
		
			
				|  |  | +    selectedMetric.value = [{metric: 'sales', color: '#0085ff', label: '销售额'},
 | 
	
		
			
				|  |  | +      {metric: 'sales_last_year', color: '#ff9500', label: '上年销售额'},
 | 
	
		
			
				|  |  | +      {metric: 'sales_last_month', color: '#3fd4cf', label: '上月销售额'},];
 | 
	
		
			
				|  |  | +  } else if (dateType.value === 'week') {
 | 
	
		
			
				|  |  | +    selectedMetric.value = weekInitData.value;
 | 
	
		
			
				|  |  |    }
 | 
	
		
			
				|  |  | -  return tmp
 | 
	
		
			
				|  |  | -})
 | 
	
		
			
				|  |  | -onBeforeMount(()=> {
 | 
	
		
			
				|  |  | -  const dup:{[key: string]: boolean} = {}
 | 
	
		
			
				|  |  | -  // 初始显示图线的三个维度
 | 
	
		
			
				|  |  | +  console.log('initData.value', initData);
 | 
	
		
			
				|  |  | +  console.log('111', selectedMetric.value);
 | 
	
		
			
				|  |  |    for (const info of selectedMetric.value) {
 | 
	
		
			
				|  |  | -    displayMetrics.value.push({ metric: info.metric, color: info.color })
 | 
	
		
			
				|  |  | -    dup[info.metric] = true
 | 
	
		
			
				|  |  | -    if (info.color) { colorsMap[info.color] = true }
 | 
	
		
			
				|  |  | +    displayMetrics.value.push({metric: info.metric, color: info.color});
 | 
	
		
			
				|  |  | +    if (info.color) {
 | 
	
		
			
				|  |  | +      colorsMap[info.color] = true;
 | 
	
		
			
				|  |  | +    }
 | 
	
		
			
				|  |  |    }
 | 
	
		
			
				|  |  | -})
 | 
	
		
			
				|  |  | +  console.log('initializeMetrics', selectedMetric.value);
 | 
	
		
			
				|  |  | +  emits('update:modelValue', selectedMetric.value);
 | 
	
		
			
				|  |  | +};
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +onBeforeMount(initializeMetrics);
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +watch(dateType, initializeMetrics);
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |  const getColor = () => {
 | 
	
		
			
				|  |  | -  for (const [k,v] of Object.entries(colorsMap)) {
 | 
	
		
			
				|  |  | +  for (const [k, v] of Object.entries(colorsMap)) {
 | 
	
		
			
				|  |  |      if (!v) {
 | 
	
		
			
				|  |  | -      colorsMap[k] = true
 | 
	
		
			
				|  |  | -      return k
 | 
	
		
			
				|  |  | +      colorsMap[k] = true;
 | 
	
		
			
				|  |  | +      return k;
 | 
	
		
			
				|  |  |      }
 | 
	
		
			
				|  |  |    }
 | 
	
		
			
				|  |  | -  return ""
 | 
	
		
			
				|  |  | -}
 | 
	
		
			
				|  |  | -const unsetColor = (color: string ) => {
 | 
	
		
			
				|  |  | +  return '';
 | 
	
		
			
				|  |  | +};
 | 
	
		
			
				|  |  | +const unsetColor = (color: string) => {
 | 
	
		
			
				|  |  |    if (XEUtils.has(colorsMap, color)) {
 | 
	
		
			
				|  |  | -    colorsMap[color] = false
 | 
	
		
			
				|  |  | +    colorsMap[color] = false;
 | 
	
		
			
				|  |  |    }
 | 
	
		
			
				|  |  | -}
 | 
	
		
			
				|  |  | +};
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  |  const changedMetric = (newVal: string, oldVal: string) => {
 | 
	
		
			
				|  |  |    for (const info of props.metricItems) {
 | 
	
		
			
				|  |  |      if (info.value === newVal) {
 | 
	
		
			
				|  |  | -      info.disabled = true 
 | 
	
		
			
				|  |  | +      info.disabled = true;
 | 
	
		
			
				|  |  |      } else if (info.value === oldVal) {
 | 
	
		
			
				|  |  | -      info.disabled = false
 | 
	
		
			
				|  |  | +      info.disabled = false;
 | 
	
		
			
				|  |  |      }
 | 
	
		
			
				|  |  |    }
 | 
	
		
			
				|  |  | -  const index = selectedMetric.value.findIndex( info => info.metric === oldVal)
 | 
	
		
			
				|  |  | +  const index = selectedMetric.value.findIndex(info => info.metric === oldVal);
 | 
	
		
			
				|  |  |    if (index > -1) {
 | 
	
		
			
				|  |  | -    selectedMetric.value[index].metric = newVal
 | 
	
		
			
				|  |  | -    selectedMetric.value[index].label = metricMap.value[newVal]
 | 
	
		
			
				|  |  | -    emits('update:modelValue', selectedMetric.value)
 | 
	
		
			
				|  |  | -    emits('change', selectedMetric.value)
 | 
	
		
			
				|  |  | +    selectedMetric.value[index].metric = newVal;
 | 
	
		
			
				|  |  | +    selectedMetric.value[index].label = metricMap.value[newVal];
 | 
	
		
			
				|  |  | +    emits('update:modelValue', selectedMetric.value);
 | 
	
		
			
				|  |  | +    emits('change', selectedMetric.value);
 | 
	
		
			
				|  |  |    }
 | 
	
		
			
				|  |  | -}
 | 
	
		
			
				|  |  | +};
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  |  const clickCard = (metric: string) => {
 | 
	
		
			
				|  |  | -  const index = selectedMetric.value.findIndex( info => info.metric === metric)
 | 
	
		
			
				|  |  | +  const index = selectedMetric.value.findIndex(info => info.metric === metric);
 | 
	
		
			
				|  |  |    if (index > -1) {  // 已存在则删除
 | 
	
		
			
				|  |  | -    if (selectedMetric.value.length <= 1 ) return
 | 
	
		
			
				|  |  | -    const tmp = selectedMetric.value[index]
 | 
	
		
			
				|  |  | -    selectedMetric.value.splice(index, 1)
 | 
	
		
			
				|  |  | -    unsetColor(tmp.color)
 | 
	
		
			
				|  |  | -    emits('update:modelValue', selectedMetric.value)
 | 
	
		
			
				|  |  | -    emits('change', selectedMetric.value)
 | 
	
		
			
				|  |  | +    if (selectedMetric.value.length <= 1) return;
 | 
	
		
			
				|  |  | +    const tmp = selectedMetric.value[index];
 | 
	
		
			
				|  |  | +    selectedMetric.value.splice(index, 1);
 | 
	
		
			
				|  |  | +    unsetColor(tmp.color);
 | 
	
		
			
				|  |  | +    emits('update:modelValue', selectedMetric.value);
 | 
	
		
			
				|  |  | +    emits('change', selectedMetric.value);
 | 
	
		
			
				|  |  |    } else {  // 不存在则添加
 | 
	
		
			
				|  |  | -    if (selectedMetric.value.length === 3) { 
 | 
	
		
			
				|  |  | -      selectedMetric.value[2].metric = metric
 | 
	
		
			
				|  |  | -      selectedMetric.value[2].label = metricMap.value[metric]
 | 
	
		
			
				|  |  | +    if (selectedMetric.value.length === 3) {
 | 
	
		
			
				|  |  | +      selectedMetric.value[2].metric = metric;
 | 
	
		
			
				|  |  | +      selectedMetric.value[2].label = metricMap.value[metric];
 | 
	
		
			
				|  |  |      } else {
 | 
	
		
			
				|  |  | -      const color = getColor()
 | 
	
		
			
				|  |  | -      selectedMetric.value.push({ metric: metric, color: color, label: metricMap.value[metric]})
 | 
	
		
			
				|  |  | +      const color = getColor();
 | 
	
		
			
				|  |  | +      selectedMetric.value.push({metric: metric, color: color, label: metricMap.value[metric]});
 | 
	
		
			
				|  |  |      }
 | 
	
		
			
				|  |  | -    emits('update:modelValue', selectedMetric.value)
 | 
	
		
			
				|  |  | -    emits('change', selectedMetric.value)
 | 
	
		
			
				|  |  |    }
 | 
	
		
			
				|  |  | -}
 | 
	
		
			
				|  |  | -watch(selectedMetric.value, () => {
 | 
	
		
			
				|  |  | -  const cache:{ [key: string]: string } = {}
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +  emits('update:modelValue', selectedMetric.value);
 | 
	
		
			
				|  |  | +  emits('change', selectedMetric.value);
 | 
	
		
			
				|  |  | +};
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +watch(selectedMetric, () => {
 | 
	
		
			
				|  |  | +  const cache: { [key: string]: string } = {};
 | 
	
		
			
				|  |  |    for (const info of selectedMetric.value) {
 | 
	
		
			
				|  |  | -    cache[info.metric] = info.color
 | 
	
		
			
				|  |  | +    cache[info.metric] = info.color;
 | 
	
		
			
				|  |  |    }
 | 
	
		
			
				|  |  |    for (const info of displayMetrics.value) {
 | 
	
		
			
				|  |  | -    const color = cache[info.metric]
 | 
	
		
			
				|  |  | +    const color = cache[info.metric];
 | 
	
		
			
				|  |  |      if (color) {
 | 
	
		
			
				|  |  | -      info.color = color
 | 
	
		
			
				|  |  | +      info.color = color;
 | 
	
		
			
				|  |  |      } else {
 | 
	
		
			
				|  |  | -      info.color = undefined
 | 
	
		
			
				|  |  | +      info.color = undefined;
 | 
	
		
			
				|  |  |      }
 | 
	
		
			
				|  |  |    }
 | 
	
		
			
				|  |  | -})
 | 
	
		
			
				|  |  | +  console.log('watch', selectedMetric.value);
 | 
	
		
			
				|  |  | +}, {deep: true});
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |  watch(
 | 
	
		
			
				|  |  | -  props.metricItems,
 | 
	
		
			
				|  |  | -  () => {
 | 
	
		
			
				|  |  | -    const dup:{[key: string]: boolean} = {}
 | 
	
		
			
				|  |  | -    for (const info of displayMetrics.value) { dup[info.metric] = true }
 | 
	
		
			
				|  |  | -    let needNum = 6 - displayMetrics.value.length
 | 
	
		
			
				|  |  | -    if (needNum > 0) {  
 | 
	
		
			
				|  |  | -      // 从所有维度中选择剩余
 | 
	
		
			
				|  |  | +    props.metricItems,
 | 
	
		
			
				|  |  | +    () => {
 | 
	
		
			
				|  |  | +      const dup: { [key: string]: boolean } = {};
 | 
	
		
			
				|  |  | +      for (const info of displayMetrics.value) {
 | 
	
		
			
				|  |  | +        dup[info.metric] = true;
 | 
	
		
			
				|  |  | +      }
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +      let needNum = 6 - displayMetrics.value.length;
 | 
	
		
			
				|  |  | +      if (needNum > 0) {
 | 
	
		
			
				|  |  | +        for (const info of props.metricItems) {
 | 
	
		
			
				|  |  | +          if (!dup[info.value]) {
 | 
	
		
			
				|  |  | +            displayMetrics.value.push({metric: info.value});
 | 
	
		
			
				|  |  | +            dup[info.value] = true;
 | 
	
		
			
				|  |  | +            needNum--;
 | 
	
		
			
				|  |  | +            if (needNum === 0) break;
 | 
	
		
			
				|  |  | +          }
 | 
	
		
			
				|  |  | +        }
 | 
	
		
			
				|  |  | +      }
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  |        for (const info of props.metricItems) {
 | 
	
		
			
				|  |  | -        if (!dup[info.value]) {
 | 
	
		
			
				|  |  | -          displayMetrics.value.push({ metric: info.value })
 | 
	
		
			
				|  |  | -          dup[info.value] = true
 | 
	
		
			
				|  |  | -          needNum --
 | 
	
		
			
				|  |  | -          if (needNum === 0) break
 | 
	
		
			
				|  |  | +        if (dup[info.value]) {
 | 
	
		
			
				|  |  | +          info.disabled = true;
 | 
	
		
			
				|  |  | +        } else {
 | 
	
		
			
				|  |  | +          info.disabled = false;
 | 
	
		
			
				|  |  |          }
 | 
	
		
			
				|  |  |        }
 | 
	
		
			
				|  |  |      }
 | 
	
		
			
				|  |  | -    for (const info of props.metricItems) {
 | 
	
		
			
				|  |  | -      if (dup[info.value]) {
 | 
	
		
			
				|  |  | -        info.disabled = true
 | 
	
		
			
				|  |  | -      } else {
 | 
	
		
			
				|  |  | -        info.disabled = false
 | 
	
		
			
				|  |  | -      }  
 | 
	
		
			
				|  |  | -    }
 | 
	
		
			
				|  |  | -  }
 | 
	
		
			
				|  |  | -)
 | 
	
		
			
				|  |  | -
 | 
	
		
			
				|  |  | +);
 | 
	
		
			
				|  |  |  </script>
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |  <style scoped>
 | 
	
	
		
			
				|  | @@ -146,4 +177,4 @@ watch(
 | 
	
		
			
				|  |  |    gap: 12px;
 | 
	
		
			
				|  |  |    width: 100%;
 | 
	
		
			
				|  |  |  }
 | 
	
		
			
				|  |  | -</style>
 | 
	
		
			
				|  |  | +</style>
 |