Browse Source

🎨 按要求调整栏目

快乐的梦鱼 4 days ago
parent
commit
649b4b3f32

+ 3 - 0
src/pages/article/common/CommonContent.ts

@@ -32,6 +32,7 @@ export function navCommonList(p: {
   mainBodyColumnId?: string|number|number[],
   mainBodyColumnId?: string|number|number[],
   modelId?: number,
   modelId?: number,
   itemType?: string,
   itemType?: string,
+  dataSolve?: IHomeCommonCategoryListTabListDataSolve[],
   detailsPage? : string|[string, Record<string, any>],
   detailsPage? : string|[string, Record<string, any>],
 }) {
 }) {
   navTo('/pages/article/common/list', {
   navTo('/pages/article/common/list', {
@@ -42,6 +43,7 @@ export function navCommonList(p: {
     modelId: p.modelId,
     modelId: p.modelId,
     itemType: p.itemType || 'article-common',
     itemType: p.itemType || 'article-common',
     detailsPage: p.detailsPage || '/pages/article/details',
     detailsPage: p.detailsPage || '/pages/article/details',
+    dataSolve: (p.dataSolve || []).join(','),
   }) 
   }) 
 }
 }
 
 
@@ -143,6 +145,7 @@ export function useHomeCommonCategoryBlock(p: HomeCommonCategoryBlockProps, load
         p.mainBodyColumnId,
         p.mainBodyColumnId,
       modelId: p.modelId,
       modelId: p.modelId,
       itemType: p.itemType,
       itemType: p.itemType,
+      dataSolve: p.dataSolve || [],
       detailsPage: p.detailsPage,
       detailsPage: p.detailsPage,
     }) 
     }) 
   }
   }

+ 9 - 1
src/pages/article/common/list.vue

@@ -16,7 +16,8 @@
 import { useLoadQuerys, stringDotNumbersToNumbers } from '@/common/composeabe/LoadQuerys';
 import { useLoadQuerys, stringDotNumbersToNumbers } from '@/common/composeabe/LoadQuerys';
 import CommonListPage from './CommonListPage.vue';
 import CommonListPage from './CommonListPage.vue';
 import CommonContent, { GetContentListParams } from '@/api/CommonContent';
 import CommonContent, { GetContentListParams } from '@/api/CommonContent';
-import { resolveCommonContentGetPageDetailUrlAuto } from './CommonContent';
+import { resolveCommonContentGetPageDetailUrlAuto, resolveCommonContentSolveProps } from './CommonContent';
+import type { IHomeCommonCategoryListTabListDataSolve } from '../data/CommonCategoryDefine';
 
 
 const { querys } = useLoadQuerys({
 const { querys } = useLoadQuerys({
   mainBodyColumnId: '',
   mainBodyColumnId: '',
@@ -25,6 +26,7 @@ const { querys } = useLoadQuerys({
   detailsPage: '',
   detailsPage: '',
   title: '',
   title: '',
   region: '',
   region: '',
+  dataSolve: '',
 });
 });
 
 
 async function loadData(
 async function loadData(
@@ -42,6 +44,12 @@ async function loadData(
     region: querys.value.region || undefined,
     region: querys.value.region || undefined,
   }), page, pageSize);
   }), page, pageSize);
 
 
+  if (querys.value.dataSolve) {
+    res.list = resolveCommonContentSolveProps(
+      res.list, 
+      querys.value.dataSolve.split(',') as IHomeCommonCategoryListTabListDataSolve[]);
+  }
+
   return res;
   return res;
 }
 }
 </script>
 </script>

+ 1 - 0
src/pages/article/data/CommonCategoryBlocks.vue

@@ -239,6 +239,7 @@ const categoryDatas = computed(() => props.categoryDefine.map(item => {
             mainBodyColumnId: content.mainBodyColumnId,
             mainBodyColumnId: content.mainBodyColumnId,
             modelId: content.modelId,
             modelId: content.modelId,
             detailsPage: item.detailsPage,
             detailsPage: item.detailsPage,
+            dataSolve: item.dataSolve || [],
           })
           })
         }
         }
       },
       },

+ 1 - 1
src/pages/article/data/CommonCategoryDetail.vue

@@ -28,7 +28,7 @@
             :content="content.content"
             :content="content.content"
           />
           />
           <text v-if="!(content.intro || content.content)">暂无简介</text>
           <text v-if="!(content.intro || content.content)">暂无简介</text>
-          <text v-if="content.from" class="size-s color-text-content-second mr-2 ">以上内容摘自 {{ content.from }}</text>
+          <text v-if="content.from" class="size-s color-text-content-second mr-2 ">以上内容摘自{{ content.from }}</text>
         </template>
         </template>
         <template v-else-if="tabRenderDefines[tabCurrentId].type === 'images'">
         <template v-else-if="tabRenderDefines[tabCurrentId].type === 'images'">
           <!-- 图片 -->
           <!-- 图片 -->

+ 2 - 2
src/pages/article/data/CommonCategoryGlobalLoader.ts

@@ -24,10 +24,10 @@ export function useCommonCategoryGlobalLoader() {
   async function loadCommonCategory() {
   async function loadCommonCategory() {
     uni.showLoading({ title: '加载中' });
     uni.showLoading({ title: '加载中' });
     try {
     try {
-      if (uni.getSystemInfoSync().platform === 'devtools') {
+      /* if (uni.getSystemInfoSync().platform === 'devtools') {
         commonCategoryData.value = DefaultCofig as IHomeCommonCategoryDefine;
         commonCategoryData.value = DefaultCofig as IHomeCommonCategoryDefine;
         return;
         return;
-      }
+      } */
       const category = (await CommonCategoryApi.getConfig()) as any as IHomeCommonCategoryDefine;
       const category = (await CommonCategoryApi.getConfig()) as any as IHomeCommonCategoryDefine;
       if (category)
       if (category)
         commonCategoryData.value = category;
         commonCategoryData.value = category;

+ 1 - 1
src/pages/article/data/CommonCategoryPathDefine.ts

@@ -1,2 +1,2 @@
 export const CommonCategoryListPath = '/pages/article/data/list';
 export const CommonCategoryListPath = '/pages/article/data/list';
-export const CommonCategoryDetailPath = '/pages/article/data/detail';
+export const CommonCategoryDetailPath = '/pages/article/data/details';

+ 5 - 0
src/pages/article/data/data-defines/Category.ts

@@ -22,6 +22,10 @@ export interface IHomeCommonCategoryCategoryDynamicDataMergeTypeGetColumns {
     overrideItems: ({
     overrideItems: ({
       id: number,
       id: number,
     } & IHomeCommonCategoryListTabNestCategoryItemDefine)[],
     } & IHomeCommonCategoryListTabNestCategoryItemDefine)[],
+    /**
+     * 每个单元的接口其他参数
+     */
+    otherParams?: Record<string, any>,
   },
   },
 }
 }
 /**
 /**
@@ -77,6 +81,7 @@ export async function doLoadDynamicCategoryDataMergeTypeGetColumns(
                   modelId: item.modelId,
                   modelId: item.modelId,
                   mainBodyColumnId: item.id,
                   mainBodyColumnId: item.id,
                 },
                 },
+                otherParams: data.params.otherParams,
               } as IHomeCommonCategoryDynamicDataCommonContent,
               } as IHomeCommonCategoryDynamicDataCommonContent,
             }
             }
           });   
           });   

+ 6 - 4
src/pages/article/data/editor/components/KeyValueEditor.vue

@@ -67,17 +67,18 @@ const props = defineProps<{
    * 默认创建的项的模板。当用户点击添加项时,会根据这个模板创建新的项。
    * 默认创建的项的模板。当用户点击添加项时,会根据这个模板创建新的项。
    * @default { key: '', value: '', type: 'string' }
    * @default { key: '', value: '', type: 'string' }
    */
    */
-  defaultCreateTemplate?: LocalItem;
+  defaultCreateTemplate?: Omit<LocalItem, 'ukey'>;
 }>();
 }>();
 const emit = defineEmits<{
 const emit = defineEmits<{
   (e: 'update:modelValue', value: Record<string, any>): void;
   (e: 'update:modelValue', value: Record<string, any>): void;
 }>();
 }>();
 
 
+type LocalItemType = 'string' | 'number' | 'boolean' | 'object' | 'array' | 'null';
 type LocalItem = {
 type LocalItem = {
   key: string;
   key: string;
   ukey: string;
   ukey: string;
   value: any;
   value: any;
-  type: 'string' | 'number' | 'boolean' | 'object' | 'array' | 'null';
+  type: LocalItemType;
 };
 };
 
 
 const modalVisible = ref(false);
 const modalVisible = ref(false);
@@ -184,11 +185,12 @@ const updateKey = (item: LocalItem) => {
 
 
 // 添加项
 // 添加项
 const addItem = () => {
 const addItem = () => {
-  const template = props.defaultCreateTemplate || {
+  const template = {
     key: `key${localItems.value.length + 1}`,
     key: `key${localItems.value.length + 1}`,
     value: '',
     value: '',
     ukey: RandomUtils.genNonDuplicateIDHEX(10),
     ukey: RandomUtils.genNonDuplicateIDHEX(10),
-    type: 'string',
+    type: 'string' as LocalItemType,
+    ...props.defaultCreateTemplate,
   };
   };
   template.key = getUseableKey(template);
   template.key = getUseableKey(template);
   localItems.value.push(template);
   localItems.value.push(template);

+ 17 - 23
src/pages/article/data/editor/components/LinkPathEditor.vue

@@ -8,14 +8,15 @@
               v-model:value="pathType" 
               v-model:value="pathType" 
               style="width: 120px; margin-right: 8px"
               style="width: 120px; margin-right: 8px"
             >
             >
-              <a-select-option v-if="!props.noParams" value="dynamic-list">动态页面列表</a-select-option>
+              <a-select-option v-if="!props.noParams" value="dynamic-list">动态列表页面</a-select-option>
+              <a-select-option v-if="!props.noParams" value="dynamic-detail">动态详情页面</a-select-option>
               <a-select-option value="internal">程序内置页面</a-select-option>
               <a-select-option value="internal">程序内置页面</a-select-option>
               <a-select-option value="custom">自定义输入</a-select-option>
               <a-select-option value="custom">自定义输入</a-select-option>
             </a-select>
             </a-select>
             
             
             <!-- 动态页面地址 -->
             <!-- 动态页面地址 -->
             <a-select 
             <a-select 
-              v-if="pathType === 'dynamic-list'"
+              v-if="pathType === 'dynamic-list' || pathType === 'dynamic-detail'"
               v-model:value="localPageConfigName"
               v-model:value="localPageConfigName"
               style="flex: 1"
               style="flex: 1"
               @change="updateLink"
               @change="updateLink"
@@ -57,11 +58,12 @@
             />
             />
           </div>
           </div>
         </a-form-item>    
         </a-form-item>    
-        <a-form-item v-if="!props.noParams && pathType !== 'dynamic-list'" label="参数设置">
+        <a-form-item v-if="!props.noParams && pathType !== 'dynamic-list' && pathType !== 'dynamic-detail'" label="参数设置">
           <KeyValueEditor
           <KeyValueEditor
-            v-model="localParams"
+            :modelValue="localParams"
             :forceOneLevel="true"
             :forceOneLevel="true"
             :defaultCreateTemplate="{ key: '', value: '', type: 'string' }"
             :defaultCreateTemplate="{ key: '', value: '', type: 'string' }"
+            @update:modelValue="localParams = $event"
           />
           />
         </a-form-item>
         </a-form-item>
       </a-collapse-panel>
       </a-collapse-panel>
@@ -74,7 +76,7 @@ import { inject, ref, watch, computed } from 'vue';
 import KeyValueEditor from './KeyValueEditor.vue';
 import KeyValueEditor from './KeyValueEditor.vue';
 import type { IHomeCommonCategoryDefine } from '@/pages/article/data/CommonCategoryDefine';
 import type { IHomeCommonCategoryDefine } from '@/pages/article/data/CommonCategoryDefine';
 import PagesJson from '@/pages.json';
 import PagesJson from '@/pages.json';
-import { CommonCategoryListPath } from '@/pages/article/data/CommonCategoryPathDefine';
+import { CommonCategoryDetailPath, CommonCategoryListPath } from '@/pages/article/data/CommonCategoryPathDefine';
 
 
 /** 从 URL 字符串中解析路径和 ? 后面的查询参数 */
 /** 从 URL 字符串中解析路径和 ? 后面的查询参数 */
 function parseUrlParams(url: string): { path: string; params: Record<string, string> } {
 function parseUrlParams(url: string): { path: string; params: Record<string, string> } {
@@ -130,7 +132,7 @@ const pageList = inject<(IHomeCommonCategoryDefine['page'][0])[]>('pageList', []
 const activeKey = ref('');
 const activeKey = ref('');
 
 
 // 跳转路径类型
 // 跳转路径类型
-const pathType = ref<'dynamic-list' | 'internal' | 'custom'>('custom');
+const pathType = ref<'dynamic-list' | 'dynamic-detail' | 'internal' | 'custom'>('custom');
 // 跳转路径
 // 跳转路径
 const linkPath = ref('');
 const linkPath = ref('');
 const localPageConfigName = ref('');
 const localPageConfigName = ref('');
@@ -146,13 +148,10 @@ const internalPages = computed(() => {
   }));
   }));
 });
 });
 
 
-let noUpdate = false;
-
 // 监听 modelValue:从 URL 字符串解析路径与 ? 后参数
 // 监听 modelValue:从 URL 字符串解析路径与 ? 后参数
 watch(
 watch(
   () => props.modelValue,
   () => props.modelValue,
   (newValue) => {
   (newValue) => {
-    noUpdate = true;
     const urlStr = typeof newValue === 'string' ? newValue : '';
     const urlStr = typeof newValue === 'string' ? newValue : '';
     const { path, params } = parseUrlParams(urlStr);
     const { path, params } = parseUrlParams(urlStr);
     linkPath.value = path;
     linkPath.value = path;
@@ -160,30 +159,20 @@ watch(
     if (linkPath.value === CommonCategoryListPath) {
     if (linkPath.value === CommonCategoryListPath) {
       pathType.value = 'dynamic-list';
       pathType.value = 'dynamic-list';
       localPageConfigName.value = localParams.value.pageConfigName || '';
       localPageConfigName.value = localParams.value.pageConfigName || '';
-    } else if (linkPath.value.startsWith('/pages/')) {
+    } else if (linkPath.value === CommonCategoryDetailPath) {
+      pathType.value = 'dynamic-detail';
+      localPageConfigName.value = localParams.value.pageConfigName || '';
+    } else  if (linkPath.value.startsWith('/pages/')) {
       pathType.value = 'internal';
       pathType.value = 'internal';
     } else {
     } else {
       pathType.value = 'custom';
       pathType.value = 'custom';
     }
     }
-    setTimeout(() => {
-      noUpdate = false;
-    }, 200);
   },
   },
   { deep: true, immediate: true }
   { deep: true, immediate: true }
 );
 );
-watch(
-  localParams,
-  () => {
-    updateLink();
-  },
-  { deep: true }
-);
 
 
 // 更新链接:输出为带 ? 参数的完整 URL 字符串
 // 更新链接:输出为带 ? 参数的完整 URL 字符串
 const updateLink = () => {
 const updateLink = () => {
-  if (noUpdate) {
-    return;
-  }
   if (props.noParams) {
   if (props.noParams) {
     emit('update:modelValue', linkPath.value);
     emit('update:modelValue', linkPath.value);
     return;
     return;
@@ -193,6 +182,11 @@ const updateLink = () => {
       pageConfigName: localPageConfigName.value || '',
       pageConfigName: localPageConfigName.value || '',
     };
     };
     linkPath.value = CommonCategoryListPath;
     linkPath.value = CommonCategoryListPath;
+  } else if (pathType.value === 'dynamic-detail') {
+    localParams.value = {
+      pageConfigName: localPageConfigName.value || '',
+    };
+    linkPath.value = CommonCategoryDetailPath;
   }
   }
   emit('update:modelValue', buildUrlWithParams(linkPath.value, localParams.value));
   emit('update:modelValue', buildUrlWithParams(linkPath.value, localParams.value));
 };
 };

+ 4 - 4
src/pages/article/data/editor/components/ValueEditor.vue

@@ -166,19 +166,19 @@ const changeType = (newType: LocalItemType) => {
   
   
   switch (newType) {
   switch (newType) {
     case 'string':
     case 'string':
-      newValue = '';
+      newValue = '' + (props.modelValue || '');
       break;
       break;
     case 'number':
     case 'number':
-      newValue = 0;
+      newValue = Number(props.modelValue) || 0;
       break;
       break;
     case 'boolean':
     case 'boolean':
       newValue = false;
       newValue = false;
       break;
       break;
     case 'object':
     case 'object':
-      newValue = {};
+      newValue = JSON.parse(JSON.stringify(props.modelValue)) || {};
       break;
       break;
     case 'array':
     case 'array':
-      newValue = [];
+      newValue = JSON.parse(JSON.stringify(props.modelValue)) || [];
       break;
       break;
     case 'null':
     case 'null':
       newValue = null;
       newValue = null;

+ 19 - 8
src/pages/article/data/editor/subpart/NestCategoryEditor.vue

@@ -43,13 +43,19 @@
               <a-checkbox v-model:checked="cat.visible" :indeterminate="cat.visible === undefined" />
               <a-checkbox v-model:checked="cat.visible" :indeterminate="cat.visible === undefined" />
             </a-form-item>
             </a-form-item>
             <a-form-item label="类型">
             <a-form-item label="类型">
-              <a-select v-model:value="cat.type" style="width: 100%" allowClear placeholder="请选择类型" @change="onTypeChange(cat, $event)">
+              <a-select
+                v-model:value="cat.type"
+                style="width: 100%"
+                allowClear
+                placeholder="请选择类型"
+                @change="onTypeChange(cat, $event)"
+              >
                 <a-select-option v-for="type in blockTypes" :key="type" :value="type">
                 <a-select-option v-for="type in blockTypes" :key="type" :value="type">
                   {{ type }}
                   {{ type }}
                 </a-select-option>
                 </a-select-option>
               </a-select>
               </a-select>
             </a-form-item>
             </a-form-item>
-            <template v-if="cat.type.startsWith('speicalMergeItem:')">
+            <template v-if="cat.type?.startsWith('speicalMergeItem:getColumns')">
               <a-divider>合并配置 (getColumns)</a-divider>
               <a-divider>合并配置 (getColumns)</a-divider>
               <a-form-item label="模型ID">
               <a-form-item label="模型ID">
                 <a-input-number v-model:value="getMergeParams(cat, 'getColumns').modelId" style="width: 100%" placeholder="模型ID" />
                 <a-input-number v-model:value="getMergeParams(cat, 'getColumns').modelId" style="width: 100%" placeholder="模型ID" />
@@ -69,7 +75,7 @@
                 <a-button type="dashed" size="small" @click="addOverrideItem(cat)">+ 添加替换项</a-button>
                 <a-button type="dashed" size="small" @click="addOverrideItem(cat)">+ 添加替换项</a-button>
               </a-form-item>
               </a-form-item>
             </template>
             </template>
-            <template v-else-if="cat.type.startsWith('speicalMergeItem:')">
+            <template v-else-if="cat.type?.startsWith('speicalMergeItem:getColumn')">
               <a-divider>合并配置 (getColumn)</a-divider>
               <a-divider>合并配置 (getColumn)</a-divider>
               <a-form-item label="模型ID">
               <a-form-item label="模型ID">
                 <a-input-number v-model:value="getMergeParams(cat, 'getColumn').modelId" style="width: 100%" placeholder="模型ID" />
                 <a-input-number v-model:value="getMergeParams(cat, 'getColumn').modelId" style="width: 100%" placeholder="模型ID" />
@@ -94,7 +100,7 @@
               <ItemTypeEditor v-model="cat.itemType" />
               <ItemTypeEditor v-model="cat.itemType" />
             </a-form-item>
             </a-form-item>
             <a-form-item label="列表页详情页">
             <a-form-item label="列表页详情页">
-              <LinkPathEditor v-model:value="cat.detailsPage" />
+              <LinkPathEditor v-model="cat.detailsPage" />
             </a-form-item>
             </a-form-item>
             <a-popconfirm title="确定删除该子分类吗?" @confirm="remove(i)">
             <a-popconfirm title="确定删除该子分类吗?" @confirm="remove(i)">
               <a-button type="link" danger size="small">删除子分类</a-button>
               <a-button type="link" danger size="small">删除子分类</a-button>
@@ -130,10 +136,15 @@ const emit = defineEmits<{
   (e: 'update:categorys', categorys: IHomeCommonCategoryListTabNestCategoryItemDefine[]): void;
   (e: 'update:categorys', categorys: IHomeCommonCategoryListTabNestCategoryItemDefine[]): void;
 }>();
 }>();
 
 
-const blockTypes = (CommonCategoryBlockType as string[]).concat([
-  'speicalMergeItem:getColumns',
-  'speicalMergeItem:getColumn',
-]);
+const blockTypes = (CommonCategoryBlockType as string[]).concat(
+  [
+    'speicalMergeItem:getColumns',
+    'speicalMergeItem:getColumn',
+  ].map((type) => (
+    CommonCategoryBlockType.map(p => `${type}:${p}`)
+  ))
+  .flat()
+);
 const titleLevels = ['h1', 'h2', 'h3'];
 const titleLevels = ['h1', 'h2', 'h3'];
 
 
 function getCategorys() {
 function getCategorys() {

+ 1 - 1
src/pages/article/details.vue

@@ -44,7 +44,7 @@
               :content="loader.content.value.content"
               :content="loader.content.value.content"
             />
             />
             <text v-if="emptyContent">暂无简介</text>
             <text v-if="emptyContent">暂无简介</text>
-            <text v-if="loader.content.value.from" class="size-s color-text-content-second mr-2 ">以上内容摘自 {{ loader.content.value.from }}</text>
+            <text v-if="loader.content.value.from" class="size-s color-text-content-second mr-2 ">以上内容摘自{{ loader.content.value.from }}</text>
           </view>
           </view>
           
           
           <!-- 推荐 -->
           <!-- 推荐 -->