@bytenew/bn-bus-ui 1.1.462 → 1.1.463

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (167) hide show
  1. package/install.js +134 -0
  2. package/package.json +20 -4
  3. package/packages/BnAddress/index.vue +141 -0
  4. package/packages/BnAddressParse/index.vue +75 -0
  5. package/packages/BnAdvancedFilter/BnFilterView.vue +145 -0
  6. package/packages/BnAdvancedFilter/index.vue +345 -0
  7. package/packages/BnAdvancedFilter/util.js +171 -0
  8. package/packages/BnCascader/BnCascader.vue +543 -0
  9. package/packages/BnCascader/BnCascaderPanel.vue +1331 -0
  10. package/packages/BnCascader/cascaderDisplay.js +102 -0
  11. package/packages/BnCheck/BnCheck.vue +253 -0
  12. package/packages/BnColumnConfig/columnConfigDialog.vue +134 -0
  13. package/packages/BnColumnConfig/component/childrenFormSetting/assocTable.vue +143 -0
  14. package/packages/BnColumnConfig/component/childrenFormSetting/assocTableSearch.vue +314 -0
  15. package/packages/BnColumnConfig/component/childrenFormSetting/index.vue +243 -0
  16. package/packages/BnColumnConfig/component/defaultSet/defaultSet.vue +114 -0
  17. package/packages/BnColumnConfig/component/defaultSet/stringDefault.vue +210 -0
  18. package/packages/BnColumnConfig/component/funcExprDialog/funcExprDialog.vue +126 -0
  19. package/packages/BnColumnConfig/component/packageFilter/index.vue +141 -0
  20. package/packages/BnColumnConfig/component/paraExplainSet/index.vue +156 -0
  21. package/packages/BnColumnConfig/component/setOption/setOption.vue +321 -0
  22. package/packages/BnColumnConfig/component/setRelationOption/ConditionList.vue +277 -0
  23. package/packages/BnColumnConfig/component/setRelationOption/LevelHeader.vue +144 -0
  24. package/packages/BnColumnConfig/component/setRelationOption/setRelationOption.vue +642 -0
  25. package/packages/BnColumnConfig/data.js +129 -0
  26. package/packages/BnColumnConfig/index.scss +23 -0
  27. package/packages/BnColumnConfig/index.vue +309 -0
  28. package/packages/BnCondVal/BnCondVal.vue +112 -0
  29. package/packages/BnCondVal/itemVal/dateRegVal.vue +39 -0
  30. package/packages/BnCondVal/itemVal/dateVal.vue +39 -0
  31. package/packages/BnCondVal/itemVal/numRegVal.vue +67 -0
  32. package/packages/BnCondVal/itemVal/numVal.vue +44 -0
  33. package/packages/BnCondVal/itemVal/relationVal.vue +73 -0
  34. package/packages/BnCondVal/itemVal/selectColumnVal.vue +58 -0
  35. package/packages/BnCondVal/itemVal/selectVal.vue +59 -0
  36. package/packages/BnCondVal/itemVal/stringVal.vue +156 -0
  37. package/packages/BnCondition/index.vue +551 -0
  38. package/packages/BnCondition/util.js +232 -0
  39. package/packages/BnDatePicker/BnDatePicker.vue +194 -0
  40. package/packages/BnDrop/BnDrop.vue +917 -0
  41. package/packages/BnEmptyTip/BnEmptyTip.vue +107 -0
  42. package/packages/BnExportOrder/BnExportOrder.vue +241 -0
  43. package/packages/BnExportOrder/validatorCode.vue +94 -0
  44. package/packages/BnFileView/BnFileView.vue +271 -0
  45. package/packages/BnFileView/FileDetail.vue +125 -0
  46. package/packages/BnFileView/videoPreview.vue +70 -0
  47. package/packages/BnFilterOption/BnFilterOption.vue +160 -0
  48. package/packages/BnFunExpr/BnFunExpr.vue +608 -0
  49. package/packages/BnImportOrder/BnImportOrder.vue +323 -0
  50. package/packages/BnImportTemplate/BnImportTemplate.vue +866 -0
  51. package/packages/BnImportTemplate/assets/merge_tip_img.png +0 -0
  52. package/packages/BnImportTemplate/assets/sheet_tip.png +0 -0
  53. package/packages/BnImportTemplate/assets/xls.png +0 -0
  54. package/packages/BnImportTemplate/components/ImportTemplateTrigger.vue +198 -0
  55. package/packages/BnImportTemplate/components/TemplateEditDialog.vue +340 -0
  56. package/packages/BnImportTemplate/components/TemplateFieldsConfig.vue +401 -0
  57. package/packages/BnImportTemplate/components/TemplateListDialog.vue +297 -0
  58. package/packages/BnInpNum/BnInpNum.vue +165 -0
  59. package/packages/BnMenus/BnMenus.vue +502 -0
  60. package/packages/BnMenus/MenuItem.vue +321 -0
  61. package/packages/BnOrderCard/BnOrderCard.vue +389 -0
  62. package/packages/BnOrderCard/orderRemark.vue +178 -0
  63. package/packages/BnOrderCard/util.js +94 -0
  64. package/packages/BnOrderDetail/BnOrderDetail.vue +338 -0
  65. package/packages/BnOrderDetail/filterLogByUser.vue +108 -0
  66. package/packages/BnOrderDetail/orderLogs.vue +53 -0
  67. package/packages/BnOrderDetail/showSubForm/index.vue +41 -0
  68. package/packages/BnOrderDetail/showSubForm/showChildTable.vue +61 -0
  69. package/packages/BnOrderDetail/showSubForm/showTimeLine.vue +131 -0
  70. package/packages/BnOrderDetail/showSubForm/tableCellCopy.vue +84 -0
  71. package/packages/BnOrderShare/index.vue +378 -0
  72. package/packages/BnOrderShare/shareUrlInp.vue +54 -0
  73. package/packages/BnRadio/BnRadio.vue +181 -0
  74. package/packages/BnRelation/BnRelation.vue +120 -0
  75. package/packages/BnSelect/BnSelect.vue +485 -0
  76. package/packages/BnSmartForm/BnBatchForm.vue +334 -0
  77. package/packages/BnSmartForm/BnBatchFormDialog.vue +423 -0
  78. package/packages/BnSmartForm/BnSmartElf/elfLog/index.vue +57 -0
  79. package/packages/BnSmartForm/BnSmartElf/index.vue +95 -0
  80. package/packages/BnSmartForm/BnSmartFormPsychic.js +629 -0
  81. package/packages/BnSmartForm/BnSmartFormUtil.js +524 -0
  82. package/packages/BnSmartForm/addressForm/index.vue +73 -0
  83. package/packages/BnSmartForm/checkboxForm/index.vue +99 -0
  84. package/packages/BnSmartForm/childrenForm/childFormFile.vue +237 -0
  85. package/packages/BnSmartForm/childrenForm/childrenFormBody.vue +260 -0
  86. package/packages/BnSmartForm/childrenForm/index.vue +110 -0
  87. package/packages/BnSmartForm/childrenForm/searchInventory.vue +115 -0
  88. package/packages/BnSmartForm/chooseAssocTable/chooseAssocTable.vue +451 -0
  89. package/packages/BnSmartForm/chooseAssocTable/chooseChildGood.vue +229 -0
  90. package/packages/BnSmartForm/chooseAssocTable/tableCellCopy.vue +84 -0
  91. package/packages/BnSmartForm/chooseChildOrder/chooseChildOrder.vue +158 -0
  92. package/packages/BnSmartForm/chooseIPaasData/chooseIPaasData.vue +307 -0
  93. package/packages/BnSmartForm/chooseIPaasData/tableCellCopy.vue +84 -0
  94. package/packages/BnSmartForm/choosePackage/choosePackage.vue +361 -0
  95. package/packages/BnSmartForm/dateDualForm/index.vue +37 -0
  96. package/packages/BnSmartForm/dateForm/index.vue +38 -0
  97. package/packages/BnSmartForm/fileForm/fileFormData.js +50 -0
  98. package/packages/BnSmartForm/fileForm/index.vue +240 -0
  99. package/packages/BnSmartForm/formItemFooter/formItemFooter.vue +38 -0
  100. package/packages/BnSmartForm/formItemTop/formItemTop.vue +42 -0
  101. package/packages/BnSmartForm/index.vue +1201 -0
  102. package/packages/BnSmartForm/numberForm/index.vue +63 -0
  103. package/packages/BnSmartForm/radioForm/index.vue +72 -0
  104. package/packages/BnSmartForm/receiveForm/index.vue +112 -0
  105. package/packages/BnSmartForm/relationForm/index.vue +82 -0
  106. package/packages/BnSmartForm/scoreForm/index.vue +39 -0
  107. package/packages/BnSmartForm/selectForm/index.vue +55 -0
  108. package/packages/BnSmartForm/showValForm/index.vue +42 -0
  109. package/packages/BnSmartForm/showValForm/showValFormTable.vue +104 -0
  110. package/packages/BnSmartForm/smartFormsCommon.scss +43 -0
  111. package/packages/BnSmartForm/stringForm/index.vue +170 -0
  112. package/packages/BnVirtPopover/index.vue +319 -0
  113. package/packages/BnWebLog/BnWebLog.vue +140 -0
  114. package/packages/BnWorkSettingDrop/advancedOptions.js +112 -0
  115. package/packages/BnWorkSettingDrop/benBenAIUtil.js +89 -0
  116. package/packages/BnWorkSettingDrop/index.vue +292 -0
  117. package/packages/font/iconfont.css +243 -0
  118. package/packages/font/iconfont.ttf +0 -0
  119. package/packages/font/iconfont.woff +0 -0
  120. package/packages/font/iconfont.woff2 +0 -0
  121. package/utils/addressParse-old.js +645 -0
  122. package/utils/addressParse.js +735 -0
  123. package/utils/config.js +68 -0
  124. package/utils/index.js +1171 -0
  125. package/dist/assocTableSearch-CmzOXI5w.js +0 -349
  126. package/dist/assocTableSearch.css +0 -1
  127. package/dist/bn-bus-ui.es.js +0 -65
  128. package/dist/bn-bus-ui.umd.js +0 -49
  129. package/dist/chooseIPaasData-jkTJEMKT.js +0 -391
  130. package/dist/chooseIPaasData.css +0 -1
  131. package/dist/defaultSet-CiYuSOzT.js +0 -297
  132. package/dist/defaultSet.css +0 -1
  133. package/dist/fileFormData-D_Q1vylE.js +0 -53
  134. package/dist/formItemFooter-BpnVUUgV.js +0 -108
  135. package/dist/formItemFooter.css +0 -1
  136. package/dist/funcExprDialog-BMc-n5FL.js +0 -139
  137. package/dist/funcExprDialog.css +0 -1
  138. package/dist/index-8GQJARcF.js +0 -44
  139. package/dist/index-8apT0r8m.js +0 -66
  140. package/dist/index-BOFu3qAH.js +0 -183
  141. package/dist/index-BSKXuSid.js +0 -89
  142. package/dist/index-BhYvDd_Q.js +0 -45
  143. package/dist/index-BhqkeVFc.js +0 -45
  144. package/dist/index-CK7_Ou7F.js +0 -89
  145. package/dist/index-Cfb8D3Fg.js +0 -58
  146. package/dist/index-D1fGD0mX.js +0 -51
  147. package/dist/index-DE_eQGbT.js +0 -746
  148. package/dist/index-DfgiBqzS.js +0 -221
  149. package/dist/index-Dobi0ms9.js +0 -66
  150. package/dist/index-DuyQNxe0.js +0 -118
  151. package/dist/index-DxpJkrN7.js +0 -64
  152. package/dist/index-FGHeG46m.js +0 -109
  153. package/dist/index-P2M7CUTe.js +0 -178
  154. package/dist/index-xCz2zysE.js +0 -135
  155. package/dist/index.css +0 -1
  156. package/dist/index2.css +0 -1
  157. package/dist/index3.css +0 -1
  158. package/dist/index4.css +0 -1
  159. package/dist/index5.css +0 -1
  160. package/dist/index6.css +0 -1
  161. package/dist/index7.css +0 -1
  162. package/dist/install--7IU60oV.js +0 -23103
  163. package/dist/install.css +0 -1
  164. package/dist/setOption-DehYZpZr.js +0 -329
  165. package/dist/setOption.css +0 -1
  166. package/dist/setRelationOption-BL-AFUoF.js +0 -5217
  167. package/dist/setRelationOption.css +0 -1
@@ -0,0 +1,170 @@
1
+ <!--单行文本组件-->
2
+ <template>
3
+ <div class="w-default-wrap">
4
+ <formItemTop :column="column" :dataBack="dataBack"/>
5
+ <div class="w-default-wrap">
6
+ <el-autocomplete
7
+ v-if="isUrlType"
8
+ v-model="column.value"
9
+ :fetch-suggestions="querySearch"
10
+ clearable
11
+ class="w-50"
12
+ :placeholder="column?.extraInfo?.placeholder || ''"
13
+ @select="handleSelect"
14
+ />
15
+ <el-input v-model="column.value" v-else-if="column?.extraInfo?.dataExtra == 'textarea'"
16
+ @input="onInput" @focus="onFocus" @blur="onBlur" clearable show-word-limit
17
+ :placeholder="column?.extraInfo?.placeholder || ''"
18
+ type="textarea" :rows="4" :maxlength="500"/>
19
+ <el-input v-model="column.value" :disabled="disabled" v-else
20
+ :placeholder="column?.extraInfo?.placeholder || ''"
21
+ @input="onInput" @focus="onFocus" @blur="onBlur" clearable show-word-limit>
22
+ </el-input>
23
+ <div class="w-margin-top6" v-if="dataBack && dataBack.key == column.columnCode">
24
+ <el-button link type="primary" style="padding-left: 0" @click="$emit('operate', this.column,'choosePackage')">选择{{column.name || ''}}</el-button>
25
+ </div>
26
+ </div>
27
+ <formItemFooter :column="column" :extraInfo="extraInfo" @operate="(column,type)=>$emit('operate', column,type)"/>
28
+ </div>
29
+ </template>
30
+ <script>
31
+ import {debounce} from "lodash";
32
+ import formItemTop from "../formItemTop/formItemTop.vue";
33
+ import formItemFooter from "../formItemFooter/formItemFooter.vue";
34
+
35
+ export default {
36
+ name: "stringForm",
37
+ components: {formItemTop, formItemFooter},
38
+ props: {
39
+ column: Object,
40
+ dataBack: Object,
41
+ extraInfo: Object,
42
+ disabled: Boolean,
43
+ postFunc: Function
44
+ },
45
+ data() {
46
+ return {
47
+ lastQueryValue: null,
48
+ lastQueryResults: []
49
+ };
50
+ },
51
+ computed: {
52
+ parsedDataExtra() {
53
+ const dataExtra = this.column?.extraInfo?.dataExtra || '';
54
+ if (!dataExtra) return null;
55
+ try {
56
+ return JSON.parse(dataExtra);
57
+ } catch (e) {
58
+ return null;
59
+ }
60
+ },
61
+ isUrlType() {
62
+ return !!this.parsedDataExtra?.searchUrl;
63
+ },
64
+ dataExtraUrl() {
65
+ return this.parsedDataExtra?.searchUrl || '';
66
+ }
67
+ },
68
+ methods: {
69
+ /**
70
+ * 输入框输入事件
71
+ * */
72
+ onInput(e) {
73
+ this.column.error = '';
74
+ this.column.warning = '';
75
+ this.$emit('onInput', this.column)
76
+ this.onChange(e)
77
+ },
78
+ /**
79
+ * 输入框Change事件
80
+ * @param {String} type 是否是其他事件类型
81
+ * */
82
+ onChange: debounce(function (e, type) {
83
+ // 当值不为空
84
+ if (this.column.value) {
85
+ this.checkValue()
86
+ }
87
+ this.$emit('onChange', this.column)
88
+ }, 500),
89
+ /**
90
+ * 输入框onFocus事件
91
+ * */
92
+ onFocus(e) {
93
+ this.$emit('focus', this.column)
94
+ },
95
+ /**
96
+ * 输入框失去焦点事件
97
+ * */
98
+ onBlur() {
99
+ this.$emit('blur', this.column)
100
+ },
101
+ /**
102
+ * 检查输入框的值,并判断是否需要调用检查数据唯一
103
+ *
104
+ * */
105
+ checkValue() {
106
+ try {
107
+ // 组件正则校验
108
+ if (this.column.extraInfo.regular) {
109
+ //获取校验规则,转化为正则表达式
110
+ let rule = new RegExp(this.column.extraInfo.regular);
111
+ if (!rule.test(this.column.value)) {
112
+ this.column.error = this.column.extraInfo.paraExplain || '请输入符合要求的' + this.column.name;
113
+ }
114
+ }
115
+ } catch (e) {
116
+ console.log("stringForm.changeErr:" + e)
117
+ }
118
+ },
119
+
120
+
121
+ /**
122
+ * 远程搜索建议(聚焦时用当前值筛选,输入变更时用输入值筛选)
123
+ */
124
+ querySearch(queryString, cb) {
125
+ //queryString为空则不请求接口 直接lastQueryResults置空即可
126
+ if (!queryString) {
127
+ this.lastQueryValue = null;
128
+ this.lastQueryResults = [];
129
+ cb([]);
130
+ return;
131
+ }
132
+ if (this.lastQueryValue === queryString) {
133
+ cb(this.lastQueryResults);
134
+ return;
135
+ }
136
+ const postData = {
137
+ ...(this.column.postData || {}),
138
+ column:this.column.columnCode,
139
+ keyword: queryString || '',
140
+ pageNo: 1,
141
+ pageSize: 50
142
+ };
143
+ const url = this.dataExtraUrl;
144
+ this.postFunc(url, postData).then(res => {
145
+ if (!res.code && res.data?.results) {
146
+ const list = res.data.results.map(i => ({ value: i.value || i.label || '', ...i }));
147
+ this.lastQueryValue = queryString;
148
+ this.lastQueryResults = list;
149
+ cb(list);
150
+ } else {
151
+ this.lastQueryValue = queryString;
152
+ this.lastQueryResults = [];
153
+ cb([]);
154
+ }
155
+ }).catch(() => {
156
+ this.lastQueryValue = queryString;
157
+ this.lastQueryResults = [];
158
+ cb([]);
159
+ });
160
+ },
161
+ handleSelect(item) {
162
+ this.column.value = item.value;
163
+ this.column.error = '';
164
+ this.column.warning = '';
165
+ this.$emit('onInput', this.column);
166
+ this.$emit('onChange', this.column);
167
+ }
168
+ }
169
+ }
170
+ </script>
@@ -0,0 +1,319 @@
1
+ <!--
2
+ * @description 虚拟弹出框组件
3
+ * 一个可以根据触发元素位置自动调整显示位置的弹出框组件
4
+ * 特点:
5
+ * 1. 自动判断上下位置
6
+ * 2. 自适应屏幕边界
7
+ * 3. 箭头始终指向触发元素
8
+ * 4. 支持hover和点击触发
9
+ -->
10
+ <template>
11
+ <!-- 使用 transition 实现弹出动画,根据位置使用不同的动画效果 -->
12
+ <transition appear :name="popoverPosition == 'bottom' ? 'el-zoom-in-top' : 'el-zoom-in-bottom'">
13
+ <div class="virtualPopover" ref="customPopover" :style="popoverStyle" :class="popoverClass"
14
+ @mouseover="onMouseEvent" @mouseleave="onMouseEvent" v-show="modal">
15
+ <!-- 箭头元素 -->
16
+ <div :class="arrowClass" :style="arrowStyle"></div>
17
+ <!-- 内容区域,阻止事件冒泡 -->
18
+ <div class="virtualPopover-modal" @click.stop="">
19
+ <slot></slot>
20
+ </div>
21
+ </div>
22
+ </transition>
23
+ </template>
24
+
25
+ <script>
26
+ export default {
27
+ name: "BnVirtPopover",
28
+ props: {
29
+ // popover的宽度,支持数字或字符串(如'200px')
30
+ width: {
31
+ type: [Number, String],
32
+ default: 220,
33
+ },
34
+ // popover的显示位置,支持 'top' 或 'bottom'
35
+ popoverPosition: {
36
+ type: String,
37
+ default: "bottom",
38
+ },
39
+ },
40
+ data() {
41
+ return {
42
+ modal: false, // 控制 popover 的显示/隐藏
43
+ popoverStyle: {}, // popover 的样式对象
44
+ popoverClass: [], // popover 的类名数组
45
+ arrowStyle: {}, // 箭头的样式对象
46
+ arrowClass: [], // 箭头的类名数组
47
+ targetEvent: undefined, // 存储触发事件的对象
48
+ closeTimer: null, // 关闭延时器
49
+ };
50
+ },
51
+ methods: {
52
+ /**
53
+ * 切换 popover 的显示状态
54
+ * 如果当前显示且点击同一个触发元素,则关闭
55
+ * 如果当前显示且点击不同触发元素,则更新位置
56
+ * 如果当前隐藏,则显示
57
+ * @param {Event} e - 触发事件对象
58
+ */
59
+ toggle(e) {
60
+ if(!e){
61
+ alert('把事件对象传进来')
62
+ }
63
+ this.targetEvent = e;
64
+ // 鼠标悬浮事件
65
+ if(e.type.indexOf('mouse')>=0){
66
+ // 鼠标离开事件
67
+ if (e.type == 'mouseleave') {
68
+ this.close(e);
69
+ } else {
70
+ this.openPopover(e);
71
+ }
72
+ }
73
+ //点击事件 或 其他
74
+ else{
75
+ if (this.modal) {
76
+ this.close(e);
77
+ } else {
78
+ this.openPopover(e);
79
+ }
80
+ }
81
+ },
82
+ /**
83
+ * 打开 popover
84
+ * @param {Event} e - 触发事件对象
85
+ */
86
+ openPopover(e) {
87
+ this.targetEvent = e;
88
+ this.open()
89
+ // 等待 DOM 更新后初始化位置
90
+ this.$nextTick(() => {
91
+ this.initPosition();
92
+ });
93
+ // 阻止事件冒泡
94
+ e && e.stopPropagation();
95
+ // 添加全局事件监听
96
+ window.addEventListener("click",this.close);
97
+ window.addEventListener("mouseup",this.onMouseup);
98
+ },
99
+ /**
100
+ * 初始化 popover 位置
101
+ * 包括:
102
+ * 1. 计算 popover 的位置和大小
103
+ * 2. 处理屏幕边界情况
104
+ * 3. 计算箭头位置
105
+ * 4. 判断显示方向(上/下)
106
+ */
107
+ initPosition() {
108
+ if (this.targetEvent && this.targetEvent.target && this.targetEvent.target.getBoundingClientRect) {
109
+ // 获取点击dom位置
110
+ const {left, top, width, height} = this.targetEvent.target.getBoundingClientRect();
111
+ // 初始样式
112
+ this.popoverStyle = {};
113
+ this.popoverClass = ["virtualPopover"];
114
+ this.arrowClass = ["virtualPopover-arrow"];
115
+ // 获取屏幕宽高
116
+ const clientWidth = window.innerWidth;
117
+ const clientHeight = window.innerHeight;
118
+ // 计算变量
119
+ const arrowWidth = 6;
120
+ const popoverGap = width > this.width ? 0 : 10; // 最小边距
121
+ const popoverLeft = left - popoverGap; // 距离左侧距离
122
+
123
+ // 计算 popover 的最终位置
124
+ let finalPopoverLeft = popoverLeft;
125
+ if (this.width && popoverLeft + this.width > clientWidth) {
126
+ // 如果超出右边界,将 popover 靠右对齐
127
+ finalPopoverLeft = clientWidth - this.width - popoverGap;
128
+ this.popoverStyle.left = `${finalPopoverLeft}px`;
129
+ } else {
130
+ this.popoverStyle.left = `${popoverLeft}px`;
131
+ }
132
+
133
+ // 计算箭头位置,使其始终指向触发元素的中心
134
+ const targetCenter = left + width / 2;
135
+ const arrowLeft = targetCenter - finalPopoverLeft - arrowWidth;
136
+
137
+ // 确保箭头不会超出 popover 的边界
138
+ const minArrowLeft = arrowWidth * 2;
139
+ const maxArrowLeft = this.width - arrowWidth * 3;
140
+ this.arrowStyle.left = `${Math.min(Math.max(arrowLeft, minArrowLeft), maxArrowLeft)}px`;
141
+
142
+ // 判断popover宽度是否超出屏幕宽度,超出则减少为最小宽度,出现滚动条
143
+ if (isNaN(this.width)) {
144
+ this.popoverStyle.width = `${this.width}`;
145
+ } else {
146
+ if (this.width + popoverGap * 2 > clientWidth) {
147
+ this.popoverStyle.width = `${clientWidth - popoverGap * 2}px`;
148
+ } else this.popoverStyle.minWidth = `${this.width}px`;
149
+ }
150
+ // 获取popover的dom位置
151
+ const {bottom: popoverBottom, height: popoverHeight} = this.$refs.customPopover.getBoundingClientRect();
152
+ // 判断popover是在上方还是下方
153
+ const bottomDistance = clientHeight - popoverBottom; // 与底部距离
154
+ let popoverPosition = this.popoverPosition;
155
+ if (top > bottomDistance && (popoverHeight === 0 || this.modal || popoverHeight >= bottomDistance)) {
156
+ popoverPosition = "top";
157
+ }
158
+ // 内容高度大于屏幕剩高度,并且上方区域大于下方区域
159
+ if (popoverPosition === "top") {
160
+ this.popoverStyle.bottom = `${clientHeight - top}px`;
161
+ } else {
162
+ this.popoverStyle.top = `${top + height}px`;
163
+ }
164
+ this.arrowClass.push(popoverPosition);
165
+ this.popoverClass.push(popoverPosition);
166
+ }
167
+ },
168
+ /**
169
+ * 监听鼠标抬起事件
170
+ * 用于判断点击位置是否在 popover 外部,决定是否关闭
171
+ * @param {MouseEvent} param0 - 鼠标事件对象,解构获取坐标
172
+ */
173
+ onMouseup({x, y}) {
174
+ if (this.$refs.customPopover && this.modal) {
175
+ if (this.targetEvent && this.targetEvent.target && this.targetEvent.target.getBoundingClientRect) {
176
+ const {left, right, top, bottom} = this.targetEvent.target.getBoundingClientRect();
177
+ if (!(x < left || x > right || y < top || y > bottom)) return;
178
+ }
179
+ const {left, right, top, bottom} = this.$refs.customPopover.getBoundingClientRect();
180
+ if (x < left || x > right || y < top || y > bottom) {
181
+ this.close()
182
+ };
183
+ }
184
+ },
185
+ /**
186
+ * 开启
187
+ */
188
+ open() {
189
+ clearTimeout(this.closeTimer);
190
+ this.closeTimer = null;
191
+ this.modal = true;
192
+ },
193
+ /**
194
+ * 关闭
195
+ */
196
+ close() {
197
+ clearTimeout(this.closeTimer);
198
+ // 当触发是点击事件时,直接关闭,不延时
199
+ if(this.targetEvent && this.targetEvent.type == 'click'){
200
+ this.modal = false;
201
+ window.removeEventListener("click", this.close);
202
+ window.removeEventListener("mouseup", this.onMouseup);
203
+ }else{
204
+ this.closeTimer = setTimeout(() => {
205
+ this.modal = false;
206
+ window.removeEventListener("click", this.close);
207
+ window.removeEventListener("mouseup", this.onMouseup);
208
+ }, 300);
209
+ }
210
+ },
211
+ /**
212
+ * 处理鼠标移入移出事件
213
+ * 用于实现 hover 效果
214
+ * 移入时清除关闭定时器
215
+ * 移出时设置延迟关闭
216
+ * @param {MouseEvent} e - 鼠标事件对象
217
+ */
218
+ onMouseEvent(e) {
219
+ if (e.type === 'mouseover' && this.targetEvent.type!='click') {
220
+ clearTimeout(this.closeTimer);
221
+ this.closeTimer = null;
222
+ this.modal = true;
223
+ }
224
+ // 只有触发事件是鼠标悬浮时,从pop移开才关闭
225
+ else if (this.targetEvent.type.indexOf('mouse')>=0 && e.type === 'mouseleave') {
226
+ clearTimeout(this.closeTimer);
227
+ this.modal = false;
228
+ window.removeEventListener("click", this.close);
229
+ window.removeEventListener("mouseup", this.onMouseup);
230
+ }
231
+ },
232
+ },
233
+ };
234
+ </script>
235
+
236
+ <!--
237
+ 样式说明:
238
+ 1. virtualPopover: 弹出框容器
239
+ 2. virtualPopover-modal: 内容区域
240
+ 3. virtualPopover-arrow: 箭头
241
+ 使用 SCSS 变量统一管理箭头大小
242
+ -->
243
+ <style lang='scss' scoped>
244
+ // 箭头大小
245
+ $arrowWidth: 6px;
246
+ .virtualPopover {
247
+ position: fixed;
248
+ z-index: 9999;
249
+ padding-top: $arrowWidth;
250
+
251
+ &-modal {
252
+ position: relative;
253
+ background: #fff;
254
+ box-shadow: 0px 12px 48px 16px rgba(0, 0, 0, 0.02),
255
+ 0px 9px 28px 0px rgba(0, 0, 0, 0.02),
256
+ 0px 6px 16px -8px rgba(0, 0, 0, 0.04);
257
+ }
258
+
259
+ &-arrow {
260
+ position: absolute;
261
+
262
+ &::before,
263
+ &::after {
264
+ content: "";
265
+ display: block;
266
+ width: 0;
267
+ height: 0;
268
+ top: 0px;
269
+ border: $arrowWidth solid transparent;
270
+ position: absolute;
271
+ z-index: 1;
272
+ }
273
+
274
+ &::before {
275
+ z-index: 2;
276
+ }
277
+
278
+ &.bottom {
279
+ top: -$arrowWidth;
280
+
281
+ &::before {
282
+ border-bottom-color: #fff;
283
+ }
284
+
285
+ &::after {
286
+ border-bottom-color: rgba(0, 0, 0, 0.08);
287
+ }
288
+ }
289
+
290
+ &.bottom::after {
291
+ top: -1px;
292
+ }
293
+
294
+ &.top {
295
+ bottom: 0;
296
+
297
+ &::before {
298
+ border-top-color: #fff;
299
+ }
300
+
301
+ &::after {
302
+ border-top-color: rgba(0, 0, 0, 0.08);
303
+ }
304
+ }
305
+
306
+ &.top::after {
307
+ top: 1px;
308
+ }
309
+ }
310
+ }
311
+
312
+ .virtualPopover.bottom {
313
+ margin-top: $arrowWidth;
314
+ }
315
+
316
+ .virtualPopover.top {
317
+ margin-bottom: $arrowWidth;
318
+ }
319
+ </style>
@@ -0,0 +1,140 @@
1
+ <!--
2
+ @Auther:辛巴
3
+ @Date:2023/02/22
4
+ @Description:复选框组件
5
+ @VERSION:1.0-->
6
+ <template>
7
+ <div>
8
+ <el-dialog v-model="show" title="接口请求日志" append-to-body width="1020px" top="10px" destroy-on-close>
9
+ <div style="height: calc(100vh - 158px);overflow-y: auto;padding: 8px 20px 20px 20px" v-loading="loading">
10
+ <div class="w-text-right">
11
+ <el-button link @click="copyText(dataList)" type="primary">复制数据</el-button>
12
+ </div>
13
+ <div style="height: calc(100% - 80px)">
14
+ <vxe-table height="100%" row-id="id" :loading="loading" :data="dataList">
15
+ <vxe-column field="url" title="路径"></vxe-column>
16
+ <vxe-column field="time" title="时间" width="160"></vxe-column>
17
+ <vxe-column field="code" title="code" width="130" :formatter="formatterCode"></vxe-column>
18
+ <vxe-column field="traceId" title="traceId"></vxe-column>
19
+ </vxe-table>
20
+ </div>
21
+ <div class="w-text-right w-margin-top6">
22
+ <el-pagination v-model:current-page="currentPage"
23
+ v-model:page-size="pageSize"
24
+ layout="prev, pager, next" @current-change="changePage"
25
+ :total="apiLogList.length">
26
+ </el-pagination>
27
+ </div>
28
+ </div>
29
+ </el-dialog>
30
+ <div class="BnWebLog" v-show="show">
31
+ <el-card class="BnWebLog-card">
32
+ <div class="w-flex-right">
33
+ <el-button type="primary" link @click="copyText(sessionInfo)">复制信息</el-button>
34
+ <el-button type="primary" link @click="show=false">关闭</el-button>
35
+ </div>
36
+ <div class="BnWebLog-card-body">
37
+ <div v-if="sessionInfo.userName">用户名:{{ sessionInfo.userName }}</div>
38
+ <div v-if="sessionInfo.userId">用户id:{{ sessionInfo.userId }}</div>
39
+ <div class="w-text-over" v-if="sessionInfo.companyName">公司名称:{{ sessionInfo.companyName }}</div>
40
+ <div v-if="sessionInfo.companyId">公司id:{{ sessionInfo.companyId }}</div>
41
+ <div v-if="sessionInfo.tableCode">表code:{{ sessionInfo.tableCode }}</div>
42
+ <div v-if="sessionInfo.appId">小程序id:{{ sessionInfo.appId }}</div>
43
+ <div v-if="sessionInfo.tableId">工作表id:{{ sessionInfo.tableId }}</div>
44
+ <div v-if="sessionInfo.taskId">任务id:{{ sessionInfo.taskId }}</div>
45
+ <div v-if="sessionInfo.workflowId">流程模板id:{{sessionInfo.workflowId}}</div>
46
+ <div v-if="sessionInfo.instanceId">流程实例id:{{sessionInfo.instanceId}}</div>
47
+ <div v-if="sessionInfo.workFlowNodeId">流程节点id:{{sessionInfo.workFlowNodeId}}</div>
48
+ <div v-if="sessionInfo.processCode">流程节点code:{{sessionInfo.processCode}}</div>
49
+ <div v-if="sessionInfo.url">工作表i地址:{{sessionInfo.url}}</div>
50
+ </div>
51
+ </el-card>
52
+ </div>
53
+ </div>
54
+ </template>
55
+
56
+ <script>
57
+ export default {
58
+ name: "BnWebLog",
59
+ data() {
60
+ return {
61
+ show: false,
62
+ apiLogList: [],
63
+ sessionInfo: {},
64
+ dataList: [],
65
+ loading: false,
66
+ currentPage: 1,
67
+ pageSize: 20,
68
+ }
69
+ },
70
+ mounted() {
71
+ document.addEventListener('keydown', this.handleShortcut);
72
+ },
73
+ beforeDestroy() {
74
+ document.removeEventListener('keydown', this.handleShortcut);
75
+ },
76
+ methods: {
77
+ /**
78
+ * 快捷键 Ctrl+Shift+? 或 Ctrl+Shift+/ 打开弹框和 sysInfoTool
79
+ */
80
+ handleShortcut(e) {
81
+ if (e.ctrlKey && e.shiftKey && (e.key === '?' || e.key === '/')) {
82
+ e.preventDefault();
83
+ this.open();
84
+ }
85
+ },
86
+ /**
87
+ * 打开日志记录
88
+ * */
89
+ open() {
90
+ this.show = true;
91
+ this.apiLogList = JSON.parse(localStorage.getItem('webLog') || 'false') || [];
92
+ this.sessionInfo = JSON.parse(localStorage.getItem('sessionInfo') || 'false') || {};
93
+ this.changePage({currentPage: 1, pageSize: 20});
94
+ },
95
+ /**
96
+ * 复制文本
97
+ */
98
+ copyText(val) {
99
+ const textarea = document.createElement('textarea');
100
+ textarea.value = JSON.stringify(val);
101
+ document.body.appendChild(textarea);
102
+ textarea.select();
103
+ document.execCommand('copy');
104
+ document.body.removeChild(textarea);
105
+ this.$message.success('复制成功');
106
+ },
107
+ /**
108
+ * 分页
109
+ * */
110
+ changePage() {
111
+ this.dataList = [];
112
+ if (this.apiLogList.length > 0) {
113
+ this.dataList = this.apiLogList.slice((this.currentPage - 1) * this.pageSize, this.currentPage * this.pageSize)
114
+ }
115
+ },
116
+ /**
117
+ * 格式化状态
118
+ * */
119
+ formatterCode({cellValue}) {
120
+ return `${cellValue}:${cellValue == 0 || cellValue == 1 ? '成功' : '失败'}`;
121
+ }
122
+ }
123
+ };
124
+ </script>
125
+
126
+ <style scoped lang="scss">
127
+ .BnWebLog {
128
+ position: fixed;
129
+ right: 0;
130
+ bottom: 10em;
131
+ z-index: 99999;
132
+
133
+ &-card {
134
+ width: 276px;
135
+ &-body{
136
+ word-break: break-all;
137
+ }
138
+ }
139
+ }
140
+ </style>