Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
S
sd-issue-list
Project
Project
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
单鹏辉
sd-issue-list
Commits
e9e2ca65
Commit
e9e2ca65
authored
Jul 04, 2026
by
单鹏辉
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
修复: ISS-山东-011 文件编码问题,重新生成 HTML 报告
parent
6753b4f0
Hide whitespace changes
Inline
Side-by-side
Showing
2 changed files
with
150 additions
and
1 deletion
+150
-1
ISS-山东-011.md
issues/ISS-山东-011.md
+1
-1
问题清单_看板.html
问题清单_看板.html
+149
-0
No files found.
issues/ISS-山东-011.md
View file @
e9e2ca65
---
---
id
:
ISS-山东-011
project
:
山东思达特
title
:
采购价格控制偏差报警问题
...
...
问题清单_看板.html
0 → 100644
View file @
e9e2ca65
<!DOCTYPE html>
<html
lang=
"zh"
><head><meta
charset=
"utf-8"
><meta
name=
"viewport"
content=
"width=device-width,initial-scale=1"
>
<title>
周例会 · 问题清单 Ledger 看板
</title>
<style>
*
{
box-sizing
:
border-box
}
body
{
margin
:
0
;
font-family
:
-apple-system
,
"Segoe UI"
,
"Microsoft YaHei"
,
sans-serif
;
background
:
#0f1115
;
color
:
#e7e9ee
;
font-size
:
14px
}
.wrap
{
max-width
:
1280px
;
margin
:
0
auto
;
padding
:
20px
}
h1
{
font-size
:
22px
;
margin
:
0
0
2px
}
.sub
{
color
:
#8b93a7
;
font-size
:
13px
;
margin-bottom
:
18px
}
.sec
{
font-size
:
13px
;
letter-spacing
:
2px
;
color
:
#8b93a7
;
margin
:
22px
0
10px
;
text-transform
:
uppercase
}
.cards
{
display
:
flex
;
flex-wrap
:
wrap
;
gap
:
12px
}
.card
{
background
:
#171a21
;
border
:
1px
solid
#232734
;
border-radius
:
10px
;
padding
:
14px
16px
;
min-width
:
150px
;
flex
:
1
}
.card
.n
{
font-size
:
26px
;
font-weight
:
700
}
.card
.l
{
color
:
#8b93a7
;
font-size
:
12px
;
margin-top
:
3px
}
.card.bad
{
border-color
:
#5a2330
;
background
:
#1d1417
}
.card.bad
.n
{
color
:
#ff6b81
}
.card.good
{
border-color
:
#1f4a36
}
.card.good
.n
{
color
:
#48d597
}
.card
.why
{
color
:
#6f7689
;
font-size
:
11px
;
margin-top
:
6px
;
line-height
:
1.4
}
.bar
{
height
:
8px
;
background
:
#232734
;
border-radius
:
4px
;
overflow
:
hidden
;
margin-top
:
6px
}
.bar
>
i
{
display
:
block
;
height
:
100%
}
.row2
{
display
:
grid
;
grid-template-columns
:
1
fr
1
fr
;
gap
:
16px
}
@media
(
max-width
:
820px
){
.row2
{
grid-template-columns
:
1
fr
}}
.panel
{
background
:
#171a21
;
border
:
1px
solid
#232734
;
border-radius
:
10px
;
padding
:
14px
16px
}
.dist
.item
{
display
:
flex
;
align-items
:
center
;
gap
:
10px
;
margin
:
7px
0
;
font-size
:
13px
}
.dist
.item
span
:first-child
{
width
:
96px
;
color
:
#b9c0d0
}
.dist
.item
span
:last-child
{
width
:
34px
;
text-align
:
right
;
color
:
#8b93a7
}
.dist
.item
.bar
{
flex
:
1
}
.controls
{
display
:
flex
;
flex-wrap
:
wrap
;
gap
:
8px
;
margin
:
14px
0
}
select
,
input
{
background
:
#171a21
;
color
:
#e7e9ee
;
border
:
1px
solid
#2a2f3d
;
border-radius
:
7px
;
padding
:
7px
10px
;
font-size
:
13px
}
input
{
flex
:
1
;
min-width
:
180px
}
.chk
{
display
:
flex
;
align-items
:
center
;
gap
:
5px
;
color
:
#b9c0d0
;
font-size
:
13px
;
padding
:
6px
8px
}
table
{
width
:
100%
;
border-collapse
:
collapse
;
margin-top
:
6px
}
th
,
td
{
text-align
:
left
;
padding
:
8px
9px
;
border-bottom
:
1px
solid
#20242e
;
font-size
:
13px
;
vertical-align
:
top
}
th
{
color
:
#8b93a7
;
font-weight
:
600
;
cursor
:
pointer
;
user-select
:
none
;
position
:
sticky
;
top
:
0
;
background
:
#0f1115
}
tr
.issue
{
cursor
:
pointer
}
tr
.issue
:hover
{
background
:
#171a21
}
.pill
{
display
:
inline-block
;
padding
:
2px
8px
;
border-radius
:
11px
;
font-size
:
11px
;
font-weight
:
600
;
white-space
:
nowrap
}
.f-
已完成
{
background
:
#103a28
;
color
:
#48d597
}
.f-
待用户验证
{
background
:
#3d3414
;
color
:
#e8c24b
}
.f-
进行中
{
background
:
#16304d
;
color
:
#5fa8ff
}
.f-
进行中\
(
返工\
)
{
background
:
#3d2414
;
color
:
#ff9b54
}
.f-
未开始
{
background
:
#262a36
;
color
:
#9aa3b5
}
.f-
已关闭
{
background
:
#22262f
;
color
:
#6f7689
}
.pr-
高
{
color
:
#ff6b81
;
font-weight
:
700
}
.pr-
中
{
color
:
#e8c24b
}
.pr-
低
{
color
:
#8b93a7
}
.od
{
color
:
#ff6b81
;
font-weight
:
700
}
.detail
{
background
:
#12151b
}
.detail
td
{
padding
:
0
}
.dbox
{
padding
:
14px
18px
}
.log
{
border-left
:
2px
solid
#2a2f3d
;
margin-left
:
6px
;
padding-left
:
14px
}
.log
.e
{
margin
:
9px
0
;
font-size
:
13px
;
line-height
:
1.45
}
.log
.meta
{
color
:
#6f7689
;
font-size
:
11px
}
.log
.meta
b
{
color
:
#9aa3b5
;
font-weight
:
600
}
.kv
{
color
:
#8b93a7
;
font-size
:
12px
;
margin
:
4px
0
}
.tag
{
display
:
inline-block
;
background
:
#202637
;
color
:
#8fb0ff
;
border-radius
:
5px
;
padding
:
1px
7px
;
font-size
:
11px
;
margin-right
:
5px
}
.note
{
color
:
#6f7689
;
font-size
:
12px
;
margin-top
:
4px
}
.foot
{
color
:
#5b6172
;
font-size
:
11px
;
margin
:
24px
0
8px
;
text-align
:
center
}
</style></head><body><div
class=
"wrap"
>
<h1>
周例会 · 问题清单 Ledger 看板
</h1>
<div
class=
"sub"
id=
"sub"
></div>
<div
class=
"sec"
>
① Excel 体检 — 这张表把什么藏起来了
</div>
<div
class=
"cards"
id=
"audit"
></div>
<div
class=
"sec"
>
② 可信汇总(由 206 个对象派生,不是手填)
</div>
<div
class=
"row2"
>
<div
class=
"panel"
><div
class=
"cards"
id=
"topnums"
></div></div>
<div
class=
"panel dist"
id=
"fsdist"
></div>
</div>
<div
class=
"row2"
style=
"margin-top:16px"
>
<div
class=
"panel dist"
id=
"ownerdist"
><div
class=
"sec"
style=
"margin:0 0 8px"
>
各责任顾问 · 未关闭(调度)
</div></div>
<div
class=
"panel dist"
id=
"pridist"
><div
class=
"sec"
style=
"margin:0 0 8px"
>
按优先级
</div></div>
</div>
<div
class=
"sec"
>
③ 工作台 — 点任意一行看 append-only 进展日志
</div>
<div
class=
"controls"
>
<select
id=
"f_owner"
></select><select
id=
"f_final"
></select><select
id=
"f_pri"
></select>
<input
id=
"f_q"
placeholder=
"搜索描述/标题/编号…"
>
<label
class=
"chk"
><input
type=
"checkbox"
id=
"f_od"
>
只看超期
</label>
<label
class=
"chk"
><input
type=
"checkbox"
id=
"f_open"
checked
>
只看未关闭
</label>
</div>
<table><thead><tr>
<th
data-k=
"id"
>
编号
</th><th
data-k=
"owner"
>
责任顾问
</th><th
data-k=
"priority"
>
优先级
</th>
<th
data-k=
"final"
>
最终状态
</th><th
data-k=
"plan"
>
计划完成
</th><th
data-k=
"nlog"
>
进展
</th><th
data-k=
"title"
>
标题
</th>
</tr></thead><tbody
id=
"tb"
></tbody></table>
<div
class=
"foot"
id=
"foot"
></div>
</div>
<script>
const
DATA
=
[{
"id"
:
"ISS-山东-000"
,
"owner"
:
"王志慧"
,
"raised_by"
:
"王志慧"
,
"raised_dept"
:
""
,
"priority"
:
"未定"
,
"category"
:
"未分类"
,
"sap"
:
"已完成"
,
"acc"
:
"NA"
,
"final"
:
"进行中"
,
"plan"
:
"2026-04-24"
,
"overdue"
:
true
,
"desc"
:
"解决思达特销售订单打印问题"
,
"desc_html"
:
"解决思达特销售订单打印问题"
,
"plan_txt"
:
"无"
,
"title"
:
"解决思达特销售订单打印问题"
,
"nlog"
:
0
,
"logs"
:
[],
"linked"
:
[],
"owner_history"
:
[],
"attachments"
:
[]},
{
"id"
:
"ISS-山东-001"
,
"owner"
:
"王志慧"
,
"raised_by"
:
"王志慧"
,
"raised_dept"
:
""
,
"priority"
:
"未定"
,
"category"
:
"未分类"
,
"sap"
:
"已完成"
,
"acc"
:
"NA"
,
"final"
:
"进行中"
,
"plan"
:
"2026-03-26"
,
"overdue"
:
true
,
"desc"
:
"思达特销售订单分析数据问题"
,
"desc_html"
:
"思达特销售订单分析数据问题"
,
"plan_txt"
:
"无"
,
"title"
:
"思达特销售订单分析数据问题"
,
"nlog"
:
0
,
"logs"
:
[],
"linked"
:
[],
"owner_history"
:
[],
"attachments"
:
[]},
{
"id"
:
"ISS-山东-002"
,
"owner"
:
"王志慧"
,
"raised_by"
:
"王志慧"
,
"raised_dept"
:
""
,
"priority"
:
"未定"
,
"category"
:
"未分类"
,
"sap"
:
"已完成"
,
"acc"
:
"NA"
,
"final"
:
"进行中"
,
"plan"
:
"2026-03-14"
,
"overdue"
:
true
,
"desc"
:
"思达特物料主数据导入报错(1.检查报错原因发现是编号问题2.结果报事件"
,
"desc_html"
:
"思达特物料主数据导入报错(1.检查报错原因发现是编号问题2.结果报事件"
,
"plan_txt"
:
"无"
,
"title"
:
"思达特物料主数据导入报错(1.检查报错原因发现是"
,
"nlog"
:
0
,
"logs"
:
[],
"linked"
:
[],
"owner_history"
:
[],
"attachments"
:
[]},
{
"id"
:
"ISS-山东-003"
,
"owner"
:
"王志慧"
,
"raised_by"
:
"王志慧"
,
"raised_dept"
:
""
,
"priority"
:
"未定"
,
"category"
:
"未分类"
,
"sap"
:
"已完成"
,
"acc"
:
"NA"
,
"final"
:
"进行中"
,
"plan"
:
"2026-03-14"
,
"overdue"
:
true
,
"desc"
:
"思达特查参加问题会议沟通(1.参加会议2.提供未清销售订单和未清采购订单的查询方式)"
,
"desc_html"
:
"思达特查参加问题会议沟通(1.参加会议2.提供未清销售订单和未清采购订单的查询方式)"
,
"plan_txt"
:
"无"
,
"title"
:
"思达特查参加问题会议沟通(1.参加会议2.提供未"
,
"nlog"
:
0
,
"logs"
:
[],
"linked"
:
[],
"owner_history"
:
[],
"attachments"
:
[]},
{
"id"
:
"ISS-山东-004"
,
"owner"
:
"王志慧"
,
"raised_by"
:
"王志慧"
,
"raised_dept"
:
""
,
"priority"
:
"未定"
,
"category"
:
"未分类"
,
"sap"
:
"已完成"
,
"acc"
:
"NA"
,
"final"
:
"进行中"
,
"plan"
:
"2026-03-14"
,
"overdue"
:
true
,
"desc"
:
"研究CDS报表报错"
,
"desc_html"
:
"研究CDS报表报错"
,
"plan_txt"
:
"无"
,
"title"
:
"研究CDS报表报错"
,
"nlog"
:
0
,
"logs"
:
[],
"linked"
:
[],
"owner_history"
:
[],
"attachments"
:
[]},
{
"id"
:
"ISS-山东-005"
,
"owner"
:
"Li Wang"
,
"raised_by"
:
"Li Wang"
,
"raised_dept"
:
""
,
"priority"
:
"未定"
,
"category"
:
"未分类"
,
"sap"
:
"已完成"
,
"acc"
:
"NA"
,
"final"
:
"进行中"
,
"plan"
:
"2025-12-04"
,
"overdue"
:
true
,
"desc"
:
"库存与实物对应不上问题"
,
"desc_html"
:
"库存与实物对应不上问题"
,
"plan_txt"
:
"无"
,
"title"
:
"思达特--库存与实物对应不上问题"
,
"nlog"
:
0
,
"logs"
:
[],
"linked"
:
[],
"owner_history"
:
[],
"attachments"
:
[]},
{
"id"
:
"ISS-山东-006"
,
"owner"
:
"王志慧"
,
"raised_by"
:
"王志慧"
,
"raised_dept"
:
""
,
"priority"
:
"未定"
,
"category"
:
"未分类"
,
"sap"
:
"已完成"
,
"acc"
:
"NA"
,
"final"
:
"进行中"
,
"plan"
:
"2026-02-11"
,
"overdue"
:
true
,
"desc"
:
"思达特项目修改权限问题"
,
"desc_html"
:
"思达特项目修改权限问题"
,
"plan_txt"
:
"无"
,
"title"
:
"思达特项目修改权限问题"
,
"nlog"
:
0
,
"logs"
:
[],
"linked"
:
[],
"owner_history"
:
[],
"attachments"
:
[]},
{
"id"
:
"ISS-山东-007"
,
"owner"
:
"单鹏辉"
,
"raised_by"
:
"单鹏辉"
,
"raised_dept"
:
""
,
"priority"
:
"未定"
,
"category"
:
"未分类"
,
"sap"
:
"已完成"
,
"acc"
:
"NA"
,
"final"
:
"进行中"
,
"plan"
:
"2026-06-01"
,
"overdue"
:
true
,
"desc"
:
"需要在CBC增加销售区域36"
,
"desc_html"
:
"需要在CBC增加销售区域36"
,
"plan_txt"
:
"无"
,
"title"
:
"新增销售区域"
,
"nlog"
:
0
,
"logs"
:
[],
"linked"
:
[],
"owner_history"
:
[],
"attachments"
:
[]},
{
"id"
:
"ISS-山东-008"
,
"owner"
:
"单鹏辉"
,
"raised_by"
:
"单鹏辉"
,
"raised_dept"
:
""
,
"priority"
:
"未定"
,
"category"
:
"未分类"
,
"sap"
:
"已完成"
,
"acc"
:
"NA"
,
"final"
:
"进行中"
,
"plan"
:
"2026-06-02"
,
"overdue"
:
true
,
"desc"
:
"物料主数据迁移,新增单位迁移时报错"
,
"desc_html"
:
"物料主数据迁移,新增单位迁移时报错"
,
"plan_txt"
:
"单位映射问题,ISO映射代码不对"
,
"title"
:
"物料主数据迁移,单位问题报错"
,
"nlog"
:
0
,
"logs"
:
[],
"linked"
:
[],
"owner_history"
:
[],
"attachments"
:
[]},
{
"id"
:
"ISS-山东-009"
,
"owner"
:
"单鹏辉"
,
"raised_by"
:
"单鹏辉"
,
"raised_dept"
:
""
,
"priority"
:
"未定"
,
"category"
:
"未分类"
,
"sap"
:
"已完成"
,
"acc"
:
"NA"
,
"final"
:
"进行中"
,
"plan"
:
"2026-06-10"
,
"overdue"
:
true
,
"desc"
:
"销售订单借单打印模板缺失3个字段信息"
,
"desc_html"
:
"销售订单借单打印模板缺失3个字段信息"
,
"plan_txt"
:
"数据源问题,系统更新时效,更换数据源"
,
"title"
:
"借单打印模板字段缺失"
,
"nlog"
:
0
,
"logs"
:
[],
"linked"
:
[],
"owner_history"
:
[],
"attachments"
:
[]},
{
"id"
:
"ISS-山东-010"
,
"owner"
:
"单鹏辉"
,
"raised_by"
:
"单鹏辉"
,
"raised_dept"
:
""
,
"priority"
:
"未定"
,
"category"
:
"未分类"
,
"sap"
:
"已完成"
,
"acc"
:
"NA"
,
"final"
:
"进行中"
,
"plan"
:
"2026-06-26"
,
"overdue"
:
true
,
"desc"
:
"采购订单设置审批流程"
,
"desc_html"
:
"采购订单设置审批流程"
,
"plan_txt"
:
"标准流程设置"
,
"title"
:
"采购审批流设定"
,
"nlog"
:
0
,
"logs"
:
[],
"linked"
:
[],
"owner_history"
:
[],
"attachments"
:
[]},
{
"id"
:
"ISS-山东-011"
,
"owner"
:
"单鹏辉"
,
"raised_by"
:
"冯越"
,
"raised_dept"
:
""
,
"priority"
:
"低"
,
"category"
:
"用户操作问题"
,
"sap"
:
"未开始"
,
"acc"
:
"NA"
,
"final"
:
"未开始"
,
"plan"
:
""
,
"overdue"
:
false
,
"desc"
:
"采购价格控制,偏差报警不能保存订单"
,
"desc_html"
:
"采购价格控制,偏差报警不能保存订单"
,
"plan_txt"
:
"待分析"
,
"title"
:
"采购价格控制偏差报警问题"
,
"nlog"
:
0
,
"logs"
:
[],
"linked"
:
[],
"owner_history"
:
[],
"attachments"
:
[]}],
S
=
{
"total"
:
12
,
"total_logs"
:
0
,
"fs"
:
{
"进行中"
:
11
,
"未开始"
:
1
},
"pri"
:
{
"未定"
:
11
,
"低"
:
1
},
"owner_open"
:
{
"王志慧"
:
6
,
"单鹏辉"
:
5
,
"Li Wang"
:
1
},
"overdue"
:
11
,
"sap_done"
:
11
,
"final_done"
:
0
,
"today"
:
"2026-07-04"
,
"audit"
:
null
};
const
fsOrder
=
[
"进行中(返工)"
,
"进行中"
,
"待用户验证"
,
"未开始"
,
"已完成"
,
"已关闭"
];
document
.
getElementById
(
'sub'
).
textContent
=
`数据源 =
${
S
.
total
}
个结构化对象(issues/*.md)· 实时重算 · 生成于
${
S
.
today
}
— 这不是那张 Excel,是它本该有的样子`
;
// ① audit
if
(
S
.
audit
){
const
a
=
S
.
audit
;
const
items
=
[
[
a
.
contradictions
,
'处状态自相矛盾'
,
'原表"SAP已完成"却"最终状态≠已完成"。Ledger 里最终状态是派生函数,结构上不可能矛盾。'
],
[
a
.
changelog_cells
,
'个单元格塞手写流水账'
,
`已拆成
${
S
.
total_logs
}
条带 时间·作者·来源 的 append-only 日志(点下方任意行看)。`
],
[
a
.
missing_priority
+
'/'
+
a
.
missing_category
,
'缺优先级/缺分类'
,
'没人强制填。Ledger 受控字段缺失即标红不过门。'
],
[
a
.
acc_distinct
,
'种"验收反馈"自由写法'
,
'同一个"已解决"68 种写法,机器没法聚合。Ledger 用受控状态+证据指针。'
]];
document
.
getElementById
(
'audit'
).
innerHTML
=
items
.
map
(
x
=>
`<div class="card bad"><div class="n">
${
x
[
0
]}
</div><div class="l">
${
x
[
1
]}
</div><div class="why">
${
x
[
2
]}
</div></div>`
).
join
(
''
);
}
else
{
document
.
getElementById
(
'audit'
).
innerHTML
=
'<div class="card">未提供源 Excel,跳过体检</div>'
;}
// ② top nums
const
pct
=
(
n
)
=>
S
.
total
?
Math
.
round
(
n
/
S
.
total
*
100
):
0
;
document
.
getElementById
(
'topnums'
).
innerHTML
=
[
[
'good'
,
S
.
total
,
'问题总数'
,
''
],
[
'good'
,
S
.
final_done
,
'最终已完成'
,
`SAP完成且用户验证 ·
${
pct
(
S
.
final_done
)}
%`
],
[
''
,
S
.
sap_done
,
'SAP 已完成'
,
`
${
pct
(
S
.
sap_done
)}
%(≠最终完成)`
],
[
'bad'
,
S
.
overdue
,
'超期未关闭'
,
'计划完成日已过'
]
].
map
(
x
=>
`<div class="card
${
x
[
0
]}
"><div class="n">
${
x
[
1
]}
</div><div class="l">
${
x
[
2
]}
</div><div class="why">
${
x
[
3
]}
</div></div>`
).
join
(
''
);
function
dist
(
el
,
obj
,
order
,
total
,
title
){
const
keys
=
order
?
order
.
filter
(
k
=>
obj
[
k
]):
Object
.
keys
(
obj
).
sort
((
a
,
b
)
=>
obj
[
b
]
-
obj
[
a
]);
const
mx
=
Math
.
max
(
1
,...
Object
.
values
(
obj
));
const
col
=
{
'已完成'
:
'#48d597'
,
'待用户验证'
:
'#e8c24b'
,
'进行中'
:
'#5fa8ff'
,
'进行中(返工)'
:
'#ff9b54'
,
'未开始'
:
'#9aa3b5'
,
'已关闭'
:
'#6f7689'
,
'高'
:
'#ff6b81'
,
'中'
:
'#e8c24b'
,
'低'
:
'#7f8aa0'
};
let
h
=
title
?
`<div class="sec" style="margin:0 0 8px">
${
title
}
</div>`
:
''
;
h
+=
keys
.
map
(
k
=>
`<div class="item"><span>
${
k
}
</span><div class="bar"><i style="width:
${
obj
[
k
]
/
mx
*
100
}
%;background:
${
col
[
k
]
||
'#5fa8ff'
}
"></i></div><span>
${
obj
[
k
]}
</span></div>`
).
join
(
''
);
el
.
innerHTML
=
h
;}
dist
(
document
.
getElementById
(
'fsdist'
),
S
.
fs
,
fsOrder
,
S
.
total
,
'按最终状态(派生)'
);
dist
(
document
.
getElementById
(
'ownerdist'
),
S
.
owner_open
,
null
,
S
.
total
,
'各责任顾问 · 未关闭(调度)'
);
dist
(
document
.
getElementById
(
'pridist'
),
S
.
pri
,[
'高'
,
'中'
,
'低'
,
'未定'
],
S
.
total
,
'按优先级'
);
// ③ table
function
opts
(
el
,
arr
,
all
){
el
.
innerHTML
=
`<option value="">
${
all
}
</option>`
+
arr
.
map
(
v
=>
`<option>
${
v
}
</option>`
).
join
(
''
);}
opts
(
document
.
getElementById
(
'f_owner'
),[...
new
Set
(
DATA
.
map
(
d
=>
d
.
owner
))].
sort
(),
'全部责任顾问'
);
opts
(
document
.
getElementById
(
'f_final'
),
fsOrder
,
'全部状态'
);
opts
(
document
.
getElementById
(
'f_pri'
),[
'高'
,
'中'
,
'低'
,
'未定'
],
'全部优先级'
);
let
sortK
=
'id'
,
sortAsc
=
true
;
const
esc
=
s
=>
(
s
||
''
).
replace
(
/
[
&<>
]
/g
,
c
=>
({
'&'
:
'&'
,
'<'
:
'<'
,
'>'
:
'>'
}[
c
]));
function
render
(){
const
fo
=
f_owner
.
value
,
ff
=
f_final
.
value
,
fp
=
f_pri
.
value
,
q
=
f_q
.
value
.
trim
(),
od
=
f_od
.
checked
,
op
=
f_open
.
checked
;
let
rows
=
DATA
.
filter
(
d
=>
(
!
fo
||
d
.
owner
===
fo
)
&&
(
!
ff
||
d
.
final
===
ff
)
&&
(
!
fp
||
d
.
priority
===
fp
)
&&
(
!
od
||
d
.
overdue
)
&&
(
!
op
||
(
d
.
final
!==
'已完成'
&&
d
.
final
!==
'已关闭'
))
&&
(
!
q
||
(
d
.
id
+
d
.
title
+
d
.
desc
).
toLowerCase
().
includes
(
q
.
toLowerCase
())));
rows
.
sort
((
a
,
b
)
=>
{
let
x
=
a
[
sortK
],
y
=
b
[
sortK
];
if
(
sortK
===
'nlog'
){
x
=+
x
;
y
=+
y
}
return
(
x
>
y
?
1
:
x
<
y
?
-
1
:
0
)
*
(
sortAsc
?
1
:
-
1
)});
tb
.
innerHTML
=
rows
.
map
(
d
=>
{
const
od
=
d
.
overdue
?
'<span class="od"> ⚠超期</span>'
:
''
;
const
logs
=
d
.
logs
.
map
(
l
=>
`<div class="e"><div class="meta"><b>
${
l
.
date
}
</b> ·
${
esc
(
l
.
author
)}
· <span class="tag">
${
esc
(
l
.
source
)}
</span></div>
${
esc
(
l
.
text
)}
</div>`
).
join
(
''
);
const
lk
=
(
d
.
linked
||
[]).
map
(
x
=>
`<span class="tag">
${
x
.
rel
}
→
${
x
.
id
}
</span>`
).
join
(
''
);
const
attChips
=
(
d
.
attachments
||
[]).
map
(
a
=>
`<span class="tag">
${
esc
(
a
.
filename
)}
</span>`
).
join
(
''
);
const
ownerHist
=
(
d
.
owner_history
||
[]).
map
(
h
=>
`<div class="e"><div class="meta"><b>
${
esc
(
h
.
date
)}
</b> ·
${
esc
(
h
.
by
)}
· <span class="tag">转派</span></div>
${
esc
(
h
.
from
)}
→
${
esc
(
h
.
to
)}
:
${
esc
(
h
.
reason
||
''
)}
</div>`
).
join
(
''
);
return
`<tr class="issue" onclick="this.nextElementSibling.style.display=this.nextElementSibling.style.display==='table-row'?'none':'table-row'">
<td>
${
d
.
id
}
</td><td>
${
esc
(
d
.
owner
)}
</td><td class="pr-
${
d
.
priority
}
">
${
d
.
priority
}
</td>
<td><span class="pill f-
${
d
.
final
}
">
${
d
.
final
}
</span></td><td>
${
d
.
plan
||
'—'
}${
od
}
</td><td>
${
d
.
nlog
}
</td><td>
${
esc
(
d
.
title
)}
</td></tr>
<tr class="detail" style="display:none"><td colspan="7"><div class="dbox">
<div class="kv"><b>
${
d
.
id
}
</b> 提出:
${
esc
(
d
.
raised_dept
)}
/
${
esc
(
d
.
raised_by
)}
SAP:
${
d
.
sap
}
验收:
${
d
.
acc
}
分类:
${
esc
(
d
.
category
)}
${
lk
}
</div>
<div class="kv">责任顾问:
${
esc
(
d
.
owner
)}
${
attChips
}
</div>
<div class="kv" style="white-space:pre-wrap">问题描述:
${
d
.
desc_html
}
</div>
<div class="kv">当前方案:
${
esc
(
d
.
plan_txt
)
||
'—'
}
</div>
<div class="sec" style="margin:12px 0 6px">责任人变更历史</div>
<div class="log">
${
ownerHist
||
'<div class="note">无</div>'
}
</div>
<div class="sec" style="margin:12px 0 6px">进展日志(append-only)</div>
<div class="log">
${
logs
||
'<div class="note">无</div>'
}
</div>
</div></td></tr>`
;}).
join
(
''
);
foot
.
textContent
=
`显示
${
rows
.
length
}
/
${
DATA
.
length
}
条 · 点行展开进展日志`
;
}
document
.
querySelectorAll
(
'th[data-k]'
).
forEach
(
th
=>
th
.
onclick
=
()
=>
{
const
k
=
th
.
dataset
.
k
;
if
(
sortK
===
k
)
sortAsc
=!
sortAsc
;
else
{
sortK
=
k
;
sortAsc
=
true
}
render
();});
[
'f_owner'
,
'f_final'
,
'f_pri'
,
'f_q'
,
'f_od'
,
'f_open'
].
forEach
(
id
=>
document
.
getElementById
(
id
).
addEventListener
(
'input'
,
render
));
render
();
</script></body></html>
\ No newline at end of file
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment