Skip to content

Commit 201ac73

Browse files
committed
feat: 短链管理复制可复制短键或短码
1 parent 39ca12b commit 201ac73

File tree

4 files changed

+68
-22
lines changed

4 files changed

+68
-22
lines changed

README.md

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22

33
一个超简单的短网址管理平台(前端)。
44

5-
[**配置后端 API:shortener**](https://git.jetsung.com/idev/shortener)
5+
[**配置后端 API:shortener**](https://git.jetsung.com/idev/shortener-server)
66

77
预览: ![Shortener](screenshot.png)
88

@@ -46,11 +46,11 @@ npm run build
4646

4747
```yaml
4848
---
49-
# https://github.com/idevsig/shortener
49+
# https://git.jetsung.com/idev/shortener-server
5050

5151
services:
5252
shortener:
53-
image: ghcr.io/idevsig/shortener:dev-amd64
53+
image: ghcr.io/idevsig/shortener-server:dev-amd64
5454
container_name: shortener
5555
restart: unless-stopped
5656
ports:

mock/account.ts

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -26,23 +26,23 @@ const accountLogin = async (req: Request, res: Response) => {
2626
const { password, username } = req.body;
2727
console.log('req:', req.body);
2828
await waitTime(2000);
29-
if (password === 'ant.design' && username === 'admin') {
29+
if (password === 'admin' && username === 'admin') {
3030
res.send({
31-
token: 'admin-token'
31+
token: 'admin-token',
3232
});
3333
access = 1;
3434
return;
3535
}
36-
if (password === 'ant.design' && username === 'user') {
36+
if (password === 'user' && username === 'user') {
3737
res.send({
38-
token: 'user-token'
38+
token: 'user-token',
3939
});
4040
access = 2;
4141
return;
4242
}
4343
res.status(401).send({
4444
errcode: 401,
45-
errinfo: 'Authentication Failed'
45+
errinfo: 'Authentication Failed',
4646
});
4747
};
4848

package.json

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -69,8 +69,8 @@
6969
"@types/history": "^5.0.0",
7070
"@types/jest": "^29.5.14",
7171
"@types/lodash": "^4.17.16",
72-
"@types/react": "^19.1.0",
73-
"@types/react-dom": "^19.1.0",
72+
"@types/react": "^19.1.2",
73+
"@types/react-dom": "^19.1.2",
7474
"@types/react-helmet": "^6.1.11",
7575
"@typescript-eslint/eslint-plugin": "^8.31.0",
7676
"@typescript-eslint/parser": "^8.31.0",

src/pages/Shortener/index.tsx

Lines changed: 58 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ import {
44
updateShorten,
55
deleteShorten,
66
} from '@/services/shortener/shorten';
7-
import { PlusOutlined } from '@ant-design/icons';
7+
import { CopyOutlined, PlusOutlined } from '@ant-design/icons';
88
import type { ActionType, ProColumns, ProFormInstance } from '@ant-design/pro-components';
99
import {
1010
FooterToolbar,
@@ -15,18 +15,28 @@ import {
1515
ProTable,
1616
} from '@ant-design/pro-components';
1717
import '@umijs/max';
18-
import { Button, message } from 'antd';
18+
import { Button, message, Tooltip } from 'antd';
1919
import React, { useRef, useState } from 'react';
2020
import type { FormValueType } from './components/UpdateForm';
2121
import UpdateForm from './components/UpdateForm';
2222
import { createStyles } from 'antd-style';
2323
import { history } from 'umi';
2424

25-
const useStyles = createStyles(() => {
25+
const useStyles = createStyles(({ token }) => {
2626
return {
2727
footerToolBar: {
2828
fontWeight: 600,
2929
},
30+
codeContainer: {
31+
display: 'flex',
32+
justifyContent: 'flex-end',
33+
alignItems: 'center',
34+
gap: 8,
35+
},
36+
copyIcon: {
37+
cursor: 'pointer',
38+
color: token.colorPrimary,
39+
},
3040
};
3141
});
3242

@@ -49,6 +59,12 @@ const TableList: React.FC = () => {
4959

5060
const { styles } = useStyles();
5161

62+
const copyToClipboard = (text: string, messageText: string) => {
63+
navigator.clipboard.writeText(text).then(() => {
64+
messageApi.success(messageText);
65+
});
66+
};
67+
5268
/**
5369
* @en-US Add node
5470
* @zh-CN 添加节点
@@ -129,21 +145,51 @@ const TableList: React.FC = () => {
129145
dataIndex: 'id',
130146
hideInSearch: true,
131147
},
148+
// {
149+
// title: '短码',
150+
// dataIndex: 'code',
151+
// copyable: true,
152+
// renderText: (text, record) => record.short_url, // 指定复制的内容
153+
// render: (dom, entity) => {
154+
// return (
155+
// <a
156+
// onClick={() => {
157+
// window.open(entity.short_url, '_blank');
158+
// }}
159+
// >
160+
// {dom}
161+
// </a>
162+
// );
163+
// },
164+
// },
132165
{
133166
title: '短码',
134167
dataIndex: 'code',
135-
copyable: true,
136-
render: (dom, entity) => {
137-
return (
168+
width: 10,
169+
render: (_, entity) => (
170+
<span className={styles.codeContainer}>
138171
<a
139-
onClick={() => {
140-
window.open(entity.short_url, '_blank');
141-
}}
172+
href={entity.short_url}
173+
target="_blank"
174+
rel="noopener noreferrer"
175+
onClick={(e) => e.stopPropagation()}
142176
>
143-
{dom}
177+
{entity.code}
144178
</a>
145-
);
146-
},
179+
<Tooltip title="复制短码">
180+
<CopyOutlined
181+
className={styles.copyIcon}
182+
onClick={() => copyToClipboard(entity.code as string, '短码复制成功')}
183+
/>
184+
</Tooltip>
185+
<Tooltip title="复制短链">
186+
<CopyOutlined
187+
className={styles.copyIcon}
188+
onClick={() => copyToClipboard(entity.short_url as string, '短链复制成功')}
189+
/>
190+
</Tooltip>
191+
</span>
192+
),
147193
},
148194
{
149195
title: '源地址',

0 commit comments

Comments
 (0)