CommonCategoryList.vue 9.1 KB

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