|
@@ -0,0 +1,312 @@
|
|
|
+function GoTo(url, isNewWindow) {
|
|
|
+ if (isNewWindow || isNewWindow === undefined) {
|
|
|
+ window.open(url)
|
|
|
+ } else {
|
|
|
+ window.location.href = url
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+function IwbAjax(opt) {
|
|
|
+ opt = opt || {}
|
|
|
+ if (!opt.url) {
|
|
|
+ alert('请传入url')
|
|
|
+ }
|
|
|
+ if (opt.method === undefined) {
|
|
|
+ opt.method = 'POST'
|
|
|
+ }
|
|
|
+ if (opt.data === undefined) {
|
|
|
+ opt.data = {}
|
|
|
+ }
|
|
|
+ opt = $.extend(
|
|
|
+ {},
|
|
|
+ {
|
|
|
+ isAlert: true,
|
|
|
+ },
|
|
|
+ opt
|
|
|
+ )
|
|
|
+ fetch(opt.url, {
|
|
|
+ method: opt.method,
|
|
|
+ headers: {
|
|
|
+ 'Content-Type': 'application/json',
|
|
|
+ },
|
|
|
+ body: JSON.stringify(opt.data),
|
|
|
+ })
|
|
|
+ .then((response) => response.json())
|
|
|
+ .then((data) => {
|
|
|
+ if (data.success) {
|
|
|
+ if (opt.isAlert) {
|
|
|
+ alert('操作成功')
|
|
|
+ }
|
|
|
+ if (opt.table) {
|
|
|
+ IwbTable($(opt.table))
|
|
|
+ }
|
|
|
+ if (opt.modal) {
|
|
|
+ $(opt.modal).modal('hide')
|
|
|
+ }
|
|
|
+ opt.success && opt.success(data)
|
|
|
+ } else {
|
|
|
+ console.error(opt.url, data.message)
|
|
|
+ if ((opt.isAlert && opt.isAlertError === undefined) || opt.isAlertError) {
|
|
|
+ alert(data.message)
|
|
|
+ }
|
|
|
+ }
|
|
|
+ })
|
|
|
+}
|
|
|
+
|
|
|
+function IwbAjax_1(opt) {
|
|
|
+ opt.isAlert = false
|
|
|
+ opt.isAlertError = true
|
|
|
+ IwbAjax(opt)
|
|
|
+}
|
|
|
+function IwbAjax_2(opt, modal, table) {
|
|
|
+ opt.modal = modal || '#modal'
|
|
|
+ opt.table = table || '#table'
|
|
|
+ IwbAjax(opt)
|
|
|
+}
|
|
|
+function IwbTable(table, opts) {
|
|
|
+ const $table = $(table)
|
|
|
+ const $tableBox = $table.closest('.table-box')
|
|
|
+ if (table.length === 0) return
|
|
|
+ const options = $table.data('options')
|
|
|
+ const defaultOptions = {
|
|
|
+ pageSize: 15,
|
|
|
+ pageNum: 1,
|
|
|
+ search: {
|
|
|
+ keyword: '',
|
|
|
+ },
|
|
|
+ }
|
|
|
+ const tableOptions = $.extend({}, options || defaultOptions, opts || {})
|
|
|
+ let isSearch = false
|
|
|
+ function ajaxTable(opt) {
|
|
|
+ if (isSearch) {
|
|
|
+ return
|
|
|
+ }
|
|
|
+ $table.data('options', opt)
|
|
|
+ loading()
|
|
|
+ const data = $.extend({}, opt.search, { pageNum: opt.pageNum, pageSize: opt.pageSize })
|
|
|
+ fetch(opt.url, {
|
|
|
+ method: 'POST',
|
|
|
+ headers: {
|
|
|
+ 'Content-Type': 'application/json',
|
|
|
+ },
|
|
|
+ body: JSON.stringify(data),
|
|
|
+ })
|
|
|
+ .then((response) => response.json())
|
|
|
+ .then((res) => {
|
|
|
+ if (res.success) {
|
|
|
+ renderTable(res.data.rows, res.data.total)
|
|
|
+ } else {
|
|
|
+ renderTable([], 0)
|
|
|
+ console.error('加载表格出错:', res.message, opt.url)
|
|
|
+ }
|
|
|
+ })
|
|
|
+ .catch((error) => {
|
|
|
+ console.error(error)
|
|
|
+ })
|
|
|
+ .finally(() => {
|
|
|
+ clearLoading()
|
|
|
+ })
|
|
|
+ }
|
|
|
+ function loading() {
|
|
|
+ isSearch = true
|
|
|
+ $tableBox.append(`<div class="table-loading"><span>正在加载中...</span></div>`)
|
|
|
+ }
|
|
|
+ function clearLoading() {
|
|
|
+ isSearch = false
|
|
|
+ $tableBox.find('.table-loading').remove()
|
|
|
+ }
|
|
|
+ function renderTable(rows, total) {
|
|
|
+ const opt = $table.data('options')
|
|
|
+ let head_str = '',
|
|
|
+ body_str = ''
|
|
|
+ for (let i = 0; i < opt.columns.length; i++) {
|
|
|
+ const col = opt.columns[i]
|
|
|
+ head_str += `<th style="${col.width ? `width: ${col.width};` : ``}${col.style ? `${col.style};` : ``}">${col.title}</th>`
|
|
|
+ }
|
|
|
+ if (rows && rows.length) {
|
|
|
+ for (let i = 0; i < rows.length; i++) {
|
|
|
+ const row = rows[i]
|
|
|
+ body_str += '<tr>'
|
|
|
+ for (let j = 0; j < opt.columns.length; j++) {
|
|
|
+ const col = opt.columns[j]
|
|
|
+ if (col.render) {
|
|
|
+ body_str += `<td>${col.render(row, rows)}</td>`
|
|
|
+ } else {
|
|
|
+ body_str += `<td>${row[col.data] || '-'}</td>`
|
|
|
+ }
|
|
|
+ }
|
|
|
+ body_str += '</tr>'
|
|
|
+ }
|
|
|
+ } else {
|
|
|
+ body_str += '<tr><td colspan="' + opt.columns.length + '" class="text-center">暂无数据</td></tr>'
|
|
|
+ }
|
|
|
+ $tableBox.fadeOut(300, () => {
|
|
|
+ let page_str = formatPage(opt.pageNum, opt.pageSize, total)
|
|
|
+ $table.parent().find('.pagination-row').html(page_str)
|
|
|
+ $table.html(`<thead><tr>${head_str}</tr></thead><tbody>${body_str}</tbody>`)
|
|
|
+ $tableBox.fadeIn(500)
|
|
|
+ })
|
|
|
+ }
|
|
|
+
|
|
|
+ function formatPage(pageNum, pageSize, total) {
|
|
|
+ const totalPages = Math.ceil(total / pageSize)
|
|
|
+ // const startIndex = (pageNum - 1) * pageSize + 1
|
|
|
+ // const endIndex = Math.min(pageNum * pageSize, total)
|
|
|
+
|
|
|
+ let str = '<div class=" d-flex align-items-center justify-content-center justify-content-md-start dt-toolbar">'
|
|
|
+ // 每页显示条数选择
|
|
|
+ str += `<div><select class="form-select form-select-solid form-select-sm" onchange="IwbTableChangePageSize(this)">`
|
|
|
+ ;[15, 25, 50, 100].forEach((size) => {
|
|
|
+ str += `<option value="${size}" ${pageSize === size ? ' selected' : ''}>${size}</option>`
|
|
|
+ })
|
|
|
+ str += '</select></div>'
|
|
|
+
|
|
|
+ // 显示记录信息
|
|
|
+ str += `<div class="dt-info">当前第 ${pageNum}/${totalPages} 页 共 ${total} 条</div></div>`
|
|
|
+
|
|
|
+ // 分页导航
|
|
|
+ str += '<div class="d-flex align-items-center justify-content-center justify-content-md-end"><div class="dt-paging paging_simple_numbers"><nav aria-label="pagination"><ul class="pagination">'
|
|
|
+
|
|
|
+ // 上一页按钮
|
|
|
+ if (pageNum > 1) {
|
|
|
+ str += '<li class="dt-paging-button page-item"><button class="page-link previous" onclick="IwbTableJumpPage(this,' + (pageNum - 1) + ')"><i class="previous"></i></button></li>'
|
|
|
+ } else {
|
|
|
+ str += '<li class="dt-paging-button page-item disabled"><button class="page-link previous"><i class="previous"></i></button></li>'
|
|
|
+ }
|
|
|
+
|
|
|
+ // 计算显示的页码范围
|
|
|
+ let startPage = Math.max(1, pageNum - 2)
|
|
|
+ let endPage = Math.min(totalPages, pageNum + 2)
|
|
|
+
|
|
|
+ // 显示第一页和省略号
|
|
|
+ if (startPage > 1) {
|
|
|
+ str += '<li class="dt-paging-button page-item"><button class="page-link" onclick="IwbTableJumpPage(this,1)">1</button></li>'
|
|
|
+ if (startPage > 2) {
|
|
|
+ str += '<li class="dt-paging-button page-item disabled"><button class="page-link ellipsis" tabindex="-1">…</button></li>'
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ // 显示页码
|
|
|
+ for (let i = startPage; i <= endPage; i++) {
|
|
|
+ if (i === pageNum) {
|
|
|
+ str += `<li class="dt-paging-button page-item active"><button class="page-link" onclick="IwbTableJumpPage(this,${i})">${i}</button></li>`
|
|
|
+ } else {
|
|
|
+ str += `<li class="dt-paging-button page-item"><button class="page-link" onclick="IwbTableJumpPage(this,${i})">${i}</button></li>`
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ // 显示最后一页和省略号
|
|
|
+ if (endPage < totalPages) {
|
|
|
+ if (endPage < totalPages - 1) {
|
|
|
+ str += '<li class="dt-paging-button page-item disabled"><button class="page-link ellipsis" tabindex="-1">…</button></li>'
|
|
|
+ }
|
|
|
+ str += `<li class="dt-paging-button page-item"><button class="page-link" onclick="IwbTableJumpPage(this,${totalPages})">${totalPages}</button></li>`
|
|
|
+ }
|
|
|
+
|
|
|
+ // 下一页按钮
|
|
|
+ if (pageNum < totalPages) {
|
|
|
+ str += '<li class="dt-paging-button page-item"><button class="page-link next" onclick="IwbTableJumpPage(this,' + (pageNum + 1) + ')"><i class="next"></i></button></li>'
|
|
|
+ } else {
|
|
|
+ str += '<li class="dt-paging-button page-item disabled"><button class="page-link next"><i class="next"></i></button></li>'
|
|
|
+ }
|
|
|
+
|
|
|
+ str += '</ul></nav></div></div>'
|
|
|
+ return str
|
|
|
+ }
|
|
|
+ ajaxTable(tableOptions)
|
|
|
+}
|
|
|
+function IwbTableSearch(that) {
|
|
|
+ const $search = $(that).closest('form.search-box')
|
|
|
+ const $table = $(that).closest('.table-box').find('.table')
|
|
|
+ const search = $table.data('options').search || {}
|
|
|
+ $search.find('.form-control,.form-select').each((i, el) => {
|
|
|
+ const v = $(el).val()
|
|
|
+ if (v.trim() !== '') {
|
|
|
+ search[$(el).attr('name')] = v
|
|
|
+ } else {
|
|
|
+ delete search[$(el).attr('name')]
|
|
|
+ }
|
|
|
+ })
|
|
|
+ IwbTable($table, { search: search, pageNum: 1 })
|
|
|
+}
|
|
|
+function IwbTableResetSearch(that) {
|
|
|
+ const $search = $(that).closest('form.search-box')
|
|
|
+ $search[0].reset()
|
|
|
+ IwbTableSearch(that)
|
|
|
+}
|
|
|
+function IwbTableJumpPage(that, pageNum) {
|
|
|
+ const $table = $(that).closest('.table-box').find('.table')
|
|
|
+ IwbTable($table, { pageNum: pageNum })
|
|
|
+}
|
|
|
+function IwbTableChangePageSize(that) {
|
|
|
+ const $table = $(that).closest('.table-box').find('.table')
|
|
|
+ const pageSize = parseInt($(that).val())
|
|
|
+ IwbTable($table, { pageSize: pageSize })
|
|
|
+}
|
|
|
+
|
|
|
+function AddModal(modal, callback) {
|
|
|
+ const $modal = $(modal)
|
|
|
+ $modal.find('.modal-header .modal-title span.prefix').html('添加')
|
|
|
+ $modal.find('.modal-body .form-control').val('')
|
|
|
+ callback && callback($modal)
|
|
|
+ $modal.modal('show')
|
|
|
+}
|
|
|
+function EditModal(modal, callback) {
|
|
|
+ const $modal = $(modal)
|
|
|
+ $modal.find('.modal-header .modal-title span.prefix').html('修改')
|
|
|
+ callback && callback($modal)
|
|
|
+ $modal.modal('show')
|
|
|
+}
|
|
|
+
|
|
|
+function Confirm(title, callback) {
|
|
|
+ if (confirm(title)) {
|
|
|
+ callback && callback()
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+function ConfirmUrl(title, url, table) {
|
|
|
+ if (confirm(title)) {
|
|
|
+ IwbAjax({
|
|
|
+ url: url,
|
|
|
+ table: table || '#table',
|
|
|
+ })
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+function ChangeHeadMenu(menu) {
|
|
|
+ $('#header_menu .menu-item').removeClass('here')
|
|
|
+ $('#header_menu ' + menu).addClass('here')
|
|
|
+}
|
|
|
+
|
|
|
+function DownloadFile(url, fileName) {
|
|
|
+ fetch(url)
|
|
|
+ .then((response) => {
|
|
|
+ if (!response.ok) {
|
|
|
+ return response.json().then((err) => {
|
|
|
+ throw new Error(err.message || '下载失败')
|
|
|
+ })
|
|
|
+ }
|
|
|
+ return response.blob()
|
|
|
+ })
|
|
|
+ .then((blob) => {
|
|
|
+ const downloadUrl = window.URL.createObjectURL(blob)
|
|
|
+ const a = document.createElement('a')
|
|
|
+ a.href = downloadUrl
|
|
|
+ a.download = fileName
|
|
|
+ document.body.appendChild(a)
|
|
|
+ a.click()
|
|
|
+ window.URL.revokeObjectURL(downloadUrl)
|
|
|
+ document.body.removeChild(a)
|
|
|
+ })
|
|
|
+ .catch((error) => {
|
|
|
+ alert(error.message)
|
|
|
+ })
|
|
|
+}
|
|
|
+
|
|
|
+// 添加字符串序列化方法
|
|
|
+String.prototype.format = function () {
|
|
|
+ let args = arguments
|
|
|
+ return this.replace(/{(\d+)}/g, function (match, index) {
|
|
|
+ return typeof args[index] != 'undefined' ? args[index] : match
|
|
|
+ })
|
|
|
+}
|