GridHeader.vue 8.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347
  1. <template>
  2. <tr class="sticky-row">
  3. <th
  4. v-if="$i18n.locale === 'zh-CN'"
  5. class="text-center sticky-col"
  6. width="50px"
  7. >
  8. <div>{{ $t('lang.gridHeader.serialNumber') }}</div>
  9. </th>
  10. <th
  11. v-else
  12. class="text-center sticky-col"
  13. width="100px"
  14. >
  15. <div>{{ $t('lang.gridHeader.serialNumber') }}</div>
  16. </th>
  17. <th
  18. class="text-center sticky-col"
  19. width="30px"
  20. :class="{'mulitiple-select': multipleSelect}"
  21. style="left:50px" @click.self="changeSelectMode"
  22. >
  23. <input
  24. v-model="isSelectAll"
  25. autocomplete="off"
  26. type="checkbox"
  27. class="select-checkbox"
  28. />
  29. </th>
  30. <th
  31. v-if="isShowEdit == undefined || isShowEdit"
  32. class="text-center sticky-col"
  33. width="95px"
  34. style="left:80px"
  35. >
  36. <div>
  37. {{ $t('lang.gridHeader.operate') }}
  38. </div>
  39. </th>
  40. <template v-if="tabGridFields != null && tabGridFields.length > 0">
  41. <th
  42. v-for="tabGridField in tabGridFields"
  43. v-show="tabGridField.visible"
  44. :id="tabGridField.fieldId" :key="'th_' + getTabGridFieldId(tabGridField)"
  45. v-tooltip="tabGridField.help"
  46. class="text-center"
  47. :width="tabGridField.width + 'px'"
  48. style="position: relative;"
  49. @dragover="ondragover($event, tabGridField)"
  50. @click="onSort(tabGridField)"
  51. >
  52. <div
  53. :id="getTabGridFieldId(tabGridField)"
  54. class="rz-handle"
  55. draggable="true"
  56. @dragstart="ondragstart($event, tabGridField)"
  57. @drag="ondrag($event, tabGridField)"
  58. @dragend="ondragend($event, tabGridField)"
  59. />
  60. <div class="td-max">
  61. <span
  62. v-if="tabGridField.mandatory"
  63. class="require-mark"
  64. >*</span>
  65. <span size="2">{{ Language.getDisplayNameTrl($i18n.locale, tabGridField) }}</span><br />
  66. <span v-if="isChineseEnglish && $i18n.locale == 'zh-CN'" size="0.5">{{ tabGridField.displayNameEng }}</span>
  67. </div>
  68. </th>
  69. </template>
  70. </tr>
  71. </template>
  72. <script>
  73. import WindowClientUtil from '../../resource/dictionary/WindowClientUtil.js';
  74. import GridColumnDef from './GridColumnDef.js';
  75. import Language from '../../common/Language.js';
  76. import Context from '../common/Context.js';
  77. import JsUtil from '../../common/JsUtil.js';
  78. import { Notify, Uuid } from 'pc-component-v3';
  79. export default {
  80. props: {
  81. windowNo: {
  82. type: String,
  83. default: null,
  84. },
  85. tabIndex: {
  86. type: Number,
  87. default: null,
  88. },
  89. tabGridFields: {
  90. type: Array,
  91. default : function(){
  92. return null;
  93. },
  94. },
  95. parentModelData: {
  96. type: Object,
  97. default : function(){
  98. return null;
  99. },
  100. },
  101. isShowEdit: {
  102. type: Boolean,
  103. default : false,
  104. },
  105. isChineseEnglish: {
  106. type: Boolean,
  107. default: null,
  108. },
  109. },
  110. emits: ['onSort', 'multipleSelect'],
  111. data: function () {
  112. this.Language = Language;
  113. return {
  114. startX: '',
  115. startWidth: '',
  116. isSelectAll: false,
  117. multipleSelect: true,
  118. };
  119. },
  120. watch: {
  121. 'isSelectAll': function (val) {
  122. var _self = this;
  123. if (_self.multipleSelect) {
  124. _self.$emit('selectAll', _self.isSelectAll);
  125. } else {
  126. _self.isSelectAll = false;
  127. }
  128. },
  129. 'parentModelData.data': {
  130. deep: true,
  131. handler(curVal, oldVal) {
  132. var _self = this;
  133. for(let index = 0; index < _self.tabGridFields.length; index ++){
  134. const tabGridField = _self.tabGridFields[index];
  135. const columnShowLogical = tabGridField.columnShowLogical;
  136. if(columnShowLogical != null && columnShowLogical.length > 0){
  137. let functionName = tabGridField.fieldName.replace('.', '_') + '_showLogical';
  138. let executeFunction = function(){
  139. let parentCtx = new _self.getContext(_self.parentModelData);
  140. try{
  141. tabGridField.visible = _self[functionName](null, parentCtx.modelData);
  142. }catch(e){
  143. console.error('js代码 %s 执行异常 %o', columnShowLogical, e);
  144. tabGridField.visible = true;
  145. }
  146. };
  147. if(_self[functionName] == null){
  148. // 执行服务端的脚本
  149. const jsUrl = _self.jsUrl;
  150. if(jsUrl == null || jsUrl == undefined){
  151. Notify.error('数据字典定义异常', '【' + tabGridField.fieldName + '】列显示逻辑的JS文件不存在,请联系管理员检查数据字典是否JS文件。', false);
  152. return;
  153. }
  154. let promise = JsUtil.dynamicLoadJsFunction(jsUrl, columnShowLogical);
  155. promise.then(dynamicFunction => {
  156. let targetFunction = dynamicFunction;
  157. if(targetFunction == null){
  158. Notify.error('数据字典定义异常', '【' + tabGridField.fieldName + '】列显示逻辑定义异常,请联系管理员检查数据字典的定义。', false);
  159. return;
  160. }
  161. _self[functionName] = targetFunction;
  162. executeFunction();
  163. }, errorData => {
  164. console.error(errorData);
  165. });
  166. }else{
  167. executeFunction();
  168. }
  169. }
  170. }
  171. },
  172. },
  173. },
  174. methods: {
  175. /**
  176. * 获取Context
  177. */
  178. getContext : Context,
  179. /**
  180. * 获取表格列的Id
  181. */
  182. getTabGridFieldId: function (tabGridField) {
  183. var tabGridFieldId = 'GridHeader' + this.windowNo + '_' + this.tabIndex + '_' + tabGridField.fieldName + '_' + tabGridField.entityFieldIndex;
  184. return tabGridFieldId;
  185. },
  186. ondragstart: function (event, tabGridField) {
  187. var _self = this;
  188. _self.startX = event.pageX;
  189. _self.startWidth = tabGridField.width;
  190. var tabGridFieldId = this.getTabGridFieldId(tabGridField);
  191. var element1 = document.getElementById(tabGridFieldId);
  192. $(element1).addClass('rz-handle-active');
  193. // event.dataTransfer.setDragImage(element1, 0, 30);
  194. event.dataTransfer.setDragImage(event.target, 0, 20);
  195. event.dataTransfer.effectAllowed = 'move';
  196. // event.dataTransfer.dropEffect = 'move';
  197. },
  198. ondrag: function (event, tabGridField) {
  199. var _self = this;
  200. if ((_self.startWidth + (event.pageX - _self.startX)) > 20) {
  201. tabGridField.width = _self.startWidth + (event.pageX - _self.startX);
  202. } else {
  203. tabGridField.width = 20;
  204. }
  205. },
  206. ondragend: function (event, tabGridField) {
  207. var _self = this;
  208. if ((_self.startWidth + (event.pageX - _self.startX)) > 20) {
  209. tabGridField.width = _self.startWidth + (event.pageX - _self.startX);
  210. } else {
  211. tabGridField.width = 20;
  212. }
  213. GridColumnDef.saveGridFieldDef(_self.windowNo, _self.tabIndex, _self.tabGridFields).then(successData => {
  214. _self.$emit('propertyChanged', _self.tabGridFields);
  215. var tabGridFieldId = _self.getTabGridFieldId(tabGridField);
  216. var element1 = document.getElementById(tabGridFieldId);
  217. $(element1).removeClass('rz-handle-active');
  218. }, errorData => {
  219. console.log(errorData);
  220. });
  221. },
  222. ondragover: function (event, tabGridField) {
  223. event.preventDefault();
  224. event.dataTransfer.dropEffect = 'move';
  225. },
  226. onSort: function (tabGridField) {
  227. this.$emit('onSort', tabGridField);
  228. },
  229. changeSelectMode: function () {
  230. this.multipleSelect = !this.multipleSelect;
  231. this.$emit('multipleSelect', this.multipleSelect);
  232. },
  233. },
  234. };
  235. </script>
  236. <style scoped>
  237. .require-mark {
  238. color: red;
  239. }
  240. .mulitiple-select {
  241. background-color: #6699cc;
  242. }
  243. .text-center {
  244. text-align: center;
  245. }
  246. th {
  247. background-color: #f7f7f7;
  248. }
  249. .td-max {
  250. max-width: 250px;
  251. }
  252. </style>
  253. <style scoped>
  254. table.curd-table th {
  255. /* position: relative; */
  256. min-width: 25px;
  257. }
  258. table th,
  259. table td {
  260. text-align: left;
  261. overflow: hidden;
  262. white-space: nowrap;
  263. text-overflow: ellipsis;
  264. /* padding: 0.75em; */
  265. border-right: 1px solid rgba(0, 0, 0, 0.05);
  266. }
  267. table th {
  268. min-width: 10px;
  269. background-color: #f8f8f8;
  270. }
  271. .rz-handle {
  272. width: 10px;
  273. height: 100%;
  274. position: absolute;
  275. top: 0;
  276. right: 0;
  277. cursor: ew-resize !important;
  278. z-index: 3;
  279. }
  280. .rz-handle.rz-handle-active {
  281. border-right: 2px solid #000;
  282. transform: scaleX(100);
  283. background: rgba(0, 0, 0, 0.05) 2px;
  284. }
  285. .rz-handle:hover {
  286. background: rgba(0, 0, 0, 0.2) 4px;
  287. }
  288. /* 固定列 */
  289. .sticky-col {
  290. position: -webkit-sticky; /* Safari */
  291. position: sticky;
  292. left: 0;
  293. background: #fafafa;
  294. z-index: 1; /* 确保固定列在其他内容之上 */
  295. }
  296. /* 固定行 */
  297. .sticky-row {
  298. position: -webkit-sticky; /* Safari */
  299. position: sticky;
  300. top: 0;
  301. background: #fafafa;
  302. z-index: 2; /* 确保固定列在其他内容之上 */
  303. }
  304. </style>