op.js 9.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352
  1. import { fGet, fSave, fPut, fDelete } from '@/api/rest'
  2. function hasArea(obj, key) {
  3. const k = key || 'area'
  4. return obj[k] instanceof Array
  5. }
  6. function Options(options, defaultOptions) {
  7. return Object.assign(defaultOptions || {}, options || {})
  8. }
  9. function fnList(options) {
  10. const opt = typeof options === 'string' ? { list: options } : Options(options, { list: 'main' })
  11. const listObj = this.self.list[opt.list]
  12. if (listObj === undefined) {
  13. return
  14. }
  15. // deal area query parameter
  16. if (hasArea(listObj)) {
  17. if (listObj.area.length > 0) {
  18. listObj.query.province_id = listObj.area[0]
  19. }
  20. if (listObj.area.length > 1) {
  21. listObj.query.city_id = listObj.area[1]
  22. }
  23. if (listObj.area.length > 2) {
  24. listObj.query.area_id = listObj.area[2]
  25. }
  26. }
  27. opt.before = opt.before || listObj.before
  28. opt.after = opt.after || listObj.after
  29. opt.error = opt.error || listObj.error
  30. listObj.loading = true
  31. const url = opt.url || listObj.url || this.self.URI
  32. const params = opt.before instanceof Function ? opt.before({ ...listObj.query }) : { ...listObj.query }
  33. fGet(url, params).then(res => {
  34. const { total, data } = res
  35. listObj.total = total
  36. listObj.list = data.map(v => {
  37. if (listObj.render instanceof Function) {
  38. return listObj.render(v)
  39. }
  40. return v
  41. })
  42. opt.after instanceof Function && opt.after(res)
  43. }).finally(() => {
  44. listObj.loading = false
  45. })
  46. }
  47. function fnFilter(options) {
  48. const opt = Options(options, { list: 'main' })
  49. this.self.list[opt.list].query ? this.self.list[opt.list].query.page = 1 : undefined
  50. this.list(opt)
  51. }
  52. function fnReset(options) {
  53. const opt = Options(options, { list: 'main' })
  54. const listObj = this.self.list[opt.list]
  55. listObj.query = listObj.query || {}
  56. listObj.query = Object.assign({ page: 1, limit: listObj.query.limit || 20 }, opt.data || {})
  57. // deal area query parameter
  58. if (hasArea(listObj)) {
  59. listObj.area = []
  60. }
  61. this.list(opt)
  62. }
  63. function fnCreate(options) {
  64. const opt = Options(options, { form: 'form', title: '新增' })
  65. opt.before instanceof Function && opt.before()
  66. const formObj = this.self.dlg[opt.form]
  67. // deal area parameter
  68. if (hasArea(formObj)) {
  69. formObj.area = []
  70. }
  71. formObj.title = opt.title || '新增'
  72. formObj.data = opt.data || {}
  73. formObj.visible = true
  74. this.self.$nextTick(() => {
  75. this.self.$refs[opt.form].clearValidate()
  76. })
  77. }
  78. function fnEdit(options) {
  79. const opt = Options(options, { form: 'form' })
  80. const formObj = this.self.dlg[opt.form]
  81. // deal area parameter
  82. if (hasArea(formObj)) {
  83. formObj.area = [opt.row.province_id, opt.row.city_id, opt.row.area_id]
  84. }
  85. formObj.title = opt.title === undefined || opt.row[opt.title] === undefined ? (opt.title || '编辑') : `编辑 - ${opt.row[opt.title]}`
  86. formObj.data = Object.assign({}, opt.row)
  87. formObj.data = Object.assign(formObj.data, opt.data || {})
  88. opt.before instanceof Function && opt.before(formObj.data)
  89. formObj.visible = true
  90. this.self.$nextTick(() => {
  91. this.self.$refs[opt.form].clearValidate()
  92. })
  93. }
  94. function fnDelete(options) {
  95. const opt = Options(options, { list: 'main', form: 'form' })
  96. const title = opt.title === undefined || opt.row[opt.title] === undefined ? (opt.title || '') : ` - ${opt.row[opt.title]}`
  97. const listObj = this.self.list[opt.list] || {}
  98. this.self.$confirm(`您是否确认要删除${title}`, '删除确认').then(() => {
  99. const url = opt.url || listObj.url || this.self.URI
  100. fDelete(url, opt.row).then(res => {
  101. this.list(opt.reload)
  102. })
  103. }).catch(() => {})
  104. }
  105. function fnSave(options) {
  106. const opt = Options(options, { form: 'form', data: {}, reload: 'main' })
  107. const thiz = this
  108. const self = this.self
  109. const formObj = self.dlg[opt.form] || {}
  110. function innerSave(data) {
  111. if (typeof opt.before === 'function') {
  112. const beforeResult = opt.before(data)
  113. if (typeof beforeResult === 'boolean' && !beforeResult) {
  114. return
  115. }
  116. }
  117. formObj.saveLoading = true
  118. const url = opt.url || self.URI
  119. fSave(url, data).then(res => {
  120. self.$message.success('保存成功')
  121. typeof opt.reload === 'string' && thiz.list(opt.reload)
  122. typeof opt.success === 'function' && opt.success(res)
  123. formObj.visible = false
  124. }).catch(err => {
  125. typeof opt.error === 'function' && opt.error(err)
  126. }).finally(() => {
  127. formObj.saveLoading = false
  128. })
  129. }
  130. if (typeof opt.form === 'string' && opt.form.length > 0) {
  131. if (formObj.data === undefined) {
  132. const err = `form ${opt.form} data not exist.`
  133. self.$message.error(err)
  134. typeof opt.error === 'function' && opt.error(err)
  135. return
  136. }
  137. const formRef = self.$refs[opt.form]
  138. if (formRef === undefined || formRef.validate === undefined) {
  139. const err = `form ${opt.form} element not exist.`
  140. self.$message.error(err)
  141. typeof opt.error === 'function' && opt.error(err)
  142. return
  143. }
  144. formRef.validate((valid) => {
  145. if (valid) {
  146. const otherData = opt.data || {}
  147. const params = { ...formObj.data, ...otherData }
  148. // deal area parameter
  149. if (hasArea(formObj) && formObj.area.length > 2) {
  150. params.province_id = formObj.area[0]
  151. params.city_id = formObj.area[1]
  152. params.area_id = formObj.area[2]
  153. }
  154. innerSave(params)
  155. }
  156. })
  157. } else {
  158. const params = opt.data || {}
  159. innerSave(params)
  160. }
  161. }
  162. function fnUpdate(options) {
  163. const opt = Options(options, { row: {}, data: {}})
  164. const params = { ...opt.row, ...opt.data }
  165. const url = opt.url || this.self.URI
  166. fSave(url, params).then(res => {
  167. typeof opt.success === 'function' ? opt.success(res) : this.list(opt.reload)
  168. })
  169. }
  170. function fnMultiSelect(options) {
  171. const opt = options || {}
  172. const listObj = this.self.list[opt.list || 'main']
  173. if (listObj === undefined) {
  174. return
  175. }
  176. listObj.selectedRows = opt.rows || []
  177. }
  178. // 批量操作
  179. function fnBatchOp(options) {
  180. const opt = Options(options, { params: {}})
  181. const list = opt.list || 'main'
  182. const listObj = this.self.list[list]
  183. if (listObj === undefined) {
  184. return
  185. }
  186. const selectedRows = listObj.selectedRows || []
  187. const ids = selectedRows.map(v => {
  188. return v.id
  189. })
  190. if (ids.length === 0) {
  191. this.self.$message.error('请先选择要操作的记录')
  192. return
  193. }
  194. const op = opt.op || '操作'
  195. this.self.$confirm(`您是否确认对选择的${ids.length}个记录进行${op}`, '提示').then(() => {
  196. const url = opt.url || listObj.url || this.self.URI
  197. const params = { ...opt.params }
  198. if (typeof opt.ids !== 'boolean' || !opt.ids) {
  199. params.ids = ids
  200. }
  201. fPut(url, params).then(res => {
  202. if (typeof opt.success === 'function') {
  203. opt.success(res)
  204. } else {
  205. this.self.$message.success('操作成功')
  206. const reload = opt.reload || list
  207. this.list({ list: reload })
  208. }
  209. })
  210. })
  211. }
  212. function fnGetSelected(options) {
  213. const opt = Options(options, {})
  214. const list = opt.list || 'main'
  215. const listObj = this.self.list[list]
  216. if (listObj === undefined) {
  217. return []
  218. }
  219. const selectedRows = listObj.selectedRows || []
  220. if (typeof opt.render === 'function') {
  221. return selectedRows.map(v => {
  222. return opt.render(v)
  223. })
  224. }
  225. return selectedRows
  226. }
  227. function fnLoadAreaList(node, resolve) {
  228. const { level, value } = node
  229. fGet('/manager/areas', { pid: level === 0 ? 1 : value }).then(res => {
  230. const { data } = res
  231. const nodes = data.map(v => {
  232. return {
  233. value: v.id,
  234. label: v.name,
  235. leaf: level + 1 >= 3
  236. }
  237. })
  238. resolve(nodes)
  239. })
  240. }
  241. function fnGetUploadProps(options) {
  242. const self = this.self
  243. const params = Object.assign({
  244. uploadUrl: '',
  245. uploadParams: {},
  246. viewUrl: '',
  247. default: 'https://dummyimage.com/500x500/EE82EE/fff.png',
  248. style: 'width:150px;height:150px;',
  249. width: 500,
  250. height: 500,
  251. beforeUpload: (file) => { fnBeforeUpload(self, file) },
  252. cropperKey: 0,
  253. cropperVisible: false
  254. }, options || {})
  255. params.default = `https://dummyimage.com/${params.width}x${params.height}/EE82EE/fff.png`
  256. return params
  257. }
  258. async function fnBeforeUpload(self) {
  259. const { view_url, form } = await fGet('/api/file/upload-credentials?type=form&file=image')
  260. self.uploadProps.viewUrl = view_url
  261. self.uploadProps.uploadUrl = form.upload_url
  262. self.uploadProps.uploadParams = form.fields
  263. return true
  264. }
  265. async function fnUpload() {
  266. const { view_url, form } = await fGet('/api/file/upload-credentials?type=form&file=image')
  267. this.self.uploadProps.viewUrl = view_url
  268. this.self.uploadProps.uploadUrl = form.upload_url
  269. this.self.uploadProps.uploadParams = form.fields
  270. this.self.uploadProps.cropperVisible = true
  271. }
  272. function fnCloseUploader() {
  273. this.self.uploadProps.cropperVisible = false
  274. }
  275. export function M(self) {
  276. this.self = self
  277. this.list = fnList
  278. this.filter = fnFilter
  279. this.reset = fnReset
  280. this.create = fnCreate
  281. this.edit = fnEdit
  282. this.delete = fnDelete
  283. this.save = fnSave
  284. this.update = fnUpdate
  285. this.multiSelect = fnMultiSelect
  286. this.getSelected = fnGetSelected
  287. this.batchOp = fnBatchOp
  288. this.loadAreaList = fnLoadAreaList
  289. this.getUploadProps = fnGetUploadProps
  290. this.upload = fnUpload
  291. this.beforeUpload = fnBeforeUpload
  292. this.closeUploader = fnCloseUploader
  293. }
  294. // --- 以下为工具类
  295. // 加载远程下拉列表
  296. export function fRemoteMethod(obj, key, render) {
  297. const params = obj.query || {}
  298. const renderRow = render || obj.render || ((v) => v)
  299. params[obj.key || 'key'] = key
  300. obj.loading = true
  301. fGet(obj.url, params).then(res => {
  302. const data = res.data || res
  303. const fields = obj.fields || []
  304. obj.options = data.map(v => {
  305. const node = {
  306. label: v[obj.labelField || 'label'] || v['name'],
  307. value: v[obj.valueField || 'value'] || v['id']
  308. }
  309. fields.forEach(field => {
  310. node[field] = v[field]
  311. })
  312. return renderRow(node)
  313. })
  314. }).finally(() => {
  315. obj.loading = false
  316. })
  317. }