yyb
11 小时以前 5b248a9716688d8132cfb02b4ba0abecd4060b06
src/views/officeProcessAutomation/ApproveManage/approve-template/components/FormConfigEditor.vue
@@ -219,10 +219,12 @@
              placeholder="选填"
              style="width: 100%"
              clearable
              filterable
              :loading="optionSourceLoading"
              @change="emitOut"
            >
              <el-option
                v-for="o in field.options.filter((x) => x.value !== '' && x.value != null)"
                v-for="o in resolvedSelectOptions(field)"
                :key="String(o.value)"
                :label="o.label || o.value"
                :value="o.value"
@@ -231,28 +233,52 @@
          </div>
          <div v-if="field.type === 'select'" class="fce-section fce-section--options">
            <div class="fce-options-head">
              <span class="fce-section-title">下拉选项</span>
              <el-button type="primary" link size="small" :icon="Plus" @click="addOption(field)">
                添加选项
              </el-button>
            </div>
            <div
              v-for="(opt, oi) in field.options"
              :key="oi"
              class="fce-option-row"
            >
              <span class="fce-option-index">{{ oi + 1 }}</span>
              <el-input v-model="opt.label" placeholder="显示文本" @input="emitOut" />
              <el-input v-model="opt.value" placeholder="选项值" class="fce-option-value" @input="emitOut" />
              <el-button
                type="danger"
                link
                :icon="Delete"
                :disabled="field.options.length <= 1"
                @click="removeOption(field, oi)"
              />
            </div>
            <span class="fce-section-title">下拉选项</span>
            <el-row :gutter="16" class="fce-source-row">
              <el-col :span="12">
                <el-form-item label="选项来源" class="fce-field-item">
                  <el-select
                    v-model="field.optionSource"
                    style="width: 100%"
                    @change="onOptionSourceChange(field)"
                  >
                    <el-option
                      v-for="s in SELECT_OPTION_SOURCE_OPTIONS"
                      :key="s.value"
                      :label="s.label"
                      :value="s.value"
                    />
                  </el-select>
                </el-form-item>
              </el-col>
            </el-row>
            <p v-if="isDynamicOptionSource(field.optionSource)" class="fce-source-tip">
              {{ optionSourceDesc(field.optionSource) }}。提交审批时将自动加载最新数据,无需手动维护选项。
            </p>
            <template v-if="!isDynamicOptionSource(field.optionSource)">
              <div class="fce-options-head">
                <span class="fce-section-subtitle">手动选项</span>
                <el-button type="primary" link size="small" :icon="Plus" @click="addOption(field)">
                  添加选项
                </el-button>
              </div>
              <div
                v-for="(opt, oi) in field.options"
                :key="oi"
                class="fce-option-row"
              >
                <span class="fce-option-index">{{ oi + 1 }}</span>
                <el-input v-model="opt.label" placeholder="显示文本" @input="emitOut" />
                <el-input v-model="opt.value" placeholder="选项值" class="fce-option-value" @input="emitOut" />
                <el-button
                  type="danger"
                  link
                  :icon="Delete"
                  :disabled="field.options.length <= 1"
                  @click="removeOption(field, oi)"
                />
              </div>
            </template>
          </div>
        </div>
      </div>
@@ -271,6 +297,12 @@
  createEmptyFormField,
  formFieldTypeLabel,
} from "../formConfigUtils.js";
import {
  SELECT_OPTION_SOURCE,
  SELECT_OPTION_SOURCE_OPTIONS,
  isDynamicOptionSource,
} from "../selectOptionSource.js";
import { useSelectOptionSources } from "../useSelectOptionSources.js";
const props = defineProps({
  modelValue: { type: Object, default: () => createEmptyFormConfigData() },
@@ -279,6 +311,8 @@
const emit = defineEmits(["update:modelValue"]);
const inner = reactive(createEmptyFormConfigData());
const { loading: optionSourceLoading, ensureForFields, getOptions } = useSelectOptionSources();
function typeLabel(type) {
  return formFieldTypeLabel(type);
@@ -289,6 +323,15 @@
  return `选填,选择模板时将预填${name}`;
}
function optionSourceDesc(source) {
  return SELECT_OPTION_SOURCE_OPTIONS.find((x) => x.value === source)?.desc || "";
}
function resolvedSelectOptions(field) {
  if (field.type !== "select") return [];
  return getOptions(field);
}
function syncFromProps(v) {
  const src = v || createEmptyFormConfigData();
  inner.summaryPlaceholder = src.summaryPlaceholder || "";
@@ -296,8 +339,10 @@
    ...createEmptyFormField(),
    ...f,
    _uid: f._uid || createEmptyFormField()._uid,
    optionSource: f.optionSource || SELECT_OPTION_SOURCE.STATIC,
    options: (f.options || [{ label: "", value: "" }]).map((o) => ({ ...o })),
  }));
  ensureForFields(inner.fields);
}
function emitOut() {
@@ -313,6 +358,7 @@
      min: f.min,
      precision: f.precision,
      defaultValue: cloneDefaultValue(f),
      optionSource: f.optionSource || SELECT_OPTION_SOURCE.STATIC,
      options: (f.options || []).map((o) => ({ label: o.label, value: o.value })),
    })),
  });
@@ -333,6 +379,7 @@
function addField() {
  inner.fields.push(createEmptyFormField());
  ensureForFields(inner.fields);
  emitOut();
}
@@ -357,10 +404,23 @@
}
function onTypeChange(field) {
  if (field.type === "select" && (!field.options || !field.options.length)) {
    field.options = [{ label: "", value: "" }];
  if (field.type === "select") {
    if (!field.optionSource) field.optionSource = SELECT_OPTION_SOURCE.STATIC;
    if (!field.options || !field.options.length) {
      field.options = [{ label: "", value: "" }];
    }
    ensureForFields(inner.fields);
  }
  resetDefaultValueForType(field);
  emitOut();
}
function onOptionSourceChange(field) {
  field.defaultValue = "";
  if (!isDynamicOptionSource(field.optionSource) && (!field.options || !field.options.length)) {
    field.options = [{ label: "", value: "" }];
  }
  ensureForFields(inner.fields);
  emitOut();
}
@@ -585,10 +645,28 @@
  margin-bottom: 10px;
}
.fce-options-head .fce-section-title {
.fce-options-head .fce-section-title,
.fce-options-head .fce-section-subtitle {
  margin-bottom: 0;
}
.fce-section-subtitle {
  font-size: 12px;
  font-weight: 600;
  color: var(--el-text-color-secondary);
}
.fce-source-row {
  margin-bottom: 4px;
}
.fce-source-tip {
  margin: 0 0 10px;
  font-size: 12px;
  color: var(--el-text-color-secondary);
  line-height: 1.5;
}
.fce-option-row {
  display: flex;
  align-items: center;