detail.vue 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449
  1. <template>
  2. <view class="dynamicModel-form-v jnpf-wrap jnpf-wrap-form" v-if="showPage">
  3. <Parser :formConf="formConf" :formData="formData" ref="dynamicForm" v-if="!loading" :key="key"
  4. @toDetail="toDetail" />
  5. <view class="u-m-t-20 dataLog-box u-flex-col u-m-b-20" v-if="formConf.dataLog && !setting.noDataLog">
  6. <view class="title u-flex">
  7. <u-icon name=" icon-ym-generator-menu" custom-prefix="icon-ym"></u-icon>
  8. <text class="u-m-l-10">修改记录</text>
  9. </view>
  10. <view class="dataLog-v" v-if="dataLogList.length">
  11. <dataLog :dataLogList="dataLogList"></dataLog>
  12. </view>
  13. <JnpfEmpty v-else />
  14. </view>
  15. <view class="buttom-actions">
  16. <CustomButton class="u-flex buttom-btn-left-inner" v-if="showMoreBtn" btnText="更多" btnType="more"
  17. iconName="more-dot-fill" size="28" @handleBtn="showAction = $event" :btnLoading="loading" />
  18. <template v-if="showEditBtn">
  19. <CustomButton class="u-flex buttom-btn-left-inner" :btnText="$t('common.cancelText')"
  20. btnIcon="icon-ym icon-ym-add-cancel" customIcon :btnLoading="loading" />
  21. <u-button class="buttom-btn" type="primary" @click.stop="handleEdit" :loading="loading">
  22. {{labelS.btn_edit}}
  23. </u-button>
  24. </template>
  25. <u-button class="cancel" @click.stop="jnpf.goBack()"
  26. v-if="!showEditBtn && !showMoreBtn">{{$t('common.cancelText')}}</u-button>
  27. </view>
  28. <u-select :list="actionList" v-model="showAction" @confirm="selectBtnconfirm" />
  29. </view>
  30. </template>
  31. <script>
  32. import CustomButton from '@/components/CustomButton'
  33. import {
  34. getConfigData,
  35. getOnlineLog,
  36. getModelInfo,
  37. getDataChange,
  38. launchFlow
  39. } from "@/api/apply/visualDev";
  40. import {
  41. getRelationFormDetail,
  42. getDataInterfaceRes
  43. } from "@/api/common.js";
  44. import Parser from "./components/detail/Parser";
  45. import dataLog from '@/components/dataLog'
  46. import deepClone from '../../../uni_modules/vk-uview-ui/libs/function/deepClone';
  47. export default {
  48. components: {
  49. Parser,
  50. dataLog,
  51. CustomButton
  52. },
  53. data() {
  54. return {
  55. dataLogList: [],
  56. actionList: [],
  57. showAction: false,
  58. showPage: false,
  59. loading: true,
  60. isPreview: "0",
  61. modelId: "",
  62. formConf: {},
  63. formData: {},
  64. dataForm: {
  65. id: "",
  66. data: "",
  67. },
  68. btnType: "",
  69. formPermissionList: {},
  70. formList: [],
  71. labelS: {}
  72. };
  73. },
  74. onLoad(option) {
  75. this.init(option)
  76. },
  77. computed: {
  78. showMoreBtn() {
  79. if (this.actionList.length && !this.setting?.noShowBtn || 0 && this.setting?.noDataLog) return true
  80. return false
  81. },
  82. showEditBtn() {
  83. if (this.btnType === 'btn_edit' && !this.setting.noShowBtn && this.setting.enableEdit) return true
  84. return false
  85. }
  86. },
  87. onShow() {
  88. setTimeout(() => {
  89. uni.$emit('initCollapse')
  90. }, 100)
  91. },
  92. onUnload() {
  93. uni.$off("refresh");
  94. },
  95. methods: {
  96. init(option) {
  97. // 提取公共解析方法
  98. const parseConfig = (rawConfig) => {
  99. try {
  100. return JSON.parse(this.jnpf.base64.decode(rawConfig)) || {}
  101. } catch (error) {
  102. return {}
  103. }
  104. }
  105. // 使用解构赋值提取配置
  106. const config = parseConfig(option.config)
  107. const {
  108. currentMenu,
  109. btnType = "",
  110. labelS: rawLabelS = {},
  111. modelId,
  112. isPreview = "0",
  113. id = ""
  114. } = config
  115. // 缓存解析结果
  116. const formPermissionList = currentMenu ? JSON.parse(decodeURIComponent(currentMenu)) : [];
  117. // 批量属性赋值
  118. Object.assign(this, {
  119. formPermissionList,
  120. formList: formPermissionList.formList || [],
  121. btnType,
  122. labelS: {
  123. btn_edit: this.$t('common.editText'),
  124. ...rawLabelS
  125. },
  126. modelId,
  127. isPreview,
  128. dataForm: {
  129. id
  130. },
  131. setting: config
  132. })
  133. // 设置导航栏标题
  134. uni.setNavigationBarTitle({
  135. title: this.$t('common.detailText')
  136. })
  137. this.getConfigData();
  138. uni.$on("refresh", () => {
  139. this.getConfigData();
  140. });
  141. },
  142. // 自定义按钮事件
  143. selectBtnconfirm(e) {
  144. var i = this.actionList.findIndex((item) => {
  145. return item.value == e[0].value
  146. })
  147. const item = this.actionList[i].actionConfig
  148. const row = this.formData
  149. // 自定义启用规则判断
  150. if (item.btnType == 1) this.handlePopup(item, row)
  151. if (item.btnType == 2) this.handleScriptFunc(item, row)
  152. if (item.btnType == 3) this.handleInterface(item, row)
  153. if (item.btnType == 4) this.handleLaunchFlow(item, [row])
  154. },
  155. //自定义按钮发起流程
  156. handleLaunchFlow(item, records) {
  157. const data = deepClone(item.launchFlow)
  158. let dataList = [];
  159. for (let i = 0; i < records.length; i++) {
  160. dataList.push(this.jnpf.getLaunchFlowParamList(data.transferList, records[i], this.getRowKey));
  161. }
  162. const query = {
  163. template: data.flowId,
  164. btnCode: item.value,
  165. currentUser: data.currentUser,
  166. customUser: data.customUser,
  167. initiator: data.initiator,
  168. hasPermission: data.hasPermission,
  169. dataList
  170. };
  171. launchFlow(query, this.modelId).then(res => {
  172. this.$u.toast(res.msg)
  173. });
  174. },
  175. //自定义按钮弹窗操作
  176. handlePopup(item, row) {
  177. let data = {
  178. config: item,
  179. modelId: this.modelId,
  180. id: row.id,
  181. row,
  182. }
  183. data = encodeURIComponent(JSON.stringify(data))
  184. uni.navigateTo({
  185. url: '/pages/apply/customBtn/index?data=' + data
  186. })
  187. },
  188. //自定义按钮JS操作
  189. handleScriptFunc(item, row) {
  190. const parameter = {
  191. data: row,
  192. refresh: this.initData,
  193. onlineUtils: this.jnpf.onlineUtils,
  194. }
  195. const func = this.jnpf.getScriptFunc.call(this, item.func)
  196. if (!func) return
  197. func.call(this, parameter)
  198. },
  199. //自定义按钮接口操作
  200. handleInterface(item, row, index) {
  201. const handlerData = () => {
  202. getModelInfo(this.modelId, row.id).then(res => {
  203. const dataForm = res.data || {};
  204. if (!dataForm.data) return;
  205. const data = {
  206. ...JSON.parse(dataForm.data),
  207. id: row.id
  208. };
  209. handlerInterface(data);
  210. })
  211. }
  212. const handlerInterface = (data) => {
  213. let query = {
  214. paramList: this.jnpf.getParamList(item.templateJson, data) || [],
  215. }
  216. getDataInterfaceRes(item.interfaceId, query).then(res => {
  217. uni.showToast({
  218. title: res.msg,
  219. icon: 'none'
  220. })
  221. if (item.isRefresh) this.initData();
  222. })
  223. }
  224. const handleFun = () => {
  225. handlerData();
  226. };
  227. if (!item.useConfirm) return handleFun()
  228. uni.showModal({
  229. title: '提示',
  230. content: item.confirmTitle || '确认执行此操作',
  231. success: (res) => {
  232. if (!res.cancel) handleFun()
  233. }
  234. })
  235. },
  236. getOnlineLog() {
  237. getOnlineLog(this.setting.modelId, this.setting.id).then(res => {
  238. this.dataLogList = res.data.list || []
  239. })
  240. },
  241. getConfigData() {
  242. this.loading = true;
  243. getConfigData(this.modelId).then((res) => {
  244. if (res.code !== 200 || !res.data) {
  245. uni.showToast({
  246. title: "暂无此页面",
  247. icon: "none",
  248. complete: () => {
  249. setTimeout(() => {
  250. uni.navigateBack();
  251. }, 1500);
  252. },
  253. });
  254. return;
  255. }
  256. this.formConf = res.data.formData ? JSON.parse(res.data.formData) : {};
  257. this.actionList = this.formConf?.appCustomBtns || []
  258. this.actionList.map((o) => {
  259. if (o.labelI18nCode) o.label = this.$t(o.labelI18nCode, o.label)
  260. })
  261. this.beforeInit(this.formConf.fields || []);
  262. this.showPage = true;
  263. this.key = +new Date();
  264. this.initData();
  265. });
  266. },
  267. beforeInit(fields) {
  268. const loop = (list) => {
  269. for (var index = 0; index < list.length; index++) {
  270. const config = list[index].__config__;
  271. if (config.children && config.children.length) loop(config.children);
  272. if (config.jnpfKey == "tableGrid") {
  273. let newList = [];
  274. for (var i = 0; i < config.children.length; i++) {
  275. let element = config.children[i];
  276. for (var j = 0; j < element.__config__.children.length; j++) {
  277. let item = element.__config__.children[j];
  278. newList.push(...item.__config__.children);
  279. }
  280. }
  281. list.splice(index, 1, ...newList);
  282. }
  283. }
  284. };
  285. loop(fields);
  286. },
  287. initData() {
  288. this.$nextTick(() => {
  289. if (this.dataForm.id) {
  290. let extra = {
  291. modelId: this.modelId,
  292. id: this.dataForm.id,
  293. type: 2,
  294. };
  295. uni.setStorageSync('dynamicModelExtra', extra)
  296. this.getRelationFormDetail()
  297. } else {
  298. this.loading = false;
  299. }
  300. this.$nextTick(() => {
  301. this.getOnlineLog()
  302. })
  303. this.key = +new Date();
  304. });
  305. },
  306. getRelationFormDetail() {
  307. const processResponse = (res) => {
  308. this.dataForm = res.data;
  309. this.loading = false;
  310. if (!this.dataForm.data) return;
  311. this.formData = {
  312. ...JSON.parse(this.dataForm.data),
  313. id: this.dataForm.id,
  314. };
  315. this.fillFormData(this.formConf, this.formData);
  316. this.initRelationForm(this.formConf.fields);
  317. };
  318. let requestParams = {
  319. id: this.dataForm.id,
  320. menuId: this.setting.menuId
  321. };
  322. if (this.setting?.sourceRelationForm) {
  323. if (this.setting.propsValue) requestParams.propsValue = this.setting.propsValue;
  324. }
  325. getDataChange(requestParams, this.modelId).then(res => {
  326. processResponse(res)
  327. }).catch(err => {
  328. this.loading = false;
  329. })
  330. },
  331. fillFormData(form, data) {
  332. const loop = (list, parent) => {
  333. for (let i = 0; i < list.length; i++) {
  334. let item = list[i];
  335. if (item.__vModel__) {
  336. if (
  337. item.__config__.jnpfKey === "relationForm" ||
  338. item.__config__.jnpfKey === "popupSelect"
  339. ) {
  340. item.__config__.defaultValue = data[item.__vModel__ + "_id"];
  341. this.$set(item, "name", item.__config__.defaultValue || "");
  342. } else {
  343. let val = data.hasOwnProperty(item.__vModel__) ?
  344. data[item.__vModel__] :
  345. item.__config__.defaultValue;
  346. item.__config__.defaultValue = val;
  347. }
  348. if (this.formPermissionList.useFormPermission) {
  349. let id = item.__config__.isSubTable ?
  350. parent.__vModel__ + "-" + item.__vModel__ :
  351. item.__vModel__;
  352. let noShow = true;
  353. if (this.formList && this.formList.length) {
  354. noShow = !this.formList.some((o) => o.enCode === id);
  355. }
  356. noShow = item.__config__.noShow ? item.__config__.noShow : noShow;
  357. this.$set(item.__config__, "noShow", noShow);
  358. }
  359. } else {
  360. if (['relationFormAttr', 'popupAttr'].includes(item.__config__.jnpfKey)) {
  361. item.__config__.defaultValue =
  362. data[item.relationField.split('_jnpfTable_')[0] + '_' + item.showField];
  363. }
  364. }
  365. if (
  366. item.__config__ &&
  367. item.__config__.children &&
  368. Array.isArray(item.__config__.children)
  369. ) {
  370. loop(item.__config__.children, item);
  371. }
  372. }
  373. };
  374. loop(form.fields);
  375. this.loading = false;
  376. },
  377. initRelationForm(componentList) {
  378. componentList.forEach((cur) => {
  379. const config = cur.__config__;
  380. if (
  381. config.jnpfKey == "relationFormAttr" ||
  382. config.jnpfKey == "popupAttr"
  383. ) {
  384. const relationKey = cur.relationField.split("_jnpfTable_")[0];
  385. componentList.forEach((item) => {
  386. const noVisibility =
  387. Array.isArray(item.__config__.visibility) &&
  388. !item.__config__.visibility.includes("app");
  389. if (
  390. relationKey == item.__vModel__ &&
  391. (noVisibility || !!item.__config__.noShow) && !cur.__vModel__
  392. ) {
  393. cur.__config__.noShow = true;
  394. }
  395. });
  396. }
  397. if (cur.__config__.children && cur.__config__.children.length)
  398. this.initRelationForm(cur.__config__.children);
  399. });
  400. },
  401. toDetail(item) {
  402. const id = item.__config__.defaultValue;
  403. if (!id) return;
  404. let config = {
  405. modelId: item.modelId,
  406. id: id,
  407. formTitle: "详情",
  408. noShowBtn: 1,
  409. noDataLog: 1,
  410. sourceRelationForm: item?.sourceRelationForm || false,
  411. propsValue: item?.propsValue || ''
  412. };
  413. this.$nextTick(() => {
  414. const url =
  415. "/pages/apply/dynamicModel/detail?config=" +
  416. this.jnpf.base64.encode(JSON.stringify(config));
  417. uni.navigateTo({
  418. url: url,
  419. });
  420. });
  421. },
  422. handleEdit() {
  423. if (this.setting.disableEdit) return;
  424. const currentMenu = encodeURIComponent(JSON.stringify(this.formPermissionList));
  425. let config = {
  426. modelId: this.modelId,
  427. isPreview: this.isPreview,
  428. id: this.setting.id,
  429. btnType: "btn_edit",
  430. currentMenu,
  431. list: this.setting.list,
  432. index: this.setting.index,
  433. menuId: this.setting.menuId
  434. };
  435. const url =
  436. "/pages/apply/dynamicModel/form?config=" +
  437. this.jnpf.base64.encode(JSON.stringify(config));
  438. uni.navigateTo({
  439. url: url,
  440. });
  441. },
  442. },
  443. };
  444. </script>
  445. <style lang="scss" scoped>
  446. page {
  447. background-color: #f0f2f6;
  448. }
  449. </style>