浏览代码

4.1.57 将curd的modeldata可在外部节目获取和设置,消息推送增加授权

liuyanpeng 1 年之前
父节点
当前提交
8864499197

+ 1 - 1
package.json

@@ -1,7 +1,7 @@
 {
   "name": "client-base-v4",
   "description": "Leanwo Prodog Client",
-  "version": "4.1.56",
+  "version": "4.1.57",
   "author": "yangzhijie1488 <yangzhijie1488@163.com>",
   "scripts": {
     "ins": "npm install --registry http://wuzhixin.vip:4873",

+ 98 - 54
src/common/pushMessage.js

@@ -2,10 +2,10 @@ import Common from './Common.js';
 import { h } from 'vue';
 import { Notify } from 'pc-component-v3';
 import TaskOpenUtil from '../workflow/TaskOpenUtil';
-import { Modal, notification } from 'ant-design-vue';
+import { message, notification } from 'ant-design-vue';
 import { MessageTwoTone } from '@ant-design/icons-vue';
 import WindowService from './WindowService.js';
-
+import { queryAuth, addAuth } from '../api/authorization/index.js';
 export default {
 
   flag: false,
@@ -106,13 +106,13 @@ export default {
     // 检查用户是否已经允许显示通知
     if (Notification.permission === 'granted') {
       // 如果已经允许,直接显示通知
-      _self.showNotification(message);
+      _self.selectTaskInfo(message.content, false);
     } else if (Notification.permission !== 'denied') {
       // 否则,请求用户允许显示通知
       Notification.requestPermission().then(permission => {
         // 如果用户允许,显示通知
         if (permission === 'granted') {
-          _self.showNotification(message);
+          _self.selectTaskInfo(message.content, false);
         }
       });
     }
@@ -120,6 +120,7 @@ export default {
 
   // 进行系统提示
   showNotification: function (message) {
+    const _self = this;
     // 创建一个新的 Notification 对象
     if (message.type == 'NEW_TASK') {
       const notification = new Notification('待处理消息', {
@@ -127,40 +128,107 @@ export default {
       });
       // 监听通知的点击事件
       notification.onclick = () => {
-        TaskOpenUtil.openTask(message.content).then(
-          successData => {
-            if (successData.type === 'newWindow') {
-              WindowService.open(successData.url, '待处理');
-            }
-          },
-          errorData => {
-            if (errorData != null) {
-              Notify.error(errorData.title, errorData.message, false);
-            }
-          },
-        );
+        _self.openNewTask(message);
       };
     } else if (message.type == 'NEW_UserReadDocument') {
       const notification = new Notification('待审阅消息', {
         body: message.content.title,
       });
       notification.onclick = () => {
-        TaskOpenUtil.openTask(message.content).then(
-          successData => {
-            if (successData.type === 'newWindow') {
-              WindowService.open(successData.url, '待处理');
-            }
-          },
-          errorData => {
-            if (errorData != null) {
-              Notify.error(errorData.title, errorData.message, false);
-            }
-          },
-        );
+        _self.openDocumentTask(message);
       };
     }
   },
 
+  // 打开待处理消息
+  openNewTask: function (taskInfo) {
+    TaskOpenUtil.openTask(taskInfo).then(
+      successData => {
+        if (successData.type === 'newWindow') {
+          WindowService.open(successData.url, '待处理');
+        }
+      },
+      errorData => {
+        if (errorData != null) {
+          Notify.error(errorData.title, errorData.message, false);
+        }
+      },
+    );
+  },
+
+  // 打开待审阅消息
+  openDocumentTask: function (taskInfo) {
+    TaskOpenUtil.openCopyTask(taskInfo).then(
+      successData => {
+        if (successData.type === 'newWindow') {
+          WindowService.open(successData.url, '抄送我的', function () {
+            console.log('打开审阅单');
+          });
+        }
+      },
+      errorData => {
+        if (errorData != null) {
+          Notify.error(errorData.title, errorData.message, false);
+        }
+      },
+    );
+  },
+
+  // 选择了taskInfo 先查询授权资源
+  selectTaskInfo: function (taskInfo, isProdog, isNewTask) {
+    const _self = this;
+    const params = {
+      userId: JSON.parse(localStorage.getItem('#LoginInfo')).userId,
+      recordId: taskInfo.recordId,
+      windowNo: taskInfo.windowNo,
+    };
+    queryAuth(params).then(
+      success => {
+        if (success.errorCode === 0) {
+          if (isProdog) {
+            if (isNewTask) {
+              _self.openNewTask(taskInfo);
+            } else {
+              _self.openDocumentTask(taskInfo);
+            }
+          } else {
+            _self.showNotification(taskInfo);
+          }
+        } else {
+          _self.addAuthorization(params, taskInfo,isProdog,isNewTask);
+        }
+      },
+      err => {
+        Common.processException(err);
+      },
+    );
+  },
+
+  // 增加授权资源
+  addAuthorization: function (params, taskInfo,isProdog,isNewTask) {
+    const _self = this;
+    addAuth(params).then(
+      success => {
+        if (success.errorCode === 0) {
+          if(isProdog){
+            if (isNewTask) {
+              _self.openNewTask(taskInfo);
+            } else {
+              _self.openDocumentTask(taskInfo);
+            }
+          } else {
+            _self.showNotification(taskInfo);
+          }
+        } else {
+          message.warning(success.errorMessage);
+        }
+      },
+      err => {
+        Common.processException(err);
+      },
+    );
+  },
+
   // 打开消息提示框
   openNotification: function (messageData) {
     const _self = this;
@@ -181,18 +249,7 @@ export default {
         onClick: () => {
           notification.close(messageData.uuid);
           // _self.replyMessage(messageData.content.id);
-          TaskOpenUtil.openTask(messageData.content).then(
-            successData => {
-              if (successData.type === 'newWindow') {
-                WindowService.open(successData.url, '待处理');
-              }
-            },
-            errorData => {
-              if (errorData != null) {
-                Notify.error(errorData.title, errorData.message, false);
-              }
-            },
-          );
+          _self.selectTaskInfo(messageData.content,true,true);
         },
       });
     } else if (messageData.type == 'NEW_UserReadDocument') {
@@ -208,20 +265,7 @@ export default {
         onClick: () => {
           notification.close(messageData.uuid);
           // _self.replyDocument(messageData.content.id);
-          TaskOpenUtil.openCopyTask(messageData.content).then(
-            successData => {
-              if (successData.type === 'newWindow') {
-                WindowService.open(successData.url, '抄送我的', function () {
-                  console.log('打开审阅单');
-                });
-              }
-            },
-            errorData => {
-              if (errorData != null) {
-                Notify.error(errorData.title, errorData.message, false);
-              }
-            },
-          );
+          _self.selectTaskInfo(messageData.content,true,false);
         },
       });
     }

+ 2 - 0
src/index.js

@@ -82,6 +82,7 @@ import FlowChart from './dashboard/FlowChart.vue';
 import DeviceManagement from './device/DeviceManagement.vue';
 import DeviceTimingSwitcher from './device/DeviceTimingSwitcher.vue';
 import OperationLog from './operationLog/OperationLog.vue';
+import ViewEdit from './window1/ViewEdit.vue';
 
 export {
   App,
@@ -154,4 +155,5 @@ export {
   DeviceManagement,
   DeviceTimingSwitcher,
   OperationLog,
+  ViewEdit,
 };

+ 2 - 0
src/routes/main_routes.js

@@ -73,6 +73,7 @@ const FlowChart = () => import('../dashboard/FlowChart.vue');
 const DeviceManagement = () =>import('../device/DeviceManagement.vue');
 const DeviceTimingSwitcher = () =>import('../device/DeviceTimingSwitcher.vue');
 const OperationLog = () =>import('../operationLog/OperationLog.vue');
+const ViewEdit = () =>import('../window1/ViewEdit.vue');
 
 import { ProcessReport } from 'pc-component-v3';
 
@@ -396,6 +397,7 @@ export default [
       { path: '/desktop/deviceManagement', component: DeviceManagement },
       { path: '/desktop/deviceTimingSwitcher', component: DeviceTimingSwitcher },
       { path: '/desktop/operationLog', component: OperationLog },
+      { path: '/desktop/viewEdit', component: ViewEdit },
 
     ],
   },

+ 34 - 0
src/window1/ViewEdit.vue

@@ -0,0 +1,34 @@
+<!-- 打开新界面编辑使用方法 -->
+<template>
+  <a-button style="margin-right: 8px;" @click="getModelData">获取ModelData</a-button>
+  <a-button style="margin-right: 8px;" @click="setModelData1">设置ModelData1</a-button>
+  <a-button style="margin-right: 8px;" @click="setModelData2">设置ModelData2</a-button>
+  <a-button style="margin-right: 8px;" @click="refresh">刷新ModelData</a-button>
+</template>
+
+<script setup>
+
+const getModelData = () => {
+  const modelDatas = window.opener.viewEditDatas;
+  console.log(modelDatas, window.opener, '获取到modelData');
+};
+
+// isViewEdit为true才允许改变curd的modelData
+const setModelData1 = () => {
+  const modelDatas = window.opener.viewEditDatas;
+  if (modelDatas.isViewEdit) {
+    modelDatas.data['description']['displayValue'][0] = 'test1';
+    window.opener.editModelDataChanged(modelDatas);
+  }
+};
+const setModelData2 = () => {
+  const modelDatas = window.opener.viewEditDatas;
+  modelDatas.data['description']['displayValue'][0] = 'test2';
+  window.opener.editModelDataChanged(modelDatas);
+};
+const refresh = () => {
+  window.opener.refreshCurdDatas();
+};
+</script>
+
+<style scoped></style>

+ 7 - 2
src/window1/tabFormEdit/TabFormEditModal.vue

@@ -151,6 +151,7 @@
                   :window-no="windowNo" :tab-index="tabIndex" :js-url="jsUrl"
                   :is-chinese-english="curdWindow.isChineseEnglish" :multiple-column="tab.tabFormView.multipleColumn"
                   @value-changed="valueChanged($event, fieldItem)" @execute-callout="executeCallout(fieldItem)"
+                  @get-model-data="getModelData" @model-data-changed="modelDataChanged" @refresh-datas="loadData"
                 />
               </template>
             </div>
@@ -1173,7 +1174,7 @@ export default {
          * 获取界面的数据
          * eg:生单界面获取modelData数据
          */
-    getModelData: function () {
+    getModelData: function (isEditModal) {
       var _self = this;
       var subTabAllData = _self.getSubTabAllData();
       if (subTabAllData.length > 0) {
@@ -1181,7 +1182,11 @@ export default {
       } else {
         _self.modelData.saveDatas = null;
       }
-      return _self.modelData;
+      if(isEditModal) {
+        window.viewEditDatas = _self.modelData;
+      } else {
+        return _self.modelData;
+      }
     },
 
     executeProcess: function (processReportNo) {

+ 421 - 218
src/window1/tabFormEdit/TabFormFieldEdit.vue

@@ -1,257 +1,179 @@
 <template>
   <div
-    v-if="modelData && modelData.data != undefined && field.visible"
-    v-show="showField"
-    class="form-group"
+    v-if="modelData && modelData.data != undefined && field.visible" v-show="showField" class="form-group"
     :class="formGroupClass"
   >
-    <label
-      v-tooltip.right="field.help"
-      class="control-label"
-      :class="formGroupLabelClass"
-      :style="field.cssStyle"
-    >
+    <label v-tooltip.right="field.help" class="control-label" :class="formGroupLabelClass" :style="field.cssStyle">
       <span v-if="field.mandatory" class="required-mark">*</span>
       <font size="2">{{ Language.getDisplayNameTrl($i18n.locale, field) }}</font><br />
       <font v-if="isChineseEnglish && $i18n.locale == 'zh-CN'" size="0.5">{{ field.displayNameEng }}</font>
     </label>
     <div class="input-group" :class="inputGroupClass">
       <input
-        v-if="fieldUtil.isTextType(field)"
-        v-model="displayValue"
-        autocomplete="off"
-        type="text"
-        class="form-control"
-        :name="field.displayName"
-        :readonly="readOnly"
-        :disabled="readOnly"
+        v-if="fieldUtil.isTextType(field)" v-model="displayValue" autocomplete="off" type="text"
+        class="form-control" :name="field.displayName" :readonly="readOnly" :disabled="readOnly"
       />
 
       <input
-        v-if="fieldUtil.isNumberType(field)"
-        v-model="displayValue"
-        autocomplete="off"
-        type="number"
-        class="form-control"
-        :name="field.displayName"
-        :readonly="readOnly"
-        :disabled="readOnly"
-        onmousewheel="return false;"
-        @mousewheel="mouseWheelEvent"
-        @change="numberFormat"
+        v-if="fieldUtil.isNumberType(field)" v-model="displayValue" autocomplete="off" type="number"
+        class="form-control" :name="field.displayName" :readonly="readOnly" :disabled="readOnly"
+        onmousewheel="return false;" @mousewheel="mouseWheelEvent" @change="numberFormat"
       />
 
       <switches
-        v-if="fieldUtil.isCheckBoxType(field)"
-        v-model="displayValue"
-        :selected="displayValue"
-        color="green"
-        :type-bold="true"
-        :disabled="readOnly"
+        v-if="fieldUtil.isCheckBoxType(field)" v-model="displayValue" :selected="displayValue" color="green"
+        :type-bold="true" :disabled="readOnly"
       />
 
       <RedGreenSelect
-        v-if="fieldUtil.isRedGreenEditorType(field)"
-        v-model="displayValue"
-        type="string"
+        v-if="fieldUtil.isRedGreenEditorType(field)" v-model="displayValue" type="string"
         :disabled="readOnly"
       />
 
       <input
-        v-if="fieldUtil.isPasswordType(field)"
-        v-model="displayValue"
-        autocomplete="off"
-        type="password"
-        class="form-control"
-        :name="field.displayName"
-        :readonly="readOnly"
-        :disabled="readOnly"
+        v-if="fieldUtil.isPasswordType(field)" v-model="displayValue" autocomplete="off" type="password"
+        class="form-control" :name="field.displayName" :readonly="readOnly" :disabled="readOnly"
       />
 
       <textarea
-        v-if="fieldUtil.isTextAreaType(field)"
-        v-model="displayValue"
-        class="form-control"
-        rows="3"
-        :name="field.displayName"
-        :style="field.cssStyle"
-        :readonly="readOnly"
-        :disabled="readOnly"
+        v-if="fieldUtil.isTextAreaType(field)" v-model="displayValue" class="form-control" rows="3"
+        :name="field.displayName" :style="field.cssStyle" :readonly="readOnly" :disabled="readOnly"
       />
 
       <Date
-        v-if="fieldUtil.isDateType(field)"
-        :model-value="displayValue"
-        :data-vv-name="field.displayName"
-        :name="field.displayName"
-        :data-vv-value-path="displayValue"
-        :readonly="readOnly"
-        style="width:100%"
+        v-if="fieldUtil.isDateType(field)" :model-value="displayValue" :data-vv-name="field.displayName"
+        :name="field.displayName" :data-vv-value-path="displayValue" :readonly="readOnly" style="width:100%"
         @update:model-value="textChanged"
       />
 
       <Time
-        v-if="fieldUtil.isTimeType(field)"
-        v-model="displayValue"
-        class="form-control"
-        :data-vv-name="field.displayName"
-        :name="field.displayName"
-        :data-vv-value-path="displayValue"
+        v-if="fieldUtil.isTimeType(field)" v-model="displayValue" class="form-control"
+        :data-vv-name="field.displayName" :name="field.displayName" :data-vv-value-path="displayValue"
         :readonly="readOnly"
       />
 
       <DateTime
-        v-if="fieldUtil.isDateTimeType(field)"
-        :model-value="displayValue"
-        :readonly="readOnly"
-        style="width:100%"
-        @update:model-value="textChanged"
+        v-if="fieldUtil.isDateTimeType(field)" :model-value="displayValue" :readonly="readOnly"
+        style="width:100%" @update:model-value="textChanged"
       />
 
       <YearPicker
-        v-if="fieldUtil.isYearType(field)"
-        :value="displayValue"
-        :readonly="readOnly"
+        v-if="fieldUtil.isYearType(field)" :value="displayValue" :readonly="readOnly"
         @selected="textChanged"
       />
 
       <VueMonthlyPicker
-        v-if="fieldUtil.isYearMonthType(field)"
-        id="month-picker"
-        v-model="month"
-        date-format="YYYY-MM"
-        class="vue-monthly-picker m-date-fieldEditView"
-        @selected="refresh"
+        v-if="fieldUtil.isYearMonthType(field)" id="month-picker" v-model="month" date-format="YYYY-MM"
+        class="vue-monthly-picker m-date-fieldEditView" @selected="refresh"
       />
 
       <ImageWidget
-        v-if="fieldUtil.isImageType(field)"
-        :uuid="uuid1"
-        :pattern-json="field.pattern"
-        :field="field"
-        :field-value="fieldValue"
-        :class-name="className"
-        :readonly="readOnly"
-        @value-changed="valueChanged"
+        v-if="fieldUtil.isImageType(field)" :uuid="uuid1" :pattern-json="field.pattern" :field="field"
+        :field-value="fieldValue" :class-name="className" :readonly="readOnly" @value-changed="valueChanged"
       />
 
       <ImageListWidget
-        v-if="fieldUtil.isImageListType(field)"
-        :field="field"
-        :field-value="fieldValue"
-        :class-name="className"
-        :readonly="readOnly"
-        @value-changed="valueChanged"
+        v-if="fieldUtil.isImageListType(field)" :field="field" :field-value="fieldValue"
+        :class-name="className" :readonly="readOnly" @value-changed="valueChanged"
       />
 
       <VideoListWidget
-        v-if="fieldUtil.isVideoType(field)"
-        :field="field"
-        :field-value="fieldValue"
-        :class-name="className"
-        :readonly="readOnly"
-        @value-changed="valueChanged"
+        v-if="fieldUtil.isVideoType(field)" :field="field" :field-value="fieldValue"
+        :class-name="className" :readonly="readOnly" @value-changed="valueChanged"
       />
 
       <FileListWidget
-        v-if="fieldUtil.isFileType(field)"
-        :field="field"
-        :field-value="fieldValue"
-        :class-name="className"
-        :readonly="readOnly"
-        @value-changed="valueChanged"
+        v-if="fieldUtil.isFileType(field)" :field="field" :field-value="fieldValue"
+        :class-name="className" :readonly="readOnly" @value-changed="valueChanged"
       />
 
       <EnumRadioGroupWidget
-        v-if="fieldUtil.isRadioButtonGroupType(field)"
-        :field="field"
-        :field-value="fieldValue"
-        :data-vv-name="field.displayName"
-        :name="field.displayName"
-        :data-vv-value-path="displayValue"
-        :readonly="readOnly"
-        @value-changed="valueChanged"
+        v-if="fieldUtil.isRadioButtonGroupType(field)" :field="field" :field-value="fieldValue"
+        :data-vv-name="field.displayName" :name="field.displayName" :data-vv-value-path="displayValue"
+        :readonly="readOnly" @value-changed="valueChanged"
       />
 
       <ManyToManySetSearchWidget
-        v-if="fieldUtil.isManyToManySetType(field)"
-        :info-window-no="field.infoWindowNo"
-        :field="field"
-        :field-value="fieldValue"
-        :readonly="readOnly"
-        :model-data="modelData"
-        :window-no="windowNo"
-        :tab-index="tabIndex"
-        @value-changed="valueChanged"
+        v-if="fieldUtil.isManyToManySetType(field)" :info-window-no="field.infoWindowNo"
+        :field="field" :field-value="fieldValue" :readonly="readOnly" :model-data="modelData" :window-no="windowNo"
+        :tab-index="tabIndex" @value-changed="valueChanged"
       />
 
       <SearchWidget
-        v-if="fieldUtil.isSearchType(field)"
-        :info-window-no="field.infoWindowNo"
-        :field="field"
-        :field-value="fieldValue"
-        :readonly="readOnly"
-        :model-data="modelData"
-        :window-no="windowNo"
-        :tab-index="tabIndex"
-        @value-changed="valueChanged"
+        v-if="fieldUtil.isSearchType(field)" :info-window-no="field.infoWindowNo" :field="field"
+        :field-value="fieldValue" :readonly="readOnly" :model-data="modelData" :window-no="windowNo"
+        :tab-index="tabIndex" @value-changed="valueChanged"
       />
 
       <EnumSelectWidget
-        v-if="fieldUtil.isEnumListType(field)"
-        :field="field"
-        :field-value="fieldValue"
-        :name="field.displayName"
-        :readonly="readOnly"
-        @value-changed="valueChanged"
+        v-if="fieldUtil.isEnumListType(field)" :field="field" :field-value="fieldValue"
+        :name="field.displayName" :readonly="readOnly" @value-changed="valueChanged"
       />
 
       <EnumMultiSelectWidget
-        v-if="fieldUtil.isEnumMultiType(field)"
-        :field="field"
-        :field-value="fieldValue"
-        :name="field.displayName"
-        :readonly="readOnly"
-        @value-changed="valueChanged"
+        v-if="fieldUtil.isEnumMultiType(field)" :field="field" :field-value="fieldValue"
+        :name="field.displayName" :readonly="readOnly" @value-changed="valueChanged"
       />
 
       <SelectWidget
-        v-if="fieldUtil.isSelectType(field)"
-        ref="selectWidget"
-        :field="field"
-        :field-value="fieldValue"
-        :window-no="windowNo"
-        :tab-index="tabIndex"
-        :readonly="readOnly"
-        :model-data="modelData"
+        v-if="fieldUtil.isSelectType(field)" ref="selectWidget" :field="field" :field-value="fieldValue"
+        :window-no="windowNo" :tab-index="tabIndex" :readonly="readOnly" :model-data="modelData"
         @value-changed="valueChanged"
       />
 
       <ButtonWidget
-        v-if="fieldUtil.isButtonType(field)"
-        :field="field"
-        :field-value="fieldValue"
-        :readonly="readOnly"
-        @value-changed="valueChanged"
-        @execute-callout="executeCallout"
+        v-if="fieldUtil.isButtonType(field)" :field="field" :field-value="fieldValue" :readonly="readOnly"
+        @value-changed="valueChanged" @execute-callout="executeCallout"
       />
 
       <RichTextAreaEditorWidget
-        v-if="fieldUtil.isRichTextAreaEditor(field)"
-        :display-value="displayValue"
-        :class-name="className"
-        :field-value="fieldValue"
-        :readonly="isReadOnly"
-        @value-changed="valueChanged"
+        v-if="fieldUtil.isRichTextAreaEditor(field)" :display-value="displayValue"
+        :class-name="className" :field-value="fieldValue" :readonly="isReadOnly" @value-changed="valueChanged"
       />
       <div v-if="fieldUtil.isGridButtonEditor(field)" style="display: inline-block">
-        <template v-for="tabFormButtonItem in field.tabFormButtonDtos" :key="tabFormButtonItem.name">
-          <a-button
-            v-if="tabFormButtonItem.action === 'OPEN_NEW_VIEW_EDIT'" type="link"
-            @click="openNewViewEdit(tabFormButtonItem)"
-          >
-            {{ tabFormButtonItem.name }}
-          </a-button>
+        <template v-for="(tabFormButtonItem,index) in field.tabFormButtonDtos" :key="tabFormButtonItem.name">
+          <template v-if="visible[index]">
+            <a-button v-if="tabFormButtonItem.action === 'EDIT'" type="link" @click="editRecord">
+              {{ tabFormButtonItem.name
+              }}
+            </a-button>
+            <a-button
+              v-if="tabFormButtonItem.action === 'RUN_PROCESS_REPORT'" type="link"
+              @click="execute(tabFormButtonItem)"
+            >
+              {{ tabFormButtonItem.name }}
+            </a-button>
+            <a-button
+              v-if="tabFormButtonItem.action === 'OPEN_CUSTOMER_WINDOW'" type="link"
+              @click="execute(tabFormButtonItem)"
+            >
+              {{ tabFormButtonItem.name }}
+            </a-button>
+            <a-button
+              v-if="tabFormButtonItem.action === 'OPEN_HTML_WINDOW'" type="link"
+              @click="execute(tabFormButtonItem)"
+            >
+              {{ tabFormButtonItem.name }}
+            </a-button>
+            <a-button
+              v-if="tabFormButtonItem.action === 'OPEN_REMOTE_COMPONENT_MODULE_IN_MODAL'" type="link"
+              @click="openRemoteComponentModule(tabFormButtonItem)"
+            >
+              {{ tabFormButtonItem.name }}
+            </a-button>
+            <a-button
+              v-if="tabFormButtonItem.action === 'OPEN_NEW_VIEW_EDIT'" type="link"
+              @click="openNewViewEdit(tabFormButtonItem)"
+            >
+              {{ tabFormButtonItem.name }}
+            </a-button>
+            <a-button
+              v-if="tabFormButtonItem.action === 'ABANDON'" danger
+              @click="abandon"
+            >
+              {{ tabFormButtonItem.name }}
+            </a-button>
+          </template>
         </template>
       </div>
       <p v-show="!validateMandatory" class="required-mark required-error">
@@ -259,6 +181,7 @@
       </p>
     </div>
   </div>
+  <component :is="modal1Component" v-model:open="modal1Open" :class-name="className" :model-data="modelData" @refresh-data="refreshDatas" />
 </template>
 
 <script>
@@ -283,11 +206,13 @@ import RedGreenSelect from '../../widget/RedGreenSelect.vue';
 import ImageWidget from '../tabFormWidget/ImageWidget.vue';
 import RichTextAreaEditorWidget from '../tabFormWidget/RichTextAreaEditorWidget.vue';
 import JsUtil from '../../common/JsUtil.js';
-import { Notify, Uuid } from 'pc-component-v3';
-
-
-
-
+import { Notify, Uuid, CssUtil } from 'pc-component-v3';
+import Common from '../../common/Common.js';
+import {Spin as ASpin, Empty as AEmpty, message } from 'ant-design-vue';
+import CustomerWindowResource from '../../api/dic/CustomerWindowResource.js';
+import HtmlWindowResource from '../../api/dic/HtmlWindowResource.js';
+import ProcessReportResource from '../../api/dic/ProcessReportResource.js';
+import { defineAsyncComponent } from 'vue';
 
 
 
@@ -310,9 +235,9 @@ export default {
     ButtonWidget,
     RichTextAreaEditorWidget,
   },
-  
+
   props: {
-   
+
     windowNo: {
       type: String,
       default: null,
@@ -335,13 +260,13 @@ export default {
     },
     field: {
       type: Object,
-      default : function(){
+      default: function () {
         return null;
       },
     },
     modelData: {
       type: Object,
-      default : function(){
+      default: function () {
         return null;
       },
     },
@@ -351,16 +276,16 @@ export default {
     },
   },
 
-  
-  emits: ['executeCallout', 'valueChanged'],
+
+  emits: ['executeCallout', 'valueChanged', 'refreshDatas','getModelData','abandonWorkflow', 'modelDataChanged'],
 
   data: function () {
     this.Language = Language;
     // eslint-disable-next-line
     var value =
       this.modelData == undefined ||
-      this.modelData.data == undefined ||
-      this.modelData.data[this.field.fieldName] == undefined
+        this.modelData.data == undefined ||
+        this.modelData.data[this.field.fieldName] == undefined
         ? ''
         : this.modelData.data[this.field.fieldName].displayValue[
           this.field.entityFieldIndex
@@ -379,6 +304,9 @@ export default {
       month: undefined,
       uuid1: Uuid.createUUID(),
       showField: true, // 显示字段
+      visible:[],
+      modal1Open: false,
+      modal1Component: null,
     };
   },
 
@@ -494,35 +422,47 @@ export default {
     'modelData.data': {
       deep: true,
       handler(curVal, oldVal) {
-        if(curVal == undefined ||
-            curVal[this.field.fieldName] == undefined ||
-            curVal[this.field.fieldName].displayValue == undefined ||
-            curVal[this.field.fieldName].displayValue.length < this.field.entityFieldIndex + 1){
+        if (curVal == undefined ||
+          curVal[this.field.fieldName] == undefined ||
+          curVal[this.field.fieldName].displayValue == undefined ||
+          curVal[this.field.fieldName].displayValue.length < this.field.entityFieldIndex + 1) {
           this.displayValue = '';
-        }else{
+        } else {
           let tempValue = curVal[this.field.fieldName].displayValue[this.field.entityFieldIndex];
-          if(fieldUtil.isCheckBoxType(this.field)){
-            if(typeof(tempValue) =='string'){
+          if (fieldUtil.isCheckBoxType(this.field)) {
+            if (typeof (tempValue) == 'string') {
               this.displayValue = (tempValue === 'true') ? true : false;
             }
-            if(typeof(tempValue) =='boolean'){
+            if (typeof (tempValue) == 'boolean') {
               this.displayValue = (tempValue === true) ? true : false;
             }
-          }else{
+          } else {
             this.displayValue = tempValue;
-          }          
+          }
         }
         this.fieldValue = curVal == undefined ? [] : curVal[this.field.fieldName];
         this.showLogical();
       },
     },
+    'field.tabFormButtonDtos': {
 
+      immediate: true,
+      handler(curVal, oldVal) {
+        const _self = this;
+        this.visible.splice(0, this.visible.length);
+        if (curVal != null) {
+          curVal.forEach(item => {
+            _self.visible.push(true);
+          });
+        }
+      },
+    },
     month: function () {
       this.textChanged(this.month);
     },
   },
 
-  mounted: function () {},
+  mounted: function () { },
 
   methods: {
     /**
@@ -534,26 +474,54 @@ export default {
     /**
      * 获取modelData中字段的显示值
      */
-    getModelDataFieldDisplayValue : function(){
-      if(this.modelData == null 
-          || this.field == null
-          || this.modelData.data[this.field.fieldName] == undefined
-          || this.modelData.data[this.field.fieldName].displayValue == undefined
-          || this.modelData.data[this.field.fieldName].displayValue.length < this.field.entityFieldIndex + 1){
+    getModelDataFieldDisplayValue: function () {
+      if (this.modelData == null
+        || this.field == null
+        || this.modelData.data[this.field.fieldName] == undefined
+        || this.modelData.data[this.field.fieldName].displayValue == undefined
+        || this.modelData.data[this.field.fieldName].displayValue.length < this.field.entityFieldIndex + 1) {
         return null;
       }
       return this.modelData.data[this.field.fieldName].displayValue[this.field.entityFieldIndex];
     },
+    refreshDatas: function () {
+      this.$emit('refreshDatas');
+    },
 
+    // 获取modelData
+    getEditModelData: function () {
+      this.$emit('getModelData', true);
+    },
+    // 更新modelData
+    editModelDataChanged: function (modelData) {
+      this.$emit('modelDataChanged', modelData);
+    },
+    // 刷新modelData
+    refreshEditData: function(){
+      window.refreshCurdDatas = this.refreshDatas;
+    },
+    // 弃审
+    abandon:function(){
+      this.$emit('abandonWorkflow');
+    },
     /**
      * 打开新界面编辑
      * @param tabButton 
      */
-    openNewViewEdit:function(tabButton){
+    openNewViewEdit: function (tabButton) {
+      const _self = this;
       //打开新界面编辑Url
       var openNewViewEditUrl = tabButton.openNewViewEditUrl;
-      //modelData过去,编辑完成后把modelData带回来
-      //待开发
+      if (!openNewViewEditUrl) {
+        message.warning('未定义打开界面地址,请您先定义。');
+        return;
+      }
+      _self.refreshEditData(); // 将刷新方法放入window中
+      _self.getEditModelData(); // 将modelData放入window中
+      window.viewEditDatas.isViewEdit = true; // 需要通过modelData来保存的标识
+      window.editModelDataChanged = _self.editModelDataChanged; // 修改modelData
+      const url = Common.getRootPath() + openNewViewEditUrl;
+      window.open(url, '_blank');
     },
     // 值改变事件
     valueChanged: function (newFieldValue) {
@@ -593,8 +561,8 @@ export default {
         ) {
           var idValue =
             this.modelData == undefined ||
-            this.modelData.data == undefined ||
-            this.modelData.data[this.field.fieldName] == undefined
+              this.modelData.data == undefined ||
+              this.modelData.data[this.field.fieldName] == undefined
               ? undefined
               : this.modelData.data[this.field.fieldName].id;
           if (idValue == null || idValue == '' || idValue < 1) {
@@ -607,8 +575,8 @@ export default {
         } else {
           var stringValue =
             this.modelData == undefined ||
-            this.modelData.data == undefined ||
-            this.modelData.data[this.field.fieldName] == undefined
+              this.modelData.data == undefined ||
+              this.modelData.data[this.field.fieldName] == undefined
               ? ''
               : this.modelData.data[this.field.fieldName].displayValue[0];
           if (stringValue == undefined || stringValue === '') {
@@ -622,12 +590,12 @@ export default {
     /**
      * 年份变化
      */
-    yearChange: function () {},
+    yearChange: function () { },
 
     /**
      * 年月选择完成
      */
-    refresh: function () {},
+    refresh: function () { },
 
     numberFormat: function () {
       if (
@@ -646,6 +614,240 @@ export default {
       }
     },
 
+    /**
+     * 获取字符串的哈希值
+     * @param input
+     */
+    getHash: function (input) {
+      let hash = 0;
+      if (input.length === 0) {
+        return hash;
+      }
+      for (let i = 0; i < input.length; i++) {
+        const char = input.charCodeAt(i);
+        hash = (hash << 5) - hash + char;
+        hash = hash & hash; // 确保返回值是一个32位有符号整数
+      }
+      return Math.abs(hash).toString();
+    },
+    /**
+     * 远程加载ES VUE组件模块,并在模态框中打开。
+     * @param jsUrl js路径
+     * @param cssUrl css路径
+     */
+    openRemoteComponentModule: function (tabButton) {
+      var _self = this;
+      let jsUrl = tabButton.remoteComponentModuleJsUrl;
+      let cssUrl = tabButton.remoteComponentModuleCssUrl;
+
+      // 显示模态框
+      // 异步的加载js组件
+      //let jsUrl = './static/client-eam-module-v3/dist/AssetCheckCreate.js';
+      //let cssUrl = './static/client-eam-module-v3/dist/AssetCheckCreate.css';
+
+      if (cssUrl != null && cssUrl.length > 0) {
+        let cssUrlHash = _self.getHash(cssUrl);
+        CssUtil.dynamicLoadCss(cssUrl, cssUrlHash);
+      }
+      // webpackIgnore:设置为 true 时,禁用动态导入解析。
+      // const testAsyncRemoteComponent  = await import(/* webpackIgnore: true */ jsUrl);
+
+      // console.log(testAsyncRemoteComponent);
+      if (jsUrl != null && jsUrl.length > 0) {
+        const testAsyncRemoteComponent = defineAsyncComponent({
+          // 加载函数
+          loader: () => {
+            return import(/* webpackIgnore: true */ jsUrl);
+          },
+          // 加载异步组件时使用的组件
+          loadingComponent: ASpin,
+          // 展示加载组件前的延迟时间,默认为 200ms
+          delay: 200,
+          // 加载失败后展示的组件
+          errorComponent: AEmpty,
+          // 如果提供了一个 timeout 时间限制,并超时了
+          // 也会显示这里配置的报错组件,默认值是:Infinity
+          timeout: 10000,
+        });
+
+        _self.modal1Component = testAsyncRemoteComponent;
+        _self.modal1Open = true;
+        console.log(_self.modal1Component);
+      }
+    },
+    //跳转或执行流程
+    execute: function (tabButton) {
+      var _self = this;
+      _self.tabButtonModel = tabButton;
+      if (tabButton.customerWindowNo != undefined && tabButton.customerWindowNo != '') {
+        CustomerWindowResource.uniqueByNo(tabButton.customerWindowNo).then(
+          successData => {
+            if (successData.errorCode == 0) {
+              tabButton.customerWindowRouteUrl = successData.data.routeUrl;
+              if (tabButton.customerWindowNo == '20221101_151823') {
+                localStorage.setItem('AssetInstance_ComplexFilterParams', JSON.stringify(_self.complexFilterParams));
+                localStorage.setItem('AssetInstance_SimpleFilterParams', _self.simpleFilterParams);
+              }
+              //跳转到tabButton.routeUrl
+              _self.switchFormRoute(tabButton);
+            }else{
+              Notify.error(_self.$t('lang.Notify.error'), successData.errorMessage, true);
+            }
+            
+          },
+          errorData => {
+            Common.processException(errorData);
+          },
+        );
+      } else if (
+        tabButton.processReportNo != undefined &&
+      tabButton.processReportNo != ''
+      ) {
+      // 判断流程报表是否有参数
+      // 如果有参数则直接跳转到流程和报表的界面。
+        if (tabButton.routerRedirect == undefined || tabButton.routerRedirect == false) {
+          if (tabButton.tipsTitle == undefined || tabButton.tipsTitle.length == 0) {
+            _self.executeProcess();
+          } else {
+            _self.titleModal = true;
+          }
+        } else {
+          this.$router.push({
+            path: '/desktop/process-report/' + tabButton.processReportNo,
+          });
+        }
+      } else if (tabButton.htmlWindowNo != undefined) {
+        HtmlWindowResource.uniqueByNo(tabButton.htmlWindowNo).then(
+          response => {
+            if (response.errorCode != 0) {
+              Notify.error(_self.$t('lang.Notify.dataDictionaryError'), response.errorMessage, true);
+              return;
+            }
+
+            const htmlWindowDto = response.data;
+            if (htmlWindowDto != undefined) {
+              var htmlWindowUrl = htmlWindowDto.htmlFileName;
+              var autoCloseInterval = htmlWindowDto.autoCloseInterval;
+              var regExp = new RegExp('[{].*?[}]', 'g');
+              var result = htmlWindowUrl.match(regExp);
+              if (htmlWindowUrl != undefined && htmlWindowUrl != '') {
+                for (var index = 0, len = result.length; index < len; index++) {
+                  var tempResult = result[index];
+                  console.log('{' + tempResult + '}匹配');
+                  if (tempResult == '{URL}') {
+                    htmlWindowUrl = htmlWindowUrl.replace(
+                      '{URL}',
+                      Common.getHostPageBaseURL(),
+                    );
+                  } else if (tempResult == '{RecordIds}') {
+                    var recordId = _self.modelData.id;
+                    htmlWindowUrl = htmlWindowUrl.replace('{RecordIds}', recordId);
+                  } else if (tempResult == '{Token}') {
+                    htmlWindowUrl = htmlWindowUrl.replace('{Token}', Common.getToken());
+                  } else {
+                    if (_self.selectedModelDatas.length == 0) {
+                      Notify.error(_self.$t('lang.Notify.error'), _self.$t('lang.tabButton.describe3'), true);
+                      return;
+                    } else if (_self.selectedModelDatas.length > 1) {
+                      Notify.error(_self.$t('lang.Notify.error'), _self.$t('lang.tabButton.describe2'), true);
+                      return;
+                    }
+                    var tempResult1 = tempResult.replace('{', '').replace('}', '');
+                    htmlWindowUrl = htmlWindowUrl.replace(
+                      tempResult,
+                      _self.getFirstSelectModelDataFieldValue(tempResult1),
+                    );
+                  }
+                }
+
+                var openWindow = window.open(htmlWindowUrl);
+
+                // 自动关闭
+                if (autoCloseInterval != undefined) {
+                  setTimeout(function () {
+                    openWindow.close();
+                    openWindow = undefined;
+                  }, autoCloseInterval * 1000);
+                }
+              }
+            }
+          },
+          errorData => {
+            Common.processException(errorData);
+          },
+        );
+      }
+    },
+    // 执行流程
+    executeProcess: function () {
+      var _self = this;
+      var ids = [_self.modelData.id];
+      ProcessReportResource.runProcessByIds(_self.tabButtonModel.processReportNo, ids).then(
+        successData => {
+          _self.modal = true;
+          _self.processReportResult = successData;
+
+          if (
+            _self.processReportResult.reportResults != undefined &&
+          _self.processReportResult.reportResults.length > 0
+          ) {
+            _self.processReportResult.reportResults.forEach(function (item, index) {
+              if (item.reportDefinitionType !== 'ExcelReport') {
+                item.previewIndex = 1;
+              } else {
+                item.previewIndex = 2;
+              }
+              if (index == 0) {
+                item.showPreview = true;
+              } else {
+                item.showPreview = false;
+              }
+            });
+          }
+          _self.titleModal = false;
+          _self.refreshDatas();
+        },
+        errorData => {
+          _self.titleModal = false;
+          Common.processException(errorData);
+        },
+      );
+    // }
+    },
+    // 切换到Form表单的路由
+    switchFormRoute: function (tabButton) {
+      const _self = this;
+      var routeDate = {
+        path: tabButton.customerWindowRouteUrl,
+        params: {
+          modelData: this.modelData,
+        },
+      };
+      // 请勿修改,会影响生单的功能
+      var uuid = _self.uuid;
+      if (uuid != undefined) {
+        routeDate.path = routeDate.path + '/' + uuid;
+      }
+
+      const frameUrl = Common.getRedirectUrl(
+        '#' + routeDate.path,
+      );
+
+      // 供子页面iframe调用,修改modelData,(举例:生单界面修改参数)。
+      // window.modelDataChanged = this.modelDataChanged;
+
+      // window.getModelData = this.getModelData;
+      let modelData = JSON.stringify(this.modelData);
+      console.log(modelData);
+      localStorage.setItem(_self.uuid + '#GenerateDocumentTool', modelData);
+
+      var iWidth = 1280;//弹出窗口的宽度;
+      var iHeight = 720; //弹出窗口的高度;
+      var iTop = (window.screen.availHeight - 30 - iHeight) / 2;//获得窗口的垂直位置;
+      var iLeft = (window.screen.availWidth - 10 - iWidth) / 2; //获得窗口的水平位置;
+      window.open(frameUrl, '_blank', 'height=' + iHeight + ',innerHeight=' + iHeight + ',width=' + iWidth + ',innerWidth=' + iWidth + ',top=' + iTop + ',left=' + iLeft + ',toolbar=no,menubar=no,scrollbars=auto,resizeable=no,location=no,status=no');
+    // window.open(frameUrl);
+    },
     /**
      * 禁止滚轮滚动影响数字
      */
@@ -665,16 +867,16 @@ export default {
         this.showField = true;
         return;
       }
-
+      _self.modelData.type = 'view';
       const functionName =
         this.field.fieldName.replace('.', '_') + '_showLogical';
 
 
-      let executeFunction = function(){
-        try{
+      let executeFunction = function () {
+        try {
           let context = new _self.getContext(_self.modelData);
           _self.showField = _self[functionName](context);
-        }catch(error){
+        } catch (error) {
           console.error(error);
           Notify.error('数据字典定义异常', '【' + logic + '】前端列显示逻辑定义异常,请联系管理员检查数据字典的定义。', false);
         }
@@ -682,7 +884,7 @@ export default {
 
       if (_self[functionName] == null) {
         const jsUrl = _self.jsUrl;
-        if(jsUrl == null || jsUrl == undefined){
+        if (jsUrl == null || jsUrl == undefined) {
           Notify.error('数据字典定义异常', '【' + logic + '】前端列显示逻辑的JS文件不存在,请联系管理员检查数据字典是否JS文件。', false);
           return;
         }
@@ -691,7 +893,7 @@ export default {
 
         promise.then(targetFunction => {
           _self[functionName] = targetFunction;
-          if(_self[functionName] == null){
+          if (_self[functionName] == null) {
             Notify.error('数据字典定义异常', '【' + logic + '】前端列显示逻辑方法不存在,请联系管理员检查数据字典。', false);
             return;
           }
@@ -699,7 +901,7 @@ export default {
         }, errorData => {
           console.error(errorData);
         });
-      }else{
+      } else {
         executeFunction();
       }
     },
@@ -721,6 +923,7 @@ input::-webkit-inner-spin-button {
 input[type="number"] {
   -moz-appearance: textfield;
 }
+
 textarea {
   overflow-y: auto !important;
   overflow-x: hidden !important;
@@ -787,7 +990,7 @@ textarea {
 
 
 <style>
-.m-date-fieldEditView > div:first-child {
+.m-date-fieldEditView>div:first-child {
   width: 100%;
 }
 </style>

+ 107 - 114
src/window1/tabFormView/TabFormFieldView.vue

@@ -1,16 +1,9 @@
 <template>
   <div
-    v-if="modelData != null && modelData.data != undefined && field.visible"
-    v-show="showField"
-    class="form-group"
+    v-if="modelData != null && modelData.data != undefined && field.visible" v-show="showField" class="form-group"
     :class="formGroupClass"
   >
-    <label
-      v-tooltip.right="field.help"
-      class="control-label"
-      :class="formGroupLabelClass"
-      :style="field.cssStyle"
-    >
+    <label v-tooltip.right="field.help" class="control-label" :class="formGroupLabelClass" :style="field.cssStyle">
       <span v-if="field.mandatory" class="required-mark">*</span>
       <font size="2">{{ Language.getDisplayNameTrl($i18n.locale, field) }}</font><br />
       <font v-if="isChineseEnglish && $i18n.locale == 'zh-CN'" size="0.5">{{ field.displayNameEng }}</font>
@@ -31,20 +24,15 @@
             !fieldUtil.isTextAreaType(field) &&
             !fieldUtil.isFileType(field) &&
             !fieldUtil.isRichTextAreaEditor(field) &&
-            !fieldUtil.isNumberType(field) && 
-            !fieldUtil.isButtonType(field) && 
-            !fieldUtil.isGridButtonEditor(field)             
-        "
-        v-tooltip.left="getFieldStringValue()"
-        class="form-control-static input-group-item"
+            !fieldUtil.isNumberType(field) &&
+            !fieldUtil.isButtonType(field) &&
+            !fieldUtil.isGridButtonEditor(field)
+        " v-tooltip.left="getFieldStringValue()" class="form-control-static input-group-item"
       >
         {{ getFieldStringValue() }}
       </p>
 
-      <p
-        v-if="fieldUtil.isNumberType(field)"
-        class="form-control-static input-group-item"
-      >
+      <p v-if="fieldUtil.isNumberType(field)" class="form-control-static input-group-item">
         {{ getFieldNumberValue() }}
       </p>
 
@@ -53,138 +41,101 @@
       </p>
 
       <p
-        v-if="fieldUtil.isTextAreaType(field)"
-        v-tooltip.left="getFieldStringValue()"
-        class="form-control-static"
-        :class="inputGroupItemClass"
-        style="word-break: break-all; white-space: pre-line"
+        v-if="fieldUtil.isTextAreaType(field)" v-tooltip.left="getFieldStringValue()" class="form-control-static"
+        :class="inputGroupItemClass" style="word-break: break-all; white-space: pre-line"
       >
         {{ getFieldStringValue() }}
       </p>
 
       <p
-        v-if="fieldUtil.isManyToManySetType(field)"
-        class="form-control-static input-group-item"
+        v-if="fieldUtil.isManyToManySetType(field)" class="form-control-static input-group-item"
         :class="inputGroupItemClass"
       >
-        <span
-          v-for="item in getManyToManyValues()"
-          :key="item"
-          class="input-group-item-manytomany"
-        >
+        <span v-for="item in getManyToManyValues()" :key="item" class="input-group-item-manytomany">
           {{ item }}
         </span>
       </p>
 
       <p
-        v-if="fieldUtil.isCheckBoxType(field)"
-        class="form-control-static input-group-item"
+        v-if="fieldUtil.isCheckBoxType(field)" class="form-control-static input-group-item"
         :class="inputGroupItemClass"
       >
         {{ getFieldStringValue() == "true" ? $t("lang.TabFormFieldView.yes") : $t("lang.TabFormFieldView.no") }}
       </p>
 
       <p
-        v-if="fieldUtil.isRedGreenEditorType(field)"
-        class="form-control-static input-group-item"
+        v-if="fieldUtil.isRedGreenEditorType(field)" class="form-control-static input-group-item"
         :class="inputGroupItemClass"
       >
         {{ getFieldStringValue() == "true" ? "红单" : "蓝单" }}
       </p>
 
       <p
-        v-if="fieldUtil.isEnumListType(field)"
-        class="form-control-static input-group-item"
+        v-if="fieldUtil.isEnumListType(field)" class="form-control-static input-group-item"
         :class="inputGroupItemClass"
       >
-        {{ getEnmuValue() === "编辑中" ? $t("lang.TabFormFieldView.editing"):
-          getEnmuValue() === "审批中" ? $t("lang.TabFormFieldView.pendingApproval"):
-          getEnmuValue() === "审批通过" ? $t("lang.TabFormFieldView.approved"):
-          getEnmuValue() === "审批不通过" ? $t("lang.TabFormFieldView.rejected"):
-          getEnmuValue() === "单据已撤回" ? $t("lang.TabFormFieldView.withdraw"):
-          getEnmuValue() === "转移" ? $t("lang.TabFormFieldView.transfer"):
-          getEnmuValue() === "报废" ? $t("lang.TabFormFieldView.disposal"):
-          getEnmuValue() === "全盘" ? $t("lang.TabFormFieldView.overall"):
-          getEnmuValue() === "抽盘" ? $t("lang.TabFormFieldView.randomInventory"):getEnmuValue()
+        {{ getEnmuValue() === "编辑中" ? $t("lang.TabFormFieldView.editing") :
+          getEnmuValue() === "审批中" ? $t("lang.TabFormFieldView.pendingApproval") :
+          getEnmuValue() === "审批通过" ? $t("lang.TabFormFieldView.approved") :
+          getEnmuValue() === "审批不通过" ? $t("lang.TabFormFieldView.rejected") :
+          getEnmuValue() === "单据已撤回" ? $t("lang.TabFormFieldView.withdraw") :
+          getEnmuValue() === "转移" ? $t("lang.TabFormFieldView.transfer") :
+          getEnmuValue() === "报废" ? $t("lang.TabFormFieldView.disposal") :
+          getEnmuValue() === "全盘" ? $t("lang.TabFormFieldView.overall") :
+          getEnmuValue() === "抽盘" ? $t("lang.TabFormFieldView.randomInventory") : getEnmuValue()
         }}
       </p>
 
       <p
-        v-if="fieldUtil.isEnumMultiType(field)"
-        class="form-control-static input-group-item"
+        v-if="fieldUtil.isEnumMultiType(field)" class="form-control-static input-group-item"
         :class="inputGroupItemClass"
       >
         {{ getMultiEnmuValue() }}
       </p>
 
       <div
-        v-if="fieldUtil.isImageType(field)"
-        class="form-control-static input-group"
-        :class="inputGroupItemClass"
-        style="display: inline-block"
-        :style="field.cssStyle"
+        v-if="fieldUtil.isImageType(field)" class="form-control-static input-group" :class="inputGroupItemClass"
+        style="display: inline-block" :style="field.cssStyle"
       >
         <ImageViewWidget
-          v-if="fieldUtil.isImageType(field)"
-          :field="field"
-          :field-value="fieldValue"
+          v-if="fieldUtil.isImageType(field)" :field="field" :field-value="fieldValue"
           :class-name="className"
         />
       </div>
       <div
-        v-if="fieldUtil.isImageListType(field)"
-        class="form-control-static"
-        :class="inputGroupItemClass"
+        v-if="fieldUtil.isImageListType(field)" class="form-control-static" :class="inputGroupItemClass"
         :style="field.cssStyle"
       >
         <ImageListViewWidget
-          v-if="fieldUtil.isImageListType(field)"
-          :key="'ImageListViewWidget' + new Date().getTime()"
-          :field="field"
-          :field-value="fieldValue"
-          :class-name="className"
+          v-if="fieldUtil.isImageListType(field)" :key="'ImageListViewWidget' + new Date().getTime()"
+          :field="field" :field-value="fieldValue" :class-name="className"
         />
       </div>
 
       <div
-        v-if="fieldUtil.isVideoType(field)"
-        class="form-control-static"
-        :class="inputGroupItemClass"
+        v-if="fieldUtil.isVideoType(field)" class="form-control-static" :class="inputGroupItemClass"
         :style="field.cssStyle"
       >
         <VideoListWidget
-          v-if="fieldUtil.isVideoType(field)"
-          :field="field"
-          :field-value="fieldValue"
-          :class-name="className"
-          :readonly="readOnly"
+          v-if="fieldUtil.isVideoType(field)" :field="field" :field-value="fieldValue"
+          :class-name="className" :readonly="readOnly"
         />
       </div>
 
       <div
-        v-if="fieldUtil.isFileType(field)"
-        :class="inputGroupItemClass"
-        :style="field.cssStyle"
+        v-if="fieldUtil.isFileType(field)" :class="inputGroupItemClass" :style="field.cssStyle"
         style="display: inline-block"
       >
         <FileListWidget
-          v-if="fieldUtil.isFileType(field)"
-          :field="field"
-          :field-value="fieldValue"
-          :class-name="className"
-          :readonly="true"
+          v-if="fieldUtil.isFileType(field)" :field="field" :field-value="fieldValue"
+          :class-name="className" :readonly="true"
         />
       </div>
 
       <div v-if="fieldUtil.isButtonType(field)" style="display: inline-block">
-        <ButtonWidget
-          :field="field"
-          :field-value="fieldValue"
-          :readonly="readOnly"
-          @execute-callout="executeCallout"
-        />
+        <ButtonWidget :field="field" :field-value="fieldValue" :readonly="readOnly" @execute-callout="executeCallout" />
       </div>
-      
+
       <div v-if="fieldUtil.isGridButtonEditor(field)" style="display: inline-block">
         <template v-for="(tabFormButtonItem, index) in field.tabFormButtonDtos" :key="tabFormButtonItem.name">
           <template v-if="visible[index]">
@@ -222,12 +173,18 @@
             >
               {{ tabFormButtonItem.name }}
             </a-button>
+            <a-button v-if="tabFormButtonItem.action === 'ABANDON'" danger @click="abandon">
+              {{ tabFormButtonItem.name }}
+            </a-button>
           </template>
         </template>
       </div>
     </div>
   </div>
-  <component :is="modal1Component" v-model:open="modal1Open" :class-name="className" :model-data="modelData" @refresh-data="refreshDatas" />
+  <component
+    :is="modal1Component" v-model:open="modal1Open" :class-name="className" :model-data="modelData"
+    @refresh-data="refreshDatas"
+  />
 </template>
 
 <script>
@@ -239,7 +196,7 @@ import fieldUtil from '../../resource/dictionary/FieldUtil.js';
 import WindowClientUtil from '../../resource/dictionary/WindowClientUtil.js';
 import Language from '../../common/Language.js';
 import Context from '../common/Context.js';
-import { Spin as ASpin, Empty as AEmpty } from 'ant-design-vue';
+import { Spin as ASpin, Empty as AEmpty, message } from 'ant-design-vue';
 import EnumSelectWidget from '../tabFormWidget/EnumSelectWidget.vue';
 import SelectWidget from '../tabFormWidget/SelectWidget.vue';
 import EnumRadioGroupWidget from '../tabFormWidget/EnumRadioGroupWidget.vue';
@@ -251,7 +208,7 @@ import ImageViewWidget from '../tabFormWidget/ImageViewWidget.vue';
 import ImageListViewWidget from '../tabFormWidget/ImageListViewWidget.vue';
 import JsUtil from '../../common/JsUtil.js';
 import { SqlApi } from 'pc-component-v3';
-import { Notify, Uuid , CssUtil} from 'pc-component-v3';
+import { Notify, Uuid, CssUtil } from 'pc-component-v3';
 import Common from '../../common/Common.js';
 import CustomerWindowResource from '../../api/dic/CustomerWindowResource.js';
 import HtmlWindowResource from '../../api/dic/HtmlWindowResource.js';
@@ -304,13 +261,13 @@ export default {
     },
   },
 
-  emits: ['executeCallout', 'refreshDatas'],
+  emits: ['executeCallout', 'refreshDatas', 'getModelData', 'abandonWorkflow'],
 
   data: function () {
     this.Language = Language;
     var value =
       this.modelData.data == undefined ||
-      this.modelData.data[this.field.fieldName] == undefined
+        this.modelData.data[this.field.fieldName] == undefined
         ? ''
         : this.modelData.data[this.field.fieldName].displayValue.join(', ');
 
@@ -322,7 +279,7 @@ export default {
       fieldValue: fieldValue,
       fieldUtil: fieldUtil,
       showField: true, // 显示字段
-      visible:[],
+      visible: [],
       modal1Open: false,
       modal1Component: null,
     };
@@ -406,8 +363,8 @@ export default {
       handler(curVal, oldVal) {
         this.displayValue =
           curVal == undefined ||
-          curVal[this.field.fieldName] == undefined ||
-          curVal[this.field.fieldName].displayValue == undefined
+            curVal[this.field.fieldName] == undefined ||
+            curVal[this.field.fieldName].displayValue == undefined
             ? ''
             : curVal[this.field.fieldName].displayValue[0];
         this.fieldValue = curVal == undefined ? [] : curVal[this.field.fieldName];
@@ -447,15 +404,51 @@ export default {
     refreshDatas: function () {
       this.$emit('refreshDatas');
     },
+    // 弃审
+    abandon: function () {
+      this.$emit('abandonWorkflow');
+    },
+    // 获取modelData
+    getEditModelData: function () {
+      this.$emit('getModelData', true);
+    },
+    // 刷新modelData
+    refreshEditData: function () {
+      window.refreshCurdDatas = this.refreshDatas;
+    },
     /**
      * 打开新界面编辑
      * @param tabButton 
      */
-    openNewViewEdit:function(tabButton){
+    openNewViewEdit: function (tabButton) {
+      const _self = this;
       //打开新界面编辑Url
       var openNewViewEditUrl = tabButton.openNewViewEditUrl;
-      //传递modelData,调接口
-      //待开发
+      if (!openNewViewEditUrl) {
+        message.warning('未定义打开界面地址,请您先定义。');
+        return;
+      }
+      _self.refreshEditData(); // 将刷新方法放入window中
+      _self.getEditModelData(); // 将modelData放入window中
+      window.viewEditDatas.isViewEdit = false; // 需要通过modelData来保存的标识
+      const url = Common.getRootPath() + openNewViewEditUrl;
+      window.open(url, '_blank');
+    },
+    /**
+     * 获取字符串的哈希值
+     * @param input
+     */
+    getHash: function (input) {
+      let hash = 0;
+      if (input.length === 0) {
+        return hash;
+      }
+      for (let i = 0; i < input.length; i++) {
+        const char = input.charCodeAt(i);
+        hash = (hash << 5) - hash + char;
+        hash = hash & hash; // 确保返回值是一个32位有符号整数
+      }
+      return Math.abs(hash).toString();
     },
     /**
      * 远程加载ES VUE组件模块,并在模态框中打开。
@@ -518,10 +511,10 @@ export default {
               }
               //跳转到tabButton.routeUrl
               _self.switchFormRoute(tabButton);
-            }else{
+            } else {
               Notify.error(_self.$t('lang.Notify.error'), successData.errorMessage, true);
             }
-            
+
           },
           errorData => {
             Common.processException(errorData);
@@ -529,10 +522,10 @@ export default {
         );
       } else if (
         tabButton.processReportNo != undefined &&
-      tabButton.processReportNo != ''
+        tabButton.processReportNo != ''
       ) {
-      // 判断流程报表是否有参数
-      // 如果有参数则直接跳转到流程和报表的界面。
+        // 判断流程报表是否有参数
+        // 如果有参数则直接跳转到流程和报表的界面。
         if (tabButton.routerRedirect == undefined || tabButton.routerRedirect == false) {
           if (tabButton.tipsTitle == undefined || tabButton.tipsTitle.length == 0) {
             _self.executeProcess();
@@ -617,7 +610,7 @@ export default {
 
           if (
             _self.processReportResult.reportResults != undefined &&
-          _self.processReportResult.reportResults.length > 0
+            _self.processReportResult.reportResults.length > 0
           ) {
             _self.processReportResult.reportResults.forEach(function (item, index) {
               if (item.reportDefinitionType !== 'ExcelReport') {
@@ -640,7 +633,7 @@ export default {
           Common.processException(errorData);
         },
       );
-    // }
+      // }
     },
     // 切换到Form表单的路由
     switchFormRoute: function (tabButton) {
@@ -674,7 +667,7 @@ export default {
       var iTop = (window.screen.availHeight - 30 - iHeight) / 2;//获得窗口的垂直位置;
       var iLeft = (window.screen.availWidth - 10 - iWidth) / 2; //获得窗口的水平位置;
       window.open(frameUrl, '_blank', 'height=' + iHeight + ',innerHeight=' + iHeight + ',width=' + iWidth + ',innerWidth=' + iWidth + ',top=' + iTop + ',left=' + iLeft + ',toolbar=no,menubar=no,scrollbars=auto,resizeable=no,location=no,status=no');
-    // window.open(frameUrl);
+      // window.open(frameUrl);
     },
     // 获取String字符串
     getFieldStringValue: function () {
@@ -716,15 +709,15 @@ export default {
         this.showField = true;
         return;
       }
-
+      _self.modelData.type = 'view';
       let functionName = this.field.fieldName.replace('.', '_') + '_showLogical';
 
 
-      let executeFunction = function(){
-        try{
+      let executeFunction = function () {
+        try {
           let context = new _self.getContext(_self.modelData);
           _self.showField = _self[functionName](context);
-        }catch(error){
+        } catch (error) {
           console.error(error);
           Notify.error('数据字典定义异常', '【' + logic + '】前端列显示逻辑定义异常,请联系管理员检查数据字典的定义。', false);
         }
@@ -736,18 +729,18 @@ export default {
           Notify.error(
             '数据字典定义异常',
             '【' +
-              logic +
-              '】前端列显示逻辑的JS文件不存在,请联系管理员检查数据字典是否JS文件。',
+            logic +
+            '】前端列显示逻辑的JS文件不存在,请联系管理员检查数据字典是否JS文件。',
             false,
           );
           return;
         }
         let promise = JsUtil.dynamicLoadJsFunction(jsUrl, logic);
         promise.then(
-          targetFunction => {            
+          targetFunction => {
             _self[functionName] = targetFunction;
 
-            if(_self[functionName] == null){
+            if (_self[functionName] == null) {
               Notify.error('数据字典定义异常', '【' + logic + '】前端列显示逻辑方法不存在,请联系管理员检查数据字典。', false);
               return;
             }

+ 8 - 3
src/window1/tabFormView/TabFormViewModal.vue

@@ -144,6 +144,7 @@
                   ref="fieldItem1" :class-name="tab.tabDataSource.className" :field="fieldItem"
                   :model-data="modelData" :multiple-column="tab.tabFormView.multipleColumn" :js-url="jsUrl"
                   :is-chinese-english="curdWindow.isChineseEnglish" @execute-callout="executeCallout(fieldItem)"
+                  @get-model-data="getModelData" @abandon-workflow="abandonWorkflow" @refresh-datas="refresh"
                 />
               </template>
             </div>
@@ -204,7 +205,7 @@
                     <TabFormFieldView
                       ref="fieldItem2" :class-name="tab.tabDataSource.className" :field="fieldItem"
                       :model-data="modelData" :multiple-column="tab.tabFormView.multipleColumn" :js-url="jsUrl"
-                      :is-chinese-english="curdWindow.isChineseEnglish" @execute-callout="executeCallout(fieldItem)"
+                      :is-chinese-english="curdWindow.isChineseEnglish" @execute-callout="executeCallout(fieldItem)" @refresh-datas="refresh"
                     />
                   </template>
                 </div>
@@ -1373,7 +1374,7 @@ export default {
          * 获取界面的数据
          * eg:生单界面获取modelData数据
          */
-    getModelData: function () {
+    getModelData: function (isViewEdit) {
       var _self = this;
       var subTabChangedData = _self.getSubTabChangedData();
       if (subTabChangedData.length > 0) {
@@ -1381,7 +1382,11 @@ export default {
       } else {
         _self.modelData.saveDatas = null;
       }
-      return _self.modelData;
+      if(isViewEdit) {
+        window.viewEditDatas = _self.modelData;
+      } else {
+        return _self.modelData;
+      }
     },
 
     /**

+ 43 - 25
src/window1/tabGridView/CellTextItem.vue

@@ -43,7 +43,7 @@
     </div>
 
     <div v-else-if="fieldUtil.isManyToManySetType(gridFieldItem)">
-      <span v-for="item, index in getManyToManyValues()" :key="index" class="selected-tag">
+      <span v-for="(item, index1) in getManyToManyValues()" :key="index1" class="selected-tag">
         {{ item }}
       </span>
     </div>
@@ -72,8 +72,8 @@
     </div>
 
     <div v-else-if="fieldUtil.isGridButtonEditor(gridFieldItem)">
-      <template v-for="(tabGridButtonItem, index) in gridFieldItem.tabGridButtonDtos" :key="tabGridButtonItem.name">
-        <template v-if="visible[index]">
+      <template v-for="(tabGridButtonItem, index2) in gridFieldItem.tabGridButtonDtos" :key="tabGridButtonItem.name">
+        <template v-if="visible[index2]">
           <a-button
             v-if="tabGridButtonItem.action === 'CREATE' || tabGridButtonItem.action === 'SAVE' || tabGridButtonItem.action === 'RUN' || tabGridButtonItem.action === 'EXPORT' || tabGridButtonItem.action === 'NOTICE' || tabGridButtonItem.action === 'REFRESH'"
             type="link" @click="buttonClick"
@@ -128,13 +128,11 @@
 
     <component
       :is="customerComponentName" v-else-if="fieldUtil.isCustomerRender(gridFieldItem)" :field="gridFieldItem"
-      :field-value="fieldValue" :class-name="className"
-      :model-data="modelData"
-      @refresh-data="refreshDatas"
+      :field-value="fieldValue" :class-name="className" :model-data="modelData" @refresh-data="refreshDatas"
     />
   </div>
 
-  
+
 
   <Modal v-model:show="modal" :full="true">
     <ProcessReportResultPreview
@@ -162,7 +160,10 @@
       </button>
     </template>
   </Modal>
-  <component :is="modal1Component" v-model:open="modal1Open" :class-name="className" :model-data="modelData" @refresh-data="refreshDatas" />
+  <component
+    :is="modal1Component" v-model:open="modal1Open" :class-name="className" :model-data="modelData"
+    @refresh-data="refreshDatas"
+  />
 </template>
 
 <script>
@@ -171,7 +172,7 @@ import {
   defineAsyncComponent,
 } from 'vue';
 import { Notify, Uuid, CssUtil } from 'pc-component-v3';
-import { Spin as ASpin, Empty as AEmpty } from 'ant-design-vue';
+import { Spin as ASpin, Empty as AEmpty, message } from 'ant-design-vue';
 import FieldUtil from '../../resource/dictionary/FieldUtil.js';
 import Common from '../../common/Common.js';
 
@@ -230,7 +231,7 @@ export default {
       type: String,
       default: null,
     },
-    index:{
+    index: {
       type: Number,
       default: null,
     },
@@ -586,15 +587,32 @@ export default {
       }
     },
 
+    // 获取modelData
+    getEditModelData: function () {
+      window.viewEditDatas = this.modelData;
+      window.viewEditDatas.isViewEdit = false;
+    },
+
+    //刷新modelData
+    refreshEditData: function(){
+      window.refreshCurdDatas = this.refreshDatas;
+    },
+
     /**
      * 打开新界面编辑
      * @param tabButton 
      */
-    openNewViewEdit:function(tabButton){
+    openNewViewEdit: function (tabButton) {
       //打开新界面编辑Url
       var openNewViewEditUrl = tabButton.openNewViewEditUrl;
-      //传递modelData,调接口
-      //待开发
+      if (!openNewViewEditUrl) {
+        message.warning('未定义打开界面地址,请您先定义。');
+        return;
+      }
+      this.getEditModelData();
+      this.refreshEditData(); // 将刷新方法放入window中
+      const url = Common.getRootPath() + openNewViewEditUrl;
+      window.open(url, '_blank');
     },
 
     /**
@@ -612,7 +630,7 @@ export default {
         hash = hash & hash; // 确保返回值是一个32位有符号整数
       }
       return Math.abs(hash).toString();
-    },    
+    },
     
     /**
      * 远程加载ES VUE组件模块。
@@ -622,8 +640,8 @@ export default {
     renderRemoteComponentModule: async function () {
       const _self = this;
 
-      
-      if(this.gridFieldItem == null || !FieldUtil.isCustomerRender(this.gridFieldItem)){
+
+      if (this.gridFieldItem == null || !FieldUtil.isCustomerRender(this.gridFieldItem)) {
         return;
       }
 
@@ -664,7 +682,7 @@ export default {
         console.log(_self.customerComponentName);
       }
     },
-  
+
     //跳转或执行流程
     execute: function (tabButton) {
       var _self = this;
@@ -680,10 +698,10 @@ export default {
               }
               //跳转到tabButton.routeUrl
               _self.switchFormRoute(tabButton);
-            }else{
+            } else {
               Notify.error(_self.$t('lang.Notify.error'), successData.errorMessage, true);
             }
-            
+
           },
           errorData => {
             Common.processException(errorData);
@@ -691,10 +709,10 @@ export default {
         );
       } else if (
         tabButton.processReportNo != undefined &&
-      tabButton.processReportNo != ''
+        tabButton.processReportNo != ''
       ) {
-      // 判断流程报表是否有参数
-      // 如果有参数则直接跳转到流程和报表的界面。
+        // 判断流程报表是否有参数
+        // 如果有参数则直接跳转到流程和报表的界面。
         if (tabButton.routerRedirect == undefined || tabButton.routerRedirect == false) {
           if (tabButton.tipsTitle == undefined || tabButton.tipsTitle.length == 0) {
             _self.executeProcess();
@@ -800,7 +818,7 @@ export default {
       var iTop = (window.screen.availHeight - 30 - iHeight) / 2;//获得窗口的垂直位置;
       var iLeft = (window.screen.availWidth - 10 - iWidth) / 2; //获得窗口的水平位置;
       window.open(frameUrl, '_blank', 'height=' + iHeight + ',innerHeight=' + iHeight + ',width=' + iWidth + ',innerWidth=' + iWidth + ',top=' + iTop + ',left=' + iLeft + ',toolbar=no,menubar=no,scrollbars=auto,resizeable=no,location=no,status=no');
-    // window.open(frameUrl);
+      // window.open(frameUrl);
     },
     // 执行流程
     executeProcess: function () {
@@ -813,7 +831,7 @@ export default {
 
           if (
             _self.processReportResult.reportResults != undefined &&
-          _self.processReportResult.reportResults.length > 0
+            _self.processReportResult.reportResults.length > 0
           ) {
             _self.processReportResult.reportResults.forEach(function (item, index) {
               if (item.reportDefinitionType !== 'ExcelReport') {
@@ -836,7 +854,7 @@ export default {
           Common.processException(errorData);
         },
       );
-    // }
+      // }
     },
     //关闭表头按钮提示框
     titleModalClose: function () {