20260914224947
This commit is contained in:
1 parent
63514476d7
commit
d26afb5fec
69 files changed
+158
-1008
No files matched your search
@@ -73,7 +73,7 @@ create table dbo.b_othercompany_partner_type (
|
||||
b_updated_at datetime2 null
|
||||
);
|
||||
|
||||
create table dbo.b_othercompany_bmfl (
|
||||
create table dbo.b_othercompany_category (
|
||||
b_id varchar(150) not null primary key,
|
||||
b_parent_id varchar(150) null,
|
||||
b_depth int not null default 0,
|
||||
@@ -88,10 +88,10 @@ create table dbo.b_othercompany_bmfl (
|
||||
b_updated_at datetime2 null
|
||||
);
|
||||
|
||||
create index ix_b_othercompany_bmfl_parent
|
||||
on dbo.b_othercompany_bmfl (b_parent_id, b_canuse, b_depth, b_xh, b_id);
|
||||
create index ix_b_othercompany_bmfl_path
|
||||
on dbo.b_othercompany_bmfl (b_path, b_canuse, b_id);
|
||||
create index ix_b_othercompany_category_parent
|
||||
on dbo.b_othercompany_category (b_parent_id, b_canuse, b_depth, b_xh, b_id);
|
||||
create index ix_b_othercompany_category_path
|
||||
on dbo.b_othercompany_category (b_path, b_canuse, b_id);
|
||||
|
||||
-- 注:b_grade 由「其他数据」迁移重建为雪花主键(原为级别编码)
|
||||
create table dbo.b_grade (
|
||||
|
||||
+17
-10
@@ -993,7 +993,7 @@ create table dbo.bf_files (
|
||||
mx_fileext varchar(50) null, -- 扩展名(小写、不含点)
|
||||
mx_mapfilename nvarchar(500) null, -- 访问地址:本地为 {url-prefix}/{org}/{yyyy}/{MM}/{dd}/{uuid}.{ext},OSS 为完整 URL
|
||||
mx_moduleid varchar(50) null, -- 业务模块编码(s_module.b_id)
|
||||
mx_cate_id varchar(50) null, -- 文件分类(bf_files_cateid.b_id)
|
||||
mx_cate_id bigint null, -- 文件分类(bf_files_category.b_id,雪花主键)
|
||||
mx_xh int not null default 0, -- 排序号(保留;当前实现固定 0,列表按 subid 倒序)
|
||||
mx_sh tinyint not null default 0, -- 审核标识(保留;当前实现固定 0)
|
||||
mx_shuser_id varchar(50) null, -- 审核人(保留)
|
||||
@@ -1011,19 +1011,24 @@ create table dbo.bf_files (
|
||||
create index ix_bf_files_host
|
||||
on dbo.bf_files (father, mx_moduleid, mx_cate_id, mx_xh, subid);
|
||||
|
||||
-- 文件分类表
|
||||
create table dbo.bf_files_cateid (
|
||||
b_id varchar(50) not null primary key, -- 分类编码
|
||||
b_name nvarchar(50) null, -- 分类名称
|
||||
b_files_type varchar(50) null, -- 允许的扩展名(逗号分隔,空 = 不限;保留)
|
||||
-- 文件分类表(按模块划分;b_module_id 为空表示跨模块通用分类)
|
||||
create table dbo.bf_files_category (
|
||||
b_id bigint not null primary key, -- 主键(雪花,新增行由前端 nextIdApi 生成)
|
||||
b_module_id varchar(50) null, -- 归属模块(s_module.b_id);NULL = 通用分类
|
||||
b_name nvarchar(50) not null, -- 分类名称
|
||||
b_i18n varchar(150) null, -- 多语言资源键(s_i18n.b_key)
|
||||
b_files_type varchar(50) null, -- 允许的扩展名(逗号分隔,空 = 不限;预留)
|
||||
b_xh int not null default 0, -- 显示顺序
|
||||
b_canuse tinyint not null default 1, -- 是否启用(0/1)
|
||||
b_bz nvarchar(200) null, -- 备注
|
||||
b_inputuser_id varchar(50) null, -- 创建人
|
||||
b_inputdatetime datetime2 null, -- 创建时间
|
||||
b_updateuser_id varchar(50) null, -- 最后修改人
|
||||
b_updatedatetime datetime2 null -- 最后修改时间
|
||||
b_created_by varchar(50) null, -- 创建人(用户账号)
|
||||
b_created_at datetime2 null, -- 创建时间
|
||||
b_updated_by varchar(50) null, -- 最后修改人
|
||||
b_updated_at datetime2 null -- 最后修改时间
|
||||
);
|
||||
|
||||
create index ix_bf_files_category_module
|
||||
on dbo.bf_files_category (b_module_id, b_canuse, b_xh, b_id);
|
||||
```
|
||||
|
||||
要点:
|
||||
@@ -1032,6 +1037,8 @@ create table dbo.bf_files_cateid (
|
||||
- **宿主关联**:`father` 存宿主业务主键(业务表 `b_id`,bigint 雪花),不建外键;删除业务数据时由业务层级联清理附件(先删存储、后删行)。
|
||||
- **存储地址**:`mx_mapfilename` 即访问地址,前端预览 / 下载直接使用。本地模式写入 `{fms.file.local.url-prefix}/{orgId}/{yyyy}/{MM}/{dd}/{uuid}.{ext}`,物理文件落在 `{fms.file.local.storage-dir}` 下的同路径;OSS 模式写入 g3oss 返回的完整 URL。
|
||||
- **保留字段**:`mx_sh*`(审核)、`mx_cut*`(缩略图)、`mx_orderid`、`mx_bz`、`mx_xh` 沿用旧库结构,当前实现未使用(写 0 / 空值),保留以兼容历史数据迁移。
|
||||
- **分类归属模块**:`bf_files_category.b_module_id` 指定分类所属模块,不填(NULL)为跨模块通用分类;分类树按当前模块过滤(`b_module_id IS NULL OR b_module_id = 当前模块`)。分类主键与 `bf_files.mx_cate_id` 类型保持一致(bigint 雪花)。
|
||||
- **风格**:分类表按新版字典表风格(应用层雪花主键、`b_created_*` 审计列、`b_canuse tinyint`);`bf_files` 的 `subid` / `father` / `mx_*` 列名已被前后端实现引用,保持现状。表名 `bf_*` 属于"明确的业务域前缀",符合第 1 节表名规范。
|
||||
- **旧库遗留**:`bf_files_type`(模块文件类型 / 数量配置)在旧库存在,但新旧系统均未使用,不迁移。
|
||||
|
||||
存储配置(`application.yaml`):
|
||||
|
||||
@@ -88,7 +88,7 @@ public final class VerifyBusinessMigration {
|
||||
}
|
||||
|
||||
private static void verifyCoreTables(Connection connection) throws Exception {
|
||||
for (String table : List.of("b_othercompany", "b_contact", "b_othercompany_bmfl")) {
|
||||
for (String table : List.of("b_othercompany", "b_contact", "b_othercompany_category")) {
|
||||
if (!tableExists(connection, table)) {
|
||||
throw new IllegalStateException("Missing core business table: dbo." + table);
|
||||
}
|
||||
|
||||
@@ -140,7 +140,8 @@ public class FileService {
|
||||
ps.setString(6, mapfilename);
|
||||
// 字符串业务键:模块编码 / 分类编码 / 用户账号均按字符串存储
|
||||
ps.setString(7, moduleId);
|
||||
ps.setString(8, cateId);
|
||||
// 分类主键为 bigint 雪花(bf_files_category.b_id),按数字写入
|
||||
ps.setObject(8, toLongOrNull(cateId));
|
||||
ps.setString(9, userId);
|
||||
ps.executeUpdate();
|
||||
}
|
||||
|
||||
Binary file not shown.
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
BIN
Binary file not shown.
Binary file not shown.
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
Binary file not shown.
Binary file not shown.
BIN
Binary file not shown.
Binary file not shown.
BIN
Binary file not shown.
Binary file not shown.
BIN
Binary file not shown.
Binary file not shown.
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
@@ -0,0 +1,29 @@
|
||||
=== 1. 视图 / 过程 / 函数中引用 b_othercompany_bmfl 的对象 ===
|
||||
name | type_desc
|
||||
(共 0 行)
|
||||
|
||||
=== 2. s_module 模块配置中的表名引用 ===
|
||||
b_id | b_module_type | b_view_table | b_save_table
|
||||
(共 0 行)
|
||||
|
||||
=== 3. v_b_othercompany 定义(确认是否 join 分类表) ===
|
||||
definition
|
||||
create view dbo.v_b_othercompany as
|
||||
select o.b_id, o.b_ywid, o.b_pycode, o.b_type, o.b_name, o.b_shortname,
|
||||
o.b_linkman, o.b_phone, o.b_addr, o.b_firstlinkdate,
|
||||
o.b_htno, o.b_htdate, o.b_htexpiredate, o.b_black, o.b_canuse,
|
||||
o.b_zl, o.b_tel, o.b_fax, o.b_www, o.b_email,
|
||||
o.b_bankacount, o.b_invaccount, o.b_cate_id,
|
||||
o.b_bz1, o.b_bz2, o.b_bz3, o.b_bz4,
|
||||
o.b_province, o.b_city, o.b_area, o.b_country,
|
||||
o.b_edicode, o.b_showcolor, o.b_type_id, o.b_from_id,
|
||||
o.b_type1_id, o.b_type2_id, o.b_type3_id, o.b_type4_id, o.b_type5_id,
|
||||
o.b_owner_id, ...(截断)
|
||||
(共 1 行)
|
||||
|
||||
=== 4. 表与索引现状 ===
|
||||
index_name | type_desc
|
||||
PK__b_otherc__4E29C30D79EECCD3 | CLUSTERED
|
||||
ix_b_othercompany_bmfl_parent | NONCLUSTERED
|
||||
ix_b_othercompany_bmfl_path | NONCLUSTERED
|
||||
(共 3 行)
|
||||
@@ -2,7 +2,7 @@ import { ref } from 'vue'
|
||||
import { loadDataApi } from '@/services/api'
|
||||
|
||||
/**
|
||||
* 文件分类逻辑 —— 加载 bf_files_cateid 扁平表,供 FmsTree 展示(分类为平铺列表,无层级)。
|
||||
* 文件分类逻辑 —— 加载 bf_files_category 扁平表,供 FmsTree 展示(分类为平铺列表,无层级)。
|
||||
* 「全部分类」虚拟根由 FmsTree 的 showRoot 注入,本组合式函数只负责取数与选中状态。
|
||||
*/
|
||||
export function useFileCategory() {
|
||||
@@ -16,11 +16,7 @@ export function useFileCategory() {
|
||||
loading.value = true
|
||||
error.value = null
|
||||
try {
|
||||
const res = await loadDataApi(
|
||||
'bf_files_cateid',
|
||||
'b_canuse = 1',
|
||||
'b_xh ASC, b_id ASC',
|
||||
)
|
||||
const res = await loadDataApi('bf_files_category', 'b_canuse = 1', 'b_xh ASC, b_id ASC')
|
||||
categories.value = res.data || []
|
||||
} catch (e) {
|
||||
error.value = e?.message || String(e)
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
/**
|
||||
* 往来单位(合作伙伴)—— 左侧分类树 + 右侧模块列表。
|
||||
*
|
||||
* 左树是 b_othercompany_bmfl(b_parent_id 是权威关系,b_depth / b_path 为派生字段),
|
||||
* 左树是 b_othercompany_category(b_parent_id 是权威关系,b_depth / b_path 为派生字段),
|
||||
* 右表由 FmsModuleListPage 按模块 v_b_othercompany 的配置驱动。页面负责三件事:
|
||||
* 选中分类 → 固定查询条件(含全部下级)、b_cate_id 列显示分类名称、分类树的维护
|
||||
* (新增 / 修改 / 删除 / 刷新 / 拖拽调层级与顺序)。
|
||||
@@ -30,7 +30,7 @@ import { usePermissionStore } from '@/stores/permissions'
|
||||
import { buildTree, collectAllKeys, filterTreeByText, findTreeNode, sortTree } from '@/utils/tree'
|
||||
|
||||
const MODULE_CODE = 'v_b_othercompany' // 右侧列表模块
|
||||
const CATEGORY_TABLE = 'b_othercompany_bmfl' // 左侧分类树表
|
||||
const CATEGORY_TABLE = 'b_othercompany_category' // 左侧分类树表
|
||||
/** 必须与 FmsTree 的 rootKey 默认值一致 */
|
||||
const ALL_CATEGORY_KEY = '__fms_tree_root__'
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/**
|
||||
* 回归用例:往来单位分类树(b_othercompany_bmfl)的新增 / 修改 / 删除 / 拖拽排序。
|
||||
* 回归用例:往来单位分类树(b_othercompany_category)的新增 / 修改 / 删除 / 拖拽排序。
|
||||
*
|
||||
* 1) b_path 为 not null 且无默认值(b_depth / b_xh / b_canuse 才有默认值),新增分类时
|
||||
* 必须按父级派生 b_depth / b_path 一起写入,否则插入直接失败;
|
||||
@@ -77,7 +77,7 @@ beforeEach(() => {
|
||||
Message.warning.mockClear()
|
||||
modalConfirm.mockReset()
|
||||
loadDataApi.mockImplementation((view) => {
|
||||
if (view === 'b_othercompany_bmfl')
|
||||
if (view === 'b_othercompany_category')
|
||||
return Promise.resolve({ data: CATEGORIES.map((row) => ({ ...row })) })
|
||||
return Promise.resolve({ data: [] })
|
||||
})
|
||||
@@ -110,7 +110,7 @@ describe('往来单位:新增分类写派生树字段', () => {
|
||||
await wrapper.vm.onCategorySubmit({ b_id: 'newcat', b_name: '新分类', b_xh: 30 })
|
||||
await flushPromises()
|
||||
|
||||
const request = lastRequestOf('b_othercompany_bmfl')
|
||||
const request = lastRequestOf('b_othercompany_category')
|
||||
expect(request.key_field).toBe('b_id')
|
||||
expect(request.inserts).toHaveLength(1)
|
||||
expect(request.inserts[0]).toMatchObject({
|
||||
@@ -131,7 +131,7 @@ describe('往来单位:新增分类写派生树字段', () => {
|
||||
await wrapper.vm.onCategorySubmit({ b_id: 'child2', b_name: '三级分类', b_xh: 20 })
|
||||
await flushPromises()
|
||||
|
||||
expect(lastRequestOf('b_othercompany_bmfl').inserts[0]).toMatchObject({
|
||||
expect(lastRequestOf('b_othercompany_category').inserts[0]).toMatchObject({
|
||||
b_id: 'child2',
|
||||
b_parent_id: 'root1',
|
||||
b_depth: 1,
|
||||
@@ -148,7 +148,7 @@ describe('往来单位:修改分类', () => {
|
||||
await wrapper.vm.onCategorySubmit({ b_id: 'child1', b_name: '改过的名字', b_xh: 99 })
|
||||
await flushPromises()
|
||||
|
||||
const request = lastRequestOf('b_othercompany_bmfl')
|
||||
const request = lastRequestOf('b_othercompany_category')
|
||||
expect(request.inserts).toBeUndefined()
|
||||
expect(request.updates).toHaveLength(1)
|
||||
expect(request.updates[0]).toEqual({ b_id: 'child1', b_name: '改过的名字', b_xh: 99 })
|
||||
@@ -190,7 +190,7 @@ describe('往来单位:删除分类的两条守卫', () => {
|
||||
await modalConfirm.mock.calls[0][0].onOk()
|
||||
await flushPromises()
|
||||
|
||||
const request = lastRequestOf('b_othercompany_bmfl')
|
||||
const request = lastRequestOf('b_othercompany_category')
|
||||
expect(request.deletes).toEqual([{ b_id: 'child1' }])
|
||||
})
|
||||
})
|
||||
|
||||
@@ -22,7 +22,7 @@ GO
|
||||
drop table if exists dbo.b_othercompany_accountbank;
|
||||
GO
|
||||
|
||||
drop table if exists dbo.b_othercompany_bmfl;
|
||||
drop table if exists dbo.b_othercompany_category;
|
||||
GO
|
||||
|
||||
drop table if exists dbo.b_othercompany_partner_type;
|
||||
@@ -126,7 +126,7 @@ GO
|
||||
分类树
|
||||
============================================================================ */
|
||||
|
||||
create table dbo.b_othercompany_bmfl (
|
||||
create table dbo.b_othercompany_category (
|
||||
b_id varchar(150) not null primary key, -- 节点编码(创建后不可改)
|
||||
b_parent_id varchar(150) null, -- 父节点编码,NULL 表示根节点
|
||||
b_depth int not null default 0, -- 树层级,根节点为 0
|
||||
@@ -142,12 +142,12 @@ create table dbo.b_othercompany_bmfl (
|
||||
);
|
||||
GO
|
||||
|
||||
create index ix_b_othercompany_bmfl_parent
|
||||
on dbo.b_othercompany_bmfl (b_parent_id, b_canuse, b_depth, b_xh, b_id);
|
||||
create index ix_b_othercompany_category_parent
|
||||
on dbo.b_othercompany_category (b_parent_id, b_canuse, b_depth, b_xh, b_id);
|
||||
GO
|
||||
|
||||
create index ix_b_othercompany_bmfl_path
|
||||
on dbo.b_othercompany_bmfl (b_path, b_canuse, b_id);
|
||||
create index ix_b_othercompany_category_path
|
||||
on dbo.b_othercompany_category (b_path, b_canuse, b_id);
|
||||
GO
|
||||
|
||||
/* ============================================================================
|
||||
|
||||
@@ -0,0 +1,70 @@
|
||||
/* ============================================================================
|
||||
文件表:bf_files(文件记录)/ bf_files_category(文件分类)
|
||||
----------------------------------------------------------------------------
|
||||
文件统一由文件服务托管:本地模式由后端写盘后落库,OSS 模式由前端取号直传后
|
||||
回调落库;业务表不存文件二进制,只通过 father 关联宿主业务主键。
|
||||
主键为应用层雪花(subid),不使用 identity —— OSS 直传链路由前端先取号。
|
||||
结构说明见《FMS新系统核心表结构设计.md》第 15 节。
|
||||
============================================================================ */
|
||||
|
||||
/* ----------------------------------------------------------------------------
|
||||
1. 文件分类(先建,被 bf_files.mx_cate_id 引用)
|
||||
---------------------------------------------------------------------------- */
|
||||
|
||||
drop table if exists dbo.bf_files_category;
|
||||
GO
|
||||
|
||||
create table dbo.bf_files_category (
|
||||
b_id bigint not null primary key, -- 主键(雪花,新增行由前端 nextIdApi 生成)
|
||||
b_module_id varchar(50) null, -- 归属模块(s_module.b_id);NULL = 通用分类
|
||||
b_name nvarchar(50) not null, -- 分类名称
|
||||
b_i18n varchar(150) null, -- 多语言资源键(s_i18n.b_key)
|
||||
b_files_type varchar(50) null, -- 允许的扩展名(逗号分隔,空 = 不限;预留)
|
||||
b_xh int not null default 0, -- 显示顺序
|
||||
b_canuse tinyint not null default 1, -- 是否启用(0/1)
|
||||
b_bz nvarchar(200) null, -- 备注
|
||||
b_created_by varchar(50) null, -- 创建人(用户账号)
|
||||
b_created_at datetime2 null, -- 创建时间
|
||||
b_updated_by varchar(50) null, -- 最后修改人
|
||||
b_updated_at datetime2 null -- 最后修改时间
|
||||
);
|
||||
GO
|
||||
|
||||
create index ix_bf_files_category_module
|
||||
on dbo.bf_files_category (b_module_id, b_canuse, b_xh, b_id);
|
||||
GO
|
||||
|
||||
/* ----------------------------------------------------------------------------
|
||||
2. 文件记录
|
||||
---------------------------------------------------------------------------- */
|
||||
|
||||
drop table if exists dbo.bf_files;
|
||||
GO
|
||||
|
||||
create table dbo.bf_files (
|
||||
subid bigint not null primary key, -- 文件主键(雪花,应用层取号:本地由后端、OSS 直传由前端先取号)
|
||||
father bigint null, -- 宿主业务主键(业务表 b_id),列表按它聚合
|
||||
mx_filename nvarchar(500) null, -- 原始文件名(含扩展名,展示与下载用)
|
||||
mx_filesize varchar(50) null, -- 文件大小(字节,字符串存储)
|
||||
mx_fileext varchar(50) null, -- 扩展名(小写、不含点)
|
||||
mx_mapfilename nvarchar(500) null, -- 访问地址:本地为 {url-prefix}/{org}/{yyyy}/{MM}/{dd}/{uuid}.{ext},OSS 为完整 URL
|
||||
mx_moduleid varchar(50) null, -- 业务模块编码(s_module.b_id)
|
||||
mx_cate_id bigint null, -- 文件分类(bf_files_category.b_id)
|
||||
mx_xh int not null default 0, -- 排序号(保留;当前实现固定 0,列表按 subid 倒序)
|
||||
mx_sh tinyint not null default 0, -- 审核标识(保留;当前实现固定 0)
|
||||
mx_shuser_id varchar(50) null, -- 审核人(保留)
|
||||
mx_shdatetime datetime2 null, -- 审核时间(保留)
|
||||
mx_cutfilename nvarchar(500) null, -- 缩略图地址(保留)
|
||||
mx_cutfilesize varchar(50) null, -- 缩略图大小(保留)
|
||||
mx_orderid varchar(50) null, -- 排序组(保留)
|
||||
mx_bz nvarchar(500) null, -- 备注(保留)
|
||||
mx_inputuser_id varchar(50) null, -- 上传人(用户账号)
|
||||
mx_inputdatetime datetime2 null, -- 上传时间
|
||||
mx_updateuser_id varchar(50) null, -- 最后修改人
|
||||
mx_updatedatetime datetime2 null -- 最后修改时间
|
||||
);
|
||||
GO
|
||||
|
||||
create index ix_bf_files_host
|
||||
on dbo.bf_files (father, mx_moduleid, mx_cate_id, mx_xh, subid);
|
||||
GO
|
||||
@@ -0,0 +1,18 @@
|
||||
/* ============================================================================
|
||||
分类表改名:b_othercompany_bmfl → b_othercompany_category
|
||||
----------------------------------------------------------------------------
|
||||
分类表命名统一为 <域>_category(去掉拼音缩写 bmfl)。
|
||||
原地改名(sp_rename),数据不动;同步改两个自定义索引名。
|
||||
已确认库内无视图 / 存储过程 / 模块配置引用旧表名,无需连带重建。
|
||||
============================================================================ */
|
||||
|
||||
exec sp_rename 'dbo.b_othercompany_bmfl', 'b_othercompany_category';
|
||||
GO
|
||||
|
||||
exec sp_rename 'dbo.b_othercompany_category.ix_b_othercompany_bmfl_parent',
|
||||
'ix_b_othercompany_category_parent', 'INDEX';
|
||||
GO
|
||||
|
||||
exec sp_rename 'dbo.b_othercompany_category.ix_b_othercompany_bmfl_path',
|
||||
'ix_b_othercompany_category_path', 'INDEX';
|
||||
GO
|
||||
@@ -1,971 +0,0 @@
|
||||
```html
|
||||
<!DOCTYPE html>
|
||||
<html lang="zh-CN">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>FMS Advanced Search Demo</title>
|
||||
|
||||
<style>
|
||||
* {
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
:root {
|
||||
--primary: #2563eb;
|
||||
--primary-soft: color-mix(in srgb, var(--primary) 8%, white);
|
||||
--border: #dcdfe6;
|
||||
--border-light: #ebeef5;
|
||||
--text: #303133;
|
||||
--text-secondary: #606266;
|
||||
--text-placeholder: #a8abb2;
|
||||
--bg: #f5f7fa;
|
||||
--white: #fff;
|
||||
--danger: #f56c6c;
|
||||
--control-height: 32px;
|
||||
}
|
||||
|
||||
body {
|
||||
margin: 0;
|
||||
font-family:
|
||||
Inter,
|
||||
"Microsoft YaHei",
|
||||
"PingFang SC",
|
||||
"Noto Sans JP",
|
||||
Arial,
|
||||
sans-serif;
|
||||
color: var(--text);
|
||||
background: var(--bg);
|
||||
font-size: 13px;
|
||||
}
|
||||
|
||||
/* ---------------- page ---------------- */
|
||||
|
||||
.page {
|
||||
height: 100vh;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
}
|
||||
|
||||
.header {
|
||||
height: 52px;
|
||||
background: #fff;
|
||||
border-bottom: 1px solid var(--border);
|
||||
display: flex;
|
||||
align-items: center;
|
||||
padding: 0 18px;
|
||||
gap: 14px;
|
||||
}
|
||||
|
||||
.header-title {
|
||||
font-size: 15px;
|
||||
font-weight: 600;
|
||||
}
|
||||
|
||||
.header-subtitle {
|
||||
color: var(--text-secondary);
|
||||
}
|
||||
|
||||
.header-spacer {
|
||||
flex: 1;
|
||||
}
|
||||
|
||||
.btn {
|
||||
height: var(--control-height);
|
||||
padding: 0 12px;
|
||||
border: 1px solid var(--border);
|
||||
border-radius: 4px;
|
||||
background: #fff;
|
||||
color: var(--text);
|
||||
cursor: pointer;
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
gap: 5px;
|
||||
}
|
||||
|
||||
.btn:hover {
|
||||
border-color: var(--primary);
|
||||
color: var(--primary);
|
||||
}
|
||||
|
||||
.btn-primary {
|
||||
background: var(--primary);
|
||||
border-color: var(--primary);
|
||||
color: #fff;
|
||||
}
|
||||
|
||||
.btn-primary:hover {
|
||||
background: #1d4ed8;
|
||||
color: #fff;
|
||||
}
|
||||
|
||||
.btn-text {
|
||||
border-color: transparent;
|
||||
background: transparent;
|
||||
color: var(--text-secondary);
|
||||
}
|
||||
|
||||
.content {
|
||||
flex: 1;
|
||||
padding: 14px 18px;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
/* ---------------- search ---------------- */
|
||||
|
||||
.search-panel {
|
||||
background: #fff;
|
||||
border: 1px solid var(--border);
|
||||
padding: 12px;
|
||||
border-radius: 4px;
|
||||
}
|
||||
|
||||
.search-row {
|
||||
display: grid;
|
||||
grid-template-columns: repeat(4, minmax(180px, 1fr));
|
||||
gap: 10px 14px;
|
||||
}
|
||||
|
||||
.field {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
min-width: 0;
|
||||
}
|
||||
|
||||
.field-label {
|
||||
flex: 0 0 auto;
|
||||
margin-right: 8px;
|
||||
white-space: nowrap;
|
||||
color: var(--text-secondary);
|
||||
}
|
||||
|
||||
.input,
|
||||
.select {
|
||||
height: var(--control-height);
|
||||
min-width: 0;
|
||||
width: 100%;
|
||||
border: 1px solid var(--border);
|
||||
border-radius: 4px;
|
||||
background: #fff;
|
||||
padding: 0 9px;
|
||||
outline: none;
|
||||
color: var(--text);
|
||||
}
|
||||
|
||||
.input:focus,
|
||||
.select:focus {
|
||||
border-color: var(--primary);
|
||||
}
|
||||
|
||||
.search-actions {
|
||||
display: flex;
|
||||
justify-content: flex-end;
|
||||
margin-top: 10px;
|
||||
gap: 6px;
|
||||
}
|
||||
|
||||
/* ---------------- table ---------------- */
|
||||
|
||||
.table-panel {
|
||||
margin-top: 12px;
|
||||
background: #fff;
|
||||
border: 1px solid var(--border);
|
||||
border-radius: 4px;
|
||||
height: calc(100% - 125px);
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
table {
|
||||
width: 100%;
|
||||
border-collapse: collapse;
|
||||
}
|
||||
|
||||
th {
|
||||
height: 38px;
|
||||
background: #fafafa;
|
||||
color: var(--text-secondary);
|
||||
font-weight: 500;
|
||||
text-align: left;
|
||||
border-bottom: 1px solid var(--border);
|
||||
padding: 0 12px;
|
||||
}
|
||||
|
||||
td {
|
||||
height: 40px;
|
||||
padding: 0 12px;
|
||||
border-bottom: 1px solid var(--border-light);
|
||||
}
|
||||
|
||||
.status {
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
padding: 2px 7px;
|
||||
border-radius: 3px;
|
||||
background: #f0f9eb;
|
||||
color: #67c23a;
|
||||
}
|
||||
|
||||
/* ---------------- drawer mask ---------------- */
|
||||
|
||||
.mask {
|
||||
position: fixed;
|
||||
inset: 0;
|
||||
background: rgba(0, 0, 0, .08);
|
||||
opacity: 0;
|
||||
pointer-events: none;
|
||||
transition: .2s;
|
||||
}
|
||||
|
||||
.mask.open {
|
||||
opacity: 1;
|
||||
pointer-events: auto;
|
||||
}
|
||||
|
||||
/* ---------------- drawer ---------------- */
|
||||
|
||||
.drawer {
|
||||
position: fixed;
|
||||
top: 0;
|
||||
right: 0;
|
||||
width: 540px;
|
||||
max-width: 90vw;
|
||||
height: 100vh;
|
||||
background: #fff;
|
||||
box-shadow: -4px 0 14px rgba(0,0,0,.12);
|
||||
transform: translateX(100%);
|
||||
transition: transform .22s ease;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
}
|
||||
|
||||
.drawer.open {
|
||||
transform: translateX(0);
|
||||
}
|
||||
|
||||
.drawer-header {
|
||||
height: 54px;
|
||||
flex: 0 0 54px;
|
||||
border-bottom: 1px solid var(--border);
|
||||
display: flex;
|
||||
align-items: center;
|
||||
padding: 0 16px;
|
||||
}
|
||||
|
||||
.drawer-title {
|
||||
font-size: 15px;
|
||||
font-weight: 600;
|
||||
}
|
||||
|
||||
.drawer-spacer {
|
||||
flex: 1;
|
||||
}
|
||||
|
||||
.close {
|
||||
width: 30px;
|
||||
height: 30px;
|
||||
border: 0;
|
||||
background: transparent;
|
||||
cursor: pointer;
|
||||
font-size: 20px;
|
||||
color: var(--text-secondary);
|
||||
}
|
||||
|
||||
.drawer-body {
|
||||
flex: 1;
|
||||
overflow: auto;
|
||||
padding: 14px 16px 80px;
|
||||
}
|
||||
|
||||
/* ---------------- saved query ---------------- */
|
||||
|
||||
.query-scheme {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 8px;
|
||||
margin-bottom: 16px;
|
||||
}
|
||||
|
||||
.query-scheme-label {
|
||||
white-space: nowrap;
|
||||
color: var(--text-secondary);
|
||||
}
|
||||
|
||||
.query-scheme .select {
|
||||
width: 190px;
|
||||
}
|
||||
|
||||
.save-btn {
|
||||
margin-left: auto;
|
||||
}
|
||||
|
||||
/* ---------------- query group ---------------- */
|
||||
|
||||
.group {
|
||||
border: 1px solid var(--border);
|
||||
border-radius: 4px;
|
||||
}
|
||||
|
||||
.group-header {
|
||||
height: 38px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
padding: 0 10px;
|
||||
background: #fafafa;
|
||||
border-bottom: 1px solid var(--border-light);
|
||||
}
|
||||
|
||||
.group-title {
|
||||
font-weight: 500;
|
||||
}
|
||||
|
||||
.group-actions {
|
||||
margin-left: auto;
|
||||
display: flex;
|
||||
gap: 8px;
|
||||
}
|
||||
|
||||
.link-btn {
|
||||
border: 0;
|
||||
background: transparent;
|
||||
padding: 0;
|
||||
cursor: pointer;
|
||||
color: var(--primary);
|
||||
font-size: 13px;
|
||||
}
|
||||
|
||||
.conditions {
|
||||
padding: 10px;
|
||||
}
|
||||
|
||||
/* ---------------- condition ---------------- */
|
||||
|
||||
.condition {
|
||||
display: grid;
|
||||
grid-template-columns: 125px 115px minmax(110px, 1fr) 26px;
|
||||
gap: 7px;
|
||||
align-items: center;
|
||||
min-height: 42px;
|
||||
}
|
||||
|
||||
.condition + .condition {
|
||||
margin-top: 5px;
|
||||
}
|
||||
|
||||
.condition .select,
|
||||
.condition .input {
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.remove-condition {
|
||||
width: 26px;
|
||||
height: 26px;
|
||||
border: 0;
|
||||
background: transparent;
|
||||
color: #a8abb2;
|
||||
cursor: pointer;
|
||||
font-size: 16px;
|
||||
}
|
||||
|
||||
.remove-condition:hover {
|
||||
color: var(--danger);
|
||||
}
|
||||
|
||||
/* ---------------- connector ---------------- */
|
||||
|
||||
.connector {
|
||||
height: 28px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.connector::before {
|
||||
content: "";
|
||||
position: absolute;
|
||||
left: 18px;
|
||||
right: 18px;
|
||||
top: 50%;
|
||||
height: 1px;
|
||||
background: var(--border-light);
|
||||
}
|
||||
|
||||
.connector span {
|
||||
position: relative;
|
||||
background: #fff;
|
||||
padding: 0 7px;
|
||||
color: var(--text-secondary);
|
||||
font-size: 12px;
|
||||
}
|
||||
|
||||
/* ---------------- group add ---------------- */
|
||||
|
||||
.add-condition {
|
||||
margin-top: 8px;
|
||||
}
|
||||
|
||||
.add-group {
|
||||
margin-top: 10px;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
}
|
||||
|
||||
/* ---------------- nested group ---------------- */
|
||||
|
||||
.nested-group {
|
||||
margin-top: 10px;
|
||||
margin-left: 12px;
|
||||
border: 1px dashed #cfd3dc;
|
||||
border-radius: 4px;
|
||||
}
|
||||
|
||||
.nested-header {
|
||||
height: 34px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
padding: 0 10px;
|
||||
background: #fafafa;
|
||||
}
|
||||
|
||||
.nested-title {
|
||||
color: var(--text-secondary);
|
||||
}
|
||||
|
||||
/* ---------------- footer ---------------- */
|
||||
|
||||
.drawer-footer {
|
||||
height: 58px;
|
||||
flex: 0 0 58px;
|
||||
border-top: 1px solid var(--border);
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: flex-end;
|
||||
gap: 8px;
|
||||
padding: 0 16px;
|
||||
background: #fff;
|
||||
}
|
||||
|
||||
/* ---------------- active filters ---------------- */
|
||||
|
||||
.active-filters {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 6px;
|
||||
margin-top: 10px;
|
||||
flex-wrap: wrap;
|
||||
}
|
||||
|
||||
.active-label {
|
||||
color: var(--text-secondary);
|
||||
}
|
||||
|
||||
.tag {
|
||||
height: 26px;
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
gap: 5px;
|
||||
padding: 0 8px;
|
||||
border: 1px solid #d9ecff;
|
||||
border-radius: 3px;
|
||||
background: #f4f9ff;
|
||||
color: #409eff;
|
||||
}
|
||||
|
||||
.tag-close {
|
||||
cursor: pointer;
|
||||
color: #79bbff;
|
||||
}
|
||||
|
||||
/* ---------------- responsive ---------------- */
|
||||
|
||||
@media (max-width: 900px) {
|
||||
.search-row {
|
||||
grid-template-columns: repeat(2, 1fr);
|
||||
}
|
||||
|
||||
.drawer {
|
||||
width: 520px;
|
||||
}
|
||||
}
|
||||
|
||||
@media (max-width: 600px) {
|
||||
.search-row {
|
||||
grid-template-columns: 1fr;
|
||||
}
|
||||
|
||||
.condition {
|
||||
grid-template-columns: 1fr 1fr;
|
||||
}
|
||||
|
||||
.condition .value {
|
||||
grid-column: 1 / 3;
|
||||
}
|
||||
|
||||
.condition .remove-condition {
|
||||
position: absolute;
|
||||
right: 10px;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
|
||||
<div class="page">
|
||||
|
||||
<!-- Header -->
|
||||
<div class="header">
|
||||
<div class="header-title">订舱管理</div>
|
||||
<div class="header-subtitle">Booking Orders</div>
|
||||
|
||||
<div class="header-spacer"></div>
|
||||
|
||||
<button class="btn">新增</button>
|
||||
<button class="btn">导出</button>
|
||||
<button class="btn" onclick="openDrawer()">高级搜索</button>
|
||||
</div>
|
||||
|
||||
<!-- Content -->
|
||||
<div class="content">
|
||||
|
||||
<!-- Simple search -->
|
||||
<div class="search-panel">
|
||||
|
||||
<div class="search-row">
|
||||
|
||||
<div class="field">
|
||||
<div class="field-label">订舱号</div>
|
||||
<input class="input" placeholder="请输入">
|
||||
</div>
|
||||
|
||||
<div class="field">
|
||||
<div class="field-label">客户</div>
|
||||
<input class="input" placeholder="请输入">
|
||||
</div>
|
||||
|
||||
<div class="field">
|
||||
<div class="field-label">业务员</div>
|
||||
<input class="input" placeholder="请输入">
|
||||
</div>
|
||||
|
||||
<div class="field">
|
||||
<div class="field-label">状态</div>
|
||||
<select class="select">
|
||||
<option>全部</option>
|
||||
<option>草稿</option>
|
||||
<option>已确认</option>
|
||||
<option>已完成</option>
|
||||
</select>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
<div class="search-actions">
|
||||
<button class="btn">重置</button>
|
||||
<button class="btn btn-primary">查询</button>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
<!-- Active conditions -->
|
||||
<div class="active-filters">
|
||||
<span class="active-label">当前条件:</span>
|
||||
|
||||
<span class="tag">
|
||||
客户 = ABC Logistics
|
||||
<span class="tag-close">×</span>
|
||||
</span>
|
||||
|
||||
<span class="tag">
|
||||
金额 > 10000
|
||||
<span class="tag-close">×</span>
|
||||
</span>
|
||||
|
||||
<span class="tag">
|
||||
日期 ≥ 2026-09-01
|
||||
<span class="tag-close">×</span>
|
||||
</span>
|
||||
</div>
|
||||
|
||||
<!-- Table -->
|
||||
<div class="table-panel">
|
||||
|
||||
<table>
|
||||
<thead>
|
||||
<tr>
|
||||
<th width="150">订舱号</th>
|
||||
<th>客户</th>
|
||||
<th>业务员</th>
|
||||
<th>金额</th>
|
||||
<th>开船日期</th>
|
||||
<th>状态</th>
|
||||
</tr>
|
||||
</thead>
|
||||
|
||||
<tbody>
|
||||
<tr>
|
||||
<td>BK202609001</td>
|
||||
<td>ABC Logistics</td>
|
||||
<td>张三</td>
|
||||
<td>25,800.00</td>
|
||||
<td>2026-09-05</td>
|
||||
<td><span class="status">已确认</span></td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td>BK202609002</td>
|
||||
<td>XYZ Shipping</td>
|
||||
<td>李四</td>
|
||||
<td>18,600.00</td>
|
||||
<td>2026-09-08</td>
|
||||
<td><span class="status">已完成</span></td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td>BK202609003</td>
|
||||
<td>ABC Logistics</td>
|
||||
<td>王五</td>
|
||||
<td>12,500.00</td>
|
||||
<td>2026-09-12</td>
|
||||
<td><span class="status">已确认</span></td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Mask -->
|
||||
<div id="mask" class="mask" onclick="closeDrawer()"></div>
|
||||
|
||||
<!-- Drawer -->
|
||||
<div id="drawer" class="drawer">
|
||||
|
||||
<div class="drawer-header">
|
||||
<div class="drawer-title">高级搜索</div>
|
||||
<div class="drawer-spacer"></div>
|
||||
<button class="close" onclick="closeDrawer()">×</button>
|
||||
</div>
|
||||
|
||||
<div class="drawer-body">
|
||||
|
||||
<!-- Query scheme -->
|
||||
<div class="query-scheme">
|
||||
|
||||
<span class="query-scheme-label">查询方案</span>
|
||||
|
||||
<select class="select">
|
||||
<option>我的查询</option>
|
||||
<option>最近一个月</option>
|
||||
<option>未完成订单</option>
|
||||
<option>高金额订单</option>
|
||||
<option>系统默认</option>
|
||||
</select>
|
||||
|
||||
<button class="btn save-btn">保存</button>
|
||||
</div>
|
||||
|
||||
<!-- Main group -->
|
||||
<div class="group">
|
||||
|
||||
<div class="group-header">
|
||||
|
||||
<span class="group-title">
|
||||
满足以下全部条件
|
||||
</span>
|
||||
|
||||
<div class="group-actions">
|
||||
<button class="link-btn">全部</button>
|
||||
<button class="link-btn">任一</button>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
<div class="conditions" id="conditions">
|
||||
|
||||
<!-- condition 1 -->
|
||||
<div class="condition">
|
||||
|
||||
<select class="select field-select">
|
||||
<option value="customer">客户</option>
|
||||
<option value="bookingNo">订舱号</option>
|
||||
<option value="sales">业务员</option>
|
||||
<option value="amount">金额</option>
|
||||
<option value="date">开船日期</option>
|
||||
<option value="status">状态</option>
|
||||
</select>
|
||||
|
||||
<select class="select operator">
|
||||
<option>=</option>
|
||||
<option>≠</option>
|
||||
<option>包含</option>
|
||||
<option>不包含</option>
|
||||
</select>
|
||||
|
||||
<input class="input value" value="ABC Logistics">
|
||||
|
||||
<button class="remove-condition">×</button>
|
||||
|
||||
</div>
|
||||
|
||||
<!-- connector -->
|
||||
<div class="connector">
|
||||
<span>AND</span>
|
||||
</div>
|
||||
|
||||
<!-- condition 2 -->
|
||||
<div class="condition">
|
||||
|
||||
<select class="select field-select">
|
||||
<option value="amount">金额</option>
|
||||
<option value="customer">客户</option>
|
||||
<option value="bookingNo">订舱号</option>
|
||||
<option value="sales">业务员</option>
|
||||
<option value="date">开船日期</option>
|
||||
<option value="status">状态</option>
|
||||
</select>
|
||||
|
||||
<select class="select operator">
|
||||
<option>></option>
|
||||
<option>>=</option>
|
||||
<option>=</option>
|
||||
<option><</option>
|
||||
<option><=</option>
|
||||
<option>≠</option>
|
||||
</select>
|
||||
|
||||
<input class="input value" value="10000">
|
||||
|
||||
<button class="remove-condition">×</button>
|
||||
|
||||
</div>
|
||||
|
||||
<!-- connector -->
|
||||
<div class="connector">
|
||||
<span>AND</span>
|
||||
</div>
|
||||
|
||||
<!-- condition 3 -->
|
||||
<div class="condition">
|
||||
|
||||
<select class="select field-select">
|
||||
<option value="date">开船日期</option>
|
||||
<option value="customer">客户</option>
|
||||
<option value="bookingNo">订舱号</option>
|
||||
<option value="sales">业务员</option>
|
||||
<option value="amount">金额</option>
|
||||
<option value="status">状态</option>
|
||||
</select>
|
||||
|
||||
<select class="select operator">
|
||||
<option>>=</option>
|
||||
<option>></option>
|
||||
<option>=</option>
|
||||
<option><</option>
|
||||
<option><=</option>
|
||||
</select>
|
||||
|
||||
<input class="input value" type="date" value="2026-09-01">
|
||||
|
||||
<button class="remove-condition">×</button>
|
||||
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
<div style="padding:0 10px 12px;">
|
||||
<button class="link-btn" onclick="addCondition()">
|
||||
+ 添加条件
|
||||
</button>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
<!-- Nested group -->
|
||||
<div class="nested-group">
|
||||
|
||||
<div class="nested-header">
|
||||
<span class="nested-title">
|
||||
满足以下任一条件
|
||||
</span>
|
||||
|
||||
<div class="group-actions">
|
||||
<button class="link-btn">删除条件组</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="conditions">
|
||||
|
||||
<div class="condition">
|
||||
|
||||
<select class="select">
|
||||
<option>港口</option>
|
||||
<option>客户</option>
|
||||
<option>业务员</option>
|
||||
</select>
|
||||
|
||||
<select class="select">
|
||||
<option>=</option>
|
||||
<option>包含</option>
|
||||
</select>
|
||||
|
||||
<input class="input" value="Shanghai">
|
||||
|
||||
<button class="remove-condition">×</button>
|
||||
|
||||
</div>
|
||||
|
||||
<div class="connector">
|
||||
<span>OR</span>
|
||||
</div>
|
||||
|
||||
<div class="condition">
|
||||
|
||||
<select class="select">
|
||||
<option>港口</option>
|
||||
<option>客户</option>
|
||||
<option>业务员</option>
|
||||
</select>
|
||||
|
||||
<select class="select">
|
||||
<option>=</option>
|
||||
<option>包含</option>
|
||||
</select>
|
||||
|
||||
<input class="input" value="Ningbo">
|
||||
|
||||
<button class="remove-condition">×</button>
|
||||
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
<div class="add-group">
|
||||
<button class="link-btn">
|
||||
+ 添加条件组
|
||||
</button>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
<div class="drawer-footer">
|
||||
<button class="btn">重置</button>
|
||||
<button class="btn">取消</button>
|
||||
<button class="btn btn-primary" onclick="doSearch()">查询</button>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
<script>
|
||||
|
||||
function openDrawer() {
|
||||
document.getElementById("drawer").classList.add("open");
|
||||
document.getElementById("mask").classList.add("open");
|
||||
}
|
||||
|
||||
function closeDrawer() {
|
||||
document.getElementById("drawer").classList.remove("open");
|
||||
document.getElementById("mask").classList.remove("open");
|
||||
}
|
||||
|
||||
function addCondition() {
|
||||
|
||||
const container = document.getElementById("conditions");
|
||||
|
||||
const connector = document.createElement("div");
|
||||
connector.className = "connector";
|
||||
connector.innerHTML = "<span>AND</span>";
|
||||
|
||||
const condition = document.createElement("div");
|
||||
condition.className = "condition";
|
||||
|
||||
condition.innerHTML = `
|
||||
<select class="select">
|
||||
<option>客户</option>
|
||||
<option>订舱号</option>
|
||||
<option>业务员</option>
|
||||
<option>金额</option>
|
||||
<option>开船日期</option>
|
||||
<option>状态</option>
|
||||
</select>
|
||||
|
||||
<select class="select">
|
||||
<option>=</option>
|
||||
<option>≠</option>
|
||||
<option>包含</option>
|
||||
<option>不包含</option>
|
||||
<option>></option>
|
||||
<option>>=</option>
|
||||
<option><</option>
|
||||
<option><=</option>
|
||||
</select>
|
||||
|
||||
<input class="input" placeholder="请输入">
|
||||
|
||||
<button class="remove-condition"
|
||||
onclick="this.parentElement.remove()">×</button>
|
||||
`;
|
||||
|
||||
container.appendChild(connector);
|
||||
container.appendChild(condition);
|
||||
}
|
||||
|
||||
function doSearch() {
|
||||
|
||||
/*
|
||||
* 实际项目中这里不直接拼 SQL。
|
||||
*
|
||||
* UI 最终转换成统一 Query AST,例如:
|
||||
*
|
||||
* {
|
||||
* type: "group",
|
||||
* operator: "AND",
|
||||
* children: [
|
||||
* {
|
||||
* field: "customer",
|
||||
* operator: "=",
|
||||
* value: "ABC Logistics"
|
||||
* },
|
||||
* {
|
||||
* field: "amount",
|
||||
* operator: ">",
|
||||
* value: 10000
|
||||
* },
|
||||
* {
|
||||
* field: "date",
|
||||
* operator: ">=",
|
||||
* value: "2026-09-01"
|
||||
* },
|
||||
* {
|
||||
* type: "group",
|
||||
* operator: "OR",
|
||||
* children: [
|
||||
* {
|
||||
* field: "port",
|
||||
* operator: "=",
|
||||
* value: "Shanghai"
|
||||
* },
|
||||
* {
|
||||
* field: "port",
|
||||
* operator: "=",
|
||||
* value: "Ningbo"
|
||||
* }
|
||||
* ]
|
||||
* ]
|
||||
* }
|
||||
*/
|
||||
|
||||
closeDrawer();
|
||||
|
||||
alert("查询条件已应用");
|
||||
}
|
||||
|
||||
</script>
|
||||
|
||||
</body>
|
||||
</html>
|
||||
```
|
||||
Reference in new issue
Block a user