common.vue 6.7 KB

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