tableColumnsMixin.js 7.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252
  1. import request from '@/utils/request';
  2. import _ from 'lodash';
  3. export default {
  4. data() {
  5. return {
  6. newColumns: [],
  7. tabMixinsInit: true //进入页面是否默认请求列配置
  8. };
  9. },
  10. created() {
  11. //从服务器获取缓存列表配置
  12. if (this.tabMixinsInit) {
  13. this.getTabColumns();
  14. }
  15. // 创建防抖函数并绑定this
  16. this.debouncedHandleColumnChange = this.debounce(
  17. this.handleColumnChangeImpl,
  18. 1000
  19. );
  20. },
  21. methods: {
  22. // 实际的列变更处理逻辑
  23. handleColumnChangeImpl() {
  24. try {
  25. const list = this.getStorage(this.cacheKeyUrl + 'Cols');
  26. if (list) {
  27. this.saveColumns(list);
  28. }
  29. } catch (error) {
  30. console.error('处理列配置出错:', error);
  31. }
  32. },
  33. // 列表变化回调
  34. handleColumnChange() {
  35. const list = this.getStorage(this.cacheKeyUrl + 'Cols');
  36. if (list) {
  37. let requireList = [];
  38. let currentList = this.getColumns()
  39. .filter((item) => item.headerSlot)
  40. .map((item) => item.prop);
  41. list.forEach((item) => {
  42. if (currentList.includes(item.prop) && !item.checked) {
  43. requireList.push(item.label);
  44. item.checked = true;
  45. }
  46. });
  47. if (requireList.length) {
  48. this.setStorage(this.cacheKeyUrl + 'Cols', list);
  49. if ('columns' in this.$options.computed) {
  50. this.columnsVersion++;
  51. } else {
  52. this.columns = [...this.columns];
  53. }
  54. this.$message.warning(
  55. `${requireList.toString()} 为必填项,无法隐藏!`
  56. );
  57. return;
  58. }
  59. }
  60. this.debouncedHandleColumnChange();
  61. },
  62. // 获取table-column配置
  63. async getTabColumns() {
  64. const res = await this.getByTableId(this.cacheKeyUrl);
  65. if (res?.columnConfig?.length > 0) {
  66. //对比接口返回和本地columns
  67. let { nlist, type } = this.columnsContrast(res.columnConfig);
  68. // 将nlist中的prop字段去重
  69. const uniqueList = _.uniqBy(nlist, 'prop');
  70. const uniqueLabelList = _.uniqBy(uniqueList, 'label');
  71. //有更新则更新服务缓存配置
  72. if (type) {
  73. this.saveColumns(uniqueLabelList);
  74. }
  75. this.setStorage(this.cacheKeyUrl + 'Cols', nlist);
  76. // 更新列
  77. if (this._computedWatchers && this._computedWatchers.columns) {
  78. // console.log('columns 是计算属性');
  79. this.columnsVersion++;
  80. } else {
  81. // console.log('columns 是 data 属性');
  82. this.columns = [...this.columns];
  83. this.newColumns = [...this.newColumns];
  84. }
  85. }
  86. },
  87. getColumns() {
  88. if (typeof this.columns == 'function') {
  89. return this.columns();
  90. } else {
  91. return this.columns;
  92. }
  93. },
  94. //服务器和本地配置columns对比
  95. columnsContrast(list) {
  96. const key = 'label';
  97. var updateType = 0;
  98. let sList = list.filter((d, i, r) => {
  99. return d[key];
  100. });
  101. let devColumns = this.newColumns?.length
  102. ? this.newColumns
  103. : this.getColumns();
  104. let dList = devColumns.filter((d, i, r) => {
  105. return d[key] && d[key] !== '序号';
  106. });
  107. const keysA = new Set(sList.map((item) => item[key]));
  108. const keysB = new Set(dList.map((item) => item[key]));
  109. // 本地 比 缓存服务端 多的对象(新增)
  110. const added = dList.filter((item) => {
  111. return !keysA.has(item[key]) && (item.prop || item.label === '操作');
  112. });
  113. // 本地 比 缓存服务端 少的对象(删除)
  114. const removed = sList.filter((item) => !keysB.has(item[key]));
  115. const removedPropSet = new Set(removed.map((item) => item[key]));
  116. // 删除 缓存中 中被移除的对象
  117. const keptA = list.filter((item) => !removedPropSet.has(item[key]));
  118. added.forEach((item) => {
  119. //新增columns字段prop参数为必填
  120. if (item.prop) {
  121. item.id = item.prop;
  122. } else if (item.columnKey) {
  123. item.id = item.columnKey;
  124. }
  125. item.checked = true;
  126. });
  127. if (added.length > 0 || removed.length > 0) {
  128. updateType = 1;
  129. }
  130. // 更新项:key 存在但内容变化
  131. const dMap = new Map(dList.map((item) => [item[key], item]));
  132. const updated = keptA.map((sItem) => {
  133. const dItem = dMap.get(sItem[key]);
  134. if (dItem && dItem.prop && sItem.prop !== dItem.prop) {
  135. updateType = 1;
  136. // 记录旧值和新值
  137. const oldValue = sItem.prop;
  138. const newValue = dItem.prop;
  139. // 遍历所有属性,动态替换匹配旧值的字段
  140. const updatedItem = { ...sItem };
  141. Object.keys(updatedItem).forEach((k) => {
  142. if (updatedItem[k] === oldValue) {
  143. updatedItem[k] = newValue;
  144. }
  145. });
  146. return updatedItem;
  147. }
  148. return sItem;
  149. });
  150. // 合并保留的对象和新增的对象
  151. return { nlist: [...updated, ...added], type: updateType };
  152. },
  153. // 提交columns配置
  154. async saveColumns(e) {
  155. const data = {
  156. tableId: this.cacheKeyUrl,
  157. columnConfig: e
  158. };
  159. const msg = await this.saveTableConfig(data);
  160. // console.log('列配置保存成功:', msg);
  161. return msg;
  162. },
  163. //获取localstorage缓存
  164. setStorage(key, value) {
  165. try {
  166. localStorage.setItem(key, JSON.stringify(value));
  167. } catch (e) {
  168. console.log('LocalStorage 存储错误:', e);
  169. if (e.name === 'QuotaExceededError') {
  170. this.clearCacheByPrefix(); //缓存不足,清除
  171. localStorage.setItem(key, JSON.stringify(value));
  172. }
  173. }
  174. },
  175. //缓存不足清除缓存
  176. clearCacheByPrefix() {
  177. const prefix = 'Cols'; // 标识后缀
  178. Object.keys(localStorage).forEach((key) => {
  179. if (key.endsWith(prefix)) {
  180. localStorage.removeItem(key);
  181. // console.log(`已清除缓存: ${key}`);
  182. }
  183. });
  184. // console.log('缓存清除完成');
  185. },
  186. //设置localstorage缓存
  187. getStorage(key) {
  188. try {
  189. const value = localStorage.getItem(key);
  190. return value ? JSON.parse(value) : null;
  191. } catch (e) {
  192. console.error('LocalStorage 解析错误:', e);
  193. return null;
  194. }
  195. },
  196. //防抖函数
  197. debounce(fn, delay) {
  198. let timer = null;
  199. return (...args) => {
  200. clearTimeout(timer);
  201. timer = setTimeout(() => {
  202. fn.apply(this, args);
  203. }, delay);
  204. };
  205. },
  206. //获取column记录接口
  207. async getByTableId(key) {
  208. try {
  209. const res = await request.get(
  210. `/sys/table-config/getByTableId/${key}`,
  211. {}
  212. );
  213. if (res.data.code == 0) {
  214. return res.data.data;
  215. }
  216. } catch (error) {
  217. console.error('获取列配置失败:', error);
  218. }
  219. },
  220. // 添加column记录接口
  221. async saveTableConfig(data) {
  222. try {
  223. const res = await request({
  224. url: '/sys/table-config/save',
  225. method: 'post',
  226. data
  227. });
  228. if (res.data.code == 0) {
  229. return res.data.data;
  230. }
  231. } catch (error) {
  232. console.error('保存列配置失败:', error);
  233. }
  234. }
  235. }
  236. };