op.js 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364
  1. import { fGet, fSave, fPut, fDelete, fSort } 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. console.log(opt.url)
  101. fDelete(url, opt.row).then(res => {
  102. this.list(opt.reload)
  103. alert('删除成功')
  104. })
  105. }).catch(() => {
  106. alert('删除失败')
  107. })
  108. }
  109. function fnSave(options) {
  110. const opt = Options(options, { form: 'form', data: {}, reload: 'main' })
  111. const thiz = this
  112. const self = this.self
  113. const formObj = self.dlg[opt.form] || {}
  114. function innerSave(data) {
  115. if (typeof opt.before === 'function') {
  116. const beforeResult = opt.before(data)
  117. if (typeof beforeResult === 'boolean' && !beforeResult) {
  118. return
  119. }
  120. }
  121. formObj.saveLoading = true
  122. const url = opt.url || self.URI
  123. fSave(url, data).then(res => {
  124. self.$message.success('保存成功')
  125. typeof opt.reload === 'string' && thiz.list(opt.reload)
  126. typeof opt.success === 'function' && opt.success(res)
  127. formObj.visible = false
  128. }).catch(err => {
  129. typeof opt.error === 'function' && opt.error(err)
  130. }).finally(() => {
  131. formObj.saveLoading = false
  132. })
  133. }
  134. if (typeof opt.form === 'string' && opt.form.length > 0) {
  135. if (formObj.data === undefined) {
  136. const err = `form ${opt.form} data not exist.`
  137. self.$message.error(err)
  138. typeof opt.error === 'function' && opt.error(err)
  139. return
  140. }
  141. const formRef = self.$refs[opt.form]
  142. if (formRef === undefined || formRef.validate === undefined) {
  143. const err = `form ${opt.form} element not exist.`
  144. self.$message.error(err)
  145. typeof opt.error === 'function' && opt.error(err)
  146. return
  147. }
  148. formRef.validate((valid) => {
  149. if (valid) {
  150. const otherData = opt.data || {}
  151. const params = { ...formObj.data, ...otherData }
  152. // deal area parameter
  153. if (hasArea(formObj) && formObj.area.length > 2) {
  154. params.province_id = formObj.area[0]
  155. params.city_id = formObj.area[1]
  156. params.area_id = formObj.area[2]
  157. }
  158. innerSave(params)
  159. }
  160. })
  161. } else {
  162. const params = opt.data || {}
  163. innerSave(params)
  164. }
  165. }
  166. function fnUpdate(options) {
  167. const opt = Options(options, { row: {}, data: {}})
  168. const params = { ...opt.row, ...opt.data }
  169. const url = opt.url || this.self.URI
  170. fSave(url, params).then(res => {
  171. typeof opt.success === 'function' ? opt.success(res) : this.list(opt.reload)
  172. })
  173. }
  174. function fnMultiSelect(options) {
  175. const opt = options || {}
  176. const listObj = this.self.list[opt.list || 'main']
  177. if (listObj === undefined) {
  178. return
  179. }
  180. listObj.selectedRows = opt.rows || []
  181. }
  182. function fnSort(options) {
  183. const opt = Options(options, { form: 'form', title: '排序' })
  184. fSort(opt.url, opt.data).then(res => {
  185. this.list(opt.reload)
  186. }).catch(() => {})
  187. }
  188. // 批量操作
  189. function fnBatchOp(options) {
  190. const opt = Options(options, { params: {}})
  191. const list = opt.list || 'main'
  192. const listObj = this.self.list[list]
  193. if (listObj === undefined) {
  194. return
  195. }
  196. const selectedRows = listObj.selectedRows || []
  197. const ids = selectedRows.map(v => {
  198. return v.id
  199. })
  200. if (ids.length === 0) {
  201. this.self.$message.error('请先选择要操作的记录')
  202. return
  203. }
  204. const op = opt.op || '操作'
  205. this.self.$confirm(`您是否确认对选择的${ids.length}个记录进行${op}`, '提示').then(() => {
  206. const url = opt.url || listObj.url || this.self.URI
  207. const params = { ...opt.params }
  208. if (typeof opt.ids !== 'boolean' || !opt.ids) {
  209. params.ids = ids
  210. }
  211. fPut(url, params).then(res => {
  212. if (typeof opt.success === 'function') {
  213. opt.success(res)
  214. } else {
  215. this.self.$message.success('操作成功')
  216. const reload = opt.reload || list
  217. this.list({ list: reload })
  218. }
  219. })
  220. })
  221. }
  222. function fnGetSelected(options) {
  223. const opt = Options(options, {})
  224. const list = opt.list || 'main'
  225. const listObj = this.self.list[list]
  226. if (listObj === undefined) {
  227. return []
  228. }
  229. const selectedRows = listObj.selectedRows || []
  230. if (typeof opt.render === 'function') {
  231. return selectedRows.map(v => {
  232. return opt.render(v)
  233. })
  234. }
  235. return selectedRows
  236. }
  237. function fnLoadAreaList(node, resolve) {
  238. const { level, value } = node
  239. fGet('/manager/areas', { pid: level === 0 ? 1 : value }).then(res => {
  240. const { data } = res
  241. const nodes = data.map(v => {
  242. return {
  243. value: v.id,
  244. label: v.name,
  245. leaf: level + 1 >= 3
  246. }
  247. })
  248. resolve(nodes)
  249. })
  250. }
  251. function fnGetUploadProps(options) {
  252. const self = this.self
  253. const params = Object.assign({
  254. uploadUrl: '',
  255. uploadParams: {},
  256. viewUrl: '',
  257. default: 'https://dummyimage.com/500x500/EE82EE/fff.png',
  258. style: 'width:150px;height:150px;',
  259. width: 500,
  260. height: 500,
  261. beforeUpload: (file) => { fnBeforeUpload(self, file) },
  262. cropperKey: 0,
  263. cropperVisible: false
  264. }, options || {})
  265. params.default = `https://dummyimage.com/${params.width}x${params.height}/EE82EE/fff.png`
  266. return params
  267. }
  268. async function fnBeforeUpload(self) {
  269. const { view_url, form } = await fGet('/api/file/upload-credentials?type=form&file=image')
  270. self.uploadProps.viewUrl = view_url
  271. self.uploadProps.uploadUrl = form.upload_url
  272. self.uploadProps.uploadParams = form.fields
  273. return true
  274. }
  275. async function fnUpload() {
  276. const { view_url, form } = await fGet('/api/file/upload-credentials?type=form&file=image')
  277. this.self.uploadProps.viewUrl = view_url
  278. this.self.uploadProps.uploadUrl = form.upload_url
  279. this.self.uploadProps.uploadParams = form.fields
  280. this.self.uploadProps.cropperVisible = true
  281. }
  282. function fnCloseUploader() {
  283. this.self.uploadProps.cropperVisible = false
  284. }
  285. export function M(self) {
  286. this.self = self
  287. this.list = fnList
  288. this.filter = fnFilter
  289. this.reset = fnReset
  290. this.create = fnCreate
  291. this.edit = fnEdit
  292. this.delete = fnDelete
  293. this.save = fnSave
  294. this.update = fnUpdate
  295. this.multiSelect = fnMultiSelect
  296. this.getSelected = fnGetSelected
  297. this.batchOp = fnBatchOp
  298. this.loadAreaList = fnLoadAreaList
  299. this.getUploadProps = fnGetUploadProps
  300. this.upload = fnUpload
  301. this.beforeUpload = fnBeforeUpload
  302. this.closeUploader = fnCloseUploader
  303. this.sort = fnSort
  304. }
  305. // --- 以下为工具类
  306. // 加载远程下拉列表
  307. export function fRemoteMethod(obj, key, render) {
  308. const params = obj.query || {}
  309. const renderRow = render || obj.render || ((v) => v)
  310. params[obj.key || 'key'] = key
  311. obj.loading = true
  312. fGet(obj.url, params).then(res => {
  313. const data = res.data || res
  314. const fields = obj.fields || []
  315. obj.options = data.map(v => {
  316. const node = {
  317. label: v[obj.labelField || 'label'] || v['name'],
  318. value: v[obj.valueField || 'value'] || v['id']
  319. }
  320. fields.forEach(field => {
  321. node[field] = v[field]
  322. })
  323. return renderRow(node)
  324. })
  325. }).finally(() => {
  326. obj.loading = false
  327. })
  328. }