Form.vue.vm 17 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416
  1. #parse("PublicMacro/FormMarco.vm")
  2. <template>
  3. ## 全屏弹窗
  4. #if(${context.popupType}=="fullScreen")
  5. ##<!-- 全屏弹窗 -->
  6. <BasicPopup v-bind="$attrs" @register="registerPopup" showOkBtn destroyOnClose
  7. #if(${context.cancelButtonText} || ${context.cancelButtonTextI18nCode})
  8. #if(${context.cancelButtonTextI18nCode}):cancelText="t('${context.cancelButtonTextI18nCode}','${context.cancelButtonText}')"
  9. #else cancelText="${context.CancelButton}"#end
  10. #end
  11. #if(${context.confirmButtonText} || ${context.confirmButtonTextI18nCode})
  12. #if(${context.confirmButtonTextI18nCode}):okText="t('${context.confirmButtonTextI18nCode}','${context.confirmButtonText}')"
  13. #else okText="${context.confirmButtonText}"#end
  14. #end
  15. @ok="handleSubmit" :closeFunc="onClose">
  16. <template #title>
  17. <a-space :size="10">
  18. <div class="text-16px font-medium">{{ title }}</div>
  19. ## <!-- 分组和树形不展示 -->
  20. #if(${context.hasConfirmAndAddBtn} && (!${context.groupTable} && !${context.treeTable}))
  21. <a-space-compact size="small" block v-if="dataForm.id">
  22. <a-tooltip :title="t('common.prevRecord')">
  23. <a-button size="small" :disabled="getPrevDisabled" @click="handlePrev">
  24. <i class="icon-ym icon-ym-caret-left text-10px"></i>
  25. </a-button>
  26. </a-tooltip>
  27. <a-tooltip :title="t('common.nextRecord')">
  28. <a-button size="small" :disabled="getNextDisabled" @click="handleNext">
  29. <i class="icon-ym icon-ym-caret-right text-10px"></i>
  30. </a-button>
  31. </a-tooltip>
  32. </a-space-compact>
  33. #end
  34. </a-space>
  35. </template>
  36. #if(${context.hasConfirmAndAddBtn} && (!${context.groupTable} && !${context.treeTable}))
  37. ## <!-- 分组和树形不展示 -->
  38. <template #insertToolbar>
  39. <JnpfCheckboxSingle v-model:value="submitType" :label="continueText" v-if="showContinueBtn" />
  40. </template>
  41. ## <!-- 分组和树形不展示 -->
  42. #end
  43. <a-row class="p-10px dynamic-form ${context.formStyle}" :style="{ margin: '0 auto', width: '${context.fullScreenWidth}' }">
  44. <a-form :colon="false" size="${context.size}" layout=#if(${context.labelPosition}=="top") "vertical" #else "horizontal" #end
  45. labelAlign=#if(${context.labelPosition}=="right") "right" #else "left" #end
  46. #if(${context.labelPosition}!="top") :labelCol="{ style: { width: '${context.labelWidth}px' } }" #end
  47. :model="dataForm" :rules="dataRule" ref="formRef" >
  48. <a-row :gutter="#if(${context.formStyle}=='word-form')0#else${context.gutter}#end">
  49. <!-- 具体表单 -->
  50. #FormRendering()
  51. <!-- 表单结束 -->
  52. </a-row>
  53. </a-form>
  54. </a-row>
  55. </BasicPopup>
  56. ##<!-- 全屏弹窗 -->
  57. #end
  58. ## 普通弹窗
  59. #if(${context.popupType}=="general")
  60. ##<!-- 普通弹窗 -->
  61. <BasicModal v-bind="$attrs" @register="registerModal" width="${context.generalWidth}"
  62. :minHeight="100"
  63. #if(${context.cancelButtonText} || ${context.cancelButtonTextI18nCode})
  64. #if(${context.cancelButtonTextI18nCode}):cancelText="t('${context.cancelButtonTextI18nCode}','${context.cancelButtonText}')"
  65. #else cancelText="${context.CancelButton}"#end
  66. #end
  67. #if(${context.confirmButtonText} || ${context.confirmButtonTextI18nCode})
  68. #if(${context.confirmButtonTextI18nCode}):okText="t('${context.confirmButtonTextI18nCode}','${context.confirmButtonText}')"
  69. #else okText="${context.confirmButtonText}"#end
  70. #end
  71. @ok="handleSubmit" :closeFunc="onClose">
  72. <template #title>
  73. <a-space :size="10">
  74. <div class="text-16px font-medium">{{ title }}</div>
  75. ## <!-- 分组和树形不展示 -->
  76. #if(${context.hasConfirmAndAddBtn} && (!${context.groupTable} && !${context.treeTable}))
  77. <a-space-compact size="small" block v-if="dataForm.id">
  78. <a-tooltip :title="t('common.prevRecord')">
  79. <a-button size="small" :disabled="getPrevDisabled" @click="handlePrev">
  80. <i class="icon-ym icon-ym-caret-left text-10px"></i>
  81. </a-button>
  82. </a-tooltip>
  83. <a-tooltip :title="t('common.nextRecord')">
  84. <a-button size="small" :disabled="getNextDisabled" @click="handleNext">
  85. <i class="icon-ym icon-ym-caret-right text-10px"></i>
  86. </a-button>
  87. </a-tooltip>
  88. </a-space-compact>
  89. #end
  90. </a-space>
  91. </template>
  92. #if(${context.hasConfirmAndAddBtn} && (!${context.groupTable} && !${context.treeTable}))
  93. ## <!-- 分组和树形不展示 -->
  94. <template #insertFooter>
  95. <div class="float-left mt-5px">
  96. <JnpfCheckboxSingle v-model:value="submitType" :label="continueText" />
  97. </div>
  98. </template>
  99. ## <!-- 分组和树形不展示 -->
  100. #end
  101. <a-row class="dynamic-form ${context.formStyle}">
  102. <a-form :colon="false" size="${context.size}" layout=#if(${context.labelPosition}=="top") "vertical" #else "horizontal" #end
  103. labelAlign=#if(${context.labelPosition}=="right") "right" #else "left" #end
  104. #if(${context.labelPosition}!="top") :labelCol="{ style: { width: '${context.labelWidth}px' } }" #end
  105. :model="dataForm" :rules="dataRule" ref="formRef">
  106. <a-row :gutter="#if(${context.formStyle}=='word-form')0#else${context.gutter}#end">
  107. <!-- 具体表单 -->
  108. #FormRendering()
  109. <!-- 表单结束 -->
  110. </a-row>
  111. </a-form>
  112. </a-row>
  113. </BasicModal>
  114. ##<!-- 普通弹窗 -->
  115. #end
  116. ## 右侧弹窗
  117. #if(${context.popupType}=="drawer")
  118. ##<!-- 右侧弹窗 -->
  119. <BasicDrawer v-bind="$attrs" @register="registerDrawer" width="${context.drawerWidth}" showFooter
  120. #if(${context.cancelButtonText} || ${context.cancelButtonTextI18nCode})
  121. #if(${context.cancelButtonTextI18nCode}):cancelText="t('${context.cancelButtonTextI18nCode}','${context.cancelButtonText}')"
  122. #else cancelText="${context.CancelButton}"#end
  123. #end
  124. #if(${context.confirmButtonText} || ${context.confirmButtonTextI18nCode})
  125. #if(${context.confirmButtonTextI18nCode}):okText="t('${context.confirmButtonTextI18nCode}','${context.confirmButtonText}')"
  126. #else okText="${context.confirmButtonText}"#end
  127. #end
  128. @ok="handleSubmit" :closeFunc="onClose">
  129. <template #title>
  130. <a-space :size="10">
  131. <div class="text-16px font-medium">{{ title }}</div>
  132. ## <!-- 分组和树形不展示 -->
  133. #if(${context.hasConfirmAndAddBtn} && (!${context.groupTable} && !${context.treeTable}))
  134. <a-space-compact size="small" block v-if="dataForm.id">
  135. <a-tooltip :title="t('common.prevRecord')">
  136. <a-button size="small" :disabled="getPrevDisabled" @click="handlePrev">
  137. <i class="icon-ym icon-ym-caret-left text-10px"></i>
  138. </a-button>
  139. </a-tooltip>
  140. <a-tooltip :title="t('common.nextRecord')">
  141. <a-button size="small" :disabled="getNextDisabled" @click="handleNext">
  142. <i class="icon-ym icon-ym-caret-right text-10px"></i>
  143. </a-button>
  144. </a-tooltip>
  145. </a-space-compact>
  146. #end
  147. </a-space>
  148. </template>
  149. #if(${context.hasConfirmAndAddBtn} && (!${context.groupTable} && !${context.treeTable}))
  150. ## <!-- 分组和树形不展示 -->
  151. <template #insertFooter>
  152. <div class="float-left mt-5px">
  153. <JnpfCheckboxSingle v-model:value="submitType" :label="continueText" />
  154. </div>
  155. </template>
  156. ## <!-- 分组和树形不展示 -->
  157. #end
  158. <a-row class="p-10px dynamic-form ${context.formStyle}">
  159. <!-- 表单 -->
  160. <a-form :colon="false" size="${context.size}" layout=#if(${context.labelPosition}=="top") "vertical" #else "horizontal" #end
  161. labelAlign=#if(${context.labelPosition}=="right") "right" #else "left" #end
  162. #if(${context.labelPosition}!="top") :labelCol="{ style: { width: '${context.labelWidth}px' } }" #end
  163. :model="dataForm" :rules="dataRule" ref="formRef" >
  164. <a-row :gutter="#if(${context.formStyle}=='word-form')0#else${context.gutter}#end">
  165. <!-- 具体表单 -->
  166. #FormRendering()
  167. <!-- 表单结束 -->
  168. </a-row>
  169. </a-form>
  170. </a-row>
  171. </BasicDrawer>
  172. ##<!-- 右侧弹窗 -->
  173. #end
  174. #if($isSelectDialog == true)
  175. <SelectModal :config="state.currTableConf" :formData="state.dataForm" ref="selectModal" @select="addForSelect"/>
  176. #end
  177. </template>
  178. <script lang="ts" setup>
  179. import { create, update, getInfo } from './helper/api';
  180. import { reactive, toRefs, nextTick, ref, unref, computed,toRaw, inject } from 'vue';
  181. #if(${context.popupType}=="fullScreen")
  182. import { BasicPopup, usePopup } from '@/components/Popup';
  183. #end
  184. #if(${context.popupType}=="general")
  185. import { BasicModal, useModal } from '@/components/Modal';
  186. #end
  187. #if(${context.popupType}=="drawer")
  188. import { BasicDrawer, useDrawer } from '@/components/Drawer';
  189. #end
  190. import { JnpfRelationForm } from '@/components/Jnpf';
  191. import { useMessage } from '@/hooks/web/useMessage';
  192. import { useI18n } from '@/hooks/web/useI18n';
  193. import { useUserStore } from '@/store/modules/user';
  194. import type { FormInstance } from 'ant-design-vue';
  195. #if($isSelectDialog == true)
  196. import SelectModal from '@/components/CommonModal/src/SelectModal.vue';
  197. #end
  198. import { thousandsFormat , getDateTimeUnit, getTimeUnit} from '@/utils/jnpf';
  199. import { getDictionaryDataSelector } from '@/api/systemData/dictionary';
  200. import { getDataInterfaceRes } from '@/api/systemData/dataInterface';
  201. import dayjs from 'dayjs';
  202. // 表单权限
  203. import { usePermission } from '@/hooks/web/usePermission';
  204. import { cloneDeep } from 'lodash-es';
  205. import { buildUUID } from '@/utils/uuid';
  206. import { CaretRightOutlined } from '@ant-design/icons-vue';
  207. interface State {
  208. #createStateParam("any")
  209. title: string;
  210. #if(${context.hasConfirmAndAddBtn})continueText: string; #end
  211. allList: any[];
  212. currIndex: number;
  213. isContinue: boolean;
  214. submitType: number;
  215. showContinueBtn: boolean;
  216. }
  217. const emit = defineEmits(['reload']);
  218. const getLeftTreeActiveInfo: (() => any) | null = inject('getLeftTreeActiveInfo', null);
  219. const userStore = useUserStore();
  220. const userInfo = userStore.getUserInfo;
  221. const { createMessage, createConfirm } = useMessage();
  222. const { t } = useI18n();
  223. #if(${context.popupType}=="fullScreen")
  224. const [registerPopup, { openPopup, setPopupProps }] = usePopup();
  225. #end
  226. #if(${context.popupType}=="general")
  227. const [registerModal, { openModal, setModalProps }] = useModal();
  228. #end
  229. #if(${context.popupType}=="drawer")
  230. const [registerDrawer, { openDrawer, setDrawerProps }] = useDrawer();
  231. #end
  232. const formRef = ref<FormInstance>();
  233. #if($isSelectDialog == true)
  234. // 子表弹窗数据
  235. const selectModal = ref(null);
  236. #end
  237. #GetChildTableColumns()
  238. const state = reactive<State>({
  239. #createStateParam()
  240. title: "",
  241. #if(${context.hasConfirmAndAddBtn}) continueText: "", #end
  242. allList: [],
  243. currIndex: 0,
  244. isContinue: false,
  245. submitType: 0,
  246. showContinueBtn: #if(${context.hasConfirmAndAddBtn}) true #else false #end,
  247. });
  248. const { title, #if(${context.hasConfirmAndAddBtn}) continueText, #end showContinueBtn, dataRule, dataForm, optionsObj, ableAll, maskConfig,submitType } = toRefs(state);
  249. const getPrevDisabled = computed(() => state.currIndex === 0);
  250. const getNextDisabled = computed(() => state.currIndex === state.allList.length - 1);
  251. // 表单权限
  252. const { hasFormP } = usePermission();
  253. defineExpose({ init });
  254. function init(data) {
  255. state.submitType = 0;
  256. state.isContinue = false;
  257. state.title = !data.id ? t('common.add2Text','新增') : t('common.editText','编辑');
  258. #if(${context.hasConfirmAndAddBtn}) state.continueText = !data.id ? t('common.continueAndAddText','确定并新增') : t('common.continueText','确定并继续'); #end
  259. setFormProps({ continueLoading: false });
  260. state.dataForm.id = data.id;
  261. #if(${context.popupType}=="fullScreen")
  262. openPopup();
  263. #end
  264. #if(${context.popupType}=="general")
  265. openModal();
  266. #end
  267. #if(${context.popupType}=="drawer")
  268. openDrawer();
  269. #end
  270. state.allList = data.allList;
  271. state.currIndex = state.allList.length && data.id ? state.allList.findIndex((item) => item.id === data.id) : 0;
  272. nextTick(() => {
  273. getForm().resetFields();
  274. #foreach($child in ${context.children})
  275. state.dataForm.${child.aliasLowName}List = [];
  276. #end
  277. setTimeout(initData, 0);
  278. });
  279. }
  280. function initData() {
  281. changeLoading(true);
  282. #InitActiveValue()
  283. if (state.dataForm.id) {
  284. getData(state.dataForm.id);
  285. } else {
  286. //初始化options
  287. #EditGetOption(false)
  288. // 设置默认值
  289. state.dataForm={
  290. #CreateDataform()
  291. };
  292. if (getLeftTreeActiveInfo) state.dataForm = {...state.dataForm, ...(getLeftTreeActiveInfo() || {}) };
  293. state.childIndex = -1;
  294. changeLoading(false);
  295. }
  296. }
  297. function getForm() {
  298. const form = unref(formRef);
  299. if (!form) {
  300. throw new Error('form is null!');
  301. }
  302. return form;
  303. }
  304. function getData(id) {
  305. getInfo(id).then((res) => {
  306. state.dataForm = res.data || {};
  307. ## 初始化options
  308. #EditGetOption(true)
  309. state.childIndex = -1;
  310. changeLoading(false);
  311. });
  312. }
  313. async function handleSubmit(type) {
  314. try {
  315. const values = await getForm()?.validate();
  316. if (!values) return;
  317. ### 非流程子表字段验证
  318. #if(!$context.isFlow)
  319. #foreach($itemModel in ${context.children})
  320. if(!$!{itemModel.aliasLowName}Exist()) return;
  321. #end
  322. #end
  323. setFormProps({ confirmLoading: true });
  324. const formMethod = state.dataForm.id ? update : create;
  325. formMethod(state.dataForm)
  326. .then((res) => {
  327. createMessage.success(res.msg);
  328. setFormProps({ confirmLoading: false });
  329. if (state.submitType == 1) {
  330. initData();
  331. state.isContinue = true;
  332. } else {
  333. setFormProps({ open: false });
  334. emit('reload');
  335. }
  336. })
  337. .catch(() => {
  338. setFormProps({ confirmLoading: false });
  339. });
  340. } catch (_) {}
  341. }
  342. function handlePrev() {
  343. state.currIndex--;
  344. handleGetNewInfo();
  345. }
  346. function handleNext() {
  347. state.currIndex++;
  348. handleGetNewInfo();
  349. }
  350. function handleGetNewInfo() {
  351. changeLoading(true);
  352. getForm().resetFields();
  353. const id = state.allList[state.currIndex].id;
  354. getData(id);
  355. }
  356. function setFormProps(data) {
  357. #if(${context.popupType}=="fullScreen")
  358. setPopupProps(data);
  359. #end
  360. #if(${context.popupType}=="general")
  361. setModalProps(data);
  362. #end
  363. #if(${context.popupType}=="drawer")
  364. setDrawerProps(data);
  365. #end
  366. }
  367. function changeLoading(loading) {
  368. #if(${context.popupType}=="fullScreen")
  369. setPopupProps({ loading });
  370. #end
  371. #if(${context.popupType}=="general")
  372. setModalProps({ loading });
  373. #end
  374. #if(${context.popupType}=="drawer")
  375. setDrawerProps({ loading });
  376. #end
  377. }
  378. async function onClose() {
  379. if (state.isContinue) emit('reload');
  380. return true;
  381. }
  382. ##合计方法
  383. #if($childSummary==true)
  384. //子表合计方法
  385. function getCmpValOfRow(row, key, summaryField) {
  386. if (!summaryField.length) return '';
  387. const isSummary = key => summaryField.includes(key);
  388. const target = row[key];
  389. if (!target) return '';
  390. let data = isNaN(target) ? 0 : Number(target);
  391. if (isSummary(key)) return data || 0;
  392. return '';
  393. }
  394. #end
  395. ##数据联动changeData方法
  396. #ChangeData()
  397. ##子表其他方法
  398. #CreateChildTableMethod()
  399. ##子表弹窗数据方法
  400. #if($isSelectDialog == true)
  401. #ChildDialogMethod()
  402. #end
  403. ##数据选项--数据字典和远端数据初始化方法
  404. #GetDataOptionsMethod()
  405. ##动态时间处理
  406. #GetRelationDate()
  407. </script>