@yorha2b-lab/autodev 1.0.21 → 1.0.23
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/package.json
CHANGED
|
@@ -38,6 +38,7 @@ const watchPage = options => {
|
|
|
38
38
|
try {
|
|
39
39
|
// 首次运行时复制 hooks 和 components 模板到目标项目
|
|
40
40
|
copyTemplateDir(options, 'hooks', config.hooksDir)
|
|
41
|
+
copyTemplateDir(options, 'utils', config.utilsDir)
|
|
41
42
|
copyTemplateDir(options, 'components', config.componentsDir)
|
|
42
43
|
} catch (error) {
|
|
43
44
|
console.error('❌ 程序运行出错:', error)
|
|
@@ -1,4 +1,67 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { initOSS } from '../utils/utils'
|
|
2
|
+
import { useState, useEffect } from 'react'
|
|
3
|
+
import { UploadOutlined } from '@ant-design/icons'
|
|
4
|
+
import { Button, Tree, Radio, Input, Upload, Select, Cascader, Checkbox, DatePicker, InputNumber, TreeSelect, AutoComplete } from 'antd'
|
|
5
|
+
|
|
6
|
+
const AliyunOSSUpload = ({ style, value, disabled, onChange }) => {
|
|
7
|
+
|
|
8
|
+
const [OSSData, setOSSData] = useState()
|
|
9
|
+
|
|
10
|
+
const init = async () => {
|
|
11
|
+
try {
|
|
12
|
+
const result = await initOss()
|
|
13
|
+
setOSSData(result)
|
|
14
|
+
} catch (err) {
|
|
15
|
+
console.log(err)
|
|
16
|
+
}
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
useEffect(() => {
|
|
20
|
+
init()
|
|
21
|
+
}, [])
|
|
22
|
+
|
|
23
|
+
const handleChange = ({ fileList }) => onChange?.([...fileList])
|
|
24
|
+
|
|
25
|
+
const onRemove = file => {
|
|
26
|
+
const files = (value || []).filter(v => v.url !== file.url)
|
|
27
|
+
onChange?.(files)
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
const getExtraData = file => ({
|
|
31
|
+
key: file.url,
|
|
32
|
+
policy: OSSData?.policy,
|
|
33
|
+
Signature: OSSData?.signature,
|
|
34
|
+
OSSAccessKeyId: OSSData?.accessId,
|
|
35
|
+
})
|
|
36
|
+
|
|
37
|
+
const beforeUpload = async file => {
|
|
38
|
+
if (!OSSData) {
|
|
39
|
+
return false
|
|
40
|
+
}
|
|
41
|
+
const expire = Number(OSSData.expire) * 1000
|
|
42
|
+
if (expire < Date.now()) {
|
|
43
|
+
await init()
|
|
44
|
+
}
|
|
45
|
+
file.url = `${OSSData.dir}/${file.name}`.replace(/\/\//g, '/')
|
|
46
|
+
return file
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
const uploadProps = {
|
|
50
|
+
onRemove,
|
|
51
|
+
name: 'file',
|
|
52
|
+
beforeUpload,
|
|
53
|
+
fileList: value,
|
|
54
|
+
data: getExtraData,
|
|
55
|
+
action: OSSData?.host,
|
|
56
|
+
onChange: handleChange,
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
return (
|
|
60
|
+
<Upload {...uploadProps} disabled={disabled} style={style}>
|
|
61
|
+
<Button icon={<UploadOutlined />}>选择文件</Button>
|
|
62
|
+
</Upload>
|
|
63
|
+
)
|
|
64
|
+
}
|
|
2
65
|
|
|
3
66
|
export const formNode = ({ item }) => {
|
|
4
67
|
|
|
@@ -14,6 +77,8 @@ export const formNode = ({ item }) => {
|
|
|
14
77
|
return <DatePicker {...commonProps} />
|
|
15
78
|
case 'number':
|
|
16
79
|
return <InputNumber {...commonProps} />
|
|
80
|
+
case 'ossUpload':
|
|
81
|
+
return <AliyunOSSUpload {...commonProps} />
|
|
17
82
|
case 'daterange':
|
|
18
83
|
return <DatePicker.RangePicker {...commonProps} />
|
|
19
84
|
case 'radio':
|
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
import dayjs from 'dayjs'
|
|
2
|
+
import { request } from './request'
|
|
3
|
+
|
|
4
|
+
export const paramsFormat = params => {
|
|
5
|
+
const cleanParams = Object.fromEntries(Object.entries(params).filter(([_, v]) => ![null, undefined, ''].includes(v)))
|
|
6
|
+
return new URLSearchParams(cleanParams).toString()
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
export const formatValue = ({ item, ind }) => {
|
|
10
|
+
if (dayjs.isDayjs(item[1])) {
|
|
11
|
+
return item[1].startOf('day').valueOf()
|
|
12
|
+
}
|
|
13
|
+
if (dayjs.isDayjs(item[1]?.[ind])) {
|
|
14
|
+
return ind === 0 ? item[1]?.[ind]?.startOf('day').valueOf() : item[1]?.[ind]?.endOf('day').valueOf()
|
|
15
|
+
}
|
|
16
|
+
return item[1]?.toString()?.trim() ?? undefined
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
export const initOSS = async (url, options) => {
|
|
20
|
+
const OSS = require('ali-oss')
|
|
21
|
+
const crypto = require('crypto-js')
|
|
22
|
+
const response = await request(url, options)
|
|
23
|
+
const { bucket, endpoint, stsToken, expiration, accessKeyId, accessKeySecret } = response?.data || {}
|
|
24
|
+
const client = new OSS({ bucket, endpoint, stsToken, accessKeyId, accessKeySecret })
|
|
25
|
+
const policy = btoa(JSON.stringify({
|
|
26
|
+
expiration,
|
|
27
|
+
conditions: [
|
|
28
|
+
["content-length-range", 0, 1024 * 1024 * 1024],
|
|
29
|
+
],
|
|
30
|
+
}))
|
|
31
|
+
const signature = crypto.enc.Base64.stringify(crypto.HmacSHA1(policy, accessKeySecret))
|
|
32
|
+
return { client, policy, signature, ...response?.data }
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
export const timeRender = ({ time, date, minute }) => {
|
|
36
|
+
if (!time) {
|
|
37
|
+
return ''
|
|
38
|
+
} else {
|
|
39
|
+
if (date) {
|
|
40
|
+
return dayjs(time).format('YYYY-MM-DD')
|
|
41
|
+
}
|
|
42
|
+
if (minute) {
|
|
43
|
+
return dayjs(time).format('YYYY-MM-DD HH:mm')
|
|
44
|
+
}
|
|
45
|
+
return dayjs(time).format('YYYY-MM-DD HH:mm:ss')
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
export const moneyRender = (value, { decimals = 2, showSymbol = true } = {}) => {
|
|
50
|
+
if (value === null || value === undefined || value === '') return '-'
|
|
51
|
+
const number = Number(value)
|
|
52
|
+
if (isNaN(number)) return '-'
|
|
53
|
+
const options = showSymbol
|
|
54
|
+
? { style: 'currency', currency: 'CNY', minimumFractionDigits: decimals }
|
|
55
|
+
: { style: 'decimal', minimumFractionDigits: decimals, maximumFractionDigits: decimals }
|
|
56
|
+
return new Intl.NumberFormat('zh-CN', options).format(number)
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
export const exportDataToExcel = async (url, options, columns, fileName, resultKey = 'data') => {
|
|
60
|
+
const response = await request(url, options)
|
|
61
|
+
if (response?.[resultKey]?.length > 0) {
|
|
62
|
+
const XLSX = require('xlsx')
|
|
63
|
+
const datas = response?.[resultKey]?.map(item => Object.fromEntries(columns.map(col => [col.title, col.render ? col.render(item[col.dataIndex])?.props?.children ?? col.render(item[col.dataIndex]) : item[col.dataIndex]])))
|
|
64
|
+
const workbook = XLSX.utils.book_new()
|
|
65
|
+
const header = columns.map(item => item.title)
|
|
66
|
+
const worksheet = XLSX.utils.json_to_sheet(datas, { header })
|
|
67
|
+
worksheet['!cols'] = Array.from(new Array(header.length)).fill({ wpx: 120 })
|
|
68
|
+
XLSX.utils.book_append_sheet(workbook, worksheet, 'Sheet1')
|
|
69
|
+
XLSX.writeFile(workbook, `${fileName}.xlsx`)
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
export const formatUnit = (value, { k = 1024, units = ['B', 'KB', 'MB', 'GB', 'TB', 'PB', 'EB'], decimals = 2 } = {}) => {
|
|
74
|
+
if (value === null || value === undefined || isNaN(value) || value === 0) {
|
|
75
|
+
return `0 ${units[0] ?? ''}`
|
|
76
|
+
}
|
|
77
|
+
const i = Math.floor(Math.log(value) / Math.log(k))
|
|
78
|
+
const index = Math.min(i, units.length - 1)
|
|
79
|
+
const result = (value / Math.pow(k, index)).toFixed(decimals)
|
|
80
|
+
return `${parseFloat(result)} ${units[index]}`
|
|
81
|
+
}
|