SubOneToOneTabEdit.vue 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535
  1. <template>
  2. <a-page-header
  3. :title="Language.getNameTrl($i18n.locale, tab)"
  4. style="border-bottom: 1px solid rgb(235, 237, 240); padding: 0px;"
  5. />
  6. <div class="m-row clearfix">
  7. <div>
  8. <div
  9. v-if="tabFormFields && mModelData"
  10. :class="{
  11. 'form-inline': tab.tabFormView.multipleColumn,
  12. 'form-horizontal': !tab.tabFormView.multipleColumn,
  13. }"
  14. >
  15. <template
  16. v-for="fieldItem in tabFormFields" :key="
  17. 'FieldEditView_' +
  18. windowNo +
  19. '_' +
  20. tab.tabIndex +
  21. '_' +
  22. fieldItem.fieldName +
  23. '_' +
  24. fieldItem.entityFieldIndex
  25. "
  26. >
  27. <FieldEditView
  28. ref="fieldItem1"
  29. :class-name="tab.tabDataSource.className"
  30. :field="fieldItem"
  31. :model-data="mModelData"
  32. :window-no="windowNo"
  33. :tab-index="tab.tabIndex"
  34. :js-url="jsUrl"
  35. :is-chinese-english="curdWindow.isChineseEnglish"
  36. :multiple-column="tab.tabFormView.multipleColumn"
  37. @value-changed="valueChanged($event, fieldItem)"
  38. @execute-callout="executeCallout(fieldItem)"
  39. />
  40. </template>
  41. </div>
  42. </div>
  43. </div>
  44. </template>
  45. <script setup>
  46. import Common from '../../common/Common';
  47. import { Notify } from 'pc-component-v3';
  48. import FieldEditView from './TabFormFieldEdit.vue';
  49. import WindowClientUtil from '../../resource/dictionary/WindowClientUtil.js';
  50. import WindowServerUtil from '../../resource/dictionary/WindowServerUtil.js';
  51. import { ref, defineExpose, defineEmits, defineProps, watch } from 'vue';
  52. import { debounce } from 'lodash';
  53. import ProcessReportResource from '../../api/dic/ProcessReportResource.js';
  54. import FieldUtil from '../../resource/dictionary/FieldUtil.js';
  55. import Context from '../common/Context.js';
  56. import { getCurrentInstance } from 'vue';
  57. import JsUtil from '../../common/JsUtil.js';
  58. import Language from '../../common/Language.js';
  59. // proxy 就是当前组件实例,可以理解为组件级别的 this,没有全局的、路由、状态管理之类的
  60. const { proxy, appContext } = getCurrentInstance();
  61. // 接受父组件传递的数据
  62. const props = defineProps({
  63. tab: {
  64. type: Object,
  65. default: () => {
  66. return {};
  67. },
  68. },
  69. parentModelData: {
  70. type: Object,
  71. default: () => {
  72. return {};
  73. },
  74. },
  75. curdWindow: {
  76. type: Object,
  77. default: () => {
  78. return {};
  79. },
  80. },
  81. windowNo: {
  82. type: String,
  83. default: null,
  84. },
  85. type: {
  86. type: String,
  87. default: null,
  88. },
  89. jsUrl: {
  90. type: String,
  91. default: null,
  92. },
  93. isChineseEnglish: {
  94. type: Boolean,
  95. default: false,
  96. },
  97. });
  98. const mModelData = ref({});
  99. const tabFormFields = ref([]);
  100. const fieldGroup = ref([]);
  101. const oldCommand = ref(null);
  102. const emits = defineEmits(['executeCallout', 'valueChanged']);
  103. const getContext = Context;
  104. /**
  105. * 查询一对一页签数据
  106. */
  107. const getOneToOneTabData = function () {
  108. const params = {
  109. windowNo: props.windowNo,
  110. tabIndex: props.tab.tabIndex,
  111. parentId: props.parentModelData == undefined ? undefined : props.parentModelData.id,
  112. };
  113. $.ajax({
  114. url: Common.getApiURL('CurdWindowResource/oneToOneTabData'),
  115. async: false,
  116. dataType: 'json',
  117. type: 'post',
  118. data: JSON.stringify(params),
  119. contentType: 'application/json',
  120. beforeSend: function (request) {
  121. Common.addTokenToRequest(request);
  122. },
  123. success: function (data) {
  124. mModelData.value = data;
  125. },
  126. error: function (XMLHttpRequest, textStatus, errorThrown) {
  127. Common.processException(XMLHttpRequest, textStatus, errorThrown);
  128. },
  129. });
  130. };
  131. /**
  132. * 获取一对一页签modelData(新建)
  133. * @param tabIndex
  134. */
  135. const createOneToOneModelData = function () {
  136. WindowServerUtil.newModelData(
  137. props.windowNo,
  138. props.tab.tabIndex,
  139. null,
  140. function (response) {
  141. if (response.errorCode != 0) {
  142. Notify.error('数据新建异常', response.errorMessage, false);
  143. return;
  144. }
  145. let newModelData = response.data;
  146. newModelData.editMode = true;
  147. mModelData.value = newModelData;
  148. },
  149. );
  150. };
  151. /**
  152. * 执行Callout
  153. */
  154. const executeCallout = function (fieldItem) {
  155. if (fieldItem.calloutProcessReportNo != null) {
  156. callout(fieldItem.calloutProcessReportNo);
  157. }
  158. };
  159. /**
  160. * callout
  161. * @param {[type]} calloutProcessReportNo [description]
  162. * @return {[type]} [description]
  163. */
  164. const callout = function (calloutProcessReportNo) {
  165. // add by jack 20180529
  166. var subTabChangedData = getSubTabChangedData();
  167. if (subTabChangedData.length > 0) {
  168. mModelData.value.vaue.saveDatas = subTabChangedData;
  169. } else {
  170. mModelData.value.vaue.saveDatas = null;
  171. }
  172. // 查询流程和报表的定义
  173. ProcessReportResource.uniqueByNo(calloutProcessReportNo).then(
  174. successData => {
  175. if (successData == null) {
  176. return;
  177. }
  178. // 执行服务端的脚本
  179. ProcessReportResource.runCallout(
  180. calloutProcessReportNo,
  181. mModelData.value.vaue,
  182. ).then(
  183. successData => {
  184. if (successData && successData.modelData) {
  185. mModelData.value.vaue = successData.modelData;
  186. }
  187. // add by jack 20180529
  188. // add by jack 20220601
  189. mModelData.value.vaue.saveDatas = undefined;
  190. },
  191. errorData => {
  192. Common.processException(errorData);
  193. },
  194. );
  195. },
  196. errorData => {
  197. Common.processException(errorData);
  198. },
  199. );
  200. };
  201. // 获取子页签发生改变的数据
  202. const getSubTabChangedData = function () {
  203. var subTabChangedRecords = [];
  204. if (props.tab.subTabs != undefined) {
  205. for (var index = 0; index < props.tab.subTabs.length; index++) {
  206. var subTabId = 'subTab' + props.tab.subTabs[index].tabIndex;
  207. // TODO
  208. // var modelDatas = $refs[subTabId][0].getChangedModelData();
  209. // if (modelDatas != undefined && modelDatas.length > 0) {
  210. // modelDatas.forEach(function (modelData) {
  211. // subTabChangedRecords.push(modelData);
  212. // });
  213. // }
  214. }
  215. }
  216. console.log(subTabChangedRecords);
  217. return subTabChangedRecords;
  218. };
  219. /**
  220. * 延迟获取页面的数据
  221. */
  222. const debounceNewAction = debounce(() => {
  223. if (props.type === 'create') {
  224. createOneToOneModelData();
  225. } else {
  226. getOneToOneTabData();
  227. }
  228. }, 1000);
  229. watch(
  230. () => [props.windowNo, props.tab, props.parentModelData, props.type],
  231. (newValue, oldValue) => {
  232. let newCommand = newValue[0]
  233. + (newValue[1] != null ? (newValue[1].name + newValue[1].tabIndex) : '-')
  234. + (newValue[2] != null ? newValue[2].id : '-')
  235. + newValue[3];
  236. if(newCommand != oldCommand.value){
  237. debounceNewAction();
  238. }
  239. oldCommand.value = newCommand;
  240. },
  241. { immediate: true },
  242. );
  243. watch(
  244. () => props.tab,
  245. (newValue, oldValue) => {
  246. tabFormFields.value = WindowClientUtil.getDetailField(newValue);
  247. console.log(tabFormFields.value);
  248. },
  249. { immediate: true },
  250. );
  251. // 值改变事件
  252. const valueChanged = function (newFieldValue, fieldItem) {
  253. console.log(fieldItem.fieldName + ' ValueChanged.');
  254. console.log(newFieldValue);
  255. var oldFieldValue = mModelData.value.data[fieldItem.fieldName];
  256. if (FieldUtil.isFieldValueEqual(newFieldValue, oldFieldValue) == false) {
  257. mModelData.value.data[fieldItem.fieldName] = newFieldValue;
  258. if (
  259. fieldItem.calloutProcessReportNo != undefined &&
  260. fieldItem.calloutProcessReportNo != null
  261. ) {
  262. callout(fieldItem.calloutProcessReportNo);
  263. }
  264. if (
  265. fieldItem.calloutLogical != undefined &&
  266. fieldItem.calloutLogical != null
  267. ) {
  268. executeCalloutJs(fieldItem, fieldItem.calloutLogical);
  269. }
  270. if (
  271. mModelData.value.changed &&
  272. fieldItem.displayType == 'ListBoxEditor'
  273. ) {
  274. // 值改变时,刷新所有下拉框的keyValues
  275. refreshSelectField(fieldItem.fieldName);
  276. }
  277. // add by jack 20170808
  278. mModelData.value.changed = true;
  279. let clearDynamicValidField = function (item) {
  280. var fieldName1 = item.fieldName;
  281. var dynamicValidFields = item.dynamicValidFields;
  282. if (
  283. fieldName0 != fieldName1 &&
  284. dynamicValidFields != undefined &&
  285. dynamicValidFields.indexOf(fieldName0) >= 0
  286. ) {
  287. var fieldValue0 = mModelData.value.data[fieldName1];
  288. fieldValue0.id = undefined;
  289. if (fieldValue0.displayValue != undefined) {
  290. fieldValue0.displayValue.splice(
  291. 0,
  292. fieldValue0.displayValue.length,
  293. );
  294. } else {
  295. fieldValue0.displayValue = [];
  296. }
  297. mModelData.value.data[fieldName1] = fieldValue0;
  298. }
  299. };
  300. // 遍历所有的字段,判断是否有动态约束
  301. // 如果有关联的动态约束,则清空字段
  302. var fieldName0 = fieldItem.fieldName;
  303. tabFormFields.value.forEach(function (item) {
  304. clearDynamicValidField(item);
  305. });
  306. let fieldGroups = props.tab.tabFormView.fieldGroups;
  307. if (fieldGroups != null && fieldGroups.length > 0) {
  308. fieldGroups.forEach(fieldGroup => {
  309. if (fieldGroup.fields != null && fieldGroup.fields != null) {
  310. fieldGroup.fields.forEach(field => {
  311. clearDynamicValidField(field);
  312. });
  313. }
  314. });
  315. }
  316. }
  317. };
  318. // 刷新下拉选择框keyValues
  319. const refreshSelectField = function (valueChangedFieldName) {
  320. if (tabFormFields.value) {
  321. tabFormFields.value.forEach(function (item) {
  322. if (item.displayType == 'ListBoxEditor') {
  323. var name1 = ':' + valueChangedFieldName;
  324. //var name2 = ":Parent_" + valueChangedFieldName;
  325. var showLogical = item.showLogical;
  326. if (showLogical != undefined && showLogical.indexOf(name1) >= 0) {
  327. refresh(item);
  328. }
  329. }
  330. });
  331. }
  332. if (fieldGroup.value) {
  333. fieldGroup.value.fields.forEach(function (item) {
  334. if (item.displayType == 'ListBoxEditor') {
  335. var name1 = ':' + valueChangedFieldName;
  336. //var name2 = ":Parent_" + valueChangedFieldName;
  337. var showLogical = item.showLogical;
  338. if (showLogical != undefined && showLogical.indexOf(name1) >= 0) {
  339. refresh(item);
  340. }
  341. }
  342. });
  343. }
  344. function refresh(item) {
  345. var obj = {
  346. windowNo: props.windowNo,
  347. tabIndex: props.tab.tabIndex,
  348. fieldName: item.fieldName,
  349. modelData: mModelData.value,
  350. };
  351. console.log('WindowEdit RefreshField');
  352. $.ajax({
  353. url: Common.getApiURL('FieldResource/refreshField'),
  354. async: false,
  355. dataType: 'json',
  356. type: 'post',
  357. data: JSON.stringify(obj),
  358. contentType: 'application/json',
  359. beforeSend: function (request) {
  360. Common.addTokenToRequest(request);
  361. },
  362. success: function (data) {
  363. if (data != undefined) {
  364. item.keyValues = data.keyValues;
  365. }
  366. },
  367. error: function (XMLHttpRequest, textStatus, errorThrown) {
  368. Common.processException(XMLHttpRequest, textStatus, errorThrown);
  369. },
  370. });
  371. }
  372. };
  373. /**
  374. * 执行JS Callout
  375. */
  376. const executeCalloutJs = function (fieldItem, scriptText) {
  377. // add by jack 20180529
  378. var subTabChangedData = getSubTabChangedData();
  379. if (subTabChangedData.length > 0) {
  380. mModelData.value.saveDatas = subTabChangedData;
  381. } else {
  382. mModelData.value.saveDatas = null;
  383. }
  384. let functionName = fieldItem.fieldName.replace('.', '_') + '_calloutjs';
  385. let executeFunction = function () {
  386. let actions = {
  387. subTabsRef: getSubTabs(),
  388. };
  389. let context = new getContext(mModelData, actions);
  390. try {
  391. proxy[functionName](context);
  392. } catch (e) {
  393. console.error(e);
  394. Notify.error('数据字典定义异常', '【' + scriptText + '】前端列显示逻辑定义异常,请联系管理员检查数据字典的定义。', false);
  395. }
  396. };
  397. if (proxy[functionName] == null) {
  398. // 执行服务端的脚本
  399. const jsUrl = props.jsUrl;
  400. if (jsUrl == null || jsUrl == undefined) {
  401. Notify.error('数据字典定义异常', '【' + scriptText + '】Callout前端逻辑的JS文件不存在,请联系管理员检查数据字典是否JS文件。', false);
  402. return;
  403. }
  404. let promise = JsUtil.dynamicLoadJsFunction(jsUrl, scriptText);
  405. promise.then(targetFunction => {
  406. console.log(targetFunction);
  407. if (targetFunction == null) {
  408. Notify.error('数据字典定义异常', '【' + scriptText + '】Callout前端逻辑定义异常,请联系管理员检查数据字典的定义。', false);
  409. return;
  410. }
  411. proxy[functionName] = targetFunction;
  412. executeFunction();
  413. }, errorData => {
  414. console.error(errorData);
  415. });
  416. } else {
  417. executeFunction();
  418. }
  419. };
  420. /**
  421. * 获取子页签的集合
  422. */
  423. const getSubTabs = function () {
  424. let subTabsRef = [];
  425. for (var tabIndex = 0; tabIndex < props.tab.subTabs.length; tabIndex++) {
  426. var subTabId = 'subTab' + props.tab.subTabs[tabIndex].tabIndex;
  427. // TODO
  428. // subTabsRef.push($refs[subTabId][0]);
  429. }
  430. return subTabsRef;
  431. };
  432. const fieldItem1 = ref();
  433. const fieldItem2 = ref();
  434. /**
  435. * 执行验证
  436. * @returns 验证错误的数量
  437. */
  438. const performValide = function(){
  439. let error = 0;
  440. if (fieldItem1.value != undefined) {
  441. fieldItem1.value.forEach(function (w) {
  442. var validateResult = w.performValide();
  443. if (!validateResult) {
  444. error++;
  445. }
  446. });
  447. }
  448. if (fieldItem2.value != undefined) {
  449. fieldItem2.value.forEach(function (w) {
  450. var validateResult = w.performValide();
  451. if (!validateResult) {
  452. error++;
  453. }
  454. });
  455. }
  456. return error;
  457. };
  458. const getModelData = function(){
  459. return mModelData.value;
  460. };
  461. defineExpose({
  462. performValide,
  463. getModelData,
  464. });
  465. </script>
  466. <style scoped></style>