Rap 原分销系统代码Web
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

371c2acc31fce0fc152260867b9955a3dc640f7c.svn-base 22KB

пре 5 месеци
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863
  1. import { initData, download } from '@/api/data'
  2. import { parseTime, downloadFile } from '@/utils/index'
  3. import Vue from 'vue'
  4. /**
  5. * CRUD配置
  6. * @author moxun
  7. * @param {*} options <br>
  8. * @return crud instance.
  9. * @example
  10. * 要使用多crud时,请在关联crud的组件处使用crud-tag进行标记,如:<jobForm :job-status="dict.job_status" crud-tag="job" />
  11. */
  12. function CRUD(options) {
  13. const defaultOptions = {
  14. tag: 'default',
  15. // id字段名
  16. idField: 'id',
  17. // 标题
  18. title: '',
  19. // 请求数据的url
  20. url: '',
  21. // 表格数据
  22. data: [],
  23. // 选择项
  24. selections: [],
  25. // 待查询的对象
  26. query: {},
  27. // 查询数据的参数
  28. params: {},
  29. // Form 表单
  30. form: {},
  31. // 重置表单
  32. defaultForm: () => {},
  33. // 排序规则,默认 id 降序, 支持多字段排序 ['id,desc', 'createTime,asc']
  34. sort: ['id,desc'],
  35. // 等待时间
  36. time: 50,
  37. // CRUD Method
  38. crudMethod: {
  39. add: (form) => {},
  40. del: (id) => {},
  41. edit: (form) => {},
  42. get: (id) => {}
  43. },
  44. // 主页操作栏显示哪些按钮
  45. optShow: {
  46. add: true,
  47. edit: true,
  48. del: true,
  49. download: true,
  50. reset: true
  51. },
  52. // 自定义一些扩展属性
  53. props: {},
  54. // 在主页准备
  55. queryOnPresenterCreated: true,
  56. // 调试开关
  57. debug: false
  58. }
  59. options = mergeOptions(defaultOptions, options)
  60. const data = {
  61. ...options,
  62. // 记录数据状态
  63. dataStatus: {},
  64. status: {
  65. add: CRUD.STATUS.NORMAL,
  66. edit: CRUD.STATUS.NORMAL,
  67. // 添加或编辑状态
  68. get cu() {
  69. if (this.add === CRUD.STATUS.NORMAL && this.edit === CRUD.STATUS.NORMAL) {
  70. return CRUD.STATUS.NORMAL
  71. } else if (this.add === CRUD.STATUS.PREPARED || this.edit === CRUD.STATUS.PREPARED) {
  72. return CRUD.STATUS.PREPARED
  73. } else if (this.add === CRUD.STATUS.PROCESSING || this.edit === CRUD.STATUS.PROCESSING) {
  74. return CRUD.STATUS.PROCESSING
  75. }
  76. throw new Error('wrong crud\'s cu status')
  77. },
  78. // 标题
  79. get title() {
  80. return this.add > CRUD.STATUS.NORMAL ? `新增${crud.title}` : this.edit > CRUD.STATUS.NORMAL ? `编辑${crud.title}` : crud.title
  81. }
  82. },
  83. msg: {
  84. submit: '提交成功',
  85. add: '新增成功',
  86. edit: '编辑成功',
  87. del: '删除成功'
  88. },
  89. page: {
  90. // 页码
  91. page: 0,
  92. // 每页数据条数
  93. size: 10,
  94. // 总数据条数
  95. total: 0
  96. },
  97. // 整体loading
  98. loading: false,
  99. // 导出的 Loading
  100. downloadLoading: false,
  101. // 删除的 Loading
  102. delAllLoading: false
  103. }
  104. const methods = {
  105. /**
  106. * 通用的提示
  107. */
  108. submitSuccessNotify() {
  109. crud.notify(crud.msg.submit, CRUD.NOTIFICATION_TYPE.SUCCESS)
  110. },
  111. addSuccessNotify() {
  112. crud.notify(crud.msg.add, CRUD.NOTIFICATION_TYPE.SUCCESS)
  113. },
  114. editSuccessNotify() {
  115. crud.notify(crud.msg.edit, CRUD.NOTIFICATION_TYPE.SUCCESS)
  116. },
  117. delSuccessNotify() {
  118. crud.notify(crud.msg.del, CRUD.NOTIFICATION_TYPE.SUCCESS)
  119. },
  120. // 搜索
  121. toQuery() {
  122. crud.page.page = 1
  123. crud.refresh()
  124. },
  125. // 刷新
  126. refresh() {
  127. if (!callVmHook(crud, CRUD.HOOK.beforeRefresh)) {
  128. return
  129. }
  130. return new Promise((resolve, reject) => {
  131. crud.loading = true
  132. // 请求数据
  133. initData(crud.url, crud.getQueryParams()).then(data => {
  134. const table = crud.getTable()
  135. if (table && table.lazy) { // 懒加载子节点数据,清掉已加载的数据
  136. table.store.states.treeData = {}
  137. table.store.states.lazyTreeNodeMap = {}
  138. }
  139. crud.page.total = data.totalElements
  140. crud.data = data.content
  141. crud.resetDataStatus()
  142. // time 毫秒后显示表格
  143. setTimeout(() => {
  144. crud.loading = false
  145. callVmHook(crud, CRUD.HOOK.afterRefresh)
  146. }, crud.time)
  147. resolve(data)
  148. }).catch(err => {
  149. crud.loading = false
  150. reject(err)
  151. })
  152. })
  153. },
  154. /**
  155. * 启动添加
  156. */
  157. toAdd() {
  158. crud.resetForm()
  159. if (!(callVmHook(crud, CRUD.HOOK.beforeToAdd, crud.form) && callVmHook(crud, CRUD.HOOK.beforeToCU, crud.form))) {
  160. return
  161. }
  162. crud.status.add = CRUD.STATUS.PREPARED
  163. callVmHook(crud, CRUD.HOOK.afterToAdd, crud.form)
  164. callVmHook(crud, CRUD.HOOK.afterToCU, crud.form)
  165. },
  166. /**
  167. * 启动编辑
  168. * @param {*} data 数据项
  169. */
  170. toEdit(data) {
  171. crud.resetForm(JSON.parse(JSON.stringify(data)))
  172. if (!(callVmHook(crud, CRUD.HOOK.beforeToEdit, crud.form) && callVmHook(crud, CRUD.HOOK.beforeToCU, crud.form))) {
  173. return
  174. }
  175. crud.status.edit = CRUD.STATUS.PREPARED
  176. crud.getDataStatus(crud.getDataId(data)).edit = CRUD.STATUS.PREPARED
  177. callVmHook(crud, CRUD.HOOK.afterToEdit, crud.form)
  178. callVmHook(crud, CRUD.HOOK.afterToCU, crud.form)
  179. },
  180. /**
  181. * 启动删除
  182. * @param {*} data 数据项
  183. */
  184. toDelete(data) {
  185. crud.getDataStatus(crud.getDataId(data)).delete = CRUD.STATUS.PREPARED
  186. },
  187. /**
  188. * 取消删除
  189. * @param {*} data 数据项
  190. */
  191. cancelDelete(data) {
  192. if (!callVmHook(crud, CRUD.HOOK.beforeDeleteCancel, data)) {
  193. return
  194. }
  195. crud.getDataStatus(crud.getDataId(data)).delete = CRUD.STATUS.NORMAL
  196. callVmHook(crud, CRUD.HOOK.afterDeleteCancel, data)
  197. },
  198. /**
  199. * 取消新增/编辑
  200. */
  201. cancelCU() {
  202. const addStatus = crud.status.add
  203. const editStatus = crud.status.edit
  204. if (addStatus === CRUD.STATUS.PREPARED) {
  205. if (!callVmHook(crud, CRUD.HOOK.beforeAddCancel, crud.form)) {
  206. return
  207. }
  208. crud.status.add = CRUD.STATUS.NORMAL
  209. }
  210. if (editStatus === CRUD.STATUS.PREPARED) {
  211. if (!callVmHook(crud, CRUD.HOOK.beforeEditCancel, crud.form)) {
  212. return
  213. }
  214. crud.status.edit = CRUD.STATUS.NORMAL
  215. crud.getDataStatus(crud.getDataId(crud.form)).edit = CRUD.STATUS.NORMAL
  216. }
  217. crud.resetForm()
  218. if (addStatus === CRUD.STATUS.PREPARED) {
  219. callVmHook(crud, CRUD.HOOK.afterAddCancel, crud.form)
  220. }
  221. if (editStatus === CRUD.STATUS.PREPARED) {
  222. callVmHook(crud, CRUD.HOOK.afterEditCancel, crud.form)
  223. }
  224. // 清除表单验证
  225. if (crud.findVM('form').$refs['form']) {
  226. crud.findVM('form').$refs['form'].clearValidate()
  227. }
  228. },
  229. /**
  230. * 提交新增/编辑
  231. */
  232. submitCU() {
  233. if (!callVmHook(crud, CRUD.HOOK.beforeValidateCU)) {
  234. return
  235. }
  236. crud.findVM('form').$refs['form'].validate(valid => {
  237. if (!valid) {
  238. return
  239. }
  240. if (!callVmHook(crud, CRUD.HOOK.afterValidateCU)) {
  241. return
  242. }
  243. if (crud.status.add === CRUD.STATUS.PREPARED) {
  244. crud.doAdd()
  245. } else if (crud.status.edit === CRUD.STATUS.PREPARED) {
  246. crud.doEdit()
  247. }
  248. })
  249. },
  250. /**
  251. * 执行添加
  252. */
  253. doAdd() {
  254. if (!callVmHook(crud, CRUD.HOOK.beforeSubmit)) {
  255. return
  256. }
  257. crud.status.add = CRUD.STATUS.PROCESSING
  258. crud.crudMethod.add(crud.form).then(() => {
  259. crud.status.add = CRUD.STATUS.NORMAL
  260. crud.resetForm()
  261. crud.addSuccessNotify()
  262. callVmHook(crud, CRUD.HOOK.afterSubmit)
  263. crud.toQuery()
  264. }).catch(() => {
  265. crud.status.add = CRUD.STATUS.PREPARED
  266. callVmHook(crud, CRUD.HOOK.afterAddError)
  267. })
  268. },
  269. /**
  270. * 执行编辑
  271. */
  272. doEdit() {
  273. if (!callVmHook(crud, CRUD.HOOK.beforeSubmit)) {
  274. return
  275. }
  276. crud.status.edit = CRUD.STATUS.PROCESSING
  277. crud.crudMethod.edit(crud.form).then(() => {
  278. crud.status.edit = CRUD.STATUS.NORMAL
  279. crud.getDataStatus(crud.getDataId(crud.form)).edit = CRUD.STATUS.NORMAL
  280. crud.editSuccessNotify()
  281. crud.resetForm()
  282. callVmHook(crud, CRUD.HOOK.afterSubmit)
  283. crud.refresh()
  284. }).catch(() => {
  285. crud.status.edit = CRUD.STATUS.PREPARED
  286. callVmHook(crud, CRUD.HOOK.afterEditError)
  287. })
  288. },
  289. /**
  290. * 执行删除
  291. * @param {*} data 数据项
  292. */
  293. doDelete(data) {
  294. let delAll = false
  295. let dataStatus
  296. const ids = []
  297. if (data instanceof Array) {
  298. delAll = true
  299. data.forEach(val => {
  300. ids.push(this.getDataId(val))
  301. })
  302. } else {
  303. ids.push(this.getDataId(data))
  304. dataStatus = crud.getDataStatus(this.getDataId(data))
  305. }
  306. if (!callVmHook(crud, CRUD.HOOK.beforeDelete, data)) {
  307. return
  308. }
  309. if (!delAll) {
  310. dataStatus.delete = CRUD.STATUS.PROCESSING
  311. }
  312. return crud.crudMethod.del(ids).then(() => {
  313. if (delAll) {
  314. crud.delAllLoading = false
  315. } else dataStatus.delete = CRUD.STATUS.PREPARED
  316. crud.dleChangePage(1)
  317. crud.delSuccessNotify()
  318. callVmHook(crud, CRUD.HOOK.afterDelete, data)
  319. crud.refresh()
  320. }).catch(() => {
  321. if (delAll) {
  322. crud.delAllLoading = false
  323. } else dataStatus.delete = CRUD.STATUS.PREPARED
  324. })
  325. },
  326. /**
  327. * 通用导出
  328. */
  329. doExport() {
  330. crud.downloadLoading = true
  331. download(crud.url + '/download', crud.getQueryParams()).then(result => {
  332. downloadFile(result, crud.title + '数据', 'xlsx')
  333. crud.downloadLoading = false
  334. }).catch(() => {
  335. crud.downloadLoading = false
  336. })
  337. },
  338. /**
  339. * 获取查询参数
  340. */
  341. getQueryParams: function() {
  342. // 清除参数无值的情况
  343. Object.keys(crud.query).length !== 0 && Object.keys(crud.query).forEach(item => {
  344. if (crud.query[item] === null || crud.query[item] === '') crud.query[item] = undefined
  345. })
  346. Object.keys(crud.params).length !== 0 && Object.keys(crud.params).forEach(item => {
  347. if (crud.params[item] === null || crud.params[item] === '') crud.params[item] = undefined
  348. })
  349. return {
  350. page: crud.page.page - 1,
  351. size: crud.page.size,
  352. sort: crud.sort,
  353. ...crud.query,
  354. ...crud.params
  355. }
  356. },
  357. // 当前页改变
  358. pageChangeHandler(e) {
  359. crud.page.page = e
  360. crud.refresh()
  361. },
  362. // 每页条数改变
  363. sizeChangeHandler(e) {
  364. crud.page.size = e
  365. crud.page.page = 1
  366. crud.refresh()
  367. },
  368. // 预防删除第二页最后一条数据时,或者多选删除第二页的数据时,页码错误导致请求无数据
  369. dleChangePage(size) {
  370. if (crud.data.length === size && crud.page.page !== 1) {
  371. crud.page.page -= 1
  372. }
  373. },
  374. // 选择改变
  375. selectionChangeHandler(val) {
  376. crud.selections = val
  377. },
  378. /**
  379. * 重置查询参数
  380. * @param {Boolean} toQuery 重置后进行查询操作
  381. */
  382. resetQuery(toQuery = true) {
  383. const defaultQuery = JSON.parse(JSON.stringify(crud.defaultQuery))
  384. const query = crud.query
  385. Object.keys(query).forEach(key => {
  386. query[key] = defaultQuery[key]
  387. })
  388. // 重置参数
  389. this.params = {}
  390. if (toQuery) {
  391. crud.toQuery()
  392. }
  393. },
  394. /**
  395. * 重置表单
  396. * @param {Array} data 数据
  397. */
  398. resetForm(data) {
  399. const form = data || (typeof crud.defaultForm === 'object' ? JSON.parse(JSON.stringify(crud.defaultForm)) : crud.defaultForm.apply(crud.findVM('form')))
  400. const crudFrom = crud.form
  401. for (const key in form) {
  402. if (crudFrom.hasOwnProperty(key)) {
  403. crudFrom[key] = form[key]
  404. } else {
  405. Vue.set(crudFrom, key, form[key])
  406. }
  407. }
  408. // add by ghl 2020-10-04 页面重复添加信息时,下拉框的校验会存在,需要找工取消
  409. if (crud.findVM('form').$refs['form']) {
  410. crud.findVM('form').$refs['form'].clearValidate()
  411. }
  412. },
  413. /**
  414. * 重置数据状态
  415. */
  416. resetDataStatus() {
  417. const dataStatus = {}
  418. function resetStatus(datas) {
  419. datas.forEach(e => {
  420. dataStatus[crud.getDataId(e)] = {
  421. delete: 0,
  422. edit: 0
  423. }
  424. if (e.children) {
  425. resetStatus(e.children)
  426. }
  427. })
  428. }
  429. resetStatus(crud.data)
  430. crud.dataStatus = dataStatus
  431. },
  432. /**
  433. * 获取数据状态
  434. * @param {Number | String} id 数据项id
  435. */
  436. getDataStatus(id) {
  437. return crud.dataStatus[id]
  438. },
  439. /**
  440. * 用于树形表格多选, 选中所有
  441. * @param selection
  442. */
  443. selectAllChange(selection) {
  444. // 如果选中的数目与请求到的数目相同就选中子节点,否则就清空选中
  445. if (selection && selection.length === crud.data.length) {
  446. selection.forEach(val => {
  447. crud.selectChange(selection, val)
  448. })
  449. } else {
  450. crud.getTable().clearSelection()
  451. }
  452. },
  453. /**
  454. * 用于树形表格多选,单选的封装
  455. * @param selection
  456. * @param row
  457. */
  458. selectChange(selection, row) {
  459. // 如果selection中存在row代表是选中,否则是取消选中
  460. if (selection.find(val => { return crud.getDataId(val) === crud.getDataId(row) })) {
  461. if (row.children) {
  462. row.children.forEach(val => {
  463. crud.getTable().toggleRowSelection(val, true)
  464. selection.push(val)
  465. if (val.children) {
  466. crud.selectChange(selection, val)
  467. }
  468. })
  469. }
  470. } else {
  471. crud.toggleRowSelection(selection, row)
  472. }
  473. },
  474. /**
  475. * 切换选中状态
  476. * @param selection
  477. * @param data
  478. */
  479. toggleRowSelection(selection, data) {
  480. if (data.children) {
  481. data.children.forEach(val => {
  482. crud.getTable().toggleRowSelection(val, false)
  483. if (val.children) {
  484. crud.toggleRowSelection(selection, val)
  485. }
  486. })
  487. }
  488. },
  489. findVM(type) {
  490. return crud.vms.find(vm => vm && vm.type === type).vm
  491. },
  492. notify(title, type = CRUD.NOTIFICATION_TYPE.INFO) {
  493. crud.vms[0].vm.$notify({
  494. title,
  495. type,
  496. duration: 2500
  497. })
  498. },
  499. updateProp(name, value) {
  500. Vue.set(crud.props, name, value)
  501. },
  502. getDataId(data) {
  503. return data[this.idField]
  504. },
  505. getTable() {
  506. return this.findVM('presenter').$refs.table
  507. },
  508. attchTable() {
  509. const table = this.getTable()
  510. this.updateProp('table', table)
  511. const that = this
  512. table.$on('expand-change', (row, expanded) => {
  513. if (!expanded) {
  514. return
  515. }
  516. const lazyTreeNodeMap = table.store.states.lazyTreeNodeMap
  517. row.children = lazyTreeNodeMap[crud.getDataId(row)]
  518. if (row.children) {
  519. row.children.forEach(ele => {
  520. const id = crud.getDataId(ele)
  521. if (that.dataStatus[id] === undefined) {
  522. that.dataStatus[id] = {
  523. delete: 0,
  524. edit: 0
  525. }
  526. }
  527. })
  528. }
  529. })
  530. }
  531. }
  532. const crud = Object.assign({}, data)
  533. // 可观测化
  534. Vue.observable(crud)
  535. // 附加方法
  536. Object.assign(crud, methods)
  537. // 记录初始默认的查询参数,后续重置查询时使用
  538. Object.assign(crud, {
  539. defaultQuery: JSON.parse(JSON.stringify(data.query)),
  540. // 预留4位存储:组件 主页、头部、分页、表单,调试查看也方便找
  541. vms: Array(4),
  542. /**
  543. * 注册组件实例
  544. * @param {String} type 类型
  545. * @param {*} vm 组件实例
  546. * @param {Number} index 该参数内部使用
  547. */
  548. registerVM(type, vm, index = -1) {
  549. const vmObj = {
  550. type,
  551. vm: vm
  552. }
  553. if (index < 0) {
  554. this.vms.push(vmObj)
  555. return
  556. }
  557. if (index < 4) { // 内置预留vm数
  558. this.vms[index] = vmObj
  559. return
  560. }
  561. this.vms.length = Math.max(this.vms.length, index)
  562. this.vms.splice(index, 1, vmObj)
  563. },
  564. /**
  565. * 取消注册组件实例
  566. * @param {*} vm 组件实例
  567. */
  568. unregisterVM(type, vm) {
  569. for (let i = this.vms.length - 1; i >= 0; i--) {
  570. if (this.vms[i] === undefined) {
  571. continue
  572. }
  573. if (this.vms[i].type === type && this.vms[i].vm === vm) {
  574. if (i < 4) { // 内置预留vm数
  575. this.vms[i] = undefined
  576. } else {
  577. this.vms.splice(i, 1)
  578. }
  579. break
  580. }
  581. }
  582. }
  583. })
  584. // 冻结处理,需要扩展数据的话,使用crud.updateProp(name, value),以crud.props.name形式访问,这个是响应式的,可以做数据绑定
  585. Object.freeze(crud)
  586. return crud
  587. }
  588. // hook VM
  589. function callVmHook(crud, hook) {
  590. if (crud.debug) {
  591. console.log('callVmHook: ' + hook)
  592. }
  593. const tagHook = crud.tag ? hook + '$' + crud.tag : null
  594. let ret = true
  595. const nargs = [crud]
  596. for (let i = 2; i < arguments.length; ++i) {
  597. nargs.push(arguments[i])
  598. }
  599. // 有些组件扮演了多个角色,调用钩子时,需要去重
  600. const vmSet = new Set()
  601. crud.vms.forEach(vm => vm && vmSet.add(vm.vm))
  602. vmSet.forEach(vm => {
  603. if (vm[hook]) {
  604. ret = vm[hook].apply(vm, nargs) !== false && ret
  605. }
  606. if (tagHook && vm[tagHook]) {
  607. ret = vm[tagHook].apply(vm, nargs) !== false && ret
  608. }
  609. })
  610. return ret
  611. }
  612. function mergeOptions(src, opts) {
  613. const optsRet = {
  614. ...src
  615. }
  616. for (const key in src) {
  617. if (opts.hasOwnProperty(key)) {
  618. optsRet[key] = opts[key]
  619. }
  620. }
  621. return optsRet
  622. }
  623. /**
  624. * 查找crud
  625. * @param {*} vm
  626. * @param {string} tag
  627. */
  628. function lookupCrud(vm, tag) {
  629. tag = tag || vm.$attrs['crud-tag'] || 'default'
  630. // function lookupCrud(vm, tag) {
  631. if (vm.$crud) {
  632. const ret = vm.$crud[tag]
  633. if (ret) {
  634. return ret
  635. }
  636. }
  637. return vm.$parent ? lookupCrud(vm.$parent, tag) : undefined
  638. }
  639. /**
  640. * crud主页
  641. */
  642. function presenter(crud) {
  643. if (crud) {
  644. console.warn('[CRUD warn]: ' + 'please use $options.cruds() { return CRUD(...) or [CRUD(...), ...] }')
  645. }
  646. return {
  647. data() {
  648. // 在data中返回crud,是为了将crud与当前实例关联,组件观测crud相关属性变化
  649. return {
  650. crud: this.crud
  651. }
  652. },
  653. beforeCreate() {
  654. this.$crud = this.$crud || {}
  655. let cruds = this.$options.cruds instanceof Function ? this.$options.cruds() : crud
  656. if (!(cruds instanceof Array)) {
  657. cruds = [cruds]
  658. }
  659. cruds.forEach(ele => {
  660. if (this.$crud[ele.tag]) {
  661. console.error('[CRUD error]: ' + 'crud with tag [' + ele.tag + ' is already exist')
  662. }
  663. this.$crud[ele.tag] = ele
  664. ele.registerVM('presenter', this, 0)
  665. })
  666. this.crud = this.$crud['defalut'] || cruds[0]
  667. },
  668. methods: {
  669. parseTime
  670. },
  671. created() {
  672. for (const k in this.$crud) {
  673. if (this.$crud[k].queryOnPresenterCreated) {
  674. this.$crud[k].toQuery()
  675. }
  676. }
  677. },
  678. destroyed() {
  679. for (const k in this.$crud) {
  680. this.$crud[k].unregisterVM('presenter', this)
  681. }
  682. },
  683. mounted() {
  684. // 如果table未实例化(例如使用了v-if),请稍后在适当时机crud.attchTable刷新table信息
  685. if (this.$refs.table !== undefined) {
  686. this.crud.attchTable()
  687. }
  688. }
  689. }
  690. }
  691. /**
  692. * 头部
  693. */
  694. function header() {
  695. return {
  696. data() {
  697. return {
  698. crud: this.crud,
  699. query: this.crud.query
  700. }
  701. },
  702. beforeCreate() {
  703. this.crud = lookupCrud(this)
  704. this.crud.registerVM('header', this, 1)
  705. },
  706. destroyed() {
  707. this.crud.unregisterVM('header', this)
  708. }
  709. }
  710. }
  711. /**
  712. * 分页
  713. */
  714. function pagination() {
  715. return {
  716. data() {
  717. return {
  718. crud: this.crud,
  719. page: this.crud.page
  720. }
  721. },
  722. beforeCreate() {
  723. this.crud = lookupCrud(this)
  724. this.crud.registerVM('pagination', this, 2)
  725. },
  726. destroyed() {
  727. this.crud.unregisterVM('pagination', this)
  728. }
  729. }
  730. }
  731. /**
  732. * 表单
  733. */
  734. function form(defaultForm) {
  735. return {
  736. data() {
  737. return {
  738. crud: this.crud,
  739. form: this.crud.form
  740. }
  741. },
  742. beforeCreate() {
  743. this.crud = lookupCrud(this)
  744. this.crud.registerVM('form', this, 3)
  745. },
  746. created() {
  747. this.crud.defaultForm = defaultForm
  748. this.crud.resetForm()
  749. },
  750. destroyed() {
  751. this.crud.unregisterVM('form', this)
  752. }
  753. }
  754. }
  755. /**
  756. * crud
  757. */
  758. function crud(options = {}) {
  759. const defaultOptions = {
  760. type: undefined
  761. }
  762. options = mergeOptions(defaultOptions, options)
  763. return {
  764. data() {
  765. return {
  766. crud: this.crud
  767. }
  768. },
  769. beforeCreate() {
  770. this.crud = lookupCrud(this)
  771. this.crud.registerVM(options.type, this)
  772. },
  773. destroyed() {
  774. this.crud.unregisterVM(options.type, this)
  775. }
  776. }
  777. }
  778. /**
  779. * CRUD钩子
  780. */
  781. CRUD.HOOK = {
  782. /** 刷新 - 之前 */
  783. beforeRefresh: 'beforeCrudRefresh',
  784. /** 刷新 - 之后 */
  785. afterRefresh: 'afterCrudRefresh',
  786. /** 删除 - 之前 */
  787. beforeDelete: 'beforeCrudDelete',
  788. /** 删除 - 之后 */
  789. afterDelete: 'afterCrudDelete',
  790. /** 删除取消 - 之前 */
  791. beforeDeleteCancel: 'beforeCrudDeleteCancel',
  792. /** 删除取消 - 之后 */
  793. afterDeleteCancel: 'afterCrudDeleteCancel',
  794. /** 新建 - 之前 */
  795. beforeToAdd: 'beforeCrudToAdd',
  796. /** 新建 - 之后 */
  797. afterToAdd: 'afterCrudToAdd',
  798. /** 编辑 - 之前 */
  799. beforeToEdit: 'beforeCrudToEdit',
  800. /** 编辑 - 之后 */
  801. afterToEdit: 'afterCrudToEdit',
  802. /** 开始 "新建/编辑" - 之前 */
  803. beforeToCU: 'beforeCrudToCU',
  804. /** 开始 "新建/编辑" - 之后 */
  805. afterToCU: 'afterCrudToCU',
  806. /** "新建/编辑" 验证 - 之前 */
  807. beforeValidateCU: 'beforeCrudValidateCU',
  808. /** "新建/编辑" 验证 - 之后 */
  809. afterValidateCU: 'afterCrudValidateCU',
  810. /** 添加取消 - 之前 */
  811. beforeAddCancel: 'beforeCrudAddCancel',
  812. /** 添加取消 - 之后 */
  813. afterAddCancel: 'afterCrudAddCancel',
  814. /** 编辑取消 - 之前 */
  815. beforeEditCancel: 'beforeCrudEditCancel',
  816. /** 编辑取消 - 之后 */
  817. afterEditCancel: 'afterCrudEditCancel',
  818. /** 提交 - 之前 */
  819. beforeSubmit: 'beforeCrudSubmitCU',
  820. /** 提交 - 之后 */
  821. afterSubmit: 'afterCrudSubmitCU',
  822. afterAddError: 'afterCrudAddError',
  823. afterEditError: 'afterCrudEditError'
  824. }
  825. /**
  826. * CRUD状态
  827. */
  828. CRUD.STATUS = {
  829. NORMAL: 0,
  830. PREPARED: 1,
  831. PROCESSING: 2
  832. }
  833. /**
  834. * CRUD通知类型
  835. */
  836. CRUD.NOTIFICATION_TYPE = {
  837. SUCCESS: 'success',
  838. WARNING: 'warning',
  839. INFO: 'info',
  840. ERROR: 'error'
  841. }
  842. export default CRUD
  843. export {
  844. presenter,
  845. header,
  846. form,
  847. pagination,
  848. crud
  849. }