新增质量模块(工艺执行书 / 样茧试缫)与报表中心
质量模块: - 11 张工艺执行书表:封面、试产、选剥茧(含混茧明细)、试缫与大样、煮茧(含分车间配温、副煮车间)、自动缫(含大样)、后缫 - 10 张样茧试缫表:原料小样/综合样主表 + 选茧、解舒、茧幅、切剖、清洁洁净、茧丝百回纤度 - 服务与接口、主控指针回写(列表 √ 标记)、封面编号自增、报表数据包 - 前端 8 张报表打印版式、7 类工艺单据与 6 类调查录入弹窗、字段驱动表单/表格组件 - 菜单种子新增「质量」目录,样茧子表增加 YjssType 判别列,避免原料小样与综合样自增 Id 重号串数据 报表中心: - 报表模板管理、锐浪 grhtml5 加载与预览、全屏设计面板、数据源 Provider(落丝记录、职工花名册) 其他:同步工作进度 1-11 文档、开发数据库快照、.gitignore 忽略运行日志目录
This commit is contained in:
@@ -0,0 +1,376 @@
|
||||
{
|
||||
"Version":"6.8.5.0",
|
||||
"Title":"职工花名册",
|
||||
"Author":"F9 报表中心",
|
||||
"Description":"示例报表:列出职工的基本信息(数据源由 DsName=RepDt_Sys_Users 提供)。",
|
||||
"Font":{
|
||||
"Name":"宋体",
|
||||
"Size":90000,
|
||||
"Weight":400,
|
||||
"Charset":134
|
||||
},
|
||||
"Printer":{
|
||||
"TopMargin":1.5,
|
||||
"BottomMargin":1.5
|
||||
},
|
||||
"DetailGrid":{
|
||||
"CenterView":true,
|
||||
"PrintAdaptMethod":"ResizeToFit",
|
||||
"Recordset":{
|
||||
"Field":[
|
||||
{
|
||||
"Name":"EmployeeCode"
|
||||
},
|
||||
{
|
||||
"Name":"EmployeeName"
|
||||
},
|
||||
{
|
||||
"Name":"Gender"
|
||||
},
|
||||
{
|
||||
"Name":"DepName"
|
||||
},
|
||||
{
|
||||
"Name":"WorktypeName"
|
||||
},
|
||||
{
|
||||
"Name":"Phone"
|
||||
},
|
||||
{
|
||||
"Name":"RuzhiDate"
|
||||
}
|
||||
]
|
||||
},
|
||||
"Column":[
|
||||
{
|
||||
"Name":"EmployeeCode",
|
||||
"Width":2.5
|
||||
},
|
||||
{
|
||||
"Name":"EmployeeName",
|
||||
"Width":2.2
|
||||
},
|
||||
{
|
||||
"Name":"Gender",
|
||||
"Width":1.2
|
||||
},
|
||||
{
|
||||
"Name":"DepName",
|
||||
"Width":2.8
|
||||
},
|
||||
{
|
||||
"Name":"WorktypeName",
|
||||
"Width":2.4
|
||||
},
|
||||
{
|
||||
"Name":"Phone",
|
||||
"Width":2.6
|
||||
},
|
||||
{
|
||||
"Name":"RuzhiDate",
|
||||
"Width":2.4
|
||||
}
|
||||
],
|
||||
"ColumnContent":{
|
||||
"Height":0.79375,
|
||||
"ColumnContentCell":[
|
||||
{
|
||||
"Column":"EmployeeCode",
|
||||
"DataField":"EmployeeCode"
|
||||
},
|
||||
{
|
||||
"Column":"EmployeeName",
|
||||
"DataField":"EmployeeName"
|
||||
},
|
||||
{
|
||||
"Column":"Gender",
|
||||
"DataField":"Gender"
|
||||
},
|
||||
{
|
||||
"Column":"DepName",
|
||||
"DataField":"DepName"
|
||||
},
|
||||
{
|
||||
"Column":"WorktypeName",
|
||||
"DataField":"WorktypeName"
|
||||
},
|
||||
{
|
||||
"Column":"Phone",
|
||||
"DataField":"Phone"
|
||||
},
|
||||
{
|
||||
"Column":"RuzhiDate",
|
||||
"DataField":"RuzhiDate"
|
||||
}
|
||||
]
|
||||
},
|
||||
"ColumnTitle":{
|
||||
"BackColor":"C0C0C0",
|
||||
"Height":0.79375,
|
||||
"Font":{
|
||||
"Name":"宋体",
|
||||
"Size":90000,
|
||||
"Bold":true,
|
||||
"Charset":134
|
||||
},
|
||||
"RepeatStyle":"OnPage",
|
||||
"ColumnTitleCell":[
|
||||
{
|
||||
"GroupTitle":false,
|
||||
"Column":"EmployeeCode",
|
||||
"BackColor":"FFFFFF",
|
||||
"Text":"工号"
|
||||
},
|
||||
{
|
||||
"GroupTitle":false,
|
||||
"Column":"EmployeeName",
|
||||
"BackColor":"FFFFFF",
|
||||
"Text":"姓名"
|
||||
},
|
||||
{
|
||||
"GroupTitle":false,
|
||||
"Column":"Gender",
|
||||
"BackColor":"FFFFFF",
|
||||
"Text":"性别"
|
||||
},
|
||||
{
|
||||
"GroupTitle":false,
|
||||
"Column":"DepName",
|
||||
"BackColor":"FFFFFF",
|
||||
"Text":"部门"
|
||||
},
|
||||
{
|
||||
"GroupTitle":false,
|
||||
"Column":"WorktypeName",
|
||||
"BackColor":"FFFFFF",
|
||||
"Text":"工种"
|
||||
},
|
||||
{
|
||||
"GroupTitle":false,
|
||||
"Column":"Phone",
|
||||
"BackColor":"FFFFFF",
|
||||
"Text":"电话"
|
||||
},
|
||||
{
|
||||
"GroupTitle":false,
|
||||
"Column":"RuzhiDate",
|
||||
"BackColor":"FFFFFF",
|
||||
"Text":"入职日期"
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
"PageHeader":{
|
||||
"Height":1.32292,
|
||||
"Control":[
|
||||
{
|
||||
"Type":"MemoBox",
|
||||
"Name":"MemoBox1",
|
||||
"Anchor":"[Top|Right]",
|
||||
"Left":9.5,
|
||||
"Top":0.396875,
|
||||
"Width":6.3,
|
||||
"Height":0.47625,
|
||||
"Font":{
|
||||
"Name":"楷体",
|
||||
"Size":120000,
|
||||
"Bold":true,
|
||||
"Charset":134
|
||||
},
|
||||
"Text":"职工花名册 · 智慧缫丝系统"
|
||||
},
|
||||
{
|
||||
"Type":"Line",
|
||||
"Name":"Line1",
|
||||
"Anchor":"[Left|Top|Right]",
|
||||
"Top":1.00542,
|
||||
"Width":16.0073,
|
||||
"Pen":{
|
||||
"Width":2
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
"PageFooter":{
|
||||
"Height":1.32292,
|
||||
"Control":[
|
||||
{
|
||||
"Type":"MemoBox",
|
||||
"Name":"MemoBox2",
|
||||
"Anchor":"[Top|Right]",
|
||||
"Left":13.2027,
|
||||
"Top":0.396875,
|
||||
"Width":2.59292,
|
||||
"Height":0.608542,
|
||||
"Text":"第[#SystemVar(PageNumber)#]页 共[#SystemVar(PageCount)#]页"
|
||||
},
|
||||
{
|
||||
"Type":"MemoBox",
|
||||
"Name":"MemoBox3",
|
||||
"Left":0.211667,
|
||||
"Top":0.396875,
|
||||
"Width":6.19125,
|
||||
"Height":0.608542,
|
||||
"Text":"打印时间:[#SystemVar(CurrentDateTime):yyyy年MM月dd日 HH:mm:ss#]"
|
||||
}
|
||||
]
|
||||
},
|
||||
"ReportHeader":[
|
||||
{
|
||||
"Height":0.978958,
|
||||
"Control":[
|
||||
{
|
||||
"Type":"StaticBox",
|
||||
"Name":"StaticBox1",
|
||||
"Center":"Horizontal",
|
||||
"Left":6.29708,
|
||||
"Top":0.185208,
|
||||
"Width":3.41313,
|
||||
"Height":0.582083,
|
||||
"Font":{
|
||||
"Name":"宋体",
|
||||
"Size":150000,
|
||||
"Bold":true,
|
||||
"Charset":134
|
||||
},
|
||||
"Text":"职工花名册"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"Height":0.6,
|
||||
"Control":[
|
||||
{
|
||||
"Type":"StaticBox",
|
||||
"Name":"LabelDep",
|
||||
"Left":0.2,
|
||||
"Top":0.05,
|
||||
"Width":1.4,
|
||||
"Height":0.5,
|
||||
"Font":{
|
||||
"Name":"宋体",
|
||||
"Size":90000,
|
||||
"Charset":134
|
||||
},
|
||||
"Text":"部门:"
|
||||
},
|
||||
{
|
||||
"Type":"StaticBox",
|
||||
"Name":"ParamDep",
|
||||
"Left":1.7,
|
||||
"Top":0.05,
|
||||
"Width":2.2,
|
||||
"Height":0.5,
|
||||
"Font":{
|
||||
"Name":"宋体",
|
||||
"Size":90000,
|
||||
"Charset":134
|
||||
},
|
||||
"Parameter":"部门"
|
||||
},
|
||||
{
|
||||
"Type":"StaticBox",
|
||||
"Name":"LabelKeyword",
|
||||
"Left":4.0,
|
||||
"Top":0.05,
|
||||
"Width":1.6,
|
||||
"Height":0.5,
|
||||
"Font":{
|
||||
"Name":"宋体",
|
||||
"Size":90000,
|
||||
"Charset":134
|
||||
},
|
||||
"Text":"关键字:"
|
||||
},
|
||||
{
|
||||
"Type":"StaticBox",
|
||||
"Name":"ParamKeyword",
|
||||
"Left":5.7,
|
||||
"Top":0.05,
|
||||
"Width":1.8,
|
||||
"Height":0.5,
|
||||
"Font":{
|
||||
"Name":"宋体",
|
||||
"Size":90000,
|
||||
"Charset":134
|
||||
},
|
||||
"Parameter":"关键字"
|
||||
},
|
||||
{
|
||||
"Type":"StaticBox",
|
||||
"Name":"LabelCount",
|
||||
"Left":7.6,
|
||||
"Top":0.05,
|
||||
"Width":1.6,
|
||||
"Height":0.5,
|
||||
"Font":{
|
||||
"Name":"宋体",
|
||||
"Size":90000,
|
||||
"Charset":134
|
||||
},
|
||||
"Text":"记录数:"
|
||||
},
|
||||
{
|
||||
"Type":"StaticBox",
|
||||
"Name":"ParamCount",
|
||||
"Left":9.3,
|
||||
"Top":0.05,
|
||||
"Width":1.2,
|
||||
"Height":0.5,
|
||||
"Font":{
|
||||
"Name":"宋体",
|
||||
"Size":90000,
|
||||
"Charset":134
|
||||
},
|
||||
"Parameter":"记录数"
|
||||
},
|
||||
{
|
||||
"Type":"StaticBox",
|
||||
"Name":"LabelQueryTime",
|
||||
"Left":10.6,
|
||||
"Top":0.05,
|
||||
"Width":2.0,
|
||||
"Height":0.5,
|
||||
"Font":{
|
||||
"Name":"宋体",
|
||||
"Size":90000,
|
||||
"Charset":134
|
||||
},
|
||||
"Text":"查询时间:"
|
||||
},
|
||||
{
|
||||
"Type":"StaticBox",
|
||||
"Name":"ParamQueryTime",
|
||||
"Left":12.7,
|
||||
"Top":0.05,
|
||||
"Width":3.3,
|
||||
"Height":0.5,
|
||||
"Font":{
|
||||
"Name":"宋体",
|
||||
"Size":90000,
|
||||
"Charset":134
|
||||
},
|
||||
"Parameter":"查询时间"
|
||||
}
|
||||
]
|
||||
}
|
||||
],
|
||||
"Parameter":[
|
||||
{
|
||||
"Name":"部门",
|
||||
"DataType":"String"
|
||||
},
|
||||
{
|
||||
"Name":"关键字",
|
||||
"DataType":"String"
|
||||
},
|
||||
{
|
||||
"Name":"记录数",
|
||||
"DataType":"Integer"
|
||||
},
|
||||
{
|
||||
"Name":"查询时间",
|
||||
"DataType":"String"
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -0,0 +1,312 @@
|
||||
{
|
||||
"Version": "6.8.5.0",
|
||||
"Title": "落丝记录",
|
||||
"Author": "F9 报表中心",
|
||||
"Description": "生产-前缫:落丝记录明细(数据源 DsName=RepDt_Prod_Lsjl)。",
|
||||
"Font": {
|
||||
"Name": "宋体",
|
||||
"Size": 90000,
|
||||
"Weight": 400,
|
||||
"Charset": 134
|
||||
},
|
||||
"Printer": {
|
||||
"TopMargin": 1.5,
|
||||
"BottomMargin": 1.5
|
||||
},
|
||||
"DetailGrid": {
|
||||
"CenterView": true,
|
||||
"PrintAdaptMethod": "ResizeToFit",
|
||||
"Recordset": {
|
||||
"Field": [
|
||||
{ "Name": "日期" },
|
||||
{ "Name": "车间" },
|
||||
{ "Name": "机组" },
|
||||
{ "Name": "庄口" },
|
||||
{ "Name": "回数" },
|
||||
{ "Name": "颜色" },
|
||||
{ "Name": "半车" },
|
||||
{ "Name": "落丝时间" },
|
||||
{ "Name": "缫丝桶数" }
|
||||
]
|
||||
},
|
||||
"Column": [
|
||||
{ "Name": "日期", "Width": 2.0 },
|
||||
{ "Name": "车间", "Width": 3.0 },
|
||||
{ "Name": "机组", "Width": 1.4 },
|
||||
{ "Name": "庄口", "Width": 3.2 },
|
||||
{ "Name": "回数", "Width": 1.4 },
|
||||
{ "Name": "颜色", "Width": 1.6 },
|
||||
{ "Name": "半车", "Width": 1.4 },
|
||||
{ "Name": "落丝时间", "Width": 1.8 },
|
||||
{ "Name": "缫丝桶数", "Width": 1.5 }
|
||||
],
|
||||
"ColumnContent": {
|
||||
"Height": 0.79375,
|
||||
"ColumnContentCell": [
|
||||
{ "Column": "日期", "DataField": "日期" },
|
||||
{ "Column": "车间", "DataField": "车间" },
|
||||
{ "Column": "机组", "DataField": "机组" },
|
||||
{ "Column": "庄口", "DataField": "庄口" },
|
||||
{ "Column": "回数", "DataField": "回数" },
|
||||
{ "Column": "颜色", "DataField": "颜色" },
|
||||
{ "Column": "半车", "DataField": "半车" },
|
||||
{ "Column": "落丝时间", "DataField": "落丝时间" },
|
||||
{ "Column": "缫丝桶数", "DataField": "缫丝桶数" }
|
||||
]
|
||||
},
|
||||
"ColumnTitle": {
|
||||
"BackColor": "C0C0C0",
|
||||
"Height": 0.79375,
|
||||
"Font": {
|
||||
"Name": "宋体",
|
||||
"Size": 90000,
|
||||
"Bold": true,
|
||||
"Charset": 134
|
||||
},
|
||||
"RepeatStyle": "OnPage",
|
||||
"ColumnTitleCell": [
|
||||
{ "GroupTitle": false, "Column": "日期", "BackColor": "FFFFFF", "Text": "日期" },
|
||||
{ "GroupTitle": false, "Column": "车间", "BackColor": "FFFFFF", "Text": "车间" },
|
||||
{ "GroupTitle": false, "Column": "机组", "BackColor": "FFFFFF", "Text": "机组" },
|
||||
{ "GroupTitle": false, "Column": "庄口", "BackColor": "FFFFFF", "Text": "庄口" },
|
||||
{ "GroupTitle": false, "Column": "回数", "BackColor": "FFFFFF", "Text": "回数" },
|
||||
{ "GroupTitle": false, "Column": "颜色", "BackColor": "FFFFFF", "Text": "颜色" },
|
||||
{ "GroupTitle": false, "Column": "半车", "BackColor": "FFFFFF", "Text": "半车" },
|
||||
{ "GroupTitle": false, "Column": "落丝时间", "BackColor": "FFFFFF", "Text": "落丝时间" },
|
||||
{ "GroupTitle": false, "Column": "缫丝桶数", "BackColor": "FFFFFF", "Text": "缫丝桶数" }
|
||||
]
|
||||
}
|
||||
},
|
||||
"PageHeader": {
|
||||
"Height": 1.32292,
|
||||
"Control": [
|
||||
{
|
||||
"Type": "MemoBox",
|
||||
"Name": "MemoBox1",
|
||||
"Anchor": "[Top|Right]",
|
||||
"Left": 9.5,
|
||||
"Top": 0.396875,
|
||||
"Width": 6.3,
|
||||
"Height": 0.47625,
|
||||
"Font": {
|
||||
"Name": "楷体",
|
||||
"Size": 120000,
|
||||
"Bold": true,
|
||||
"Charset": 134
|
||||
},
|
||||
"Text": "落丝记录 · 智慧缫丝系统"
|
||||
},
|
||||
{
|
||||
"Type": "Line",
|
||||
"Name": "Line1",
|
||||
"Anchor": "[Left|Top|Right]",
|
||||
"Top": 1.00542,
|
||||
"Width": 16.0073,
|
||||
"Pen": {
|
||||
"Width": 2
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
"PageFooter": {
|
||||
"Height": 1.32292,
|
||||
"Control": [
|
||||
{
|
||||
"Type": "MemoBox",
|
||||
"Name": "MemoBox2",
|
||||
"Anchor": "[Top|Right]",
|
||||
"Left": 13.2027,
|
||||
"Top": 0.396875,
|
||||
"Width": 2.59292,
|
||||
"Height": 0.608542,
|
||||
"Text": "第[#SystemVar(PageNumber)#]页 共[#SystemVar(PageCount)#]页"
|
||||
},
|
||||
{
|
||||
"Type": "MemoBox",
|
||||
"Name": "MemoBox3",
|
||||
"Left": 0.211667,
|
||||
"Top": 0.396875,
|
||||
"Width": 6.19125,
|
||||
"Height": 0.608542,
|
||||
"Text": "打印时间:[#SystemVar(CurrentDateTime):yyyy年MM月dd日 HH:mm:ss#]"
|
||||
}
|
||||
]
|
||||
},
|
||||
"ReportHeader": [
|
||||
{
|
||||
"Height": 0.978958,
|
||||
"Control": [
|
||||
{
|
||||
"Type": "StaticBox",
|
||||
"Name": "StaticBoxTitle",
|
||||
"Center": "Horizontal",
|
||||
"Left": 6.29708,
|
||||
"Top": 0.185208,
|
||||
"Width": 3.41313,
|
||||
"Height": 0.582083,
|
||||
"Font": {
|
||||
"Name": "宋体",
|
||||
"Size": 150000,
|
||||
"Bold": true,
|
||||
"Charset": 134
|
||||
},
|
||||
"Text": "落丝记录"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"Height": 1.2,
|
||||
"Control": [
|
||||
{
|
||||
"Type": "StaticBox",
|
||||
"Name": "LabelDateStart",
|
||||
"Left": 0.3,
|
||||
"Top": 0.05,
|
||||
"Width": 1.3,
|
||||
"Height": 0.5,
|
||||
"Font": { "Name": "宋体", "Size": 90000, "Charset": 134 },
|
||||
"Text": "开始日期:"
|
||||
},
|
||||
{
|
||||
"Type": "MemoBox",
|
||||
"Name": "ParamDateStart",
|
||||
"Left": 1.6,
|
||||
"Top": 0.05,
|
||||
"Width": 2.5,
|
||||
"Height": 0.5,
|
||||
"Font": { "Name": "宋体", "Size": 90000, "Charset": 134 },
|
||||
"Text": "[#{开始日期}#]"
|
||||
},
|
||||
{
|
||||
"Type": "StaticBox",
|
||||
"Name": "LabelDateEnd",
|
||||
"Left": 4.4,
|
||||
"Top": 0.05,
|
||||
"Width": 1.3,
|
||||
"Height": 0.5,
|
||||
"Font": { "Name": "宋体", "Size": 90000, "Charset": 134 },
|
||||
"Text": "结束日期:"
|
||||
},
|
||||
{
|
||||
"Type": "MemoBox",
|
||||
"Name": "ParamDateEnd",
|
||||
"Left": 5.7,
|
||||
"Top": 0.05,
|
||||
"Width": 2.5,
|
||||
"Height": 0.5,
|
||||
"Font": { "Name": "宋体", "Size": 90000, "Charset": 134 },
|
||||
"Text": "[#{结束日期}#]"
|
||||
},
|
||||
{
|
||||
"Type": "StaticBox",
|
||||
"Name": "LabelDep",
|
||||
"Left": 8.5,
|
||||
"Top": 0.05,
|
||||
"Width": 1.3,
|
||||
"Height": 0.5,
|
||||
"Font": { "Name": "宋体", "Size": 90000, "Charset": 134 },
|
||||
"Text": "车间:"
|
||||
},
|
||||
{
|
||||
"Type": "MemoBox",
|
||||
"Name": "ParamDep",
|
||||
"Left": 9.8,
|
||||
"Top": 0.05,
|
||||
"Width": 2.5,
|
||||
"Height": 0.5,
|
||||
"Font": { "Name": "宋体", "Size": 90000, "Charset": 134 },
|
||||
"Text": "[#{车间}#]"
|
||||
},
|
||||
{
|
||||
"Type": "StaticBox",
|
||||
"Name": "LabelJizu",
|
||||
"Left": 12.6,
|
||||
"Top": 0.05,
|
||||
"Width": 1.3,
|
||||
"Height": 0.5,
|
||||
"Font": { "Name": "宋体", "Size": 90000, "Charset": 134 },
|
||||
"Text": "机组:"
|
||||
},
|
||||
{
|
||||
"Type": "MemoBox",
|
||||
"Name": "ParamJizu",
|
||||
"Left": 13.9,
|
||||
"Top": 0.05,
|
||||
"Width": 2.5,
|
||||
"Height": 0.5,
|
||||
"Font": { "Name": "宋体", "Size": 90000, "Charset": 134 },
|
||||
"Text": "[#{机组}#]"
|
||||
},
|
||||
{
|
||||
"Type": "StaticBox",
|
||||
"Name": "LabelZk",
|
||||
"Left": 0.3,
|
||||
"Top": 0.6,
|
||||
"Width": 1.3,
|
||||
"Height": 0.5,
|
||||
"Font": { "Name": "宋体", "Size": 90000, "Charset": 134 },
|
||||
"Text": "庄口:"
|
||||
},
|
||||
{
|
||||
"Type": "MemoBox",
|
||||
"Name": "ParamZk",
|
||||
"Left": 1.6,
|
||||
"Top": 0.6,
|
||||
"Width": 2.5,
|
||||
"Height": 0.5,
|
||||
"Font": { "Name": "宋体", "Size": 90000, "Charset": 134 },
|
||||
"Text": "[#{庄口}#]"
|
||||
},
|
||||
{
|
||||
"Type": "StaticBox",
|
||||
"Name": "LabelCount",
|
||||
"Left": 4.4,
|
||||
"Top": 0.6,
|
||||
"Width": 1.3,
|
||||
"Height": 0.5,
|
||||
"Font": { "Name": "宋体", "Size": 90000, "Charset": 134 },
|
||||
"Text": "记录数:"
|
||||
},
|
||||
{
|
||||
"Type": "MemoBox",
|
||||
"Name": "ParamCount",
|
||||
"Left": 5.7,
|
||||
"Top": 0.6,
|
||||
"Width": 2.5,
|
||||
"Height": 0.5,
|
||||
"Font": { "Name": "宋体", "Size": 90000, "Charset": 134 },
|
||||
"Text": "[#{记录数}#]"
|
||||
},
|
||||
{
|
||||
"Type": "StaticBox",
|
||||
"Name": "LabelQueryTime",
|
||||
"Left": 8.5,
|
||||
"Top": 0.6,
|
||||
"Width": 1.3,
|
||||
"Height": 0.5,
|
||||
"Font": { "Name": "宋体", "Size": 90000, "Charset": 134 },
|
||||
"Text": "查询时间:"
|
||||
},
|
||||
{
|
||||
"Type": "MemoBox",
|
||||
"Name": "ParamQueryTime",
|
||||
"Left": 9.8,
|
||||
"Top": 0.6,
|
||||
"Width": 3.6,
|
||||
"Height": 0.5,
|
||||
"Font": { "Name": "宋体", "Size": 90000, "Charset": 134 },
|
||||
"Text": "[#{查询时间}#]"
|
||||
}
|
||||
]
|
||||
}
|
||||
],
|
||||
"Parameter": [
|
||||
{ "Name": "开始日期", "DataType": "String" },
|
||||
{ "Name": "结束日期", "DataType": "String" },
|
||||
{ "Name": "车间", "DataType": "String" },
|
||||
{ "Name": "机组", "DataType": "String" },
|
||||
{ "Name": "庄口", "DataType": "String" },
|
||||
{ "Name": "记录数", "DataType": "Integer" },
|
||||
{ "Name": "查询时间", "DataType": "String" }
|
||||
]
|
||||
}
|
||||
@@ -1,4 +1,5 @@
|
||||
using System.Data;
|
||||
using System.Text;
|
||||
using FreeSql;
|
||||
using F9WebAiTest.Application.Interfaces.SnowflakeID;
|
||||
using F9WebAiTest.Domain.Common;
|
||||
@@ -10,6 +11,8 @@ using SysMenu = F9WebAiTest.Domain.Entities.SYS.RBAC.Menu;
|
||||
using SysRole = F9WebAiTest.Domain.Entities.SYS.RBAC.Role;
|
||||
using SysPermission = F9WebAiTest.Domain.Entities.SYS.RBAC.Permission;
|
||||
using SysRolePermission = F9WebAiTest.Domain.Entities.SYS.RBAC.RolePermission;
|
||||
using SysReport = F9WebAiTest.Domain.Entities.SYS.Reports.Report;
|
||||
using SysReportFile = F9WebAiTest.Domain.Entities.SYS.Reports.ReportFile;
|
||||
|
||||
namespace F9WebAiTest.Infrastructure.Data;
|
||||
|
||||
@@ -88,6 +91,20 @@ public static class DbSeeder
|
||||
// 6.69 修正前缫部门的职责类型(车间班次菜单随"生产-前缫"一起处理)
|
||||
FixQianxianDutyType(fsql);
|
||||
|
||||
// 6.695 质量模块(工艺执行书 / 样茧试缫)
|
||||
SeedQcMenus(fsql, snowflake);
|
||||
|
||||
// 6.71 报表中心菜单(/report 目录 + 报表中心/报表管理两个页面)
|
||||
SeedReportMenus(fsql, snowflake);
|
||||
// 6.72 旧版内嵌模板(sys_reports.template_data)迁移为独立模板实例 ReportFile
|
||||
MigrateReportTemplateToFile(fsql, snowflake);
|
||||
|
||||
// 6.72 报表中心示例报表(职工花名册)
|
||||
SeedSampleReport(fsql, snowflake);
|
||||
|
||||
// 6.73 落丝记录报表(生产-前缫,DsName=RepDt_Prod_Lsjl)
|
||||
SeedLsjlReport(fsql, snowflake);
|
||||
|
||||
// 6.7 为菜单创建权限单元(Permission),并修正旧菜单权限关联(统一权限模型)
|
||||
FixMenuPermissions(fsql, snowflake);
|
||||
|
||||
@@ -156,6 +173,7 @@ public static class DbSeeder
|
||||
EnsureColumn(fsql, "NotificationTypes", "RouteTemplate", "TEXT NOT NULL DEFAULT ''");
|
||||
EnsureColumn(fsql, "NotificationMessages", "Category", "INTEGER NOT NULL DEFAULT 0");
|
||||
EnsureColumn(fsql, "NotificationMessages", "RoutePath", "TEXT NOT NULL DEFAULT ''");
|
||||
EnsureColumn(fsql, "sys_reports", "report_file_id", "INTEGER NOT NULL DEFAULT 0");
|
||||
}
|
||||
|
||||
/// <summary>为已有表补加列(列已存在则忽略)</summary>
|
||||
@@ -735,6 +753,42 @@ public static class DbSeeder
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 质量模块菜单:一级目录「质量」+ 工艺执行书 / 样茧试缫 两个页面。
|
||||
/// 模块落在「生产-后缫」之后、消息中心之前。
|
||||
/// </summary>
|
||||
private static void SeedQcMenus(IFreeSql fsql, ISnowflakeIdGenerator snowflake)
|
||||
{
|
||||
try
|
||||
{
|
||||
EnsureTopMenuWithChildren(fsql, snowflake, "/qc", "质量", "Medal", 7,
|
||||
new (string Name, string Path, string Component, string Permission, string Icon, int Sort)[]
|
||||
{
|
||||
("工艺执行书", "/qc/gyzxs", "qc/gyzxs/index", "qc:gyzxs:list", "Document", 1),
|
||||
("样茧试缫", "/qc/yjss", "qc/yjss/index", "qc:yjss:list", "DataAnalysis", 2)
|
||||
});
|
||||
|
||||
foreach (var (path, sort) in new (string Path, int Sort)[]
|
||||
{
|
||||
("/attendance", 2), ("/base", 3), ("/employee", 4),
|
||||
("/prod/qianxian", 5), ("/prod/houxian", 6), ("/qc", 7),
|
||||
("/notification", 8), ("/sys", 9), ("/report", 10)
|
||||
})
|
||||
{
|
||||
fsql.Update<SysMenu>()
|
||||
.Set(x => x.SortOrder, sort)
|
||||
.Where(x => x.ParentId == 0 && x.Path == path && x.SortOrder != sort)
|
||||
.ExecuteAffrows();
|
||||
}
|
||||
|
||||
Console.WriteLine("[DbSeeder] 质量模块菜单已就绪(工艺执行书 / 样茧试缫)");
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Console.WriteLine($"[DbSeeder] 质量模块菜单种子跳过:{ex.Message}");
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 确保一个一级目录菜单及其下属页面菜单存在(含父级、图标、启用状态校正),并给 admin 角色授权。
|
||||
/// 注意:图标名必须是 Element Plus 图标组件名。
|
||||
@@ -894,6 +948,22 @@ public static class DbSeeder
|
||||
// 2. 修正旧菜单权限关联(permission_id 旧值 = Menu.Id,改为 Permission.Id)
|
||||
fsql.Ado.ExecuteNonQuery($"UPDATE sys_rbac_role_permissions SET permission_id = {perm.Id} WHERE permission_id = {menu.Id};");
|
||||
}
|
||||
|
||||
// 3. 清理失效的菜单权限单元:ResourceId 不对应任何菜单
|
||||
// (前端曾用 Number() 传雪花 Id,超出 2^53 后精度丢失,写入的 resource_id 在菜单表里查不到,
|
||||
// 表现为「勾选保存后重新打开仍是未勾选、该角色登录也看不到菜单」)
|
||||
var menuIds = fsql.Select<SysMenu>().ToList().Select(m => m.Id).ToHashSet();
|
||||
var orphanPerms = fsql.Select<SysPermission>()
|
||||
.Where(p => p.ResourceType == Resource_Type_Enum.菜单).ToList()
|
||||
.Where(p => !menuIds.Contains(p.ResourceId)).ToList();
|
||||
foreach (var bad in orphanPerms)
|
||||
{
|
||||
fsql.Ado.ExecuteNonQuery($"DELETE FROM sys_rbac_role_permissions WHERE permission_id = {bad.Id};");
|
||||
fsql.Ado.ExecuteNonQuery($"DELETE FROM sys_rbac_permissions WHERE id = {bad.Id};");
|
||||
}
|
||||
if (orphanPerms.Count > 0)
|
||||
Console.WriteLine($"[DbSeeder] 已清理 {orphanPerms.Count} 条失效菜单权限单元(资源 Id 不存在)");
|
||||
|
||||
Console.WriteLine("[DbSeeder] 菜单权限单元同步完成");
|
||||
}
|
||||
catch (Exception ex)
|
||||
@@ -901,4 +971,399 @@ public static class DbSeeder
|
||||
Console.WriteLine($"[DbSeeder] 菜单权限单元同步跳过:{ex.Message}");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>报表中心菜单(/report 目录 + 报表中心 / 报表管理 两个页面菜单,admin 授权)</summary>
|
||||
private static void SeedReportMenus(IFreeSql fsql, ISnowflakeIdGenerator snowflake)
|
||||
{
|
||||
try
|
||||
{
|
||||
EnsureTopMenuWithChildren(fsql, snowflake, "/report", "报表中心", "DataAnalysis", 9,
|
||||
new (string Name, string Path, string Component, string Permission, string Icon, int Sort)[]
|
||||
{
|
||||
("报表中心", "/report/center", "report/center/index", "report:center:list", "PieChart", 1),
|
||||
("报表管理", "/report/manage", "report/manage/index", "report:manage:list", "Document", 2)
|
||||
});
|
||||
Console.WriteLine("[DbSeeder] 报表中心菜单已就绪");
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Console.WriteLine($"[DbSeeder] 报表中心菜单种子跳过:{ex.Message}");
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 旧版把模板二进制直接存在 sys_reports.template_data,现模板是独立实体 ReportFile(DesignContent 文本),
|
||||
/// Report 通过 ReportFileId 关联。启动时把旧数据迁移过去,迁移完成后清空旧字段。
|
||||
/// </summary>
|
||||
private static void MigrateReportTemplateToFile(IFreeSql fsql, ISnowflakeIdGenerator snowflake)
|
||||
{
|
||||
try
|
||||
{
|
||||
var legacy = fsql.Select<SysReport>()
|
||||
.Where(r => !r.IsDeleted && r.ReportFileId == 0 && r.TemplateData != null && r.TemplateData.Length > 0)
|
||||
.ToList();
|
||||
foreach (var report in legacy)
|
||||
{
|
||||
var text = Encoding.UTF8.GetString(report.TemplateData!);
|
||||
if (text.Length > 0 && text[0] == '\uFEFF') text = text.Substring(1);
|
||||
|
||||
var file = new SysReportFile(snowflake.CreateId(), report.Id, text);
|
||||
fsql.Insert(file).ExecuteAffrows();
|
||||
report.BindReportFile(file.Id);
|
||||
report.ClearLegacyTemplate();
|
||||
fsql.Update<SysReport>().SetSource(report).ExecuteAffrows();
|
||||
Console.WriteLine($"[DbSeeder] 报表「{report.Name}」模板已迁移到 ReportFile#{file.Id}");
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Console.WriteLine($"[DbSeeder] 报表模板迁移跳过:{ex.Message}");
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>报表中心示例报表:职工花名册(模板为独立 ReportFile 实例 + F9 ReportConfig 查询配置)</summary>
|
||||
private static void SeedSampleReport(IFreeSql fsql, ISnowflakeIdGenerator snowflake)
|
||||
{
|
||||
try
|
||||
{
|
||||
const string code = "employee_directory";
|
||||
const string name = "职工花名册";
|
||||
const string sql = "SELECT login_name AS LoginName, user_name AS UserName, phone_number AS PhoneNumber, email AS Email FROM sys_rbac_users WHERE is_deleted = 0 ORDER BY id LIMIT 1000";
|
||||
// F9 ReportConfig:DsName 指向后端查询提供者;Parms 定义动态查询控件
|
||||
const string config = "{\"DsName\":\"RepDt_Sys_Users\",\"ViewerType\":0,\"Parms\":[" +
|
||||
"{\"Name\":\"q_dep\",\"Label\":\"部门\",\"Prompt\":\"含子部门,留空为全部\",\"IsRequired\":false," +
|
||||
"\"ControlType\":\"AntdUI.Select\",\"Ds_Static\":null,\"Ds_Service\":\"/sys/department\",\"DefaultValue\":\"\"}," +
|
||||
"{\"Name\":\"q_like\",\"Label\":\"关键字\",\"Prompt\":\"按工号 / 姓名模糊查询\",\"IsRequired\":false," +
|
||||
"\"ControlType\":\"AntdUI.Input\",\"Ds_Static\":null,\"Ds_Service\":null,\"DefaultValue\":\"\"}]}";
|
||||
|
||||
var exist = fsql.Select<SysReport>().Where(r => r.Code == code && !r.IsDeleted).First();
|
||||
var templateJson = LoadEmbeddedTemplateJson("employee_directory.grf");
|
||||
|
||||
// 老版本种子生成的是手写 6.6.8.1 模板(设计器 6.8 无法打开),这里统一替换为 6.8.5.0 官方结构模板
|
||||
bool needReplaceTemplate = false;
|
||||
if (exist != null)
|
||||
{
|
||||
var file = fsql.Select<SysReportFile>().Where(f => f.ReportId == exist.Id && !f.IsDeleted).First();
|
||||
needReplaceTemplate = file == null || !file.DesignContent.Contains("6.8.5.0");
|
||||
}
|
||||
|
||||
if (exist == null)
|
||||
{
|
||||
var report = new SysReport(snowflake.CreateId(), code, name, "职工管理", "示例报表:按部门 / 关键字查询职工基本信息。", sql, "[]", 1, config);
|
||||
|
||||
// 模板实例:ReportFile(对齐 F9 Report.ReportFileId)
|
||||
if (templateJson != null)
|
||||
{
|
||||
var file = new SysReportFile(snowflake.CreateId(), report.Id, templateJson);
|
||||
fsql.Insert(file).ExecuteAffrows();
|
||||
report.BindReportFile(file.Id);
|
||||
}
|
||||
fsql.Insert(report).ExecuteAffrows();
|
||||
|
||||
// 创建对应权限单元
|
||||
var perm = new SysPermission(snowflake.CreateId(), Permission_Type_Enum.Visble, Resource_Type_Enum.报表, code, report.Id);
|
||||
perm.SetCode($"report:{code}:visble");
|
||||
fsql.Insert(perm).ExecuteAffrows();
|
||||
|
||||
// 授权给 admin 角色
|
||||
var adminRole = fsql.Select<SysRole>().Where(r => r.Code == "admin").First();
|
||||
if (adminRole != null)
|
||||
{
|
||||
fsql.Insert(new SysRolePermission(snowflake.CreateId(), adminRole.Id, perm.Id)).ExecuteAffrows();
|
||||
}
|
||||
Console.WriteLine("[DbSeeder] 示例报表「职工花名册」已创建");
|
||||
}
|
||||
else
|
||||
{
|
||||
// 已存在:替换旧模板 / 补全缺失的模板与查询配置
|
||||
bool changed = false;
|
||||
if (needReplaceTemplate && templateJson != null)
|
||||
{
|
||||
var file = fsql.Select<SysReportFile>().Where(f => f.ReportId == exist.Id && !f.IsDeleted).First();
|
||||
if (file != null)
|
||||
{
|
||||
file.UpdateContent(templateJson);
|
||||
fsql.Update<SysReportFile>().SetSource(file).ExecuteAffrows();
|
||||
}
|
||||
else
|
||||
{
|
||||
file = new SysReportFile(snowflake.CreateId(), exist.Id, templateJson);
|
||||
fsql.Insert(file).ExecuteAffrows();
|
||||
exist.BindReportFile(file.Id);
|
||||
}
|
||||
changed = true;
|
||||
}
|
||||
if (string.IsNullOrEmpty(exist.Config) || !exist.Config.Contains("q_dep"))
|
||||
{
|
||||
exist.UpdateBasic(exist.Code, exist.Name, exist.Category, exist.Description, exist.DataSql, exist.DataParams, exist.SortOrder, config);
|
||||
changed = true;
|
||||
}
|
||||
if (changed)
|
||||
{
|
||||
fsql.Update<SysReport>().SetSource(exist).ExecuteAffrows();
|
||||
Console.WriteLine("[DbSeeder] 已更新示例报表模板/查询配置");
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Console.WriteLine($"[DbSeeder] 示例报表种子跳过:{ex.Message}");
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 落丝记录报表(生产-前缫):DsName=RepDt_Prod_Lsjl,参数为日期范围 / 车间 / 机组 / 庄口 / 关键字。
|
||||
/// 已存在的报表只补齐查询配置,不覆盖用户在设计器里维护的 .grf 模板。
|
||||
/// </summary>
|
||||
private static void SeedLsjlReport(IFreeSql fsql, ISnowflakeIdGenerator snowflake)
|
||||
{
|
||||
try
|
||||
{
|
||||
const string code = "PROD_QS_1";
|
||||
const string name = "落丝记录";
|
||||
const string category = "生产.前缫";
|
||||
const string dsName = "RepDt_Prod_Lsjl";
|
||||
|
||||
// 日期范围参数默认值用「不限」:避免 paramInitialValue 把空值默认成今天,导致只查当天
|
||||
const string config = "{\"DsName\":\"RepDt_Prod_Lsjl\",\"ViewerType\":0,\"Parms\":[" +
|
||||
"{\"Name\":\"q_date_start\",\"Label\":\"开始日期\",\"Prompt\":\"留空则不限开始日期\",\"IsRequired\":false," +
|
||||
"\"ControlType\":\"AntdUI.DatePicker\",\"Ds_Static\":null,\"Ds_Service\":null,\"DefaultValue\":\"不限\"}," +
|
||||
"{\"Name\":\"q_date_end\",\"Label\":\"结束日期\",\"Prompt\":\"留空则不限结束日期\",\"IsRequired\":false," +
|
||||
"\"ControlType\":\"AntdUI.DatePicker\",\"Ds_Static\":null,\"Ds_Service\":null,\"DefaultValue\":\"不限\"}," +
|
||||
"{\"Name\":\"q_dep\",\"Label\":\"车间\",\"Prompt\":\"含子车间,留空为全部\",\"IsRequired\":false," +
|
||||
"\"ControlType\":\"F9-DEP-QS-SELECT\",\"Ds_Static\":null,\"Ds_Service\":null,\"DefaultValue\":\"\"}," +
|
||||
"{\"Name\":\"q_jizu\",\"Label\":\"机组\",\"Prompt\":\"留空为全部\",\"IsRequired\":false," +
|
||||
"\"ControlType\":\"AntdUI.Input\",\"Ds_Static\":null,\"Ds_Service\":null,\"DefaultValue\":\"\"}," +
|
||||
"{\"Name\":\"q_zk\",\"Label\":\"庄口\",\"Prompt\":\"点击选择庄口\",\"IsRequired\":false," +
|
||||
"\"ControlType\":\"F9-GYZK-SELECT\",\"Ds_Static\":null,\"Ds_Service\":null,\"DefaultValue\":\"\"}," +
|
||||
"{\"Name\":\"q_like\",\"Label\":\"关键字\",\"Prompt\":\"庄口 / 规格 / 颜色\",\"IsRequired\":false," +
|
||||
"\"ControlType\":\"AntdUI.Input\",\"Ds_Static\":null,\"Ds_Service\":null,\"DefaultValue\":\"\"}]}";
|
||||
|
||||
const string description = "生产-前缫:按日期范围 / 车间 / 机组 / 庄口查询落丝记录明细。";
|
||||
|
||||
var exist = fsql.Select<SysReport>().Where(r => r.Code == code && !r.IsDeleted).First();
|
||||
|
||||
if (exist == null)
|
||||
{
|
||||
var report = new SysReport(snowflake.CreateId(), code, name, category, description, "", "[]", 2, config);
|
||||
|
||||
var newTemplate = LoadEmbeddedTemplateJson("lsjl.grf");
|
||||
if (newTemplate != null)
|
||||
{
|
||||
var newFile = new SysReportFile(snowflake.CreateId(), report.Id, newTemplate);
|
||||
fsql.Insert(newFile).ExecuteAffrows();
|
||||
report.BindReportFile(newFile.Id);
|
||||
}
|
||||
fsql.Insert(report).ExecuteAffrows();
|
||||
|
||||
var perm = new SysPermission(snowflake.CreateId(), Permission_Type_Enum.Visble, Resource_Type_Enum.报表, code, report.Id);
|
||||
perm.SetCode($"report:{code}:visble");
|
||||
fsql.Insert(perm).ExecuteAffrows();
|
||||
|
||||
var adminRole = fsql.Select<SysRole>().Where(r => r.Code == "admin").First();
|
||||
if (adminRole != null)
|
||||
fsql.Insert(new SysRolePermission(snowflake.CreateId(), adminRole.Id, perm.Id)).ExecuteAffrows();
|
||||
|
||||
Console.WriteLine("[DbSeeder] 落丝记录报表已创建(DsName=RepDt_Prod_Lsjl)");
|
||||
return;
|
||||
}
|
||||
|
||||
// 已存在:DsName 未指向该 Provider、或参数标签全为空(程序生成的占位配置)时补齐查询配置
|
||||
// (数据 SQL 清空,避免与 DsName 混淆)
|
||||
var changed = false;
|
||||
if (string.IsNullOrEmpty(exist.Config) || !exist.Config.Contains(dsName)
|
||||
|| ConfigParamsMissingLabel(exist.Config))
|
||||
{
|
||||
exist.UpdateBasic(exist.Code, exist.Name,
|
||||
string.IsNullOrWhiteSpace(exist.Category) ? category : exist.Category,
|
||||
string.IsNullOrWhiteSpace(exist.Description) ? description : exist.Description,
|
||||
"", exist.DataParams, exist.SortOrder, config);
|
||||
changed = true;
|
||||
Console.WriteLine("[DbSeeder] 落丝记录报表查询配置已更新(DsName=RepDt_Prod_Lsjl)");
|
||||
}
|
||||
|
||||
// 模板是占位模板(无标题 / 无参数声明,多为早期上传测试产物)时,替换为内置规范模板;
|
||||
// 旧版内置模板有两类问题一并升级:
|
||||
// 1) 用 Parameter 属性绑定报表参数(GR 推荐 [#{参数名}#] 文本标记)
|
||||
// 2) 把「查询条件」(q_*) 误当成模板参数(那是查询面板的东西,不是报表参数)
|
||||
var templateJson = LoadEmbeddedTemplateJson("lsjl.grf");
|
||||
var file = fsql.Select<SysReportFile>().Where(f => f.ReportId == exist.Id && !f.IsDeleted).First();
|
||||
var oursTemplate = file != null && file.DesignContent.Contains("\"Author\": \"F9 报表中心\"");
|
||||
var legacyParamBinding = oursTemplate
|
||||
&& (file!.DesignContent.Contains("\"Parameter\": \"开始日期\"")
|
||||
|| TemplateHasQueryParams(file.DesignContent)
|
||||
|| TemplateHasStaticBoxParamBinding(file.DesignContent));
|
||||
if (templateJson != null && (file == null || legacyParamBinding || IsPlaceholderReportTemplate(file.DesignContent)))
|
||||
{
|
||||
if (file == null)
|
||||
{
|
||||
file = new SysReportFile(snowflake.CreateId(), exist.Id, templateJson);
|
||||
fsql.Insert(file).ExecuteAffrows();
|
||||
}
|
||||
else
|
||||
{
|
||||
file.UpdateContent(templateJson);
|
||||
fsql.Update<SysReportFile>().SetSource(file).ExecuteAffrows();
|
||||
}
|
||||
exist.BindReportFile(file.Id);
|
||||
changed = true;
|
||||
Console.WriteLine("[DbSeeder] 落丝记录报表模板已更新为内置模板(标题 + 查询参数区)");
|
||||
}
|
||||
|
||||
if (changed) fsql.Update<SysReport>().SetSource(exist).ExecuteAffrows();
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Console.WriteLine($"[DbSeeder] 落丝记录报表种子跳过:{ex.Message}");
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 判断查询条件配置是否缺少标签(Parms 为空,或所有 Label 都为空 → 程序生成的占位配置)。
|
||||
/// 用户手工配过标签的配置不会被种子覆盖。
|
||||
/// </summary>
|
||||
private static bool ConfigParamsMissingLabel(string config)
|
||||
{
|
||||
if (string.IsNullOrWhiteSpace(config)) return true;
|
||||
try
|
||||
{
|
||||
using var doc = System.Text.Json.JsonDocument.Parse(config);
|
||||
if (!doc.RootElement.TryGetProperty("Parms", out var ps)
|
||||
|| ps.ValueKind != System.Text.Json.JsonValueKind.Array
|
||||
|| ps.GetArrayLength() == 0)
|
||||
return true;
|
||||
|
||||
foreach (var p in ps.EnumerateArray())
|
||||
{
|
||||
if (p.ValueKind != System.Text.Json.JsonValueKind.Object) continue;
|
||||
var label = p.TryGetProperty("Label", out var l) && l.ValueKind == System.Text.Json.JsonValueKind.String
|
||||
? l.GetString() ?? ""
|
||||
: "";
|
||||
if (!string.IsNullOrWhiteSpace(label)) return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
catch
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 判断模板是否把报表参数绑在 StaticBox 上(实测 [#{参数}#] 只在 MemoBox 生效,StaticBox 原样输出)。
|
||||
/// </summary>
|
||||
private static bool TemplateHasStaticBoxParamBinding(string content)
|
||||
{
|
||||
if (string.IsNullOrWhiteSpace(content) || content.StartsWith("_WR", StringComparison.Ordinal)) return false;
|
||||
try
|
||||
{
|
||||
using var doc = System.Text.Json.JsonDocument.Parse(content);
|
||||
return ContainsStaticBoxParamBinding(doc.RootElement);
|
||||
}
|
||||
catch
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
private static bool ContainsStaticBoxParamBinding(System.Text.Json.JsonElement el)
|
||||
{
|
||||
if (el.ValueKind == System.Text.Json.JsonValueKind.Object)
|
||||
{
|
||||
var type = el.TryGetProperty("Type", out var t) && t.ValueKind == System.Text.Json.JsonValueKind.String
|
||||
? t.GetString() ?? ""
|
||||
: "";
|
||||
var text = el.TryGetProperty("Text", out var x) && x.ValueKind == System.Text.Json.JsonValueKind.String
|
||||
? x.GetString() ?? ""
|
||||
: "";
|
||||
if (type == "StaticBox" && text.Contains("[#{")) return true;
|
||||
|
||||
foreach (var prop in el.EnumerateObject())
|
||||
if (ContainsStaticBoxParamBinding(prop.Value)) return true;
|
||||
}
|
||||
else if (el.ValueKind == System.Text.Json.JsonValueKind.Array)
|
||||
{
|
||||
foreach (var item in el.EnumerateArray())
|
||||
if (ContainsStaticBoxParamBinding(item)) return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 判断模板是否把「查询条件」(q_* 参数) 误写成了模板参数。
|
||||
/// 模板参数应来自后端 Parameter_Data(如 车间 / 记录数 / 查询时间),不是查询面板的 q_*。
|
||||
/// </summary>
|
||||
private static bool TemplateHasQueryParams(string content)
|
||||
{
|
||||
if (string.IsNullOrWhiteSpace(content) || content.StartsWith("_WR", StringComparison.Ordinal)) return false;
|
||||
try
|
||||
{
|
||||
using var doc = System.Text.Json.JsonDocument.Parse(content);
|
||||
if (!doc.RootElement.TryGetProperty("Parameter", out var ps)
|
||||
|| ps.ValueKind != System.Text.Json.JsonValueKind.Array)
|
||||
return false;
|
||||
|
||||
foreach (var p in ps.EnumerateArray())
|
||||
{
|
||||
if (p.ValueKind != System.Text.Json.JsonValueKind.Object) continue;
|
||||
if (!p.TryGetProperty("Name", out var n) || n.ValueKind != System.Text.Json.JsonValueKind.String) continue;
|
||||
if ((n.GetString() ?? "").StartsWith("q_", StringComparison.Ordinal)) return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
catch
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 判断模板是否为占位模板:JSON 格式、Title 为空、且没有声明任何 Parameter。
|
||||
/// GR7 设计器保存的 _WR 压缩模板无法判断,一律视为正常模板(不覆盖)。
|
||||
/// </summary>
|
||||
private static bool IsPlaceholderReportTemplate(string content)
|
||||
{
|
||||
if (string.IsNullOrWhiteSpace(content) || content.StartsWith("_WR", StringComparison.Ordinal)) return false;
|
||||
try
|
||||
{
|
||||
using var doc = System.Text.Json.JsonDocument.Parse(content);
|
||||
var root = doc.RootElement;
|
||||
var title = root.TryGetProperty("Title", out var t) && t.ValueKind == System.Text.Json.JsonValueKind.String
|
||||
? t.GetString() ?? ""
|
||||
: "";
|
||||
var hasParamDecl = root.TryGetProperty("Parameter", out var p)
|
||||
&& p.ValueKind == System.Text.Json.JsonValueKind.Array
|
||||
&& p.GetArrayLength() > 0;
|
||||
return string.IsNullOrWhiteSpace(title) && !hasParamDecl;
|
||||
}
|
||||
catch
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>从嵌入资源读取报表 .grf 模板 JSON 文本(.grf 为 UTF-8 JSON,GR7 向下兼容 GR6 格式)</summary>
|
||||
private static string? LoadEmbeddedTemplateJson(string fileName)
|
||||
{
|
||||
try
|
||||
{
|
||||
var asm = typeof(DbSeeder).Assembly;
|
||||
var resName = asm.GetManifestResourceNames()
|
||||
.FirstOrDefault(n => n.EndsWith("." + fileName, StringComparison.OrdinalIgnoreCase));
|
||||
if (string.IsNullOrEmpty(resName)) return null;
|
||||
|
||||
using var stream = asm.GetManifestResourceStream(resName);
|
||||
if (stream == null) return null;
|
||||
using var reader = new StreamReader(stream, new UTF8Encoding(false));
|
||||
var json = reader.ReadToEnd();
|
||||
|
||||
// 统一去 BOM 后保存(ReportFile.DesignContent 存纯文本,输出 .grf 时再补 BOM)
|
||||
return json.Length > 0 && json[0] == '\uFEFF' ? json.Substring(1) : json;
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Console.WriteLine($"[DbSeeder] 读取嵌入模板失败:{ex.Message}");
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -15,6 +15,8 @@
|
||||
<ItemGroup>
|
||||
<!-- 工种基础数据种子(来源于 F9 系统 biz_base_worktype 三张表导出) -->
|
||||
<EmbeddedResource Include="Data\SeedData\*.json" />
|
||||
<!-- 报表中心示例 .grf 模板(GR6.8.5.0 格式;GR7 设计器向下兼容,可直接打开编辑) -->
|
||||
<EmbeddedResource Include="Assets\ReportTemplates\*.grf" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
|
||||
+5
-1
@@ -20,7 +20,11 @@ internal class DepartmentWriteRepository : F9RepositoryBase, IDepartmentWriteRep
|
||||
public async Task<bool> UpdateAsync(Department dep)
|
||||
{
|
||||
dep.UpdatedAt = DateTime.Now;
|
||||
return await Orm.Update<Department>().SetSource(dep).ExecuteAffrowsAsync() > 0;
|
||||
// 编辑只覆盖业务字段:启用/禁用有独立命令,不能被 SetSource 连带重置;创建信息与删除标记同理
|
||||
return await Orm.Update<Department>()
|
||||
.SetSource(dep)
|
||||
.IgnoreColumns(x => new { x.IsActive, x.IsDeleted, x.CreatedAt, x.CreatedBy })
|
||||
.ExecuteAffrowsAsync() > 0;
|
||||
}
|
||||
|
||||
public async Task<bool> SoftDeleteAsync(long id)
|
||||
|
||||
Reference in New Issue
Block a user