# 数据格式化
# JSON数据格式化
const todayILearn = {
_id: 1,
content: '今天学习 JSON.stringify(),我很开心!',
created_at: 'Mon Nov 25 2019 14:03:55 GMT+0800 (中国标准时间)',
updated_at: 'Mon Nov 25 2019 16:03:55 GMT+0800 (中国标准时间)'
}
将上面这个对象处理成下面这个对象
const todayILearn = {
id: 1,
content: '今天学习 JSON.stringify(),我很开心!',
createdAt: 'Mon Nov 25 2019 14:03:55 GMT+0800 (中国标准时间)',
updatedAt: 'Mon Nov 25 2019 16:03:55 GMT+0800 (中国标准时间)'
}
也就是在不改变属性的值的前提下,将对象属性修改一下。 把_id
改成 id
,把 updated_at
改成 updatedAt
,把 created_at
改成 createdAt
。
# 方案:序列化+ replace
美学典范
const mapObj = {
_id: "id",
created_at: "createdAt",
updated_at: "updatedAt"
};
JSON.parse(
JSON.stringify(todayILearn).replace(
/_id|created_at|updated_at/gi,
matched => mapObj[matched]
)
)
// {
// id: 1,
// content: '今天学习 JSON.stringify(),我很开心!',
// createdAt: 'Mon Nov 25 2019 14:03:55 GMT+0800 (中国标准时间)',
// updatedAt: 'Mon Nov 25 2019 16:03:55 GMT+0800 (中国标准时间)'
// }
# 接口数据格式化
# 约定
要明确所有的接口格式都要如下返回:
{
status: 200,
code: 10000,
message: '',
data: {
...
},
}
# 处理数据
credit.js
import dayjs from 'dayjs'
import { apiRequest as Axios, courseRequest } from '@@/utils/axios'
import { injectRowKey } from '@@/utils/rowKey'
import { getCreateTime } from '@@/utils/format'
import { decodeUniqueId } from '@@/utils/crypto'
const decodeName = code => {
switch (code) {
case 'finance_quotient_course_study_add_200':
return '学习课程'
case 'finance_quotient_course_notes_add_200':
return '写笔记'
case 'finance_quotient_course_praxis_add_200':
return '做测试题'
case 'finance_quotient_transfer_1_ratio':
return '历史积分导入'
case 'finance_quotient_course_note_share_add_400':
return '分享笔记'
case 'finance_quotient_exchange_subtract_1_ratio':
return '积分兑换'
}
}
const creditFormat = item => {
return {
name: decodeName(item.creditRuleCode),
createdAt: item.createdAt || new Date().valueOf(),
createdTime: getCreateTime(item.createdAt * 1000),
action: item.action,
amount: item.amount,
tradeNumber: item.tradeNumber,
isValid: item.isValid === 1, // 0-无效,1-有效
}
}
class CreditService {
async list(pageNum = 1, pageSize = 10) {
const {
data: { items = [], total },
} = await Axios.get('/user-center/credit/transactions', {
params: {
pageNum,
pageSize,
creditTypeCode: 'fq_credit',
},
})
const list = items.map(creditFormat)
return { items: injectRowKey(list), total: total || items.length }
}
}
export default new CreditService()
# 调用
import creditService from '@@/services/credit'
action = {
handleFetch: async () => {
const { items, total } = await creditService.list(current.pageNum, pageSize)
this.setState({
...
})
},
}
# 依赖
rowKey.js
import UUID from 'uuid'
// 设置数据唯一标识
export const setRowKey = data => {
return Object.assign({ rowKey: UUID() }, data)
}
// 数组遍历设置唯一标识
export const injectRowKey = dataSource => {
return Array.isArray(dataSource) ? dataSource.map(setRowKey) : []
}
format.js
import dayjs from 'dayjs'
const currentYear = new Date().getFullYear()
const startDay = new Date(new Date().toLocaleDateString()).valueOf()
const endDay = startDay + 24 * 60 * 60 * 1000
const timeFormatList = [
{
check: time => time >= startDay && time < endDay,
render: time => '今天 ' + dayjs(time).format('HH:mm'),
},
{
check: time => dayjs(time).year() === currentYear,
render: time => dayjs(time).format('MM-DD HH:mm'),
},
{
check: () => true,
render: time => dayjs(time).format('YYYY-MM-DD HH:mm'),
},
]
export const getCreateTime = createdAt => {
const format = timeFormatList.find(item => {
if (item.check(createdAt)) {
return item
}
})
return format.render(createdAt)
}
export const timeFormat = time => {
const thisYear = dayjs(time).year()
if (thisYear === currentYear) {
return dayjs(time).format('M月DD日')
} else {
return dayjs(time).format('YYYY年M月DD日')
}
}
const checkList = [
{
check: value => value >= 1000 * 10000,
format: value => '999万+',
},
{
check: value => value >= 10000,
format: value => {
const result = Math.round(+value / 10000)
if (result === 1000) {
return '999万+'
}
return `${result}万`
},
},
{
check: value => value >= 0,
format: value => value,
},
]
// 数字格式化
export const numberFormat = number => {
const checker = checkList.find(item => item.check(number))
return checker.format(number)
}
// 商品价格格式化
export const priceFormat = (price = 0, precison = 2) => {
price = Number(price) || 0
return +price.toFixed(precison)
}
// 收益率格式化
export const profitRateFormat = (profitRate = 0) => {
return (profitRate * 100).toFixed(2) + '%'
}
// 有符号收益率格式化
export const signedProfitRateFormat = (profitRate = 0) => {
if (profitRate > 0) {
return `+${(profitRate * 100).toFixed(2)}%`
} else {
return `${(profitRate * 100).toFixed(2)}%`
}
}
// 百分比格式化
export const percentageFormat = (number = 0) => {
return Math.round(number * 100) + '%'
}
crypto.js
// 课程资源自定义编号拼接
export const encodeUniqueId = (productId, chapterId, resourceId) => {
return [productId, chapterId, resourceId].join('-')
}
// 课程资源自定义编号解析
export const decodeUniqueId = uniqueId => {
const [productId, chapterId, resourceId] = uniqueId.split('-')
return [productId, chapterId, resourceId].map(item => parseInt(item, 10))
}
// 课程资源自定义编号解析
export const parseUniqueId = uniqueId => {
const [productId, chapterId, resourceId] = uniqueId.split('-').map(item => parseInt(item, 10))
return { productId, chapterId, resourceId }
}
// 原生交互数据编码
export const encodeHybrid = data => {
const payload = Object.assign({}, data)
return btoa(encodeURIComponent(JSON.stringify(payload)))
}
// 原生交互数据解码
export const decodeHybrid = str => {
try {
return JSON.parse(decodeURIComponent(atob(str)))
} catch (error) {
console.warn(error)
return {}
}
}