1 功能图
2 工作回顾
2.1 欢迎页
这个界面可以看出我的css基础有点差,一个简单的静态界面,还是出了很多莫名其妙的bug,在忙完这阵之后考虑看一下阮一峰的flex布局,感觉flex布局可以用的很强。没啥技术含量,不多说了。
2.2 审批页
这部分主要分成两部分,一打开首先说审批列表,点击列表中的草稿项可以进行草稿详情。
2.2.1 审批列表
这部分的主要内容是一个表格,渲染所有待审批的草稿,表格中还要实现通过/不通过以及批量操作。
首先是组件框架的搭建,实现在表格中渲染需要的数据,还有批量的基础框架搭建。框架搭建完就开始获取数据填入,这里就要使用mock进行模拟请求,并将得到的数据放进表中。其中,商品可以选择是否根据状态筛选。
之后,渲染两个按钮,分别为通过/不通过,操作需要加上二次确认弹窗,在弹窗中对数据进行操作,这部分可以将对草稿的审批操作进行封装,只需修改操作入参即可。
async function confirm(record: any, targetStatus: number) {const gmtIds = [];gmtIds.push(Number(record.gmtId));try {const res = await setDraftStatus(targetStatus, gmtIds);if (res.success) {actionRef.current!.reload();}setSelectedRows([]);actionRef.current?.reloadAndRest?.();} catch (err) {console.log(err);}}
2.2.2 审批详情
这个界面分为上下两部分,上部分为数据介绍,下部分为审批操作。
首先是数据的获取,首先要得到审批列表页传入的gmtId,有两种方法,一种是通过history.push传入的参数解析,另一种是解析url中的gmtId。
// 处理history.state得到gmtId
const history: any = useHistory();
const gmtId = history.location.state.gmtId;
// 处理url得到gmtId
const url: string = window.location.pathname;
console.log(url);
上部分用表格的形式展示草稿数据,同时进行判定,如果与原数据不一致,则用特殊的css进行渲染,并通过悬浮窗在鼠标悬停时进行原数据的渲染。
const getDifference = (a: any, b: any) => {
const changes = (object: any, base: any) => {
return _.transform(object, (result: any, value, key) => {
if (!_.isEqual(value, base[key])) {
result[key] =
_.isObject(value) && _.isObject(base[key]) ? changes(value, base[key]) : value;
}
});
};
return changes(a, b);
}; const diff = (type: string): boolean => {
return gmtData.goods[type] !== goodData[type];
};
剩下要做的事情就是,把所有数据渲染一遍,对时间进行格式处理,对列表数据转换成对应文本。
最后的sku列表渲染十分复杂,于是我找了@升正(huangshengpu.hsp)封装好的组件,感谢大佬。
2.3 其他
零零散散做了点别的,比如给侧边栏加了点好看的图标(工作量不超过50个字母😂)。
回归正题,第一次接触mock,也学习到了很多,从一开始只会模拟最简单的接口,到后面逐渐研究如何进行传参,用mock模拟后端还挺有趣的。
async function confirm(record: any, targetStatus: number) {
const gmtIds = [];
gmtIds.push(Number(record.gmtId));
try {
const res = await setDraftStatus(targetStatus, gmtIds);
if (res.success) {
actionRef.current!.reload();
}
setSelectedRows([]);
actionRef.current?.reloadAndRest?.();
} catch (err) {
console.log(err);
}
}
export async function setDraftStatus(targetStatus: number, gmtIds: number[]) {
return request<API.DraftList>('/api/setDraftStatus', {
method: 'POST',
data: {
targetStatus: targetStatus,
gmtIds: gmtIds,
},
});
}
function setDraftStatus(req: Request, res: Response) {
const { targetStatus, gmtIds } = req.body;
copyList.data.forEach((i) => {
if (gmtIds.indexOf(i.gmtId) !== -1) {
// 替代
i.gmtStatus = targetStatus;
}
});
res.json(copyList);
}
然后对git熟悉了好多,特别是团队操作应该咋pull/merge之类的,还会搞分支,相比之前个人开发无脑commit push进步了好多。
2.4 不足
基本功能算是完成了,但是没有亮点,列表渲染了,也就只是渲染了,连查询功能都没做;详情页写了,也只是渲染了数据,和简单的展示了diff,没有新颖的功能。
还有就是数据结构以及系分做的太拉了,下次一定要多花点时间好好分,好好确定,这样真的会省很多时间。
3 结果
| 内容 | 完成情况 | 备注 |
|---|---|---|
| 欢迎页 | 100% | |
| 审批列表页 | 90% | 查询功能未完成 |
| 批量审批组件封装 | 100% | |
| 审批详情页 | 90% | sku组件没有自己实现,而是使用了别人封装的 |
| diff组件封装 | 100% |
4 CR
4.1 封装审批异步操作
async function confirm(record: any, targetStatus: number) {
const gmtIds = [];
gmtIds.push(Number(record.gmtId));
try {
const res = await setDraftStatus(targetStatus, gmtIds);
if (res.success) {
actionRef.current!.reload();
}
setSelectedRows([]);
actionRef.current?.reloadAndRest?.();
} catch (err) {
console.log(err);
}
}
4.2 状态必须搞枚举
enum gmtStatusType {
PendingApproval = 0,
HaveCoverd = 1,
PendingCover = 2,
Abandon = 3,
Editable = 4,
}
setDraftStatus(gmtStatusType.Editable, gmtIds)
4.3 .map抽离欢迎页
memberData.map((item, index) => {
return (
<Card className="card-box" key={index}>
<div className={item.avatar} />
<h4 className="name">{item.name}</h4>
<div dangerouslySetInnerHTML={{ __html: item.intro }} />
</Card>
);
})
4.4 封装diff函数
const getDifference = (a: any, b: any) => {
const changes = (object: any, base: any) => {
return _.transform(object, (result: any, value, key) => {
if (!_.isEqual(value, base[key])) {
result[key] =
_.isObject(value) && _.isObject(base[key]) ? changes(value, base[key]) : value;
}
});
};
return changes(a, b);
};
4.5 抽离商品详情
goodDataShow.map((i) => {
return (
<Descriptions.Item label={i.label} key={i.label} span={i.span}>
<Popover
trigger="hover"
title={i.diff ? '原数据' : ''}
content={i.diff ? i.oldContent : ''}
>
<span className={i.diff ? 'diff' : ''}>{i.content}</span>
</Popover>
</Descriptions.Item>
);
})
5 学习笔记
5.1 实现两种方法的路由传参
法1: 处理history.state得到gmtId
// 传参
history.push({
pathname: './detail/' + record.gmtId,
state: { gmtId: record.gmtId },
});
// 获取:处理history.state得到gmtId
const history: any = useHistory();
const gmtId = history.location.state.gmtId;
// 路由,:gmtId是关键
{ path: '/approval/detail/:gmtId', access: 'canAdmin', component: './approval/ApprovalDetail' },
法2: 处理url得到gmtId
// 处理url得到gmtId
const url: string = window.location.pathname;
console.log(url);
// 这里拿到还是很长一串带/的字符串,要splice处理
