tableColumnsMixin.js 7.3 KB

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