feat(all): 初始化版本
This commit is contained in:
330
leopard-web/src/util/amis.tsx
Normal file
330
leopard-web/src/util/amis.tsx
Normal file
@@ -0,0 +1,330 @@
|
||||
import {AlertComponent, attachmentAdpator, makeTranslator, render, type Schema, ToastComponent} from 'amis'
|
||||
|
||||
import 'amis/lib/themes/antd.css'
|
||||
import 'amis/lib/helper.css'
|
||||
import 'amis/sdk/iconfont.css'
|
||||
import '@fortawesome/fontawesome-free/css/all.min.css'
|
||||
import axios from 'axios'
|
||||
import {isEqual} from 'licia'
|
||||
|
||||
export const commonInfo = {
|
||||
debug: isEqual(import.meta.env.MODE, 'development'),
|
||||
baseUrl: 'http://localhost:9786',
|
||||
}
|
||||
|
||||
const __ = makeTranslator('zh')
|
||||
|
||||
const responseAdaptor = () => (response: any) => {
|
||||
let payload = response.data || {} // blob 下可能会返回内容为空?
|
||||
if (payload.hasOwnProperty('errno')) {
|
||||
payload.status = payload.errno
|
||||
payload.msg = payload.errmsg
|
||||
} else if (payload.hasOwnProperty('no')) {
|
||||
payload.status = payload.no
|
||||
payload.msg = payload.error
|
||||
}
|
||||
return {
|
||||
...response,
|
||||
data: payload,
|
||||
}
|
||||
}
|
||||
|
||||
export const amisRender = (schema: Schema, data: Record<any, any> = {}) => {
|
||||
const theme = 'antd'
|
||||
const locale = 'zh-CN'
|
||||
return (
|
||||
<>
|
||||
<ToastComponent
|
||||
theme={theme}
|
||||
key="toast"
|
||||
position={'top-right'}
|
||||
locale={locale}
|
||||
/>
|
||||
<AlertComponent theme={theme} key="alert" locale={locale}/>
|
||||
{render(
|
||||
schema,
|
||||
{
|
||||
data: {
|
||||
...commonInfo,
|
||||
...data,
|
||||
},
|
||||
theme: theme,
|
||||
},
|
||||
{
|
||||
enableAMISDebug: commonInfo.debug,
|
||||
fetcher: async (api: any) => {
|
||||
let {url, method, data, responseType, config, headers} = api
|
||||
config = config || {}
|
||||
config.url = url
|
||||
config.withCredentials = true
|
||||
responseType && (config.responseType = responseType)
|
||||
|
||||
if (config.cancelExecutor) {
|
||||
config.cancelToken = new (axios as any).CancelToken(
|
||||
config.cancelExecutor,
|
||||
)
|
||||
}
|
||||
|
||||
config.headers = headers || {}
|
||||
config.method = method
|
||||
config.data = data
|
||||
|
||||
if (method === 'get' && data) {
|
||||
config.params = data
|
||||
} else if (data && data instanceof FormData) {
|
||||
// config.headers['Content-Type'] = 'multipart/form-data';
|
||||
} else if (
|
||||
data &&
|
||||
typeof data !== 'string' &&
|
||||
!(data instanceof Blob) &&
|
||||
!(data instanceof ArrayBuffer)
|
||||
) {
|
||||
data = JSON.stringify(data)
|
||||
config.headers['Content-Type'] = 'application/json'
|
||||
}
|
||||
|
||||
// 支持返回各种报错信息
|
||||
config.validateStatus = function () {
|
||||
return true
|
||||
}
|
||||
|
||||
let response = await axios(config)
|
||||
response = await attachmentAdpator(response, __, api)
|
||||
response = responseAdaptor()(response)
|
||||
|
||||
if (response.status >= 400) {
|
||||
if (response.data) {
|
||||
// 主要用于 raw: 模式下,后端自己校验登录,
|
||||
if (
|
||||
response.status === 401 &&
|
||||
response.data.location &&
|
||||
response.data.location.startsWith('http')
|
||||
) {
|
||||
location.href = response.data.location.replace(
|
||||
'{{redirect}}',
|
||||
encodeURIComponent(location.href),
|
||||
)
|
||||
return new Promise(() => {
|
||||
})
|
||||
} else if (response.data.msg) {
|
||||
throw new Error(response.data.msg)
|
||||
} else {
|
||||
throw new Error(
|
||||
'System.requestError' + JSON.stringify(response.data, null, 2),
|
||||
)
|
||||
}
|
||||
} else {
|
||||
throw new Error(
|
||||
`${'System.requestErrorStatus'} ${response.status}`,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
return response
|
||||
},
|
||||
isCancel: (value: any) => (axios as any).isCancel(value),
|
||||
},
|
||||
)}
|
||||
</>
|
||||
)
|
||||
}
|
||||
|
||||
export function horizontalFormOptions() {
|
||||
return {
|
||||
mode: 'horizontal',
|
||||
horizontal: {
|
||||
leftFixed: 'sm',
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
export function crudCommonOptions() {
|
||||
return {
|
||||
affixHeader: false,
|
||||
stopAutoRefreshWhenModalIsOpen: true,
|
||||
resizable: false,
|
||||
syncLocation: false,
|
||||
silentPolling: true,
|
||||
columnsTogglable: false,
|
||||
}
|
||||
}
|
||||
|
||||
export function readOnlyDialogOptions() {
|
||||
return {
|
||||
actions: [],
|
||||
showCloseButton: false,
|
||||
closeOnEsc: true,
|
||||
closeOnOutside: true,
|
||||
disabled: true,
|
||||
}
|
||||
}
|
||||
|
||||
export function paginationCommonOptions(perPage = true, maxButtons = 5) {
|
||||
let option = {
|
||||
type: 'pagination',
|
||||
layout: [
|
||||
'pager',
|
||||
],
|
||||
maxButtons: maxButtons,
|
||||
showPageInput: false,
|
||||
perPageAvailable: [10, 15, 20, 50, 100, 200],
|
||||
}
|
||||
if (perPage) {
|
||||
option.layout.push('perPage')
|
||||
}
|
||||
return option
|
||||
}
|
||||
|
||||
export function paginationTemplate(perPage = 20, maxButtons = 5, extraHeaders: Array<Schema | string> = [], extraFooters: Array<Schema | string> = []) {
|
||||
return {
|
||||
perPage: perPage,
|
||||
headerToolbar: [
|
||||
'reload',
|
||||
paginationCommonOptions(true, maxButtons),
|
||||
...extraHeaders,
|
||||
],
|
||||
footerToolbar: [
|
||||
'statistics',
|
||||
paginationCommonOptions(true, maxButtons),
|
||||
...extraFooters,
|
||||
],
|
||||
}
|
||||
}
|
||||
|
||||
export function copyField(field: string, tips = '复制', ignoreLength = 0) {
|
||||
let tpl = ignoreLength === 0 ? `\${${field}}` : `\${TRUNCATE(${field}, ${ignoreLength})}`
|
||||
return {
|
||||
type: 'wrapper',
|
||||
size: 'none',
|
||||
body: [
|
||||
{
|
||||
type: 'tpl',
|
||||
className: 'mr-1',
|
||||
tpl: tpl,
|
||||
},
|
||||
{
|
||||
type: 'action',
|
||||
level: 'link',
|
||||
label: '',
|
||||
icon: 'fa fa-copy',
|
||||
size: 'xs',
|
||||
actionType: 'copy',
|
||||
content: `\$${field}`,
|
||||
tooltip: `${tips}`,
|
||||
},
|
||||
],
|
||||
}
|
||||
}
|
||||
|
||||
export function mappingItem(label: string, value: string, color = 'bg-info') {
|
||||
return {
|
||||
label: label,
|
||||
value: value,
|
||||
color: color,
|
||||
}
|
||||
}
|
||||
|
||||
export function mappingField(field: string, mapping: Array<Record<string, string>>) {
|
||||
let mapData: Record<string, string> = {
|
||||
'*': `<span class='label bg-gray-300'>\${${field}}</span>`,
|
||||
}
|
||||
mapping.forEach(item => {
|
||||
mapData[item['value']] = `<span class='label ${item['color']}'>${item['label']}</span>`
|
||||
})
|
||||
return {
|
||||
type: 'mapping',
|
||||
value: `\${${field}}`,
|
||||
map: mapData,
|
||||
}
|
||||
}
|
||||
|
||||
export function filterableField(mapping: Array<Record<string, any>>, multiple = false) {
|
||||
return {
|
||||
multiple: multiple,
|
||||
options: [
|
||||
...mapping,
|
||||
],
|
||||
}
|
||||
}
|
||||
|
||||
export function time(field: string) {
|
||||
return {
|
||||
type: 'tpl',
|
||||
tpl: `\${IF(${field}, DATETOSTR(${field}, 'YYYY-MM-DD HH:mm:ss'), undefined)}`,
|
||||
}
|
||||
}
|
||||
|
||||
export function pictureFromIds(field: string) {
|
||||
return `\${ARRAYMAP(${field},id => '${commonInfo.baseUrl}/upload/download/' + id)}`
|
||||
}
|
||||
|
||||
export const formInputFileStaticColumns = [
|
||||
{
|
||||
name: 'filename',
|
||||
label: '文件名',
|
||||
},
|
||||
{
|
||||
type: 'operation',
|
||||
label: '操作',
|
||||
width: 140,
|
||||
buttons: [
|
||||
{
|
||||
type: 'action',
|
||||
label: '预览',
|
||||
level: 'link',
|
||||
icon: 'fas fa-eye',
|
||||
},
|
||||
{
|
||||
type: 'action',
|
||||
label: '下载',
|
||||
level: 'link',
|
||||
icon: 'fa fa-download',
|
||||
actionType: 'ajax',
|
||||
// api: {
|
||||
// ...apiGet('${base}/upload/download/${id}'),
|
||||
// responseType: 'blob',
|
||||
// }
|
||||
},
|
||||
],
|
||||
},
|
||||
]
|
||||
|
||||
export function formInputSingleFileStatic(field: string, label: string) {
|
||||
return {
|
||||
visibleOn: '${static}',
|
||||
type: 'control',
|
||||
label: label,
|
||||
required: true,
|
||||
body: {
|
||||
type: 'table',
|
||||
source: `\${${field}|asArray}`,
|
||||
columns: formInputFileStaticColumns,
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
export function formInputMultiFileStatic(field: string, label: string) {
|
||||
return {
|
||||
visibleOn: '${static}',
|
||||
type: 'input-table',
|
||||
label: label,
|
||||
name: field,
|
||||
required: true,
|
||||
resizable: false,
|
||||
columns: formInputFileStaticColumns,
|
||||
}
|
||||
}
|
||||
|
||||
export function remoteOptions(type: string = 'select', name: string) {
|
||||
return {
|
||||
type: type,
|
||||
source: `get:${commonInfo.baseUrl}/constants/options/${name}`,
|
||||
}
|
||||
}
|
||||
|
||||
export function remoteMappings(name: string, field: string) {
|
||||
return {
|
||||
type: 'mapping',
|
||||
source: `get:${commonInfo.baseUrl}/constants/mappings/${name}/${field}`,
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user