| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360 |
- <template>
- <div class="dynamic-data-editor">
- <LinkedinOutlined class="icon" />
- <a-form class="form" layout="vertical" size="small">
- <a-form-item label="数据源类型">
- <a-select
- :value="currentType"
- style="width: 100%"
- :options="typeOptions"
- placeholder="选择类型"
- @change="onTypeChange"
- />
- </a-form-item>
- <template v-if="currentType === 'commonContent'">
- <a-form-item label="模型 ID (modelId)">
- <a-input-number
- :value="(modelValue as IHomeCommonCategoryDynamicDataCommonContent)?.params?.modelId"
- style="width: 100%"
- :min="1"
- placeholder="模型ID"
- @update:value="(v: number | undefined) => setCommonContent('modelId', v)"
- />
- </a-form-item>
- <a-form-item label="栏目 ID (mainBodyColumnId)">
- <a-input
- :value="mainBodyColumnIdDisplay('commonContent')"
- placeholder="数字或逗号分隔的多个ID,如 320 或 315,316"
- @change="(e: Event) => setMainBodyColumnId('commonContent', (e.target as HTMLInputElement)?.value)"
- />
- </a-form-item>
- <a-form-item label="其他参数 (otherParams)">
- <KeyValueEditor
- :modelValue="(modelValue as IHomeCommonCategoryDynamicDataCommonContent)?.otherParams"
- @update:modelValue="(v: Record<string, any>) => setOtherParams(v)"
- />
- </a-form-item>
- </template>
- <template v-else-if="currentType === 'detailContent'">
-
- <a-form-item label="内容 ID">
- <a-input
- :value="(modelValue as IHomeCommonCategoryDynamicDataDetailContent)?.params?.id"
- @change="(e: Event) => setDetailContent('id', Number((e.target as HTMLInputElement)?.value))"
- />
- </a-form-item>
- <a-form-item label="模型 ID (modelId)">
- <a-input-number
- :value="(modelValue as IHomeCommonCategoryDynamicDataDetailContent)?.params?.modelId"
- style="width: 100%"
- :min="1"
- placeholder="可选,模型ID"
- @update:value="(v: number | undefined) => setDetailContent('modelId', v)"
- />
- </a-form-item>
- <a-form-item label="其他参数 (otherParams)">
- <KeyValueEditor
- :modelValue="(modelValue as IHomeCommonCategoryDynamicDataCommonContent)?.otherParams"
- @update:modelValue="(v: Record<string, any>) => setOtherParams(v)"
- />
- </a-form-item>
- </template>
- <template v-else-if="currentType === 'parentKey'">
-
- <a-form-item label="读取键">
- <a-input
- :value="(modelValue as IHomeCommonCategoryDynamicDataParentKey)?.key"
- @change="(e: Event) => setParentKey((e.target as HTMLInputElement)?.value)"
- />
- </a-form-item>
- </template>
- <template v-else-if="currentType === 'serializedApi'">
- <a-form-item label="序列化接口名称 (name)">
- <a-select
- :value="(modelValue as IHomeCommonCategoryDynamicDataSerializedApi)?.name"
- style="width: 100%"
- show-search
- :filter-option="filterOption"
- :options="serializedApiOptions"
- placeholder="选择或输入接口名"
- @change="(v: string) => setSerializedApi('name', v)"
- />
- </a-form-item>
- <a-form-item label="栏目 ID (params.mainBodyColumnId)">
- <a-input
- :value="mainBodyColumnIdDisplay('serializedApi')"
- placeholder="可选,数字或逗号分隔"
- @change="(e: Event) => setSerializedApiMainBodyColumnId((e.target as HTMLInputElement)?.value)"
- />
- </a-form-item>
- <a-form-item label="其他参数 (otherParams)">
- <KeyValueEditor
- :modelValue="(modelValue as IHomeCommonCategoryDynamicDataSerializedApi)?.otherParams"
- @update:modelValue="(v: Record<string, any>) => setOtherParams(v)"
- />
- </a-form-item>
- </template>
- <template v-else-if="currentType === 'request'">
- <a-form-item label="是否添加token (addToken)">
- <a-switch
- :checked="(modelValue as IHomeCommonCategoryDynamicDataRequest)?.addToken"
- @change="(v: boolean) => setRequestAddToken(v)"
- />
- </a-form-item>
- <a-form-item label="请求方法 (method)">
- <a-select
- :value="(modelValue as IHomeCommonCategoryDynamicDataRequest)?.method"
- style="width: 100%"
- :options="methodOptions"
- @change="(v: 'OPTIONS' | 'GET' | 'HEAD' | 'POST' | 'PUT' | 'DELETE') => setRequest('method', v)"
- />
- </a-form-item>
- <a-form-item label="请求 URL (url)">
- <a-input
- :value="(modelValue as IHomeCommonCategoryDynamicDataRequest)?.url"
- placeholder="https://..."
- @change="(e: Event) => setRequest('url', (e.target as HTMLInputElement)?.value)"
- />
- </a-form-item>
- <a-form-item label="查询参数 (querys) JSON">
- <KeyValueEditor
- :modelValue="(modelValue as IHomeCommonCategoryDynamicDataRequest)?.querys"
- @update:modelValue="(v: Record<string, any>) => setRequest('querys', v)"
- />
- </a-form-item>
- <a-form-item label="请求体参数 (params) JSON">
- <KeyValueEditor
- :modelValue="(modelValue as IHomeCommonCategoryDynamicDataRequest)?.otherParams"
- @update:modelValue="(v: Record<string, any>) => setRequest('otherParams', v)"
- />
- </a-form-item>
- <a-form-item label="自定义数据处理脚本 (dataSolve)">
- <a-input
- :value="(modelValue as IHomeCommonCategoryDynamicDataRequest)?.dataSolve"
- @change="(e: Event) => setRequestDataSolve((e.target as HTMLInputElement)?.value)"
- />
- </a-form-item>
- </template>
- <template v-else-if="currentType === 'staticData'">
- <a-form-item label="静态数据 (data)">
- <KeyValueEditor
- :modelValue="{ array: (modelValue as IHomeCommonCategoryDynamicDataStaticData)?.data }"
- @update:modelValue="(v: Record<string, any>) => setStaticData('data', v.array)"
- />
- </a-form-item>
- </template>
- </a-form>
- </div>
- </template>
- <script setup lang="ts">
- import { computed } from 'vue';
- import type {
- IHomeCommonCategoryDynamicData,
- IHomeCommonCategoryDynamicDataCommonContent,
- IHomeCommonCategoryDynamicDataSerializedApi,
- IHomeCommonCategoryDynamicDataRequest,
- IHomeCommonCategoryDynamicDataDetailContent,
- IHomeCommonCategoryDynamicDataParentKey,
- IHomeCommonCategoryDynamicDataStaticData,
- } from '@/pages/article/data/CommonCategoryDynamicData';
- import { SerializedApiMap } from '@/pages/article/data/CommonCategoryDynamicData';
- import KeyValueEditor from './KeyValueEditor.vue';
- import { LinkedinOutlined } from '@ant-design/icons-vue';
- const props = defineProps<{
- modelValue?: IHomeCommonCategoryDynamicData | null;
- }>();
- const emit = defineEmits<{
- (e: 'update:modelValue', v: IHomeCommonCategoryDynamicData | undefined): void;
- }>();
- const typeOptions = [
- { value: 'commonContent', label: '通用内容 (commonContent)' },
- { value: 'detailContent', label: '详情内容 (detailContent)' },
- { value: 'serializedApi', label: '序列化接口 (serializedApi)' },
- { value: 'parentKey', label: '从父键读 (parentKey)' },
- { value: 'request', label: '请求 (request)' },
- ];
- const methodOptions = [
- { value: 'GET', label: 'GET' },
- { value: 'POST', label: 'POST' },
- { value: 'PUT', label: 'PUT' },
- { value: 'DELETE', label: 'DELETE' },
- { value: 'HEAD', label: 'HEAD' },
- { value: 'OPTIONS', label: 'OPTIONS' },
- ];
- const serializedApiOptions = computed(() =>
- Object.keys(SerializedApiMap).map((name) => ({ value: name, label: `${name} (${SerializedApiMap[name].description})` }))
- );
- const currentType = computed(() => props.modelValue?.type ?? null);
- function filterOption(input: string, option: { value: string; label: string }) {
- return option.label.toLowerCase().includes(input.toLowerCase());
- }
- function mainBodyColumnIdDisplay(source: 'commonContent' | 'serializedApi'): string {
- const val = source === 'commonContent'
- ? (props.modelValue as IHomeCommonCategoryDynamicDataCommonContent)?.params?.mainBodyColumnId
- : (props.modelValue as IHomeCommonCategoryDynamicDataSerializedApi)?.params?.mainBodyColumnId;
- if (val == null) return '';
- if (Array.isArray(val)) return val.join(',');
- return String(val);
- }
- function parseMainBodyColumnId(input: string): string | number | number[] | undefined {
- const s = input?.trim();
- if (!s) return undefined;
- const parts = s.split(',').map((p) => p.trim()).filter(Boolean);
- if (parts.length === 0) return undefined;
- if (parts.length === 1) {
- const n = Number(parts[0]);
- return Number.isNaN(n) ? parts[0] : n;
- }
- const nums = parts.map((p) => Number(p));
- return nums.every((n) => !Number.isNaN(n)) ? nums : undefined;
- }
- function onTypeChange(type: 'commonContent' | 'serializedApi' | 'request') {
- if (type === 'commonContent') {
- emit('update:modelValue', {
- type: 'commonContent',
- params: { modelId: 1, mainBodyColumnId: undefined, typeId: undefined },
- otherParams: {},
- });
- } else if (type === 'serializedApi') {
- emit('update:modelValue', {
- type: 'serializedApi',
- name: Object.keys(SerializedApiMap)[0] ?? 'ProjectsContent',
- otherParams: {},
- });
- } else if (type === 'request') {
- emit('update:modelValue', {
- type: 'request',
- method: 'GET',
- url: '',
- otherParams: {},
- });
- } else if (type === 'detailContent') {
- emit('update:modelValue', {
- type: 'detailContent',
- params: { id: 0, modelId: 0 },
- otherParams: {},
- });
- } else if (type === 'parentKey') {
- emit('update:modelValue', {
- type: 'parentKey',
- key: '',
- });
- }
- }
- function setCommonContent(key: 'modelId' | 'typeId'|'otherParams', value: number | Record<string, any> | undefined) {
- const cur = props.modelValue as IHomeCommonCategoryDynamicDataCommonContent | undefined;
- if (!cur || cur.type !== 'commonContent') return;
- const next = { ...cur, params: { ...cur.params, [key]: value } };
- emit('update:modelValue', next);
- }
- function setOtherParams(value: Record<string, any> | undefined) {
- const cur = props.modelValue;
- const next = { ...cur, otherParams: value } as IHomeCommonCategoryDynamicData ;
- emit('update:modelValue', next);
- }
- function setMainBodyColumnId(source: 'commonContent' | 'serializedApi', input: string) {
- const parsed = parseMainBodyColumnId(input);
- if (source === 'commonContent') {
- const cur = props.modelValue as IHomeCommonCategoryDynamicDataCommonContent | undefined;
- if (!cur || cur.type !== 'commonContent') return;
- emit('update:modelValue', { ...cur, params: { ...cur.params, mainBodyColumnId: parsed } });
- } else {
- const cur = props.modelValue as IHomeCommonCategoryDynamicDataSerializedApi | undefined;
- if (!cur || cur.type !== 'serializedApi') return;
- emit('update:modelValue', { ...cur, params: { ...cur.params, mainBodyColumnId: parsed } });
- }
- }
- function setParentKey(key: string) {
- const cur = props.modelValue as IHomeCommonCategoryDynamicDataParentKey | undefined;
- if (!cur || cur.type !== 'parentKey') return;
- emit('update:modelValue', { ...cur, key });
- }
- function setSerializedApi(key: 'name'|'otherParams', value: any) {
- const cur = props.modelValue as IHomeCommonCategoryDynamicDataSerializedApi | undefined;
- if (!cur || cur.type !== 'serializedApi') return;
- emit('update:modelValue', { ...cur, [key]: value });
- }
- function setSerializedApiMainBodyColumnId(input: string) {
- const parsed = parseMainBodyColumnId(input);
- const cur = props.modelValue as IHomeCommonCategoryDynamicDataSerializedApi | undefined;
- if (!cur || cur.type !== 'serializedApi') return;
- const params = { ...cur.params, mainBodyColumnId: parsed };
- emit('update:modelValue', { ...cur, params: Object.keys(params).length ? params : undefined });
- }
- function setRequest(key: 'method' | 'url'|'otherParams'|'querys', value: string|Record<string, any>) {
- const cur = props.modelValue as IHomeCommonCategoryDynamicDataRequest | undefined;
- if (!cur || cur.type !== 'request') return;
- emit('update:modelValue', { ...cur, [key]: value });
- }
- function setDetailContent(key: 'id' | 'modelId', value: number | undefined) {
- const cur = props.modelValue as IHomeCommonCategoryDynamicDataDetailContent | undefined;
- if (!cur || cur.type !== 'detailContent') return;
- const next = { ...cur, params: { ...cur.params, [key]: value } };
- emit('update:modelValue', next);
- }
- function setRequestDataSolve(value: string) {
- const cur = props.modelValue as IHomeCommonCategoryDynamicDataRequest | undefined;
- if (!cur || cur.type !== 'request') return;
- emit('update:modelValue', { ...cur, dataSolve: value });
- }
- function setRequestAddToken(value: boolean) {
- const cur = props.modelValue as IHomeCommonCategoryDynamicDataRequest | undefined;
- if (!cur || cur.type !== 'request') return;
- emit('update:modelValue', { ...cur, addToken: value });
- }
- function setStaticData(key: 'data', value: Record<string, any>[]) {
- const cur = props.modelValue as IHomeCommonCategoryDynamicDataStaticData | undefined;
- if (!cur || cur.type !== 'staticData') return;
- emit('update:modelValue', { ...cur, [key]: value });
- }
- </script>
- <style lang="scss" scoped>
- .dynamic-data-editor {
- font-size: 12px;
- display: flex;
- align-items: flex-start;
- gap: 8px;
- .form {
- flex: 1;
-
- }
- .icon {
- color: #c55900;
- font-size: 16px;
- margin-top: 5px;
- }
- }
- </style>
|