初始提交:QuickTeam 工单接口导入工具

用「WCF + 通用存储过程网关」接口替代 Selenium(D://Learning//Python//工单自动化)导入工单:
单 Sprint 12 个项目 175s 跑完(旧方案 25~35 分钟),失败可断点续跑且不重复建单。

- 分层:transport(HTTP/协议)/ api(存储过程语义)/ domain(纯规则)/
  workflow(阶段编排)/ store(SQLite 台账)/ report / CLI
- 幂等:台账驱动断点续跑;dry-run 与跳过行不污染进度;--rollback-on-fail 清理半成品
- 命令:plan / apply / report / status,真实写入需 --yes
- tools:只读探针、存储过程源码导出(sp_helptext)、导入诊断
- docs:调研与设计文档(含联调踩到的 5 个坑)+ 6 个关键存储过程源码

实测:Sprint 2026 Sprint 10 的 12 个项目全部完成建单→导入→确认→推送 TFS,
工单 225134–225145,35 个功能模块,重跑 plan 全部 skip-pushed。69 个单测通过。
This commit is contained in:
chenshoulin
2026-11-05 19:14:25 +08:00
commit 58850314cf
32 changed files with 4590 additions and 0 deletions
@@ -0,0 +1,11 @@
CREATE PROCEDURE [QuickTeam].[usp_BatchImportWorkFeaturesByFeatureIds]␍
@FeatureIds nvarchar(max)␍
AS␍
BEGIN␍
select FeatureCode AS N'模块代码',FeatureName as N'服务模块' , FeatureContent as N'服务内容',FeatureCode+'('+FeatureName+':'+FeatureContent+')' as BackLogItemCode FROM QuickTeam.Feature WHERE FeatureId in (select Data from [QuickTeam].[StringSplit]␍
(@FeatureIds,',')␍
) and FeatureCode!=''␍
END␍
␍
--test␍
--exec [QuickTeam].[usp_BatchGetWorkFeaturesByWorkSheetIds] '1,5'␍
@@ -0,0 +1,38 @@
-- =============================================␍
-- Author: <Author,,Name>␍
-- Create date: <Create Date,,>␍
-- Description: <Description,,>␍
-- =============================================␍
CREATE PROCEDURE [QuickTeam].[usp_GetWeeklyWorkSheetsByProjectId] ␍
@ProjectId nvarchar(50),␍
@Monday nvarchar(50),␍
@Sunday nvarchar(50)␍
AS␍
BEGIN␍
␍
DECLARE @dt datetime,@qstartday datetime,@qendday datetime␍
SET @dt=convert(datetime,@Monday)␍
--2.指定日期所在季度的第一天或最后一天␍
SELECT @qstartday=DATEADD(qq, DATEDIFF(qq, 0, @dt), 0) ,␍
@qendday=DATEADD(Day,-1,␍
CONVERT(char(8),␍
DATEADD(Month,␍
1+DATEPART(Quarter,@dt)*3-Month(@dt),␍
@dt),␍
120)+'1')␍
␍
select ␍
ws.[WorkSheetId]␍
,ws.WorkSheetCode␍
,ws.[ProjectId]␍
,ws.[ProjectName]␍
,ws.[StartTime]␍
,ws.[EndTime]␍
,ws.Finished␍
,ws.[Status]␍
from [QuickTeam].[QuickTeam].[WorkSheet] ws ␍
where projectid=@ProjectId AND DeleteFlag<>1 and isReclaimed=0␍
and ((StartTime between @qstartday and @qendday) or (EndTime between @qstartday and @qendday))␍
order by Finished ,WorkSheetId␍
␍
END␍
+12
View File
@@ -0,0 +1,12 @@
CREATE PROCEDURE [QuickTeam].[usp_GetWorkSheetById] ␍
@WorkSheetId bigint␍
AS␍
BEGIN␍
SET NOCOUNT ON;␍
--select * from [QuickTeam].[WorkSheet] where WorkSheetId=@WorkSheetId␍
select ws.*,wv.VersionCode from [QuickTeam].[WorkSheet] as ws␍
left join [QuickTeam].[WorkSheetVersion] wv on ws.CurrentVersionId=wv.VersionId␍
where ws.WorkSheetId=@WorkSheetId␍
END␍
␍
␍
+77
View File
@@ -0,0 +1,77 @@
-- =============================================␍
-- Author: <Author,,Name>␍
-- Create date: <Create Date,,>␍
-- Description: <Description,,>␍
-- =============================================␍
CREATE PROCEDURE [QuickTeam].[usp_GetWorkSheetsById] ␍
@ProjectId nvarchar(50),␍
@isReclaimed bit=0␍
AS␍
BEGIN␍
SELECT␍
WorksheetId,␍
convert(nvarchar,sum([PaymentPercent])) as PaymentPercent␍
into #receiv␍
FROM [QuickTeam].[QuickTeam].[WorksheetPayment] group by WorksheetId␍
␍
select t.*␍
,(case ␍
when t.Finished='02' or t.Finished='03' then N'无回款'␍
else ␍
case when rs.StatusAlia=N'回款已经确认' and PaymentPercent is null then N'开票已经确认'␍
else iif(rs.StatusAlia=N'回款已经确认',rs.StatusAlia+N'(累计回款:'+r.PaymentPercent+'%)',rs.StatusAlia) end␍
end␍
) as 'ReceiveStatusName'␍
--,rs.StatusAlia␍
--,iif(rs.StatusAlia=N'回款已经确认',rs.StatusAlia+N'(累计回款:'+r.PaymentPercent+'%)',rs.StatusAlia) as 'ReceiveStatusName'␍
,s.ServiceTypeAlias, r.PaymentPercent,e.Effort,f.Effort CurrentEffort from (␍
select ws.*,''as VersionId,'' as VersionCode,'' as VersionStatus,'' as NextOperator,'' as Operator from [QuickTeam].[QuickTeam].[WorkSheet] ws␍
union␍
select ␍
ws.[WorkSheetId]␍
,wv.VersionCode as WorkSheetCode␍
,ws.[ProjectId]␍
,ws.[ProjectName]␍
,ws.[SystemName]␍
,ws.[Evaluator]␍
,ws.[TechnicalLeader]␍
,ws.[CustomerLeader]␍
,ws.[StartTime]␍
,ws.[EndTime]␍
,wv.[UpdateTime]␍
,ws.[Status]␍
,ws.ReceiveStatus␍
,ws.Finished␍
,ws.Finishtime␍
,ws.[ServiceType]␍
,ws.[ImplementContent]␍
,ws.[OtherInstructions]␍
,ws.CurrentVersionId␍
,ws.isMerge␍
,ws.DeleteFlag␍
,ws.Operation ␍
,ws.OperateUserName␍
,ws.isReclaimed␍
,ws.BelongTeam␍
,wv.VersionId,wv.VersionCode,wv.VersionStatus,wv.NextOperator,wv.Operator from [QuickTeam].[QuickTeam].[WorkSheet] ws ␍
join [QuickTeam].[WorkSheetVersion] wv␍
on ws.WorkSheetId=wv.WorkSheetId ␍
␍
) as t␍
left join #receiv r on r.WorksheetId=t.WorkSheetId␍
left join (␍
select distinct ServiceType,ServiceTypeAlias from ␍
QuickTeam.ServiceTypeTaskName) s␍
on t.ServiceType=s.ServiceType␍
left join QuickTeam.WorkSheetReceiveStatus rs on t.receiveStatus=rs.statusid␍
left join (SELECT [VersionId]␍
,sum([Effort]) [Effort]␍
FROM [QuickTeam].[QuickTeam].[WorkSheetTask] group by VersionId) e on t.VersionId=e.VersionId␍
left join (SELECT [VersionId]␍
,sum([Effort]) [Effort]␍
FROM [QuickTeam].[QuickTeam].[WorkSheetTask] group by VersionId) f on t.CurrentVersionId=f.VersionId␍
where projectid=@ProjectId AND t.DeleteFlag<>1 and isReclaimed=@isReclaimed␍
order by Finished ,WorkSheetId,VersionId␍
␍
drop table #receiv␍
END␍
+55
View File
@@ -0,0 +1,55 @@
CREATE PROCEDURE [QuickTeam].[usp_InsertWorkSheet]␍
-- Add the parameters for the stored procedure here␍
AS␍
BEGIN␍
-- SET NOCOUNT ON added to prevent extra result sets from␍
-- interfering with SELECT statements.␍
SET NOCOUNT ON;␍
␍
-- Insert statements for procedure here␍
INSERT INTO [QuickTeam].[WorkSheet]␍
([WorkSheetCode]␍
,[ProjectId]␍
,[ProjectName]␍
,[SystemName]␍
,[Evaluator]␍
,[TechnicalLeader]␍
,[CustomerLeader]␍
,[StartTime]␍
,[EndTime]␍
,[UpdateTime]␍
,[Status]␍
,ReceiveStatus␍
,[Finished]␍
,[FinishTime]␍
,[ServiceType]␍
,[ImplementContent]␍
,[OtherInstructions]␍
,isMerge␍
,isReclaimed␍
,BelongTeam␍
)␍
VALUES␍
(''␍
,N''␍
,N''␍
,''␍
,''␍
,''␍
,''␍
,GETDATE()␍
,dateadd(m,1,getdate())␍
,GETDATE()␍
,''␍
,'00'␍
,'00'␍
,null␍
,''␍
,''␍
,''␍
,'0'␍
,0␍
,''␍
);␍
select scope_identity() as WorkSheetId␍
END␍
+68
View File
@@ -0,0 +1,68 @@
CREATE PROCEDURE [QuickTeam].[usp_UpdateWorkSheetById]␍
@WorkSheetId bigint,␍
@ProjectId nvarchar(50),␍
--@TeamId nvarchar(50),␍
@ProjectName nvarchar(50),␍
@SystemName nvarchar(50),␍
@Evaluator nvarchar(50),␍
@TechnicalLeader nvarchar(50),␍
@CustomerLeader nvarchar(50),␍
@StartTime datetime,␍
@EndTime datetime,␍
@Status nvarchar(5)='01' ,␍
@ServiceType nvarchar(20),␍
@ImplementContent nvarchar(500),␍
@OtherInstructions nvarchar(1000),␍
@Operator nvarchar(50),␍
@DeleteFlag NVARCHAR(2),␍
@Operation NVARCHAR(10),␍
@BelongTeam NVARCHAR(50)␍
␍
␍
␍
AS␍
BEGIN␍
declare @length int␍
select @length=len([Status]) from [QuickTeam].[WorkSheet] where WorkSheetId=@WorkSheetId␍
update QuickTeam.WorkSheet ␍
set [WorkSheetCode]=@ProjectName+'_'+CONVERT(varchar(100), @EndTime, 112)+'_'+CONVERT(nvarchar(10),@WorkSheetId)␍
,[ProjectId]=@ProjectId␍
,[ProjectName]=@ProjectName␍
,[SystemName]=@SystemName␍
,[Evaluator]=@Evaluator␍
,[TechnicalLeader]=@TechnicalLeader␍
,[CustomerLeader]=@CustomerLeader␍
,[StartTime]=@StartTime␍
,[EndTime]=@EndTime␍
,[UpdateTime]=getdate()␍
,[Status]=@Status␍
,[ServiceType]=@ServiceType␍
,[ImplementContent]=@ImplementContent␍
,[OtherInstructions]=@OtherInstructions␍
,Operation=@Operation␍
,DeleteFlag=@DeleteFlag␍
,OperateUserName=@Operator␍
,BelongTeam=@BelongTeam␍
where WorkSheetId=CONVERT(BIGINT,@WorkSheetId)␍
␍
if(@length=0)␍
begin␍
INSERT INTO [QuickTeam].[WorkSheetVersion]␍
([VersionCode]␍
,[VersionStatus]␍
,NextOperator␍
,[WorkSheetId]␍
,Operator␍
,UpdateTime␍
)␍
VALUES␍
(N'技术责任人确认版'␍
,'N'␍
,'TechnicalLeader'␍
,@WorkSheetId␍
,''␍
,getdate()␍
)␍
end␍
select @@ERROR as Result␍
END␍
+51
View File
@@ -0,0 +1,51 @@
CREATE PROCEDURE [QuickTeam].[usp_VerifyWorkSheetById]␍
@WorkSheetId bigint␍
,@VersionId int␍
,@NextVersionCode nvarchar(50)␍
,@NextOperator nvarchar(50)␍
,@Percent int ␍
,@Operator nvarchar(50)␍
AS␍
BEGIN␍
␍
␍
␍
declare @ParentEffortStatus nvarchar(10),@PreEffortStatus nvarchar(5)='Y',@NextVersionId int,@Count int,@CurrentVersionId int␍
select @ParentEffortStatus=replace(str(status+1,2,0),' ','0') from [QuickTeam].[WorkSheet] where WorkSheetId=@WorkSheetId␍
select @Count= count(*) from [QuickTeam].[WorkSheetVersion] where NextOperator='CustomerLeader' and WorkSheetId=@WorkSheetId␍
if(@Count=2)␍
begin␍
--update [QuickTeam].[WorkSheet] set Status=@ParentEffortStatus where WorkSheetId=@WorkSheetId␍
update [QuickTeam].[WorkSheetVersion] set VersionStatus=@PreEffortStatus,Operator=@Operator,UpdateTime=getdate() where WorkSheetId=@WorkSheetId and VersionId=@VersionId␍
select @CurrentVersionId=max(VersionId) from [QuickTeam].[WorkSheetVersion] where WorkSheetId=@WorkSheetId and VersionStatus='Y'␍
update [QuickTeam].[WorkSheet] set Status=@ParentEffortStatus,CurrentVersionId=@CurrentVersionId ,UpdateTime=GETDATE(),Operation=N'Verify',OperateUserName=@Operator where WorkSheetId=@WorkSheetId␍
end␍
else␍
begin␍
--插入下一版本␍
insert into [QuickTeam].[WorkSheetVersion]([VersionCode]␍
,[VersionStatus]␍
,[NextOperator]␍
,[WorkSheetId]␍
,Operator␍
,UpdateTime␍
) ␍
select @NextVersionCode,'N',@NextOperator,@WorkSheetId,'',GETDATE()␍
---更新当前版本␍
update [QuickTeam].[WorkSheetVersion] set VersionStatus=@PreEffortStatus ,Operator=@Operator,UpdateTime=getdate() where WorkSheetId=@WorkSheetId and VersionId=@VersionId␍
␍
set @NextVersionId=scope_identity()␍
insert into QuickTeam.WorkSheetTask([FeatureId]␍
,[VersionId]␍
,[TaskCode]␍
,[Effort])␍
select [FeatureId]␍
,@NextVersionId␍
,[TaskCode]␍
,Effort from QuickTeam.WorkSheetTask where VersionId=@VersionId␍
select @CurrentVersionId=max(VersionId) from [QuickTeam].[WorkSheetVersion] where WorkSheetId=@WorkSheetId and VersionStatus='Y'␍
update [QuickTeam].[WorkSheet] set Status=@ParentEffortStatus,CurrentVersionId=@CurrentVersionId ,UpdateTime=GETDATE() where WorkSheetId=@WorkSheetId␍
end ␍
␍
select @@ERROR As Result␍
END␍