Bladeren bron

feat: add PricingTagManager component

feat/alipay-payment
fengsilin 1 maand geleden
bovenliggende
commit
deda039c96
1 gewijzigde bestanden met toevoegingen van 216 en 0 verwijderingen
  1. +216
    -0
      web/src/pages/Setting/Ratio/PricingTagManager.jsx

+ 216
- 0
web/src/pages/Setting/Ratio/PricingTagManager.jsx Bestand weergeven

@@ -0,0 +1,216 @@
/*
Copyright (C) 2025 QuantumNous

This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as
published by the Free Software Foundation, either version 3 of the
License, or (at your option) any later version.

This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Affero General Public License for more details.

You should have received a copy of the GNU Affero General Public License
along with this program. If not, see <https://www.gnu.org/licenses/>.

For commercial licensing, please contact support@quantumnous.com
*/

import React, { useState, useEffect, useCallback, useRef } from 'react';
import {
Button,
Table,
Modal,
Form,
Input,
Space,
Popconfirm,
Typography,
Tag as SemiTag,
} from '@douyinfe/semi-ui';
import { IconPlus, IconEdit, IconDelete } from '@douyinfe/semi-icons';
import { useTranslation } from 'react-i18next';
import { pricingTagApi } from '../../../helpers/api';
import { showError, showSuccess } from '../../../helpers';

const PricingTagManager = () => {
const { t } = useTranslation();
const [tags, setTags] = useState([]);
const [loading, setLoading] = useState(false);
const [modalVisible, setModalVisible] = useState(false);
const [editingTag, setEditingTag] = useState(null);
const formRef = useRef();

const loadTags = useCallback(async () => {
setLoading(true);
try {
const res = await pricingTagApi.getAll();
if (res.data.success) {
setTags(res.data.data);
}
} catch (e) {
showError(e);
} finally {
setLoading(false);
}
}, []);

useEffect(() => {
loadTags();
}, [loadTags]);

const handleCreate = () => {
setEditingTag(null);
setModalVisible(true);
};

const handleEdit = (record) => {
setEditingTag(record);
setModalVisible(true);
};

const handleDelete = async (id) => {
try {
const res = await pricingTagApi.delete(id);
if (res.data.success) {
showSuccess(t('删除成功'));
loadTags();
}
} catch (e) {
showError(e);
}
};

const handleSubmit = async () => {
try {
const values = await formRef.current.validate();
if (editingTag) {
const res = await pricingTagApi.update(editingTag.id, values);
if (res.data.success) {
showSuccess(t('更新成功'));
setModalVisible(false);
loadTags();
}
} else {
const res = await pricingTagApi.create(values);
if (res.data.success) {
showSuccess(t('创建成功'));
setModalVisible(false);
loadTags();
}
}
} catch (e) {
showError(e);
}
};

const columns = [
{
title: t('标签名称'),
dataIndex: 'name',
key: 'name',
render: (text, record) => (
<Space>
<SemiTag color={record.color}>{text}</SemiTag>
</Space>
),
},
{
title: t('颜色'),
dataIndex: 'color',
key: 'color',
render: (color) => (
<div style={{ display: 'flex', alignItems: 'center', gap: 8 }}>
<div
style={{
width: 20,
height: 20,
backgroundColor: color,
borderRadius: 4,
border: '1px solid #ddd',
}}
/>
<Typography.Text>{color}</Typography.Text>
</div>
),
},
{
title: t('描述'),
dataIndex: 'description',
key: 'description',
},
{
title: t('排序'),
dataIndex: 'sort_order',
key: 'sort_order',
width: 80,
},
{
title: t('操作'),
key: 'action',
width: 150,
render: (_, record) => (
<Space>
<Button icon={<IconEdit />} onClick={() => handleEdit(record)} />
<Popconfirm
title={t('确定删除此标签?')}
onConfirm={() => handleDelete(record.id)}
>
<Button icon={<IconDelete />} type="danger" />
</Popconfirm>
</Space>
),
},
];

return (
<div>
<div style={{ marginBottom: 16 }}>
<Button icon={<IconPlus />} onClick={handleCreate}>
{t('添加标签')}
</Button>
</div>

<Table
columns={columns}
dataSource={tags}
loading={loading}
pagination={false}
rowKey="id"
/>

<Modal
title={editingTag ? t('编辑标签') : t('添加标签')}
visible={modalVisible}
onCancel={() => setModalVisible(false)}
onOk={handleSubmit}
>
<Form getFormApi={(api) => (formRef.current = api)} initValues={editingTag}>
<Form.Input
field="name"
label={t('标签名称')}
rules={[{ required: true, message: t('请输入标签名称') }]}
/>
<Form.Input
field="color"
label={t('颜色')}
placeholder="#1890ff"
/>
<Form.TextArea
field="description"
label={t('描述')}
maxLength={200}
/>
<Form.InputNumber
field="sort_order"
label={t('排序')}
defaultValue={0}
/>
</Form>
</Modal>
</div>
);
};

export default PricingTagManager;

Laden…
Annuleren
Opslaan