CommonCategoryListBlock.vue 8.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253
  1. <template>
  2. <CommonListPage
  3. v-if="currentCommonCategoryDefine && !loading"
  4. :startTabIndex="pageStartTab"
  5. :hasPadding="hasPadding"
  6. :hasBg="hasBg"
  7. v-bind="currentCommonCategoryDefine.content.props as any || undefined"
  8. :title="currentCommonCategoryDefine.title || undefined"
  9. :load="loadData"
  10. :tabs="tabs"
  11. :dropDownNames="dropdownNames"
  12. :showListTabIds="showListTabIds"
  13. :detailsPage="detailsPage"
  14. :detailsParams="detailsParams"
  15. >
  16. <template #list="{ tabId }">
  17. <CommonCategoryBlocks
  18. v-if="tabRenderDefines[tabId]?.type === 'nestCategory'"
  19. :categoryDefine="tabRenderDefines[tabId].categoryDefine"
  20. :parentData="currentParentData"
  21. />
  22. <CommonCategoryBlocks
  23. v-else-if="tabRenderDefines[tabId]?.type === 'list' && tabRenderDefines[tabId].preInsertCategorys?.length"
  24. :categoryDefine="tabRenderDefines[tabId].categoryDefine"
  25. :parentData="currentParentData"
  26. />
  27. </template>
  28. </CommonListPage>
  29. <LoadingPage v-else />
  30. </template>
  31. <script setup lang="ts">
  32. import { computed, onMounted, ref, watch } from 'vue';
  33. import { navTo } from '@/components/utils/PageAction';
  34. import { doGetDynamicListDataParams, doLoadDynamicCategoryDataMergeTypeGetColumns, doLoadDynamicDropdownData, doLoadDynamicListData } from './CommonCategoryDynamicData';
  35. import { type IHomeCommonCategoryDefine, type IHomeCommonCategoryListDefine, type IHomeCommonCategoryListTabDefine, type IHomeCommonCategoryListTabNestCategoryItemDefine } from './CommonCategoryDefine';
  36. import { resolveCommonContentSolveProps } from '../common/CommonContent';
  37. import { waitTimeOut } from '@imengyu/imengyu-utils';
  38. import type { SimpleDropDownPickerItem } from '@/common/components/SimpleDropDownPicker.vue';
  39. import type { CommonListPageProps, DropDownNames } from '../common/CommonListPage.vue';
  40. import type { CategoryDefine } from './CommonCategoryBlocks';
  41. import CommonListPage from '../common/CommonListPage.vue';
  42. import CommonCategoryBlocks from './CommonCategoryBlocks.vue';
  43. import LoadingPage from '@/components/display/loading/LoadingPage.vue';
  44. /**
  45. * 动态通用内容 - 通用列表页
  46. */
  47. const props = withDefaults(defineProps<{
  48. currentCommonCategoryDefine: IHomeCommonCategoryDefine['page'][0],
  49. currentCommonCategoryContentDefine: IHomeCommonCategoryListDefine,
  50. pageStartTab?: number,
  51. pageQuerys?: Record<string, any>,
  52. parentData?: any,
  53. hasPadding?: boolean,
  54. hasBg?: boolean,
  55. }>(), {
  56. pageStartTab: 0,
  57. pageQuerys: () => ({}),
  58. hasPadding: true,
  59. hasBg: true,
  60. });
  61. const emit = defineEmits<{
  62. (e: 'error', error: any): void;
  63. }>();
  64. const loading = ref(false);
  65. async function loadPageConfig() {
  66. loading.value = true;
  67. await waitTimeOut(50);
  68. try {
  69. //特殊处理
  70. let hasNestCategory = false;
  71. for (const [_, tab] of Object.entries(tabDefines.value)) {
  72. if (tab.type === 'nestCategory') {
  73. tab.categorys = await doLoadDynamicCategoryDataMergeTypeGetColumns(tab.categorys)
  74. hasNestCategory = true;
  75. } else if (tab.type === 'list') {
  76. tab.preInsertCategorys = await doLoadDynamicCategoryDataMergeTypeGetColumns(tab.preInsertCategorys || [])
  77. hasNestCategory = true;
  78. }
  79. }
  80. if (hasNestCategory)
  81. await waitTimeOut(50);
  82. //加载下拉列表
  83. const result = [] as DropDownNames[];
  84. for (const [key, tab] of Object.entries(tabRenderDefines.value)) {
  85. if (tab.type !== 'list')
  86. continue;
  87. if (tab.dropdownDefines) {
  88. for (const dropdown of tab.dropdownDefines) {
  89. const data : SimpleDropDownPickerItem[] = (dropdown.addAll ? [{
  90. id: 0,
  91. name: dropdown.addAll
  92. }] : []);
  93. if (dropdown.data) {
  94. data.push(...(await doLoadDynamicDropdownData(dropdown.data)).map((item) => ({
  95. id: item[dropdown.data.idKey || 'id'],
  96. name: item[dropdown.data.nameKey || 'title'],
  97. })))
  98. }
  99. result.push({
  100. options: data,
  101. activeTab: [Number(key)],
  102. defaultSelectedValue: dropdown.formQueryKey ? (
  103. props.pageQuerys[dropdown.formQueryKey] as number || 0
  104. ) : dropdown.defaultValue || 0,
  105. })
  106. }
  107. }
  108. }
  109. dropdownNames.value = result;
  110. } catch (error) {
  111. emit('error', error);
  112. } finally {
  113. loading.value = false;
  114. }
  115. }
  116. watch(() => props.currentCommonCategoryDefine, loadPageConfig, { immediate: true });
  117. watch(() => props.currentCommonCategoryDefine?.content, loadPageConfig);
  118. watch(() => props.currentCommonCategoryContentDefine, loadPageConfig);
  119. onMounted(loadPageConfig);
  120. type RenderTabDefine = IHomeCommonCategoryListTabDefine & {
  121. categoryDefine?: CategoryDefine[];
  122. };
  123. const tabDefines = computed(() => props.currentCommonCategoryContentDefine?.props.tabs || []);
  124. const tabRenderDefines = computed(() => {
  125. const result = {} as Record<number, RenderTabDefine>;
  126. try {
  127. tabDefines.value.forEach((item, i) => {
  128. const renderItem : RenderTabDefine = {
  129. ...item,
  130. };
  131. function loadNestCategoryData(items: IHomeCommonCategoryListTabNestCategoryItemDefine[]) {
  132. return items
  133. .filter((item) => item.visible !== false)
  134. .map((item) => {
  135. return {
  136. ...item,
  137. showTitle: item.showTitle !== false,
  138. title: item.text,
  139. content: item.data,
  140. type: item.type as CategoryDefine['type'],
  141. }
  142. });
  143. }
  144. switch (item.type) {
  145. case 'list':
  146. renderItem.categoryDefine = loadNestCategoryData(item.preInsertCategorys || []);
  147. break;
  148. case 'jump':
  149. break;
  150. case 'nestCategory':
  151. renderItem.categoryDefine = loadNestCategoryData(item.categorys);
  152. break;
  153. }
  154. result[i] = renderItem;
  155. });
  156. } catch (error) {
  157. emit('error', error);
  158. }
  159. return result;
  160. });
  161. const showListTabIds = computed(() => {
  162. const define = tabDefines.value;
  163. if (define.length === 0)
  164. return undefined;
  165. return define
  166. .map((item, i) => ({ type: item.type, id: i }))
  167. .filter((item) => item.type === 'list')
  168. .map((item) => item.id);
  169. })
  170. const tabs = computed<CommonListPageProps['tabs']>(() => {
  171. const define = tabDefines.value;
  172. return define.filter((item) => item.visible !== false).map((item, i) => {
  173. switch (item.type) {
  174. default:
  175. case 'list':
  176. return {
  177. id: i,
  178. text: item.text,
  179. width: item.width,
  180. };
  181. case 'jump':
  182. return {
  183. id: i,
  184. text: item.text,
  185. onlyJump: true,
  186. jump: () => navTo(item.url, item.params),
  187. width: item.width,
  188. };
  189. case 'nestCategory':
  190. return {
  191. id: i,
  192. text: item.text,
  193. width: item.width,
  194. };
  195. }
  196. });
  197. });
  198. const dropdownNames = ref<DropDownNames[]>([]);
  199. const detailsPage = computed(() => {
  200. if (tabDefines.value.find((item) => item.detailsPage)) {
  201. const result = {} as Record<number, string|[string, Record<string, any>]>;
  202. tabDefines.value.forEach((item, i) => {
  203. result[i] = item.detailsPage || '';
  204. });
  205. return result;
  206. }
  207. return props.currentCommonCategoryContentDefine?.props.detailsPage || undefined;
  208. });
  209. const detailsParams = ref<Record<string, any>>({});
  210. const currentParentData = ref<any[]>([]);
  211. async function loadData(
  212. page: number,
  213. pageSize: number,
  214. searchText: string,
  215. dropDownValues: number[],
  216. tabSelect: number
  217. ) {
  218. const tab = tabRenderDefines.value[tabSelect];
  219. if (!tab)
  220. throw new Error(`配置有误 tab:${tabSelect}`);
  221. if (tab.type !== 'list')
  222. return { list: [], total: 0 };
  223. if (!tab.data)
  224. throw new Error(`配置有误 tab:${tabSelect} 没有配置列表数据`);
  225. detailsParams.value = {
  226. ...(doGetDynamicListDataParams(tab.data)),
  227. };
  228. const res = await doLoadDynamicListData(
  229. tab.data,
  230. page,
  231. pageSize,
  232. searchText,
  233. tab.dropdownDefines || [],
  234. dropDownValues,
  235. props.parentData,
  236. );
  237. if (res && tab.dataSolve)
  238. res.list = resolveCommonContentSolveProps(res.list, tab.dataSolve);
  239. currentParentData.value = res?.list || [];
  240. return res;
  241. }
  242. </script>