index.vue 4.43 KB
<template>
  <div>
    <div style="display: flex; width: 100%; align-items: center">
      <a-input
        :placeholder="placeholder"
        :disabled="disabled"
        :value="displayValue"
        readonly
        style="flex: 1"
      />
      <a-button type="primary" @click="openModal" :disabled="disabled">选人</a-button>
    </div>

    <a-modal
      v-model:visible="visible"
      :title="title"
      width="60vw"
      @ok="handleOk"
      @cancel="handleCancel"
    >
      <div class="modal-content">
        <OrganizationIdTree
          @select="handleOrgSelect"
          isOpen="true"
          class="org-tree"
        />
        <div class="user-list">
          <a-radio-group
            v-if="mode === 'single'"
            v-model:value="selectedValue"
          >
            <a-radio
              v-for="user in userList"
              :key="user.id"
              :value="user"
              :style="radioStyle"
            >
              {{ user.username }}
            </a-radio>
          </a-radio-group>

          <a-checkbox-group
            v-else
            v-model:value="selectedValues"
          >
            <a-checkbox
              v-for="user in userList"
              :key="user.id"
              :value="user"
              :style="checkboxStyle"
            >
              {{ user.username }}
            </a-checkbox>
          </a-checkbox-group>
        </div>
      </div>
    </a-modal>
  </div>
</template>
<script setup lang="ts">
import { ref} from 'vue';
import { useUserStore } from '/@/store/modules/user';
import { OrganizationIdTree } from '/@/views/common/organizationIdTree';

const props = defineProps({
  modelValue: { type: [Object, Array] }, // 单选对象/多选数组
  mode: { type: String, default: 'single' }, // single/multiple
  label: { type: String, default: '报修人' },
  placeholder: { type: String, default: '请选择' },
  disabled: Boolean,
  required: Boolean,
  title: { type: String, default: '选择人员' },
  showLabel: { type: Boolean, default: true },
  // 新增字段映射配置
  valueField: { type: String, default: 'id' },
  displayField: { type: String, default: 'username' }
});

const emit = defineEmits(['update:modelValue', 'change']);

const userStore = useUserStore();
const visible = ref(false);
const displayValue = ref('');
const userList = ref([]);
const selectedValue = ref(null);
const selectedValues = ref([]);


// 处理多选模式初始化
const openModal = async () => {
  visible.value = true;
  console.log(userList,'userList')

  if (props.mode === 'single') {
    selectedValue.value = userList.value.find(u => u.id === props.modelValue);
  } else {
    // 将父组件传递的 ID 数组转换为用户对象数组
    const selectedIds = props.modelValue || [];
    selectedValues.value = userList.value.filter(u =>
      selectedIds.includes(u[props.valueField])
    );
  }
};

// 修改确认逻辑
const handleOk = () => {
  if (props.mode === 'single') {
    if (!selectedValue.value && props.required) {
      return Promise.reject('请选择人员');
    }
    // 发送完整用户对象给父组件
    emit('update:modelValue', {
      id: selectedValue.value.id,
      username: selectedValue.value.username
    });
    displayValue.value = selectedValue?.value?.username || '';

  } else {
    // 提取指定字段的值
    const output = selectedValues.value.map(u => u[props.valueField]);

    // 更新显示值
    displayValue.value = selectedValues.value
      .map(u => u[props.displayField])
      .join(', ');

    // 发送给父组件
    emit('update:modelValue', output);
    emit('change', output);
    console.log(selectedValue,'selectedValue?.value')
  }
  visible.value = false;
};

// 取消选择
const handleCancel = () => {
  visible.value = false;
};

// 样式配置
const radioStyle = {
  display: 'block',
  height: '30px',
  lineHeight: '30px'
};

const checkboxStyle = {
  display: 'block',
  height: '30px',
  lineHeight: '30px',
  width: '100%',
  marginLeft: 0
};
</script>

<style scoped>
.modal-content {
  display: flex;
  padding: 20px;
  height: 50vh;
  overflow: hidden;
}

.org-tree {
  flex: 0 0 30%;
  overflow-y: auto;
  padding-right: 20px;
  border-right: 1px solid #e8e8e8;
}

.user-list {
  flex: 1;
  padding-left: 20px;
  overflow-y: auto;
}

.inputTitle.required::before {
  display: inline-block;
  margin-right: 4px;
  color: #ff4d4f;
  font-size: 14px;
  font-family: SimSun, sans-serif;
  line-height: 1;
  content: '*';
}
</style>