触发器,弹出窗口,合约状态改变时

触发器,弹出窗口,合同状态改变时。

客户要求系统具有类似QQ弹窗的效果,当一条流程状态改变时,另一用户只要开着客户端,右下角弹窗。

USE [XXXXX]
GO
/****** Object:  Trigger [dbo].[trg_biz_Cont]    Script Date: 2016/4/28 11:21:37 ******/
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO


ALTER TRIGGER [dbo].[trg_biz_Cont] ON [dbo].[biz_Cont] AFTER INSERT, UPDATE
AS 
BEGIN
  IF UPDATE(ContStatusId)
  BEGIN


 declare @batchid uniqueidentifier = newid();


 WITH CTE_ToDo_DeptTask AS 
 (
 SELECT 10102 AS BizTypeId, '处理监督' AS ToDo, 'f101002' AS Uri, 100 AS ContStatusId
 UNION
 SELECT 10103, '处理检验', 'f101501', 100
 UNION
 SELECT 10104, '处理计量', 'f101502', 100
 UNION
 SELECT 0, '评审合同', 'f101004', 110
 UNION
 SELECT 0, '签发合同', 'f101006', 120
 UNION
 SELECT 10101, '分配委托任务', 'f101007', 130
 )
 INSERT INTO GNotification(GContent, GNavigateUri, BizId, CreateBatchId)
 SELECT '您有新的待办事项【' + CTE_ToDo_DeptTask.ToDo + '】: ' + ISNULL (INSERTED.ProdName,'') + '(' + INSERTED.ContNo + ')'
 , CTE_ToDo_DeptTask.Uri, INSERTED.ContId, @batchid FROM INSERTED 
  INNER JOIN DELETED ON DELETED.ContId = INSERTED.ContId 
 INNER JOIN CTE_ToDo_DeptTask ON IIF(CTE_ToDo_DeptTask.BizTypeId = 0, INSERTED.BizTypeId, CTE_ToDo_DeptTask.BizTypeId) = INSERTED.BizTypeId 
 WHERE INSERTED.ContStatusId = CTE_ToDo_DeptTask.ContStatusId 
 --AND NOT EXISTS(SELECT 1 FROM DELETED WHERE DELETED.ContId = INSERTED.ContId AND DELETED.ContStatusId = INSERTED.ContStatusId) --用于判定ContStatusId确实发生了变化
      and INSERTED.ContStatusId != DELETED.ContStatusId 




 INSERT INTO GNotificationReceiver(GNotiId, GReceiveUserId)
 SELECT n.GNotiId, u.UserId FROM GNotification n
 INNER JOIN biz_Cont c ON c.ContId = n.BizId
 CROSS APPLY
 (
     SELECT u1.UserId FROM sys_User u1  
 WHERE EXISTS(SELECT 1 FROM View_UserFucntion uf WHERE uf.UserId = u1.UserId AND uf.FunctionId = CONVERT(INT, SUBSTRING(n.GNavigateUri, 2, 1000))) --客户必须是有功能权限的
 AND 
  (
 (c.ContStatusId in (100,110) AND u1.DeptId = c.AcceptDeptId)  --处理合同的时候需判断受理部门
 OR (c.ContStatusId = 110) AND  u1.DeptId  = 5             -----总师办评审不判断部门
 OR (c.ContStatusId = 120) --签发时无需判断
 OR (c.ContStatusId = 130 AND u1.DeptId = c.AcceptDeptId OR c.ContId IN (SELECT ContId FROM biz_DeptTask WHERE DeptId = u1.DeptId)) --分配委托任务的时候需判断受理部门或部门任务
  )
 ) u  
 WHERE n.CreateBatchId = @batchid
  END   
END



--------思路:既然要通知,可以通过WINDOWS中的服务,来巡查通知表3秒一次。构建两个通知表  GNotification  ,GNotificationReceiver,一个关于权限的视图View_UserFucntion


当合同表状态改变时,根据情况插入通知表和通知人表。达到弹窗的目的。

其中有几个SQLSERVER2005以上版本用到的函数,方法,比如 WHIT_CTE   , IIF(),  CROSS APPLY 

感兴趣的可以搜索学习如何使用。 WITH_CTE 和 IIF() 很简单。

说一下 CROSS APPLY,套用别人的,看图举例:


触发器,弹出窗口,合约状态改变时


它是先得出左表【dbo.Customers】里的数据,然后把此数据一条一条的放入右表表式中,分别得出结果集,最后把结果集整合到一起就是最终的返回结果集了(T1的数据 像for循环一样 一条一条的进入到T2中 然后返回一个集合  最后把所有的集合整合到一块  就是最终的结果),最后我们再理解一下上面让记着的话(使用apply就像是先计算左输入,让后为左输入中的每一行计算一次右输入)是不是有所明白了。


本人水平比较一般,如有错漏,请大侠指正。