common.vue 7.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247
  1. <template>
  2. <view>
  3. <CommonRoot>
  4. <LoadingPage v-if="loading" />
  5. <FlexCol :padding="30">
  6. <Alert
  7. v-if="localSavedState"
  8. type="info"
  9. message="您的修改已经暂存,可以放心离开,下次接着编辑"
  10. />
  11. <Height :height="20" />
  12. <DynamicForm
  13. ref="formRef"
  14. :options="formDefine"
  15. :model="formModel"
  16. :globalParams="querys"
  17. />
  18. <Height :height="20" />
  19. <Button v-if="querys.isView" type="primary" :loading="loading" @click="backPrev(false)">返回</Button>
  20. <Button v-else type="primary" :loading="loading" @click="submit">提交</Button>
  21. </FlexCol>
  22. <XBarSpace />
  23. </CommonRoot>
  24. </view>
  25. </template>
  26. <script setup lang="ts">
  27. import { nextTick, ref, watch, type Ref } from 'vue';
  28. import { useCollectStore } from '@/store/collect';
  29. import { useLoadQuerys } from '@/common/composeabe/LoadQuerys';
  30. import { getVillageInfoForm, getVillageInfoFormIds, type SingleForm } from './forms';
  31. import { showError } from '@/common/composeabe/ErrorDisplay';
  32. import { backAndCallOnPageBack } from '@/components/utils/PageAction';
  33. import { toast } from '@/components/utils/DialogAction';
  34. import { confirm } from '@/components/dialog/CommonRoot';
  35. import { Debounce, ObjectUtils, RequestApiError, waitTimeOut } from '@imengyu/imengyu-utils';
  36. import VillageInfoApi, { CommonInfoModel } from '@/api/inhert/VillageInfoApi';
  37. import DynamicForm from '@/components/dynamic/DynamicForm.vue';
  38. import LoadingPage from '@/components/display/loading/LoadingPage.vue';
  39. import Button from '@/components/basic/Button.vue';
  40. import CommonRoot from '@/components/dialog/CommonRoot.vue';
  41. import FlexCol from '@/components/layout/FlexCol.vue';
  42. import Height from '@/components/layout/space/Height.vue';
  43. import XBarSpace from '@/components/layout/space/XBarSpace.vue';
  44. import type { IDynamicFormOptions, IDynamicFormRef } from '@/components/dynamic';
  45. import Alert from '@/components/feedback/Alert.vue';
  46. const loading = ref(false);
  47. const subTitle = ref('');
  48. const collectStore = useCollectStore();
  49. const formRef = ref<IDynamicFormRef>();
  50. const formModel = ref(new CommonInfoModel()) as Ref<CommonInfoModel>;
  51. const formDefine = ref<IDynamicFormOptions>({
  52. formItems: [],
  53. formAdditionaProps: {
  54. labelWidth: '220rpx',
  55. labelAlign: 'left',
  56. innerStyle: {
  57. borderRadius: '20rpx',
  58. overflow: 'hidden',
  59. },
  60. },
  61. });
  62. let currentFormInfo : SingleForm|null = null;
  63. const { querys } = useLoadQuerys({
  64. villageId: 0,
  65. villageVolunteerId: 0,
  66. catalogId: 0,
  67. subType: '',
  68. subId: 0,
  69. subKey: '',
  70. subTitle: '',
  71. id: 0,
  72. isView: false,
  73. }, async (querys) => {
  74. loading.value = true;
  75. if (querys.subTitle) {
  76. subTitle.value = querys.subTitle;
  77. uni.setNavigationBarTitle({ title: subTitle.value + '详情', })
  78. }
  79. if (!formRef.value)
  80. return;
  81. let formData = undefined;
  82. await waitTimeOut(800);
  83. try {
  84. currentFormInfo = getVillageInfoForm(querys.subType, querys.subId);
  85. const [model, forms] = currentFormInfo;
  86. formModel.value = new model() as any;
  87. formDefine.value = {
  88. ...formDefine.value,
  89. ...forms(formRef as any),
  90. readonly: querys.isView,
  91. disabled: querys.isView,
  92. };
  93. if (querys.id >= 0) {
  94. let findId = querys.id;
  95. if (querys.subType === 'overview') {
  96. const list = await VillageInfoApi.getList(
  97. collectStore.getCollectModuleId(querys.subType),
  98. querys.subType,
  99. undefined,
  100. undefined,
  101. querys.villageId,
  102. querys.villageVolunteerId,
  103. querys.catalogId,
  104. );
  105. if (list?.length > 0)
  106. findId = list[0].id;
  107. }
  108. formData = await VillageInfoApi.getInfo(
  109. collectStore.getCollectModuleId(querys.subType),
  110. querys.subType,
  111. querys.subId,
  112. querys.subKey,
  113. querys.villageId,
  114. querys.villageVolunteerId,
  115. querys.catalogId,
  116. findId,
  117. model,
  118. );
  119. }
  120. } catch (e) {
  121. console.log(e);
  122. if (!(e instanceof RequestApiError && e.errorMessage.startsWith('请完成')))
  123. showError(e, undefined, () => backPrev(false));
  124. } finally {
  125. loading.value = false;
  126. }
  127. if (!querys.isView) {
  128. try {
  129. formData = await loadLocalSave(formData as CommonInfoModel);
  130. } catch (e) {
  131. console.log(e);
  132. showError(e, '加载本地保存数据失败');
  133. }
  134. }
  135. if (formData)
  136. formModel.value = formData as any;
  137. await nextTick();
  138. await waitTimeOut(400);
  139. formRef.value.initDefaultValuesToModel();
  140. console.log(formModel.value);
  141. await waitTimeOut(1000);
  142. if (!querys.isView)
  143. canSaveNow = true;
  144. });
  145. async function submit() {
  146. if (!formRef.value)
  147. return;
  148. try {
  149. await formRef.value.validate();
  150. } catch {
  151. toast('有必填项未填写,请检查');
  152. return;
  153. }
  154. try {
  155. loading.value = true;
  156. await waitTimeOut(800);
  157. await VillageInfoApi.updateInfo(
  158. collectStore.getCollectModuleId(querys.value.subType),
  159. querys.value.subType,
  160. querys.value.subKey,
  161. querys.value.subId,
  162. querys.value.villageId,
  163. querys.value.villageVolunteerId,
  164. querys.value.catalogId,
  165. formModel.value as CommonInfoModel,
  166. );
  167. deleteLocalSave();
  168. confirm({
  169. content: '您的提交已成功,感谢您的参与!',
  170. cancelText: '继续编辑',
  171. confirmText: '返回列表',
  172. icon: 'success',
  173. onConfirm: () => backPrev(true),
  174. })
  175. } catch (e) {
  176. showError(e);
  177. } finally {
  178. loading.value = false;
  179. }
  180. }
  181. function backPrev(needRefresh: boolean) {
  182. backAndCallOnPageBack('list', {
  183. needRefresh,
  184. });
  185. }
  186. const localSavedState = ref(false);
  187. const saveLocalSaveDebounce = new Debounce(1000, saveLocalSave);
  188. let canSaveNow = false;
  189. function getSaveName() {
  190. return `FormLocalSave-${querys.value.id}-${querys.value.subType}-${querys.value.subId}-${querys.value.villageId}-${querys.value.villageVolunteerId}`;
  191. }
  192. async function loadLocalSave(formData: CommonInfoModel|undefined) {
  193. if (!currentFormInfo)
  194. return formData;
  195. console.log('加载暂存数据');
  196. const saveName = getSaveName();
  197. const saveData = uni.getStorageSync(saveName);
  198. if (saveData) {
  199. const res = await confirm({
  200. content: '您有上次编辑未完成的内容,是否要从上次的编辑数据继续?',
  201. cancelText: '取消',
  202. confirmText: '继续',
  203. icon: 'prompt',
  204. })
  205. if (res) {
  206. const d = JSON.parse(saveData);
  207. d.id = 0;
  208. formData = new currentFormInfo[0]().fromServerSide(d) as CommonInfoModel;
  209. console.log('有暂存数据', formData);
  210. } else
  211. deleteLocalSave();
  212. }
  213. return formData;
  214. }
  215. function deleteLocalSave() {
  216. const saveName = getSaveName();
  217. uni.removeStorageSync(saveName);
  218. localSavedState.value = false;
  219. }
  220. function saveLocalSave() {
  221. const saveName = getSaveName();
  222. uni.setStorageSync(saveName, JSON.stringify(formModel.value.toServerSide()));
  223. localSavedState.value = true;
  224. console.log('保存暂存数据');
  225. }
  226. watch(formModel, () => {
  227. if (!canSaveNow)
  228. return;
  229. saveLocalSaveDebounce.executeWithDelay();
  230. }, { deep: true })
  231. </script>