Table.js 47 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214
  1. import {formatDate, formatDateTime, copyObj, inArray, formatTime} from '../util.js';
  2. import selectpage from '../components/SelectPage.js';
  3. import tableTemp from './template/TableTemp.js';
  4. const setValue=function(obj, path, value){
  5. const keys = path.split('.');
  6. if (keys.length === 1) {
  7. obj[path] = value;
  8. return;
  9. }
  10. const currentKey = keys[0];
  11. if (!obj.hasOwnProperty(currentKey)) {
  12. obj[currentKey] = {};
  13. }
  14. const nextObj = obj[currentKey];
  15. const nextPath = keys.slice(1).join('.');
  16. setValue(nextObj, nextPath, value);
  17. }
  18. const getValue=function(row,field){
  19. let fieldarr=field.split('.');
  20. for(let i=0;i<fieldarr.length;i++){
  21. row=row[fieldarr[i]];
  22. if(row==undefined){
  23. return row;
  24. }
  25. }
  26. return row;
  27. }
  28. export default {
  29. name: "Table",
  30. components:{'SelectPage':selectpage},
  31. data: function () {
  32. return {
  33. menutype:Yunqi.app.window.menutype,
  34. loading:true,
  35. sortData:'',
  36. expandRowKeys:[],
  37. /*需要reset的数据begin*/
  38. list:[],
  39. total:0,
  40. summary:'',
  41. currentPage:1,
  42. pageSize:10,
  43. selections:[],
  44. searchValue:'',
  45. /*需要reset的数据end*/
  46. table_:{
  47. columns:'',
  48. toolbar:[],
  49. searchFormVisible:true,
  50. },
  51. treeExpandAll_:false,
  52. mainFrameExpand:false,
  53. tabList:{},
  54. tabsValue:'',
  55. rightToolOption:{type:'font',list:{large:'大',default:'中',small:'小'}},
  56. pageFont:'default',
  57. download:{
  58. show:false,
  59. field:[],
  60. filter:1,
  61. page:0,
  62. },
  63. importResult:{
  64. show:false,
  65. success:0,
  66. fail:[]
  67. }
  68. }
  69. },
  70. template:tableTemp,
  71. props:{
  72. columns:{
  73. type: Array,
  74. required: true
  75. },
  76. extend:{
  77. type:Object,
  78. default:{
  79. index_url: '',
  80. add_url: '',
  81. edit_url: '',
  82. del_url: '',
  83. multi_url: '',
  84. download_url:'',
  85. import_url:'',
  86. recyclebin_url:''
  87. }
  88. },
  89. searchFormVisible:{
  90. type:Boolean,
  91. default:true
  92. },
  93. commonSearch:{
  94. type:Boolean,
  95. default:true
  96. },
  97. search:{
  98. type:String,
  99. default:''
  100. },
  101. style:{
  102. type:Object,
  103. default: {width:'100%'}
  104. },
  105. pagination:{
  106. type:Boolean,
  107. default:true
  108. },
  109. toolbar:{
  110. type:String,
  111. default:'refresh,add,edit,del'
  112. },
  113. pk:{
  114. type:String,
  115. default:'id'
  116. },
  117. sortName:{
  118. type:String,
  119. default:'id'
  120. },
  121. order:{
  122. type:String,
  123. default:'desc'
  124. },
  125. tabs:{
  126. type:String,
  127. default:''
  128. },
  129. isTree:{
  130. type:Boolean,
  131. default:false
  132. },
  133. treeExpandAll:{
  134. type:Boolean,
  135. default:false
  136. },
  137. showSummary:{
  138. type:Boolean,
  139. default:false
  140. },
  141. multiHeader:{
  142. type:Boolean,
  143. default:false
  144. },
  145. auth:{
  146. type:Object,
  147. default:{
  148. edit: true,
  149. add: true,
  150. multi:true,
  151. del:true,
  152. import:true,
  153. download:true,
  154. recyclebin:true
  155. }
  156. },
  157. addForm:{
  158. type:Object,
  159. default:{
  160. icon:'fa fa-plus-square-o',
  161. title:__('添加'),
  162. expand:false,
  163. width:800,
  164. height:550
  165. }
  166. },
  167. editForm:{
  168. type:Object,
  169. default:{
  170. icon:'fa fa-pencil-square-o',
  171. title:__('编辑'),
  172. expand:false,
  173. width:800,
  174. height:550
  175. }
  176. },
  177. onRender:{
  178. type:Function,
  179. default:function(){}
  180. },
  181. },
  182. mounted:function(){
  183. this.table_.searchFormVisible=this.searchFormVisible;
  184. this.table_.toolbar=this.toolbar.split(',');
  185. if(!this.pagination){
  186. this.pageSize=10000;
  187. }
  188. this.reset();
  189. this.rowDrop();
  190. },
  191. methods:{
  192. reset:function(){
  193. let columns=copyObj(this.columns);
  194. for(let i=0;i<columns.length;i++){
  195. if(this.isTree && i===1){
  196. columns[i].type='';
  197. }
  198. if(columns[i].children){
  199. columns[i].visible=true;
  200. for(let j=0;j<columns[i].children.length;j++){
  201. if(columns[i].children[j].children){
  202. columns[i].children[j].visible=true;
  203. for (let k=0;k<columns[i].children[j].children.length;k++){
  204. columns[i].children[j].children[k]=this.formatColumn(columns[i].children[j].children[k]);
  205. }
  206. }else{
  207. columns[i].children[j]=this.formatColumn(columns[i].children[j]);
  208. }
  209. }
  210. }else{
  211. columns[i]=this.formatColumn(columns[i]);
  212. }
  213. }
  214. this.table_.columns=columns;
  215. this.searchValue='';
  216. this.currentPage=1;
  217. this.list=[];
  218. this.total=0;
  219. this.selections=[];
  220. this.dataList();
  221. },
  222. formatColumn:function (column){
  223. let operate={form:'input',value:'',size:'default',placeholder:column.title};
  224. /**简写begin**/
  225. if((column.field && column.operate==undefined) || column.operate=='='){
  226. operate.filter='=';
  227. operate.type='text';
  228. column.operate=operate;
  229. }
  230. if(column.operate=='!=' || column.operate=='<>'){
  231. operate.filter='<>';
  232. operate.type='text';
  233. column.operate=operate;
  234. }
  235. if(column.operate=='null' || column.operate=='NULL'){
  236. operate.filter='IS NULL';
  237. operate.form='hidden';
  238. column.operate=operate;
  239. }
  240. if(column.operate=='not null' || column.operate=='NOT NULL'){
  241. operate.filter='IS NOT NULL';
  242. operate.form='hidden';
  243. column.operate=operate;
  244. }
  245. if(column.operate=='like' || column.operate=='LIKE'){
  246. operate.filter='LIKE';
  247. operate.type='text';
  248. column.operate=operate;
  249. }
  250. if(column.operate=='not like' || column.operate=='NOT LIKE'){
  251. operate.filter='NOT LIKE';
  252. operate.type='text';
  253. column.operate=operate;
  254. }
  255. if(column.operate=='select' || column.operate=='SELECT'){
  256. operate.filter='=';
  257. operate.form='select';
  258. column.operate=operate;
  259. }
  260. if(column.operate=='selects' || column.operate=='SELECTS'){
  261. operate.filter='in';
  262. operate.form='select';
  263. operate.multiple=true;
  264. operate.value=[];
  265. column.operate=operate;
  266. }
  267. if(column.operate=='checkbox' || column.operate=='CHECKBOX'){
  268. operate.filter='in';
  269. operate.form='checkbox';
  270. operate.value=[];
  271. column.operate=operate;
  272. }
  273. if(column.operate=='radio' || column.operate=='RADIO'){
  274. operate.filter='=';
  275. operate.form='radio';
  276. column.operate=operate;
  277. }
  278. if(column.operate=='find_in_set' || column.operate=='FIND_IN_SET'){
  279. operate.filter='FIND_IN_SET';
  280. operate.form='select';
  281. column.operate=operate;
  282. }
  283. if(column.operate=='between' || column.operate=='BETWEEN'){
  284. operate.filter='between';
  285. operate.form='between';
  286. operate.value=[];
  287. column.operate=operate;
  288. }
  289. if(column.operate=='not between' || column.operate=='NOT BETWEEN'){
  290. operate.filter='not between';
  291. operate.form='between';
  292. operate.value=[];
  293. column.operate=operate;
  294. }
  295. if(column.operate=='date' || column.operate=='DATE'){
  296. operate.filter='=';
  297. operate.form='date-picker';
  298. operate.type='date';
  299. column.operate=operate;
  300. }
  301. if(column.operate=='datetime' || column.operate=='DATETIME'){
  302. operate.filter='=';
  303. operate.form='date-picker';
  304. operate.type='datetime';
  305. column.operate=operate;
  306. }
  307. if(column.operate=='daterange' || column.operate=='DATERANGE'){
  308. operate.filter='between time';
  309. operate.form='date-picker';
  310. operate.type='daterange';
  311. column.operate=operate;
  312. }
  313. if(column.operate=='time' || column.operate=='TIME'){
  314. operate.form='time-picker';
  315. operate.filter='=';
  316. operate.type='time';
  317. column.operate=operate;
  318. }
  319. if(column.operate=='timerange' || column.operate=='TIMERANGE'){
  320. operate.form='time-picker';
  321. operate.type='timerange';
  322. operate.filter='between';
  323. column.operate=operate;
  324. }
  325. if(column.operate=='area' || column.operate=='AREA'){
  326. operate.form='cascader';
  327. operate.url='ajax/area';
  328. operate.level=3;
  329. column.operate=operate;
  330. }
  331. if(column.operate=='category' || column.operate=='CATEGORY'){
  332. operate.form='cascader';
  333. operate.url='ajax/category';
  334. operate.level=2;
  335. column.operate=operate;
  336. }
  337. /**简写end**/
  338. if(typeof column.operate=='object'){
  339. for(let k in column.operate){
  340. if(typeof column.operate[k]=='string'){
  341. column.operate[k]=column.operate[k].toLowerCase();
  342. }
  343. }
  344. if(column.operate.form=='selectpage'){
  345. operate.filter='=';
  346. }
  347. if(column.operate.form=='cascader'){
  348. column.operate.props=Object.assign({expandTrigger:'hover',multiple:false,children:'childlist',value:'id',label:'name',lazy:false},column.operate.props);
  349. if(column.operate.url && column.operate.level){
  350. column.operate.props.lazy=true;
  351. column.operate.props.expandTrigger='click';
  352. let url=column.operate.url;
  353. column.operate.props.lazyLoad=function(node,resolve){
  354. let pid=0;
  355. let level=column.operate.level;
  356. if(node.level){
  357. pid=node.value;
  358. }
  359. Yunqi.ajax.get(url,{pid:pid}).then(res=>{
  360. if(res instanceof Array){
  361. res.map(t=>{
  362. if(node.level>=level-1){
  363. t.leaf=true;
  364. }
  365. return t;
  366. });
  367. resolve(res);
  368. }else{
  369. resolve([]);
  370. }
  371. });
  372. };
  373. delete column.operate.options;
  374. }
  375. operate.filter='=';
  376. }
  377. if(column.operate.form=='date-picker'){
  378. if(column.operate.type=='date'){
  379. operate.format='YYYY-MM-DD';
  380. operate.filter='=';
  381. }
  382. if(column.operate.type=='year'){
  383. operate.format='YYYY年';
  384. operate.filter='=';
  385. }
  386. if(column.operate.type=='month'){
  387. operate.format='YYYY年MM月';
  388. operate.filter='=';
  389. }
  390. if(column.operate.type=='dates'){
  391. operate.format='YYYY-MM-DD';
  392. operate.filter='=';
  393. }
  394. if(column.operate.type=='datetime'){
  395. operate.format='YYYY-MM-DD HH:mm:ss';
  396. operate.filter='=';
  397. }
  398. if(column.operate.type=='daterange') {
  399. operate.format = 'YYYY-MM-DD';
  400. operate.filter='between time';
  401. operate.shortcuts = [
  402. {
  403. text: '今天', value: function () {
  404. const start = new Date();
  405. return [start, start];
  406. }
  407. },
  408. {
  409. text: '昨天', value: function () {
  410. const start = new Date();
  411. start.setTime(start.getTime() - 3600 * 1000 * 24 * 1);
  412. return [start, start];
  413. }
  414. },
  415. {
  416. text: '最近7天', value: function () {
  417. const end = new Date();
  418. const start = new Date();
  419. start.setTime(start.getTime() - 3600 * 1000 * 24 * 6);
  420. return [start, end];
  421. }
  422. },
  423. {
  424. text: '最近30天', value: function () {
  425. const end = new Date();
  426. const start = new Date();
  427. start.setTime(start.getTime() - 3600 * 1000 * 24 * 29);
  428. return [start, end];
  429. }
  430. },
  431. {
  432. text: '本月', value: function () {
  433. const end = new Date();
  434. const start = new Date(formatDate(end).slice(0, 7) + '-01');
  435. return [start, end];
  436. }
  437. },
  438. {
  439. text: '上月', value: function () {
  440. const currentDate = new Date();
  441. let lastMonth = currentDate.getMonth() - 1;
  442. let year = currentDate.getFullYear();
  443. if (lastMonth < 0) {
  444. year--;
  445. lastMonth = 11;
  446. }
  447. let firstDay = new Date(year, lastMonth, 1);
  448. let lastDay = new Date(year, lastMonth + 1, 0);
  449. return [firstDay, lastDay];
  450. }
  451. },
  452. {
  453. text: '今年', value: function () {
  454. let currentDate = new Date();
  455. let year = currentDate.getFullYear();
  456. let start = new Date(year, 0, 1);
  457. let end = new Date(year, 11, 31);
  458. return [start, end];
  459. }
  460. },
  461. {
  462. text: '去年', value: function () {
  463. let currentDate = new Date();
  464. let year = currentDate.getFullYear() - 1;
  465. let start = new Date(year, 0, 1);
  466. let end = new Date(year, 11, 31);
  467. return [start, end];
  468. }
  469. },
  470. ];
  471. }
  472. }
  473. //如果用户自定义了属性,则优先使用
  474. for(let key in operate){
  475. column.operate[key]=(column.operate[key]!==undefined)?column.operate[key]:operate[key];
  476. }
  477. }
  478. //通过visible隐藏数据
  479. if(column.visible!='none'){
  480. column.visible=(column.visible===false)?false:true;
  481. }
  482. if(column.field=='operate' || column.checkbox || column.treeExpand){
  483. if(column.field=='operate' && !column.direction){
  484. column.direction='row';
  485. }
  486. if(column.field=='operate' && !column.align){
  487. column.align='center';
  488. }
  489. if(column.field=='operate' && column.action){
  490. for(let kss in column.action){
  491. if(typeof column.action[kss]=='object' && typeof column.action[kss].method=='string'){
  492. column.action[kss].method=Yunqi.app[column.action[kss].method];
  493. }
  494. if(typeof column.action[kss]=='object' && !column.action[kss].visible){
  495. column.action[kss].visible=function(){return true;};
  496. }
  497. }
  498. }
  499. return column;
  500. }
  501. //默认格式
  502. column.formatter=(column.field && (column.formatter===undefined || column.formatter===false))?Yunqi.formatter.text:column.formatter;
  503. //初始化tabs
  504. if(this.tabs && column.field==this.tabs){
  505. this.tabList=column.searchList || {};
  506. }
  507. return column;
  508. },
  509. dataList:function(){
  510. this.loading=true;
  511. //设置排序规则
  512. let sort=this.sortName;
  513. let order=this.order;
  514. if(this.sortData && this.sortData.order.startsWith('desc')){
  515. order='desc';
  516. sort=this.sortData.prop;
  517. }
  518. if(this.sortData && this.sortData.order.startsWith('asc')){
  519. order='asc';
  520. sort=this.sortData.prop;
  521. }
  522. //设置filter
  523. let filter=[];
  524. if(this.tabs && this.tabsValue){
  525. filter.push({
  526. field:this.tabs,
  527. op:'=',
  528. value:this.tabsValue
  529. });
  530. }
  531. for(let i=0;i<this.table_.columns.length;i++){
  532. if(this.table_.columns[i].operate){
  533. if(this.table_.columns[i].operate.value instanceof Array && this.table_.columns[i].operate.value.length===0){
  534. continue;
  535. }
  536. if(this.table_.columns[i].operate.value==='' || this.table_.columns[i].operate.value===null || this.table_.columns[i].operate.value===undefined){
  537. continue;
  538. }
  539. let value=this.table_.columns[i].operate.value;
  540. if(value instanceof Function){
  541. value=value();
  542. }
  543. if(this.table_.columns[i].operate.form=='cascader'){
  544. value=value[value.length-1];
  545. }
  546. //格式化日期时间
  547. if(this.table_.columns[i].operate.form=='date-picker'){
  548. switch (this.table_.columns[i].operate.type){
  549. case 'date':
  550. value=formatDate(this.table_.columns[i].operate.value);
  551. break;
  552. case 'dates':
  553. value=value.map(res=>{
  554. res=formatDate(res);
  555. return res;
  556. });
  557. break;
  558. case 'year':
  559. value=this.table_.columns[i].operate.value.getFullYear();
  560. break;
  561. case 'month':
  562. value=formatDate(this.table_.columns[i].operate.value).slice(0,7);
  563. break;
  564. case 'daterange':
  565. let begin1=formatDate(this.table_.columns[i].operate.value[0])+' 00:00:00';
  566. let end1=formatDate(this.table_.columns[i].operate.value[1])+' 23:59:59';
  567. value=[begin1,end1];
  568. break;
  569. }
  570. }
  571. if(this.table_.columns[i].operate.form=='time-picker'){
  572. let timeValue=this.table_.columns[i].operate.value;
  573. if(timeValue instanceof Array){
  574. value=[formatTime(timeValue[0]),formatTime(timeValue[1])];
  575. }else{
  576. value=formatTime(timeValue);
  577. }
  578. }
  579. filter.push({
  580. field:this.table_.columns[i].operate.name?this.table_.columns[i].operate.name:this.table_.columns[i].field,
  581. op:this.table_.columns[i].operate.filter?this.table_.columns[i].operate.filter:false,
  582. value:value
  583. });
  584. }
  585. }
  586. let json={
  587. sort:sort,
  588. order:order,
  589. filter:[]
  590. };
  591. //下载
  592. if(this.download.show){
  593. let field=[];
  594. let searchList={};
  595. json.listAction=this.extend.index_url;
  596. this.table_.columns.forEach(res=>{
  597. if(inArray(this.download.field,res.field)){
  598. field.push({
  599. field:res.field,
  600. title:res.title,
  601. });
  602. if(res.searchList){
  603. searchList[res.field]=res.searchList;
  604. }
  605. }
  606. });
  607. json.field=field;
  608. json.searchList=searchList;
  609. json.isTree=this.isTree;
  610. if(this.download.page){
  611. json.page=this.currentPage;
  612. json.limit=this.pageSize;
  613. }else{
  614. json.page=1;
  615. json.limit=100000;
  616. }
  617. if(this.download.filter){
  618. json.filter=filter;
  619. }
  620. Yunqi.ajax.json(this.extend.download_url,json,true,false).then(data=>{
  621. let url=Yunqi.config.baseUrl+this.extend.download_url;
  622. if(url.indexOf('?')!=-1){
  623. url+='&file='+data;
  624. }else{
  625. url+='?file='+data;
  626. }
  627. location.href=url;
  628. this.loading=false;
  629. this.download.show=false;
  630. }).catch(error=>{
  631. this.loading=false;
  632. });
  633. }else{
  634. json.searchValue=this.searchValue;
  635. json.search=this.search;
  636. json.filter=filter;
  637. json.page=this.currentPage;
  638. json.limit=this.pageSize;
  639. Yunqi.ajax.json(this.extend.index_url,json).then(data=>{
  640. this.total=data.total;
  641. this.render(data.rows);
  642. Vue.nextTick(()=>{
  643. this.onRender(this.list);
  644. });
  645. this.summary=data.summary;
  646. this.loading=false;
  647. }).catch(error=>{
  648. this.loading=false;
  649. });
  650. }
  651. },
  652. render:function(list){
  653. for(let j=0;j<list.length;j++){
  654. let row=list[j];
  655. this.formatRow(row);
  656. if(row.childlist){
  657. this.render(row.childlist);
  658. }
  659. }
  660. this.list=list;
  661. },
  662. formatRow:function (row){
  663. row._formatter={};
  664. for(let i=0;i<this.table_.columns.length;i++){
  665. let columns1=this.table_.columns[i];
  666. if(columns1.children){
  667. for(let j=0;j<columns1.children.length;j++){
  668. let columns2=this.table_.columns[i].children[j];
  669. if(columns2.children){
  670. for(let k=0;k<columns2.children.length;k++){
  671. let columns3=columns2.children[k];
  672. if(columns3.field===undefined){
  673. continue;
  674. }
  675. let formatter=this.getFormatter(row,columns3);
  676. row._formatter[columns3.field]=formatter;
  677. }
  678. }else{
  679. if(columns2.field===undefined){
  680. continue;
  681. }
  682. let formatter=this.getFormatter(row,columns2);
  683. row._formatter[columns2.field]=formatter;
  684. }
  685. }
  686. }else{
  687. if(columns1.field===undefined){
  688. continue;
  689. }
  690. let formatter=this.getFormatter(row,columns1);
  691. row._formatter[columns1.field]=formatter;
  692. }
  693. }
  694. },
  695. getFormatter:function (row,columns){
  696. let value=getValue(row,columns.field);
  697. let formatter=copyObj(Yunqi.formatter.text);
  698. if(columns.searchList){
  699. value=(columns.searchList[value]!==undefined)?columns.searchList[value]:value;
  700. }
  701. if(columns.field=='operate'){
  702. return true;
  703. }
  704. if(!columns.formatter){
  705. formatter.value=value;
  706. }
  707. if(columns.formatter && typeof columns.formatter=='function'){
  708. let rx=columns.formatter(value,row);
  709. if(rx===undefined || rx===''){
  710. rx='-';
  711. }
  712. if(typeof rx == 'object'){
  713. formatter=copyObj(rx);
  714. if(formatter._name=='button' && typeof formatter.click=='string'){
  715. let clickstr=formatter.click;
  716. formatter.click=function(row){
  717. Yunqi.app[clickstr](row);
  718. }
  719. }
  720. }else{
  721. formatter.value=rx;
  722. }
  723. }
  724. if(columns.formatter && typeof columns.formatter=='object'){
  725. formatter=copyObj(columns.formatter);
  726. if(formatter._name=='images'){
  727. value=value?value.split(','):[];
  728. }
  729. if(formatter._name=='date' && typeof value=='number'){
  730. value=formatDate(new Date(value*1000));
  731. }
  732. if(formatter._name=='datetime'){
  733. if(typeof value=='number'){
  734. value=formatDateTime(new Date(value*1000)).slice(0,16);
  735. }else if(!value){
  736. value='-';
  737. }
  738. }
  739. if(formatter._name=='select'){
  740. for(let k in columns.searchList){
  741. if(value==columns.searchList[k]){
  742. value=k;
  743. }
  744. }
  745. }
  746. if(formatter._name=='tags'){
  747. if(value instanceof Array){
  748. }else{
  749. value=value?value.split(','):[];
  750. }
  751. if(columns.searchList){
  752. value=value.map(ts=>{
  753. ts=(columns.searchList[ts]!==undefined)?columns.searchList[ts]:ts;
  754. return ts;
  755. });
  756. }
  757. }
  758. if(formatter._name=='switch' && columns.searchList){
  759. let xs=0,activeValue,inactiveValue;
  760. for(let k in columns.searchList){
  761. if(k==='0')k=0;
  762. if(k==='1')k=1;
  763. if(k===0 || k===1){
  764. activeValue=1;
  765. inactiveValue=0;
  766. }else if(k==='normal' || k==='hidden'){
  767. activeValue='normal';
  768. inactiveValue='hidden';
  769. }else{
  770. if(xs===0){
  771. activeValue=k;
  772. }
  773. if(xs===1){
  774. inactiveValue=k;
  775. }
  776. }
  777. if(value==columns.searchList[k]){
  778. value=k;
  779. }
  780. xs++;
  781. }
  782. formatter.activeValue=activeValue;
  783. formatter.inactiveValue=inactiveValue;
  784. }
  785. formatter.value=value;
  786. }
  787. return formatter;
  788. },
  789. rowDrop:function(){
  790. const _this = this;
  791. const tbody = document.querySelector('.el-table__body-wrapper tbody');
  792. class TreeClass{
  793. constructor(index) {
  794. this.index = index;
  795. this.j = 0;
  796. this.arr=[];
  797. }
  798. getItem(list) {
  799. for(let i=0;i<list.length;i++){
  800. if(this.j===this.index){
  801. return list[i];
  802. }
  803. this.j++;
  804. if(list[i].childlist && list[i].childlist.length>0){
  805. let item = this.getItem(list[i].childlist);
  806. if(item){
  807. return item;
  808. }
  809. }
  810. }
  811. return false;
  812. }
  813. getList(list,pid){
  814. for(let i=0;i<list.length;i++){
  815. if(list[i].pid==pid){
  816. this.arr.push(list[i]);
  817. }
  818. if(list[i].childlist && list[i].childlist.length>0){
  819. this.getList(list[i].childlist,pid);
  820. }
  821. }
  822. return this.arr;
  823. }
  824. };
  825. Sortable.create(tbody, {
  826. // 指定父元素下可被拖拽的子元素
  827. draggable: ".el-table__row",
  828. animation: 100,
  829. handle:'.sortableButton',
  830. ghostClass: "sortable-ghost",
  831. chosenClass: "sortable-chosen",
  832. dragClass: "sortable-drag",
  833. onEnd ({ newIndex, oldIndex }) {
  834. let data=[];
  835. if(_this.isTree){
  836. let new_item=(new TreeClass(newIndex)).getItem(_this.list);
  837. let old_item=(new TreeClass(oldIndex)).getItem(_this.list);
  838. if(new_item.weigh===undefined || old_item.weigh===undefined){
  839. Yunqi.message.error(__('没有weigh属性,排序失败'));
  840. return;
  841. }
  842. if(new_item.pid!==old_item.pid){
  843. Yunqi.message.error(__('只支持在同级别表内拖拽'));
  844. return;
  845. }
  846. //找到影响拖拽的其他行,并修改weigh属性
  847. let list=(new TreeClass(oldIndex)).getList(_this.list,old_item.pid);
  848. let weigh=new_item.weigh;
  849. data.push({id:old_item.id,weigh:weigh});
  850. //从上往下拖
  851. if(newIndex>oldIndex){
  852. for(let i=list.length-1;i>=0;i--){
  853. if(list[i].id==old_item.id){
  854. break;
  855. }
  856. if(list[i].weigh<new_item.weigh){
  857. continue;
  858. }
  859. if(list[i].weigh<=old_item.weigh){
  860. data.push({
  861. id:list[i].id,
  862. weigh:list[i].weigh+1
  863. });
  864. }
  865. }
  866. }
  867. //从下往上拖
  868. if(newIndex<oldIndex){
  869. for(let i=0;i<list.length;i++){
  870. if(list[i].id==old_item.id){
  871. break;
  872. }
  873. if(list[i].weigh<=new_item.weigh){
  874. data.push({
  875. id:list[i].id,
  876. weigh:list[i].weigh-1
  877. });
  878. }
  879. }
  880. }
  881. }else{
  882. let new_weigh=_this.list[newIndex].weigh;
  883. let old_weigh=_this.list[oldIndex].weigh;
  884. if(new_weigh===undefined || old_weigh===undefined){
  885. Yunqi.message.error(__('没有weigh属性,排序失败'));
  886. return;
  887. }
  888. data.push({id:_this.list[oldIndex].id,weigh:new_weigh});
  889. let line=Math.abs(oldIndex-newIndex);
  890. let weigh=_this.list[newIndex].weigh;
  891. (newIndex>oldIndex)?weigh++:weigh--;
  892. let i=0;
  893. while(i<line){
  894. data.push({
  895. id:(newIndex>oldIndex)?_this.list[newIndex-i].id:_this.list[newIndex+i].id,
  896. weigh:(newIndex>oldIndex)?weigh++:weigh--
  897. });
  898. i++;
  899. }
  900. }
  901. const elloading=ElementPlus.ElLoading.service({text:'排序中..'});
  902. const promise=data.map(res=>{
  903. return new Promise((resolve, reject)=>{
  904. Yunqi.ajax.post(_this.extend.multi_url,{ids:res.id,field:'weigh',value:res.weigh},false,false).then(res=>{
  905. resolve();
  906. }).catch(err=>{
  907. reject();
  908. });
  909. });
  910. });
  911. Promise.all(promise).then(res=>{
  912. elloading.close();
  913. top.ElementPlus.ElMessage({
  914. message: '排序完成',
  915. type: 'success'
  916. });
  917. _this.reload();
  918. }).catch(err=>{
  919. elloading.close();
  920. });
  921. }
  922. });
  923. },
  924. tabChange:function (e){
  925. this.tabsValue=e;
  926. this.reload();
  927. },
  928. reload:function(){
  929. this.selections=[];
  930. this.dataList();
  931. },
  932. blurSearch:function(){
  933. this.dataList();
  934. },
  935. del:function(){
  936. let ids=[];
  937. this.selections.forEach(res=>{
  938. ids.push(res[this.pk]);
  939. });
  940. Yunqi.api.del(this.extend.del_url,ids,()=>{
  941. this.dataList();
  942. this.selections=[];
  943. });
  944. },
  945. delOne:function(row){
  946. Yunqi.api.del(this.extend.del_url,row[this.pk],()=>{
  947. this.dataList();
  948. this.selections=[];
  949. });
  950. },
  951. selectOne:function(e){
  952. this.selections=e;
  953. },
  954. submit:function(){
  955. this.currentPage=1;
  956. this.dataList();
  957. },
  958. selectAll:function(e){
  959. this.selections=e;
  960. },
  961. handleSizeChange:function(size){
  962. this.pageSize=size;
  963. this.dataList();
  964. },
  965. handleCurrentChange:function(page){
  966. this.currentPage=page;
  967. this.dataList();
  968. },
  969. changeSort:function(e){
  970. if(!e.order){
  971. this.sortData='';
  972. }else{
  973. this.sortData=e;
  974. }
  975. this.dataList();
  976. },
  977. changeVisiable:function(field){
  978. let columns=this.table_.columns;
  979. for(let i=0;i<columns.length;i++){
  980. if(columns[i].children){
  981. let show1=false;
  982. for(let j=0;j<columns[i].children.length;j++){
  983. if(columns[i].children[j].children){
  984. let show2=false;
  985. for (let k=0;k<columns[i].children[j].children.length;k++){
  986. if(columns[i].children[j].children[k].field==field){
  987. columns[i].children[j].children[k].visible=!columns[i].children[j].children[k].visible;
  988. }
  989. show2=show2 || columns[i].children[j].children[k].visible;
  990. }
  991. columns[i].children[j].visible=show2;
  992. }else{
  993. if(columns[i].children[j].field==field){
  994. columns[i].children[j].visible=!columns[i].children[j].visible;
  995. }
  996. }
  997. show1=show1 || columns[i].children[j].visible;
  998. }
  999. columns[i].visible=show1;
  1000. }else{
  1001. if(columns[i].field==field){
  1002. columns[i].visible=!columns[i].visible;
  1003. }
  1004. }
  1005. }
  1006. },
  1007. changeShow:function(status){
  1008. let ids=[];
  1009. this.selections.forEach(res=>{
  1010. ids.push(res[this.pk]);
  1011. });
  1012. let options={
  1013. ids:ids,
  1014. field:'status',
  1015. value:status
  1016. };
  1017. Yunqi.api.multi(this.extend.multi_url,options,()=>{
  1018. this.dataList();
  1019. this.selections=[];
  1020. });
  1021. },
  1022. changeSwitch:function(row,field){
  1023. let value=row._formatter[field].value;
  1024. setValue(row,field,value);
  1025. let options={
  1026. ids:row[this.pk],
  1027. field:field,
  1028. value:value
  1029. };
  1030. Yunqi.api.multi(this.extend.multi_url,options,()=>{
  1031. this.render(this.list);
  1032. });
  1033. },
  1034. changeSelect:function(row,field){
  1035. let value=row._formatter[field].value;
  1036. setValue(row,field,value);
  1037. let options={
  1038. ids:row[this.pk],
  1039. field:field,
  1040. value:value
  1041. };
  1042. Yunqi.api.multi(this.extend.multi_url,options,()=>{
  1043. this.render(this.list);
  1044. });
  1045. },
  1046. changeExpand:function () {
  1047. this.mainFrameExpand=!this.mainFrameExpand;
  1048. if(this.mainFrameExpand){
  1049. Yunqi.api.expand();
  1050. }else{
  1051. Yunqi.api.compress();
  1052. }
  1053. },
  1054. changeSelectpage:function (r){
  1055. for(let i=0;i<this.table_.columns.length;i++){
  1056. if(this.table_.columns[i].field==r.field){
  1057. this.table_.columns[i].operate.value=r.value;
  1058. return;
  1059. }
  1060. }
  1061. },
  1062. clickRightToolBar:function (btn){
  1063. if(btn=='column'){
  1064. let show=[];
  1065. let columns=this.table_.columns;
  1066. for(let i=0;i<columns.length;i++){
  1067. if(columns[i].children){
  1068. for(let j=0;j<columns[i].children.length;j++){
  1069. if(columns[i].children[j].children){
  1070. for (let k=0;k<columns[i].children[j].children.length;k++){
  1071. show.push(columns[i].children[j].children[k]);
  1072. }
  1073. }else{
  1074. show.push(columns[i].children[j]);
  1075. }
  1076. }
  1077. }else{
  1078. show.push(columns[i]);
  1079. }
  1080. }
  1081. this.rightToolOption={type:'column',list:show};
  1082. }
  1083. if(btn=='font'){
  1084. this.rightToolOption={type:'font',list:{large:'大',default:'中',small:'小'}};
  1085. }
  1086. if(btn=='download'){
  1087. if(!this.extend.download_url){
  1088. Yunqi.message.error('download_url未设置');
  1089. return;
  1090. }
  1091. this.download.show=true;
  1092. }
  1093. },
  1094. clickLink:function (str,triger='copy'){
  1095. if(triger=='redict'){
  1096. window.open(str,'_blank');
  1097. }
  1098. if(triger=='copy'){
  1099. navigator.clipboard.writeText(str);
  1100. Yunqi.message.success('复制成功');
  1101. }
  1102. },
  1103. changeFont:function (key){
  1104. this.pageFont=key;
  1105. this.$refs.rightToolSelect.visible=false
  1106. this.table_.searchFormVisible=!this.table_.searchFormVisible;
  1107. setTimeout(()=>{
  1108. this.table_.searchFormVisible=!this.table_.searchFormVisible;
  1109. },50);
  1110. },
  1111. recyclebin:function (){
  1112. if(this.extend.recyclebin_url==undefined){
  1113. Yunqi.message.error(__('recyclebin_url未设置'));
  1114. return;
  1115. }
  1116. let table={
  1117. width:'80%',
  1118. height:690,
  1119. title:__('回收站'),
  1120. url:this.extend.recyclebin_url+'?action=list',
  1121. icon:'fa fa-recycle',
  1122. close:function (){
  1123. let id=top.Yunqi.app.activeTab.id;
  1124. let tab=top.document.getElementById('addtabs-'+id).contentWindow;
  1125. let doc=tab.document.getElementsByClassName('refresh');
  1126. if(doc.length>0){
  1127. doc[0].click();
  1128. }
  1129. }
  1130. };
  1131. Yunqi.api.open(table);
  1132. },
  1133. add:function () {
  1134. if(this.extend.add_url==undefined){
  1135. Yunqi.message.error(__('add_url未设置'));
  1136. return;
  1137. }
  1138. let form={...this.addForm,title:__('添加'),url:this.extend.add_url,icon:'fa fa-plus'};
  1139. if(form.expand==undefined){
  1140. form.expand=false;
  1141. }
  1142. form.close=function (refresh=false){
  1143. if(!refresh){
  1144. return
  1145. }
  1146. let id=top.Yunqi.app.activeTab.id;
  1147. let tab=top.document.getElementById('addtabs-'+id).contentWindow;
  1148. let doc=tab.document.getElementsByClassName('refresh');
  1149. if(doc.length>0){
  1150. doc[0].click();
  1151. }
  1152. };
  1153. Yunqi.api.open(form);
  1154. },
  1155. edit:function (row) {
  1156. if(this.extend.edit_url==undefined){
  1157. Yunqi.message.error(__('edit_url未设置'));
  1158. return;
  1159. }
  1160. let form={...this.editForm,title:__('编辑'),icon:'fa fa-pencil-square-o'};
  1161. if(form.expand==undefined){
  1162. form.expand=false;
  1163. }
  1164. let ids=[];
  1165. if(row){
  1166. ids.push(row[this.pk]);
  1167. }else{
  1168. this.selections.forEach(res=>{
  1169. ids.push(res[this.pk]);
  1170. });
  1171. }
  1172. let time=0;
  1173. ids.forEach(res=>{
  1174. setTimeout(()=>{
  1175. form.url=(this.extend.edit_url.indexOf('?')!=-1)?this.extend.edit_url+'&ids='+res:this.extend.edit_url+'?ids='+res,
  1176. form.close=function (refresh=false){
  1177. if(!refresh){
  1178. return;
  1179. }
  1180. let id=top.Yunqi.app.activeTab.id;
  1181. let tab=top.document.getElementById('addtabs-'+id).contentWindow;
  1182. let doc=tab.document.getElementsByClassName('refresh');
  1183. if(doc.length>0){
  1184. doc[0].click();
  1185. }
  1186. };
  1187. Yunqi.api.open(form);
  1188. },time);
  1189. time+=100;
  1190. });
  1191. },
  1192. previewImg(imgs){
  1193. Yunqi.api.previewImg(imgs);
  1194. },
  1195. importExcel:function (){
  1196. document.querySelector('.importUpload button').click();
  1197. },
  1198. handleImportSuccess:function (e){
  1199. let file=e.data.url;
  1200. if(!this.extend.import_url){
  1201. Yunqi.message.error('import_url未设置');
  1202. return;
  1203. }
  1204. Yunqi.ajax.post(this.extend.import_url,{file:file}).then(res=>{
  1205. this.importResult.success=res.success;
  1206. this.importResult.fail=res.fail;
  1207. this.importResult.show=true;
  1208. this.reload();
  1209. });
  1210. }
  1211. }
  1212. };