|
@@ -3,32 +3,161 @@ import {
|
|
|
HolderOutlined,
|
|
|
MoreOutlined,
|
|
|
} from "@ant-design/icons";
|
|
|
-import { Col, Row, Form, Input, Select, Button, Tooltip, Popover, Popconfirm } from "antd";
|
|
|
-import React from "react";
|
|
|
+import {
|
|
|
+ Col,
|
|
|
+ Row,
|
|
|
+ Form,
|
|
|
+ Input,
|
|
|
+ Select,
|
|
|
+ Button,
|
|
|
+ Tooltip,
|
|
|
+ Popover,
|
|
|
+ Popconfirm,
|
|
|
+} from "antd";
|
|
|
+import React, { useState } from "react";
|
|
|
import CustomColorPicker from "@/components/CustomColorPicker";
|
|
|
+import { ColumnItem, TableItemType } from "@/type";
|
|
|
+import { TABLE_TYPE_OPTIONS, DATA_TYPE_OPTIONS } from "@/constants";
|
|
|
+import { uuid } from "@/utils";
|
|
|
+import { DataType } from "@/enum";
|
|
|
|
|
|
-export default function TableItem() {
|
|
|
+export default function TableItem({
|
|
|
+ data,
|
|
|
+ onChange,
|
|
|
+}: {
|
|
|
+ data: TableItemType;
|
|
|
+ onChange: (data: TableItemType) => void;
|
|
|
+}) {
|
|
|
const [collapsed, setCollapsed] = React.useState(false);
|
|
|
- const ColumnItem = () => {
|
|
|
+
|
|
|
+ const [table, setTable] = React.useState(data?.table);
|
|
|
+ const [tableColumnList, setTableColumnList] = React.useState(data?.tableColumnList);
|
|
|
+
|
|
|
+ const handleTableChange = (key: string, value: any) => {
|
|
|
+ onChange({
|
|
|
+ tableColumnList,
|
|
|
+ table: { ...table, [key]: value },
|
|
|
+ });
|
|
|
+ setTable({ ...table, [key]: value });
|
|
|
+ };
|
|
|
+
|
|
|
+ const handleColumnChange = (index: number, value: any) => {
|
|
|
+ tableColumnList[index] = { ...tableColumnList[index], ...value };
|
|
|
+ onChange({
|
|
|
+ tableColumnList,
|
|
|
+ table,
|
|
|
+ });
|
|
|
+ setTableColumnList([...tableColumnList]);
|
|
|
+ };
|
|
|
+
|
|
|
+ // 添加表
|
|
|
+ const handleAddChildTable = () => {};
|
|
|
+
|
|
|
+ // 添加字段
|
|
|
+ const handleAddColumn = () => {
|
|
|
+ const newColumn: ColumnItem = {
|
|
|
+ id: uuid(),
|
|
|
+ schemaName: "",
|
|
|
+ name: "",
|
|
|
+ en_name: "",
|
|
|
+ cn_name: "",
|
|
|
+ type: DataType.Nvarchar,
|
|
|
+ maxLength: 100,
|
|
|
+ precision: 0,
|
|
|
+ scale: 0,
|
|
|
+ isRequired: false,
|
|
|
+ isUnique: false,
|
|
|
+ isPreDefined: false,
|
|
|
+ defaultValue: "",
|
|
|
+ };
|
|
|
+ onChange({
|
|
|
+ table,
|
|
|
+ tableColumnList: [...tableColumnList, newColumn],
|
|
|
+ });
|
|
|
+ setTableColumnList([...tableColumnList, newColumn]);
|
|
|
+ };
|
|
|
+
|
|
|
+ // 删除表
|
|
|
+ const handleDeleteTable = () => {};
|
|
|
+
|
|
|
+ const ColumnItem = ({
|
|
|
+ column,
|
|
|
+ onChange,
|
|
|
+ }: {
|
|
|
+ column: ColumnItem;
|
|
|
+ onChange: (data: ColumnItem) => void;
|
|
|
+ }) => {
|
|
|
+ const [data, setData] = useState(column);
|
|
|
+ const handleChange = (key: string, value: any) => {
|
|
|
+ onChange({
|
|
|
+ ...data,
|
|
|
+ [key]: value,
|
|
|
+ });
|
|
|
+ setData({
|
|
|
+ ...data,
|
|
|
+ [key]: value,
|
|
|
+ });
|
|
|
+ };
|
|
|
return (
|
|
|
- <div className="column-item flex gap-4px items-center jutify-space-between hover:bg-gray-100">
|
|
|
+ <div className="column-item flex gap-4px items-center jutify-space-between hover:bg-gray-100 mb-4px">
|
|
|
<HolderOutlined className="cursor-move" />
|
|
|
<Tooltip title="字段编码">
|
|
|
- <Input placeholder="字段编码" />
|
|
|
+ <Input
|
|
|
+ placeholder="编码"
|
|
|
+ value={data.schemaName}
|
|
|
+ className="flex-1"
|
|
|
+ onChange={(e) => handleChange("schemaName", e.target.value)}
|
|
|
+ />
|
|
|
</Tooltip>
|
|
|
<Tooltip title="字段类型">
|
|
|
- <Select placeholder="字段" />
|
|
|
- </Tooltip>
|
|
|
- <Tooltip title="字段长度,精度用逗号分割">
|
|
|
- <Input placeholder="长度" />
|
|
|
+ <Select
|
|
|
+ placeholder="类型"
|
|
|
+ className="w-80px"
|
|
|
+ options={DATA_TYPE_OPTIONS}
|
|
|
+ value={data.type}
|
|
|
+ onChange={(value) => handleChange("type", value)}
|
|
|
+ dropdownStyle={{width: 120}}
|
|
|
+ />
|
|
|
</Tooltip>
|
|
|
<Tooltip title="非空">
|
|
|
- <div className="rounded-4px cus-btn w-32px h-32px bg-#eee flex-none text-center leading-32px cursor-pointer hover:bg-#ddd">
|
|
|
+ <div
|
|
|
+ className="
|
|
|
+ rounded-4px
|
|
|
+ cus-btn
|
|
|
+ w-32px
|
|
|
+ h-32px
|
|
|
+ bg-#eee
|
|
|
+ flex-none
|
|
|
+ text-center
|
|
|
+ leading-32px
|
|
|
+ cursor-pointer
|
|
|
+ hover:bg-#ddd"
|
|
|
+ style={
|
|
|
+ data.isRequired ? { background: "#1677ff", color: "#fff" } : {}
|
|
|
+ }
|
|
|
+ onClick={() => handleChange("isRequired", !data.isRequired)}
|
|
|
+ >
|
|
|
!
|
|
|
</div>
|
|
|
</Tooltip>
|
|
|
<Tooltip title="唯一">
|
|
|
- <div className="rounded-4px cus-btn w-32px h-32px bg-#eee flex-none text-center leading-32px cursor-pointer hover:bg-#ddd">
|
|
|
+ <div
|
|
|
+ className="
|
|
|
+ rounded-4px
|
|
|
+ cus-btn
|
|
|
+ w-32px
|
|
|
+ h-32px
|
|
|
+ bg-#eee
|
|
|
+ flex-none
|
|
|
+ text-center
|
|
|
+ leading-32px
|
|
|
+ cursor-pointer
|
|
|
+ hover:bg-#ddd"
|
|
|
+ style={
|
|
|
+ data.isUnique ? { background: "#1677ff", color: "#fff" } : {}
|
|
|
+ }
|
|
|
+ onClick={() => handleChange("isUnique", !data.isRequired)}
|
|
|
+ >
|
|
|
1
|
|
|
</div>
|
|
|
</Tooltip>
|
|
@@ -39,8 +168,18 @@ export default function TableItem() {
|
|
|
<div className="w-200px">
|
|
|
<Form layout="vertical">
|
|
|
<Form.Item label="字段名称" name="pkName">
|
|
|
- <Input className="w-full" placeholder="中文" />
|
|
|
- <Input className="w-full" placeholder="英文" />
|
|
|
+ <Input
|
|
|
+ className="w-full"
|
|
|
+ placeholder="中文"
|
|
|
+ value={data.cn_name}
|
|
|
+ onChange={(e) => handleChange("cn_name", e.target.value)}
|
|
|
+ />
|
|
|
+ <Input
|
|
|
+ className="w-full"
|
|
|
+ placeholder="英文"
|
|
|
+ value={data.en_name}
|
|
|
+ onChange={(e) => handleChange("en_name", e.target.value)}
|
|
|
+ />
|
|
|
</Form.Item>
|
|
|
<Form.Item label="描述" name="pkName">
|
|
|
<Input.TextArea
|
|
@@ -52,10 +191,30 @@ export default function TableItem() {
|
|
|
placeholder="描述英文..."
|
|
|
/>
|
|
|
</Form.Item>
|
|
|
+ <Form.Item label="长度">
|
|
|
+ <Input
|
|
|
+ placeholder="请输入"
|
|
|
+ value={data.maxLength}
|
|
|
+ onChange={(e) => handleChange("maxLength", e.target.value)}
|
|
|
+ />
|
|
|
+ </Form.Item>
|
|
|
+ <Form.Item label="精度">
|
|
|
+ <Input
|
|
|
+ placeholder="请输入"
|
|
|
+ value={data.precision}
|
|
|
+ onChange={(e) => handleChange("precision", e.target.value)}
|
|
|
+ />
|
|
|
+ </Form.Item>
|
|
|
<Form.Item label="默认值" name="pkName">
|
|
|
- <Input className="w-full" placeholder="默认值" />
|
|
|
+ <Input
|
|
|
+ className="w-full"
|
|
|
+ placeholder="默认值"
|
|
|
+ value={data.defaultValue}
|
|
|
+ onChange={(e) =>
|
|
|
+ handleChange("defaultValue", e.target.value)
|
|
|
+ }
|
|
|
+ />
|
|
|
</Form.Item>
|
|
|
-
|
|
|
</Form>
|
|
|
</div>
|
|
|
}
|
|
@@ -69,7 +228,8 @@ export default function TableItem() {
|
|
|
};
|
|
|
|
|
|
return (
|
|
|
- <div className="
|
|
|
+ <div
|
|
|
+ className="
|
|
|
w-full
|
|
|
border-l-solid
|
|
|
border-l-[#e6e6e6]
|
|
@@ -77,7 +237,12 @@ export default function TableItem() {
|
|
|
border-b-solid
|
|
|
border-b-[#e4e4e4]
|
|
|
border-b-[1px]
|
|
|
- p-l-16px">
|
|
|
+ m-b-4px
|
|
|
+ p-l-16px"
|
|
|
+ style={{
|
|
|
+ borderLeftColor: table.style?.color || '#eee'
|
|
|
+ }}
|
|
|
+ >
|
|
|
<div
|
|
|
className="
|
|
|
header
|
|
@@ -91,48 +256,76 @@ export default function TableItem() {
|
|
|
m-b-[10px]"
|
|
|
onClick={() => setCollapsed(!collapsed)}
|
|
|
>
|
|
|
- <div className="font-bold">数据表名</div>
|
|
|
+ <div className="font-bold">
|
|
|
+ {table.schemaName}({table.cn_name})
|
|
|
+ </div>
|
|
|
<div>
|
|
|
<Popover
|
|
|
trigger="click"
|
|
|
placement="right"
|
|
|
content={
|
|
|
- <div className="w-200px">
|
|
|
+ <div className="w-200px" onClick={(e) => e.stopPropagation()}>
|
|
|
<Form layout="vertical">
|
|
|
<Form.Item label="表名称" name="pkName">
|
|
|
- <Input className="w-full" placeholder="中文" />
|
|
|
- <Input className="w-full" placeholder="英文" />
|
|
|
- </Form.Item>
|
|
|
- <Form.Item label="描述" name="pkName">
|
|
|
- <Input.TextArea
|
|
|
+ <Input
|
|
|
className="w-full"
|
|
|
- placeholder="中文..."
|
|
|
+ placeholder="中文"
|
|
|
+ value={table.cn_name}
|
|
|
+ onChange={(e) =>
|
|
|
+ handleTableChange("cn_name", e.target.value)
|
|
|
+ }
|
|
|
/>
|
|
|
- <Input.TextArea
|
|
|
+ <Input
|
|
|
className="w-full"
|
|
|
- placeholder="英文..."
|
|
|
+ placeholder="英文"
|
|
|
+ value={table.en_name}
|
|
|
+ onChange={(e) =>
|
|
|
+ handleTableChange("en_name", e.target.value)
|
|
|
+ }
|
|
|
/>
|
|
|
</Form.Item>
|
|
|
+ <Form.Item label="描述" name="pkName">
|
|
|
+ <Input.TextArea className="w-full" placeholder="中文..." />
|
|
|
+ <Input.TextArea className="w-full" placeholder="英文..." />
|
|
|
+ </Form.Item>
|
|
|
</Form>
|
|
|
</div>
|
|
|
}
|
|
|
>
|
|
|
- <i className="iconfont icon-shezhi mr-[10px] cursor-pointer" />
|
|
|
+ <i
|
|
|
+ className="iconfont icon-shezhi mr-[10px] cursor-pointer"
|
|
|
+ onClick={(e) => e.stopPropagation()}
|
|
|
+ />
|
|
|
</Popover>
|
|
|
<i className="iconfont icon-open" />
|
|
|
</div>
|
|
|
</div>
|
|
|
- <div className="content overflow-hidden" style={{ height: collapsed ? 0 : "auto" }}>
|
|
|
+ <div
|
|
|
+ className="content overflow-hidden"
|
|
|
+ style={{ height: collapsed ? 0 : "auto" }}
|
|
|
+ >
|
|
|
<Form layout="horizontal" labelCol={{ span: 8 }}>
|
|
|
<Row gutter={8}>
|
|
|
<Col span={12}>
|
|
|
<Form.Item label="编码">
|
|
|
- <Input />
|
|
|
+ <Input
|
|
|
+ placeholder="请输入"
|
|
|
+ value={table.schemaName}
|
|
|
+ onChange={(e) =>
|
|
|
+ handleTableChange("schemaName", e.target.value)
|
|
|
+ }
|
|
|
+ />
|
|
|
</Form.Item>
|
|
|
</Col>
|
|
|
<Col span={12}>
|
|
|
<Form.Item label="别名">
|
|
|
- <Input />
|
|
|
+ <Input
|
|
|
+ placeholder="请输入"
|
|
|
+ value={table.aliasName}
|
|
|
+ onChange={(e) =>
|
|
|
+ handleTableChange("aliasName", e.target.value)
|
|
|
+ }
|
|
|
+ />
|
|
|
</Form.Item>
|
|
|
</Col>
|
|
|
</Row>
|
|
@@ -141,18 +334,41 @@ export default function TableItem() {
|
|
|
labelCol={{ span: 4 }}
|
|
|
wrapperCol={{ span: 21 }}
|
|
|
>
|
|
|
- <Select />
|
|
|
+ <Select
|
|
|
+ placeholder="请选择"
|
|
|
+ options={TABLE_TYPE_OPTIONS}
|
|
|
+ value={table.type}
|
|
|
+ onChange={(val) => handleTableChange("type", val)}
|
|
|
+ />
|
|
|
</Form.Item>
|
|
|
</Form>
|
|
|
|
|
|
<div className="flex justify-between m-b-10px">
|
|
|
- <CustomColorPicker>
|
|
|
- <div className="rounded-4px cus-btn w-32px h-32px bg-#eee flex-none cursor-pointer shadow-inner"></div>
|
|
|
+ <CustomColorPicker
|
|
|
+ color={table.style?.background}
|
|
|
+ onChange={(color) =>
|
|
|
+ handleTableChange("style", { ...table.style, color })
|
|
|
+ }
|
|
|
+ >
|
|
|
+ <div
|
|
|
+ className="rounded-4px cus-btn w-32px h-32px bg-#eee flex-none cursor-pointer shadow-inner"
|
|
|
+ style={{ background: table.style?.color || "#eee" }}
|
|
|
+ ></div>
|
|
|
</CustomColorPicker>
|
|
|
<div className="flex gap-4px">
|
|
|
- <Button type="primary">添加子表</Button>
|
|
|
- <Button type="primary">添加字段</Button>
|
|
|
- <Popconfirm okType="primary" title="确定删除该表?" okText="确定" cancelText="取消">
|
|
|
+ <Button type="primary" onClick={handleAddChildTable}>
|
|
|
+ 添加子表
|
|
|
+ </Button>
|
|
|
+ <Button type="primary" onClick={handleAddColumn}>
|
|
|
+ 添加字段
|
|
|
+ </Button>
|
|
|
+ <Popconfirm
|
|
|
+ okType="primary"
|
|
|
+ title="确定删除该表?"
|
|
|
+ okText="确定"
|
|
|
+ cancelText="取消"
|
|
|
+ onConfirm={handleDeleteTable}
|
|
|
+ >
|
|
|
<div className="rounded-4px cus-btn w-32px h-32px bg-#eee flex-none text-center leading-32px color-red cursor-pointer">
|
|
|
<DeleteOutlined />
|
|
|
</div>
|
|
@@ -161,7 +377,15 @@ export default function TableItem() {
|
|
|
</div>
|
|
|
|
|
|
<div className="column-content border-solid border-1px border-#e4e4e4 border-x-none p-y-10px">
|
|
|
- <ColumnItem />
|
|
|
+ {tableColumnList.map((item, index) => {
|
|
|
+ return (
|
|
|
+ <ColumnItem
|
|
|
+ column={item}
|
|
|
+ key={item.id}
|
|
|
+ onChange={(val) => handleColumnChange(index, val)}
|
|
|
+ />
|
|
|
+ );
|
|
|
+ })}
|
|
|
</div>
|
|
|
</div>
|
|
|
</div>
|