WXL (wul)
4 天以前 cb3c799e1bd6a7cf5dd5c7e3cadee238bf67b729
src/components/SortCheckbox/index.vue
@@ -18,11 +18,22 @@
    <div v-if="selectedOrder.length > 0" class="selection-order-display">
      <span class="order-label">服务执行顺序:</span>
      <span
        v-for="(value, index) in selectedOrder"
        :key="value"
        v-for="(item, index) in selectedOrder"
        :key="item.value"
        class="order-item"
      >
        {{ getSelectedIndex(index) }}.{{ getLabelByValue(value) }}
        {{ getSelectedIndex(index) }}.{{ getLabelByValue(item.value) }}
        <el-tooltip content="设置补偿时间" placement="top">
          <el-input-number
            v-model="item.compensateTime"
            :min="0"
            :max="60"
            size="mini"
            controls-position="right"
            class="compensate-time-input"
            @change="handleCompensateTimeChange(item.value, $event)"
          />
        </el-tooltip>
        <span v-if="index < selectedOrder.length - 1">、</span>
      </span>
    </div>
@@ -44,6 +55,10 @@
      type: Array,
      default: () => [],
    },
    initialselectedOrder: {
      type: Array,
      default: () => [],
    },
    valueKey: {
      type: String,
      default: "value",
@@ -52,42 +67,95 @@
      type: String,
      default: "label",
    },
    // 新增:默认补偿时间
    defaultCompensateTime: {
      type: Number,
      default: 0,
    },
  },
  data() {
    return {
      checkedValues: [],
      selectedOrder: [],
      selectedOrder: [], // 现在格式为 [{value, compensateTime}]
    };
  },
  watch: {
    value: {
      immediate: true,
      handler(newVal) {
        if (JSON.stringify(newVal) !== JSON.stringify(this.checkedValues)) {
          this.checkedValues = [...newVal];
          this.selectedOrder = [...newVal];
        if (
          Array.isArray(newVal) &&
          newVal.length > 0 &&
          typeof newVal[0] === "object"
        ) {
          console.log(this.selectedOrder, "111");
          // 1. 传入的是对象数组 [{ sort, preachform, compensateTime }]
          this.checkedValues = newVal.map((item) => item.preachform); // 提取 preachform 组成选中值数组
          // 构建 selectedOrder,优先使用传入的 compensateTime,否则用默认值
          this.selectedOrder = newVal.map((item) => ({
            value: item.preachform,
            compensateTime: item.hasOwnProperty("compensateTime")
              ? item.compensateTime
              : this.defaultCompensateTime,
          }));
        } else {
          // 2. 传入的是字符串数组 (如 ["1", "3", "4"],兼容之前的用法)
          if (JSON.stringify(newVal) !== JSON.stringify(this.checkedValues)) {
            this.checkedValues = [...newVal];
            console.log(this.selectedOrder, "222");
            console.log(this.newVal, "22");
            // 构建或更新 selectedOrder,保留已有的 compensateTime
            const newOrder = [];
            newVal.forEach((value) => {
              const existingItem = this.selectedOrder.find(
                (item) => item.value === value
              );
              if (existingItem) {
                newOrder.push(existingItem);
              } else {
                newOrder.push({
                  value,
                  compensateTime: this.hasOwnProperty(value)
                    ? this.hasOwnProperty(value)
                    : this.defaultCompensateTime,
                });
              }
            });
            this.selectedOrder = newOrder;
          }
        }
      },
      deep: true, // 建议添加 deep: true 以确保对象数组内的变化能被捕获
    },
    checkedValues(newVal, oldVal) {
      console.log(this.selectedOrder, "333");
      // 处理选中项的变化
      const added = newVal.filter((item) => !oldVal.includes(item));
      const removed = oldVal.filter((item) => !newVal.includes(item));
      added.forEach((value) => {
        if (!this.selectedOrder.includes(value)) {
          this.selectedOrder.push(value);
        if (!this.selectedOrder.find((item) => item.value === value)) {
          this.selectedOrder.push({
            value,
            compensateTime: this.defaultCompensateTime,
          });
        }
      });
      removed.forEach((value) => {
        const index = this.selectedOrder.indexOf(value);
        const index = this.selectedOrder.findIndex(
          (item) => item.value === value
        );
        if (index > -1) {
          this.selectedOrder.splice(index, 1);
        }
      });
      // 更新父组件的 v-model 绑定值(选中值数组)
      this.$emit("input", [...newVal]);
      this.$emit("change", [...newVal], [...this.selectedOrder]);
      // 触发 change 事件,传递完整的业务数据
      this.emitChangeEvent();
    },
  },
  methods: {
@@ -98,9 +166,7 @@
      return typeof option === "object" ? option[this.labelKey] : option;
    },
    getLabelByValue(value) {
      const option = this.options.find(
        (opt) => this.getValue(opt) === value
      );
      const option = this.options.find((opt) => this.getValue(opt) === value);
      return option ? this.getLabel(option) : value;
    },
    getSelectedIndex(index) {
@@ -110,12 +176,53 @@
        return `(${index + 1})`;
      }
    },
    getSelectionOrder() {
      return [...this.selectedOrder];
    // 处理补偿时间变化
    handleCompensateTimeChange(value, newTime) {
      const item = this.selectedOrder.find((item) => item.value === value);
      if (item) {
        item.compensateTime = newTime;
        // 补偿时间变化时,只触发 change 事件,不触动 v-model
        this.emitChangeEvent();
      }
    },
    hasOwnProperty(patfrom) {
      console.log(patfrom);
      console.log(this.initialselectedOrder);
      // 使用find方法查找匹配的对象
      const foundObject = this.initialselectedOrder.find(
        (item) => item.preachform === patfrom
      );
      // 如果找到对象,返回其compensateTime;否则返回false
      return foundObject ? foundObject.compensateTime : false;
    },
    // 发射变化事件
    emitChangeEvent() {
      // 转换数据格式为父组件需要的格式
      const outputData = this.selectedOrder.map((item, index) => ({
        sort: index + 1,
        preachform: item.value,
        compensateTime: item.compensateTime,
      }));
      this.$emit("change", outputData); // 发射 change 事件,传递完整数据
    },
    // 获取当前选择顺序和补偿时间
    getSelectionOrder() {
      return this.selectedOrder.map((item, index) => ({
        sort: index + 1,
        preachform: item.value,
        compensateTime: item.compensateTime,
      }));
    },
    // 设置选择顺序和补偿时间
    setSelectionOrder(orderedValues) {
      this.selectedOrder = [...orderedValues];
      this.checkedValues = [...orderedValues];
      this.selectedOrder = orderedValues.map((item) => ({
        value: item.preachform,
        compensateTime: item.compensateTime || this.defaultCompensateTime,
      }));
      this.checkedValues = orderedValues.map((item) => item.preachform);
      this.emitChangeEvent();
    },
  },
};
@@ -139,6 +246,9 @@
  background-color: #f5f7fa;
  border-radius: 4px;
  border: 1px solid #ebeef5;
  display: flex;
  flex-wrap: wrap;
  align-items: center;
}
.order-label {
@@ -150,6 +260,14 @@
.order-item {
  color: #409eff;
  font-weight: 500;
  display: inline-flex;
  align-items: center;
  margin-right: 8px;
}
.compensate-time-input {
  width: 90px;
  margin-left: 8px;
}
/* 响应式设计:小屏幕时换行 */
@@ -160,6 +278,12 @@
  .selection-order-display {
    padding: 8px;
    flex-direction: column;
    align-items: flex-start;
  }
  .order-item {
    margin-bottom: 8px;
  }
}
</style>