构建管理员审批系统的最佳实践

Best Practices to Build an Admin Approval System

应该有一个管理面板的子系统,不同的用户可以管理他们的产品,但每个更改都应该在影响主产品之前得到管理员的批准 table。 主要有三个 table:

  1. Product : 存储已最终批准并在整个系统中使用的产品
  2. Changes_versions :与产品 Table 具有一对多关系的 table 表示每个更改版本由 who 、 when 和 is approved/rejected 由 admin 或仍处于 Pending 状态。table 结构如下:

    CREATE TABLE `changes_versions` (
      `xid` int(11) unsigned NOT NULL AUTO_INCREMENT,
      `xcreated_date` datetime DEFAULT NULL,
      `xupdated_date` timestamp NULL DEFAULT NULL,
      `xversion` int(11) DEFAULT NULL,
      `xobject_id` int(11) DEFAULT NULL,
      `xobject_type` varchar(255) DEFAULT NULL,
      `xstate` enum('PENDING','ACCEPTED','REJECTED') DEFAULT 'PENDING',
      PRIMARY KEY (`xid`)
    ) ENGINE=InnoDB AUTO_INCREMENT=165 DEFAULT CHARSET=utf8
    
  3. 更改:table 与 Changes_versions 具有一对多关系 table 保留主 Table 的每一列更改记录(这里我指的是产品 table) 并且通过管理员批准 change_version 记录,其相关更改记录将放在主 table 列中。 table结构如下:

    CREATE TABLE `changes` (
      `xid` int(11) unsigned NOT NULL AUTO_INCREMENT,
      `xcreated_date` datetime DEFAULT NULL,
      `xcreated_by` varchar(255) DEFAULT NULL,
      `xupdated_date` timestamp NULL DEFAULT NULL,
      `xupdated_by` varchar(255) DEFAULT NULL,
      `xversion_id` int(11) DEFAULT NULL,
      `xcolumn_name` varchar(255) DEFAULT NULL,
      `xcolumn_value` varchar(255) DEFAULT NULL,
      `xstate` enum('PENDING','ACCEPTED','REJECTED') DEFAULT 'PENDING',
      `xadmin_review` text,
      PRIMARY KEY (`xid`)
    ) ENGINE=InnoDB AUTO_INCREMENT=764 DEFAULT CHARSET=utf8
    

使用此系统和 table 我处理记录更改的模式,用户获取记录列表,如果用户有任何待处理状态 change_version,系统将提取其相关更改记录并放置它们在获取的产品行的右列中(临时仅用于显示),因此即使用户有任何未决状态更改 he/she 也可以在 his/hes 面板中看到其更改(不是主系统,只有 his/her面板)。

问题是关于插入新记录,我可以创建一个 change_version 记录并将所有用户数据保存到更改 table 指向新的 change_vesrion 记录但是 change_vesrsion记录未连接到任何产品记录,因为没有记录。

请注意,基于系统复杂性和当前稳定性,我不想向产品 table 添加任何列来指示这是临时记录。

所以我想要一个策略来处理问题,比如当我在用户面板中对产品进行分页并用最后的待定更改填充它们时,没有用于插入记录的产品记录来填充更改,因此用户看不到 his/her之前插入的产品。


我还应该注意到,这个 table 的结构对于这个 question.this 的结构来说有些复杂,因为 changes_vesrsion 和更改 table 的保存和呈现许多具有不同结构的 table 的历史和管理审批流程。

我认为 SQL 视图在这里很方便,更改您的 table 名称并添加一个标志字段,临时行被该字段标记,然后创建一个名称为 Product 的视图并排除它视图中此字段标记的字段和行,这样您的原始 Table(现在已转换为视图)将保持不变

让我先用我的话描述一下你的问题(如果我错了请纠正我)。

您的系统中有不同的项目(如产品),每个项目类型有一个 (InnoDB) table。 每个项目 table 都有一个 AUTO_INCREMENT 列(如 id)。 您有一个项目版本 table (changes_versions) 来存储特定项目的不同版本。 该项目由

列标识
  • xobject_type(如 'product')引用 table
  • xobject_id 这是一个 "polymorphic foreign key" 引用上面 table 的 PK

问题:当用户创建新项目时,不应将其插入到项目中 table, 但您需要一个参考才能存储在 xobject_id 列中。

可能的解决方案:"Reserve" 通过在事务中插入和删除行来获取 ID。

示例:

start transaction;
insert into products(column_1, column_2) values ('value_1', 'value_2');
delete from products where id = last_insert_id();
select last_insert_id();
commit;

您将获得:

  • 插入的行永远不会对其他用户可见,因为它在同一事务中被删除。
  • last_insert_id() 仍会 return 从删除的行中自动生成的 ID;
  • 该 ID 将为 "burned",因此引擎将不再生成它。
  • 当管理员接受该项目时,您仍然可以手动插入该 ID。
  • 不需要更改数据库架构。

演示:http://rextester.com/IJB42705

解决此问题的方法是按照描述创建所有 table,当用户在 changes_version table 中创建产品时,应该有一个 mysql 事件 定期检查product table 中的每条记录并将其与changes_version table 匹配。如果在 changed_version table 中发现任何更改或新插入,则 product table 应相应地 inserted/updated。

修改后的解决方案:

您可以通过在用户登录时将 changes_version 中的用户记录插入产品 table 并在注销时将其删除来实现。这适用于尚未移入 product table 的产品,您可以通过查询查看。

如果您有前端源,那么您可以仅向用户显示 changes_version 记录,并在获得批准后通过触发器将其移动到 product table。