skill-bill 0.1.0 → 0.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (298) hide show
  1. package/SKILL.md +127 -0
  2. package/dist/.gen-inputs.json +14 -0
  3. package/dist/cli/cmd_read.js +133 -142
  4. package/dist/cli/cmd_read.js.map +1 -1
  5. package/dist/cli/registry.d.ts +15 -0
  6. package/dist/cli/registry.d.ts.map +1 -0
  7. package/dist/cli/registry.js +22 -0
  8. package/dist/cli/registry.js.map +1 -0
  9. package/dist/fetch/db.d.ts +4 -0
  10. package/dist/fetch/db.d.ts.map +1 -1
  11. package/dist/fetch/db.js +12 -0
  12. package/dist/fetch/db.js.map +1 -1
  13. package/dist/fetch/index.d.ts +1 -1
  14. package/dist/fetch/index.d.ts.map +1 -1
  15. package/dist/fetch/index.js +1 -1
  16. package/dist/fetch/index.js.map +1 -1
  17. package/dist/help/index.d.ts +1 -0
  18. package/dist/help/index.d.ts.map +1 -1
  19. package/dist/help/index.js +1 -0
  20. package/dist/help/index.js.map +1 -1
  21. package/dist/help/lookup.d.ts.map +1 -1
  22. package/dist/help/lookup.js +3 -2
  23. package/dist/help/lookup.js.map +1 -1
  24. package/dist/help/writeWire.d.ts +16 -0
  25. package/dist/help/writeWire.d.ts.map +1 -0
  26. package/dist/help/writeWire.js +109 -0
  27. package/dist/help/writeWire.js.map +1 -0
  28. package/dist/output.d.ts +21 -0
  29. package/dist/output.d.ts.map +1 -0
  30. package/dist/output.js +48 -0
  31. package/dist/output.js.map +1 -0
  32. package/dist/policy/category.d.ts +5 -0
  33. package/dist/policy/category.d.ts.map +1 -1
  34. package/dist/policy/category.js +9 -2
  35. package/dist/policy/category.js.map +1 -1
  36. package/dist/policy/index.d.ts +1 -1
  37. package/dist/policy/index.d.ts.map +1 -1
  38. package/dist/policy/index.js +1 -1
  39. package/dist/policy/index.js.map +1 -1
  40. package/dist/policy/record.d.ts +12 -0
  41. package/dist/policy/record.d.ts.map +1 -1
  42. package/dist/policy/record.js +27 -0
  43. package/dist/policy/record.js.map +1 -1
  44. package/dist/policy/wakewords.d.ts +4 -0
  45. package/dist/policy/wakewords.d.ts.map +1 -1
  46. package/dist/policy/wakewords.js +12 -7
  47. package/dist/policy/wakewords.js.map +1 -1
  48. package/dist/query/commands.d.ts +19 -0
  49. package/dist/query/commands.d.ts.map +1 -0
  50. package/dist/query/commands.js +40 -0
  51. package/dist/query/commands.js.map +1 -0
  52. package/dist/query/detail.d.ts +26 -0
  53. package/dist/query/detail.d.ts.map +1 -0
  54. package/dist/query/detail.js +115 -0
  55. package/dist/query/detail.js.map +1 -0
  56. package/dist/query/index.d.ts +13 -0
  57. package/dist/query/index.d.ts.map +1 -0
  58. package/dist/query/index.js +12 -0
  59. package/dist/query/index.js.map +1 -0
  60. package/dist/query/list.d.ts +78 -0
  61. package/dist/query/list.d.ts.map +1 -0
  62. package/dist/query/list.js +110 -0
  63. package/dist/query/list.js.map +1 -0
  64. package/dist/query/read.d.ts +21 -0
  65. package/dist/query/read.d.ts.map +1 -0
  66. package/dist/query/read.js +301 -0
  67. package/dist/query/read.js.map +1 -0
  68. package/dist/record/collect.d.ts +18 -0
  69. package/dist/record/collect.d.ts.map +1 -0
  70. package/dist/record/collect.js +15 -0
  71. package/dist/record/collect.js.map +1 -0
  72. package/dist/record/collectBody.d.ts +29 -0
  73. package/dist/record/collectBody.d.ts.map +1 -0
  74. package/dist/record/collectBody.js +196 -0
  75. package/dist/record/collectBody.js.map +1 -0
  76. package/dist/record/commands.d.ts +11 -0
  77. package/dist/record/commands.d.ts.map +1 -0
  78. package/dist/record/commands.js +22 -0
  79. package/dist/record/commands.js.map +1 -0
  80. package/dist/record/index.d.ts +14 -0
  81. package/dist/record/index.d.ts.map +1 -0
  82. package/dist/record/index.js +12 -0
  83. package/dist/record/index.js.map +1 -0
  84. package/dist/record/receipt.d.ts +16 -0
  85. package/dist/record/receipt.d.ts.map +1 -0
  86. package/dist/record/receipt.js +11 -0
  87. package/dist/record/receipt.js.map +1 -0
  88. package/dist/record/receiptBody.d.ts +5 -0
  89. package/dist/record/receiptBody.d.ts.map +1 -0
  90. package/dist/record/receiptBody.js +112 -0
  91. package/dist/record/receiptBody.js.map +1 -0
  92. package/dist/record/scene-batch.d.ts +3 -0
  93. package/dist/record/scene-batch.d.ts.map +1 -0
  94. package/dist/record/scene-batch.js +211 -0
  95. package/dist/record/scene-batch.js.map +1 -0
  96. package/dist/record/scene-borrow.d.ts +3 -0
  97. package/dist/record/scene-borrow.d.ts.map +1 -0
  98. package/dist/record/scene-borrow.js +285 -0
  99. package/dist/record/scene-borrow.js.map +1 -0
  100. package/dist/record/scene-collect.d.ts +3 -0
  101. package/dist/record/scene-collect.d.ts.map +1 -0
  102. package/dist/record/scene-collect.js +294 -0
  103. package/dist/record/scene-collect.js.map +1 -0
  104. package/dist/record/scene-expense.d.ts +3 -0
  105. package/dist/record/scene-expense.d.ts.map +1 -0
  106. package/dist/record/scene-expense.js +21 -0
  107. package/dist/record/scene-expense.js.map +1 -0
  108. package/dist/record/scene-income.d.ts +3 -0
  109. package/dist/record/scene-income.d.ts.map +1 -0
  110. package/dist/record/scene-income.js +219 -0
  111. package/dist/record/scene-income.js.map +1 -0
  112. package/dist/record/scene-installment.d.ts +3 -0
  113. package/dist/record/scene-installment.d.ts.map +1 -0
  114. package/dist/record/scene-installment.js +248 -0
  115. package/dist/record/scene-installment.js.map +1 -0
  116. package/dist/record/scene-lend.d.ts +3 -0
  117. package/dist/record/scene-lend.d.ts.map +1 -0
  118. package/dist/record/scene-lend.js +273 -0
  119. package/dist/record/scene-lend.js.map +1 -0
  120. package/dist/record/scene-photo.d.ts +3 -0
  121. package/dist/record/scene-photo.d.ts.map +1 -0
  122. package/dist/record/scene-photo.js +262 -0
  123. package/dist/record/scene-photo.js.map +1 -0
  124. package/dist/record/scene-plain.d.ts +3 -0
  125. package/dist/record/scene-plain.d.ts.map +1 -0
  126. package/dist/record/scene-plain.js +221 -0
  127. package/dist/record/scene-plain.js.map +1 -0
  128. package/dist/record/scene-refund.d.ts +3 -0
  129. package/dist/record/scene-refund.d.ts.map +1 -0
  130. package/dist/record/scene-refund.js +281 -0
  131. package/dist/record/scene-refund.js.map +1 -0
  132. package/dist/record/scene-reimburse-done.d.ts +3 -0
  133. package/dist/record/scene-reimburse-done.d.ts.map +1 -0
  134. package/dist/record/scene-reimburse-done.js +288 -0
  135. package/dist/record/scene-reimburse-done.js.map +1 -0
  136. package/dist/record/scene-reimburse.d.ts +3 -0
  137. package/dist/record/scene-reimburse.d.ts.map +1 -0
  138. package/dist/record/scene-reimburse.js +224 -0
  139. package/dist/record/scene-reimburse.js.map +1 -0
  140. package/dist/record/scene-repay.d.ts +3 -0
  141. package/dist/record/scene-repay.d.ts.map +1 -0
  142. package/dist/record/scene-repay.js +294 -0
  143. package/dist/record/scene-repay.js.map +1 -0
  144. package/dist/record/scene-restore.d.ts +3 -0
  145. package/dist/record/scene-restore.d.ts.map +1 -0
  146. package/dist/record/scene-restore.js +250 -0
  147. package/dist/record/scene-restore.js.map +1 -0
  148. package/dist/record/scene-undo.d.ts +3 -0
  149. package/dist/record/scene-undo.d.ts.map +1 -0
  150. package/dist/record/scene-undo.js +262 -0
  151. package/dist/record/scene-undo.js.map +1 -0
  152. package/dist/record/scene-update.d.ts +3 -0
  153. package/dist/record/scene-update.d.ts.map +1 -0
  154. package/dist/record/scene-update.js +249 -0
  155. package/dist/record/scene-update.js.map +1 -0
  156. package/dist/record/scene.d.ts +79 -0
  157. package/dist/record/scene.d.ts.map +1 -0
  158. package/dist/record/scene.js +39 -0
  159. package/dist/record/scene.js.map +1 -0
  160. package/dist/record/slots.d.ts +16 -0
  161. package/dist/record/slots.d.ts.map +1 -0
  162. package/dist/record/slots.js +72 -0
  163. package/dist/record/slots.js.map +1 -0
  164. package/dist/record/write.d.ts +9 -0
  165. package/dist/record/write.d.ts.map +1 -0
  166. package/dist/record/write.js +186 -0
  167. package/dist/record/write.js.map +1 -0
  168. package/dist/render/envelope.d.ts.map +1 -1
  169. package/dist/render/envelope.js +21 -8
  170. package/dist/render/envelope.js.map +1 -1
  171. package/dist/render/errors.d.ts +1 -1
  172. package/dist/render/errors.d.ts.map +1 -1
  173. package/dist/render/errors.js.map +1 -1
  174. package/dist/render/helpFile.d.ts +85 -0
  175. package/dist/render/helpFile.d.ts.map +1 -0
  176. package/dist/render/helpFile.js +110 -0
  177. package/dist/render/helpFile.js.map +1 -0
  178. package/dist/render/helpPaths.d.ts +19 -0
  179. package/dist/render/helpPaths.d.ts.map +1 -0
  180. package/dist/render/helpPaths.js +19 -0
  181. package/dist/render/helpPaths.js.map +1 -0
  182. package/dist/render/html.js +1 -1
  183. package/dist/render/html.js.map +1 -1
  184. package/dist/render/index.d.ts +5 -1
  185. package/dist/render/index.d.ts.map +1 -1
  186. package/dist/render/index.js +4 -1
  187. package/dist/render/index.js.map +1 -1
  188. package/dist/render/templates.js +1 -1
  189. package/dist/render/templates.js.map +1 -1
  190. package/dist/render/views.d.ts +0 -22
  191. package/dist/render/views.d.ts.map +1 -1
  192. package/dist/render/views.js +1 -16
  193. package/dist/render/views.js.map +1 -1
  194. package/dist/shared/blockedSlots.d.ts +39 -0
  195. package/dist/shared/blockedSlots.d.ts.map +1 -0
  196. package/dist/shared/blockedSlots.js +105 -0
  197. package/dist/shared/blockedSlots.js.map +1 -0
  198. package/dist/shared/candidatePick.d.ts +50 -0
  199. package/dist/shared/candidatePick.d.ts.map +1 -0
  200. package/dist/shared/candidatePick.js +115 -0
  201. package/dist/shared/candidatePick.js.map +1 -0
  202. package/dist/shared/collectFrame.d.ts +15 -0
  203. package/dist/shared/collectFrame.d.ts.map +1 -0
  204. package/dist/shared/collectFrame.js +34 -0
  205. package/dist/shared/collectFrame.js.map +1 -0
  206. package/dist/shared/commandSpec.d.ts +72 -0
  207. package/dist/shared/commandSpec.d.ts.map +1 -0
  208. package/dist/shared/commandSpec.js +2 -0
  209. package/dist/shared/commandSpec.js.map +1 -0
  210. package/dist/shared/copyArea.d.ts +51 -0
  211. package/dist/shared/copyArea.d.ts.map +1 -0
  212. package/dist/shared/copyArea.js +122 -0
  213. package/dist/shared/copyArea.js.map +1 -0
  214. package/dist/shared/diffTable.d.ts +26 -0
  215. package/dist/shared/diffTable.d.ts.map +1 -0
  216. package/dist/shared/diffTable.js +77 -0
  217. package/dist/shared/diffTable.js.map +1 -0
  218. package/dist/shared/docPage.d.ts +17 -0
  219. package/dist/shared/docPage.d.ts.map +1 -0
  220. package/dist/shared/docPage.js +111 -0
  221. package/dist/shared/docPage.js.map +1 -0
  222. package/dist/shared/duplicateNote.d.ts +40 -0
  223. package/dist/shared/duplicateNote.d.ts.map +1 -0
  224. package/dist/shared/duplicateNote.js +96 -0
  225. package/dist/shared/duplicateNote.js.map +1 -0
  226. package/dist/shared/emptyNote.d.ts +15 -0
  227. package/dist/shared/emptyNote.d.ts.map +1 -0
  228. package/dist/shared/emptyNote.js +27 -0
  229. package/dist/shared/emptyNote.js.map +1 -0
  230. package/dist/shared/errorReceipt.d.ts +21 -0
  231. package/dist/shared/errorReceipt.d.ts.map +1 -0
  232. package/dist/shared/errorReceipt.js +37 -0
  233. package/dist/shared/errorReceipt.js.map +1 -0
  234. package/dist/shared/flowSteps.d.ts +25 -0
  235. package/dist/shared/flowSteps.d.ts.map +1 -0
  236. package/dist/shared/flowSteps.js +49 -0
  237. package/dist/shared/flowSteps.js.map +1 -0
  238. package/dist/shared/installmentPreview.d.ts +23 -0
  239. package/dist/shared/installmentPreview.d.ts.map +1 -0
  240. package/dist/shared/installmentPreview.js +144 -0
  241. package/dist/shared/installmentPreview.js.map +1 -0
  242. package/dist/shared/outsideScan.d.ts +34 -0
  243. package/dist/shared/outsideScan.d.ts.map +1 -0
  244. package/dist/shared/outsideScan.js +116 -0
  245. package/dist/shared/outsideScan.js.map +1 -0
  246. package/dist/shared/pageIdentity.d.ts +30 -0
  247. package/dist/shared/pageIdentity.d.ts.map +1 -0
  248. package/dist/shared/pageIdentity.js +33 -0
  249. package/dist/shared/pageIdentity.js.map +1 -0
  250. package/dist/shared/pageShell.d.ts +24 -0
  251. package/dist/shared/pageShell.d.ts.map +1 -0
  252. package/dist/shared/pageShell.js +42 -0
  253. package/dist/shared/pageShell.js.map +1 -0
  254. package/dist/shared/photoEscape.d.ts +53 -0
  255. package/dist/shared/photoEscape.d.ts.map +1 -0
  256. package/dist/shared/photoEscape.js +139 -0
  257. package/dist/shared/photoEscape.js.map +1 -0
  258. package/dist/shared/prefillNote.d.ts +21 -0
  259. package/dist/shared/prefillNote.d.ts.map +1 -0
  260. package/dist/shared/prefillNote.js +78 -0
  261. package/dist/shared/prefillNote.js.map +1 -0
  262. package/dist/shared/receiptParts.d.ts +12 -0
  263. package/dist/shared/receiptParts.d.ts.map +1 -0
  264. package/dist/shared/receiptParts.js +38 -0
  265. package/dist/shared/receiptParts.js.map +1 -0
  266. package/dist/shared/recentPicks.d.ts +26 -0
  267. package/dist/shared/recentPicks.d.ts.map +1 -0
  268. package/dist/shared/recentPicks.js +41 -0
  269. package/dist/shared/recentPicks.js.map +1 -0
  270. package/dist/shared/recordPicker.d.ts +32 -0
  271. package/dist/shared/recordPicker.d.ts.map +1 -0
  272. package/dist/shared/recordPicker.js +201 -0
  273. package/dist/shared/recordPicker.js.map +1 -0
  274. package/dist/shared/rowEditorTable.d.ts +31 -0
  275. package/dist/shared/rowEditorTable.d.ts.map +1 -0
  276. package/dist/shared/rowEditorTable.js +103 -0
  277. package/dist/shared/rowEditorTable.js.map +1 -0
  278. package/dist/shared/summaryRow.d.ts +44 -0
  279. package/dist/shared/summaryRow.d.ts.map +1 -0
  280. package/dist/shared/summaryRow.js +82 -0
  281. package/dist/shared/summaryRow.js.map +1 -0
  282. package/dist/shared/typeBadge.d.ts +21 -0
  283. package/dist/shared/typeBadge.d.ts.map +1 -0
  284. package/dist/shared/typeBadge.js +68 -0
  285. package/dist/shared/typeBadge.js.map +1 -0
  286. package/dist/shared/userWording.d.ts +54 -0
  287. package/dist/shared/userWording.d.ts.map +1 -0
  288. package/dist/shared/userWording.js +131 -0
  289. package/dist/shared/userWording.js.map +1 -0
  290. package/dist/shared/writeParts.d.ts +62 -0
  291. package/dist/shared/writeParts.d.ts.map +1 -0
  292. package/dist/shared/writeParts.js +39 -0
  293. package/dist/shared/writeParts.js.map +1 -0
  294. package/dist/triggers/wake-assets.d.ts +37 -0
  295. package/dist/triggers/wake-assets.d.ts.map +1 -0
  296. package/dist/triggers/wake-assets.js +951 -0
  297. package/dist/triggers/wake-assets.js.map +1 -0
  298. package/package.json +10 -4
@@ -0,0 +1,24 @@
1
+ /** 页面模板与页头的入参:标题三件套 + 已组合好的正文 + 页面标记五件。 */
2
+ export interface PageShellInput {
3
+ /** head 的 `<title>` 文本。 */
4
+ readonly docTitle: string;
5
+ /** 正文 H1。 */
6
+ readonly title: string;
7
+ /** 正文副标题(空串=不写这一行)。 */
8
+ readonly subtitle: string;
9
+ /** `<section>` 上的槽位:`collect`=过程型采集页、`receipt`=结果型回执整页、`list`=查询域列表页。 */
10
+ readonly slot: 'collect' | 'receipt' | 'list';
11
+ /** `<section>` 上**选页用的那一枚**:`collect`/`receipt`/`list`;与 `slot` 同值,下游选页读它。 */
12
+ readonly page: 'collect' | 'receipt' | 'list';
13
+ /** `<section>` 上的形状(=本次 envelope 的形状,与老回执页同一枚;契约,不随页型改)。 */
14
+ readonly shape: string;
15
+ /** `<section>` 上的命令名(对外全名)。 */
16
+ readonly key: string;
17
+ /** 已组合好的页内块序列。 */
18
+ readonly content: string;
19
+ /** 这一页属于哪个域(眉标那一行):缺省 `write`=写入域;查询域给 `query`。 */
20
+ readonly domain?: 'write' | 'query';
21
+ }
22
+ /** 页面模板与页头:`<section>` 段 + 标题三件套 + 整页装配。一页只调一次。 */
23
+ export declare function pageShell(input: PageShellInput): string;
24
+ //# sourceMappingURL=pageShell.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"pageShell.d.ts","sourceRoot":"","sources":["../../src/shared/pageShell.ts"],"names":[],"mappings":"AA0BA,2CAA2C;AAC3C,MAAM,WAAW,cAAc;IAC7B,2BAA2B;IAC3B,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;IAC1B,aAAa;IACb,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,uBAAuB;IACvB,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;IAC1B,yEAAyE;IACzE,QAAQ,CAAC,IAAI,EAAE,SAAS,GAAG,SAAS,GAAG,MAAM,CAAC;IAC9C,8EAA8E;IAC9E,QAAQ,CAAC,IAAI,EAAE,SAAS,GAAG,SAAS,GAAG,MAAM,CAAC;IAC9C,4DAA4D;IAC5D,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,+BAA+B;IAC/B,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAC;IACrB,kBAAkB;IAClB,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IACzB,mDAAmD;IACnD,QAAQ,CAAC,MAAM,CAAC,EAAE,OAAO,GAAG,OAAO,CAAC;CACrC;AAED,mDAAmD;AACnD,wBAAgB,SAAS,CAAC,KAAK,EAAE,cAAc,GAAG,MAAM,CAevD"}
@@ -0,0 +1,42 @@
1
+ /** 页面模板与页头(每张页都有的第一件,**唯一定义地**):`<section>` 段 + 标题三件套 + 整页装配。
2
+ *
3
+ * 谁在用(两个能力,指名):
4
+ * ① `src/record/`——写入域:过程型采集页(页头 + 九块正文)与结果型回执整页(页头 + 回执块序列);
5
+ * ② `src/query/`——查询域:通用查询列表页(页头 + KPI 行 + 数据表 + 复制区)同走本件,
6
+ * 眉标给 `domain: 'query'`。
7
+ * 本票实测:本包 `src/` 下真引用本件的就是上面两个域,再无第三处。
8
+ *
9
+ * 分工(三件不要混):
10
+ * - `./docPage.ts`=文档装配那一层(`fillTemplate` 包裹、样式资产注入),本件往下调它,不重写;
11
+ * - 本件=页面模板与页头的取值口径(**眉标两域各一句**、标题三件套只出一处;`data-page` 是选页那一枚标记);
12
+ * - 页内块序列(表单/摘要行/复制区…)归各域自己,本件不管;类型徽章另立 `./typeBadge.ts`。
13
+ *
14
+ * 口径出处:`docs/skills/skill-bill/t407-页面块清单-16词.md` 第一节第 1 行。
15
+ * 1.1 节硬口径照旧:`blocksCss()` 拼进 `TemplateAssets.sharedCssText` 再交 `fillTemplate`(住 `./docPage.ts`),
16
+ * 不得走 `StyleSheetInput.extraCss`。
17
+ */
18
+ import { assembleDocPage } from './docPage.js';
19
+ import { writeSection } from './writeParts.js';
20
+ /** 眉标(正文标题上方那一行):每域一句,**取值只在本件**,别处不得再写这些字面量。 */
21
+ const PAGE_EYEBROW = {
22
+ write: '记账 · 写入域',
23
+ query: '记账 · 查询域',
24
+ };
25
+ /** 页面模板与页头:`<section>` 段 + 标题三件套 + 整页装配。一页只调一次。 */
26
+ export function pageShell(input) {
27
+ const body = writeSection({
28
+ slot: input.slot,
29
+ page: input.page,
30
+ shape: input.shape,
31
+ key: input.key,
32
+ content: input.content,
33
+ });
34
+ return assembleDocPage({
35
+ docTitle: input.docTitle,
36
+ title: input.title,
37
+ eyebrow: PAGE_EYEBROW[input.domain ?? 'write'],
38
+ subtitle: input.subtitle,
39
+ content: body,
40
+ });
41
+ }
42
+ //# sourceMappingURL=pageShell.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"pageShell.js","sourceRoot":"","sources":["../../src/shared/pageShell.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;GAgBG;AACH,OAAO,EAAE,eAAe,EAAE,MAAM,cAAc,CAAC;AAC/C,OAAO,EAAE,YAAY,EAAE,MAAM,iBAAiB,CAAC;AAE/C,iDAAiD;AACjD,MAAM,YAAY,GAAgD;IAChE,KAAK,EAAE,UAAU;IACjB,KAAK,EAAE,UAAU;CAClB,CAAC;AAwBF,mDAAmD;AACnD,MAAM,UAAU,SAAS,CAAC,KAAqB;IAC7C,MAAM,IAAI,GAAG,YAAY,CAAC;QACxB,IAAI,EAAE,KAAK,CAAC,IAAI;QAChB,IAAI,EAAE,KAAK,CAAC,IAAI;QAChB,KAAK,EAAE,KAAK,CAAC,KAAK;QAClB,GAAG,EAAE,KAAK,CAAC,GAAG;QACd,OAAO,EAAE,KAAK,CAAC,OAAO;KACvB,CAAC,CAAC;IACH,OAAO,eAAe,CAAC;QACrB,QAAQ,EAAE,KAAK,CAAC,QAAQ;QACxB,KAAK,EAAE,KAAK,CAAC,KAAK;QAClB,OAAO,EAAE,YAAY,CAAC,KAAK,CAAC,MAAM,IAAI,OAAO,CAAC;QAC9C,QAAQ,EAAE,KAAK,CAAC,QAAQ;QACxB,OAAO,EAAE,IAAI;KACd,CAAC,CAAC;AACL,CAAC"}
@@ -0,0 +1,53 @@
1
+ import type { BillRow } from '../fetch/db.js';
2
+ import type { DuplicateProbe } from './duplicateNote.js';
3
+ import type { PrefillMark } from './prefillNote.js';
4
+ import type { SummaryFacts } from './summaryRow.js';
5
+ /** 采集页那几格取值,一次给全(`pickOf`/`probeOf`/`factsOf` 三个名字合成这一个粗入口):
6
+ * ① `pick` 三枚选择器的候选(分类退到哪一侧由 `kind` 定);② `probe` 重复检测的探针;
7
+ * ③ `facts` 摘要行的事实。三个都只读本次参数与近期记录,不碰库。 */
8
+ export declare function valuesOf(input: {
9
+ readonly recent: readonly BillRow[];
10
+ readonly params: Record<string, unknown>;
11
+ readonly kind: string;
12
+ readonly today: string;
13
+ }): {
14
+ readonly pick: Record<string, readonly string[]>;
15
+ readonly probe: DuplicateProbe;
16
+ readonly facts: SummaryFacts;
17
+ };
18
+ /** 字段卡要的一格(普通数据:名字/中文名/怎么给/是否必需)。**收在件内**:外面照这个形状给普通对象。 */
19
+ interface FieldSlot {
20
+ readonly name: string;
21
+ readonly label: string;
22
+ readonly hint: string;
23
+ readonly required: boolean;
24
+ }
25
+ /** 采集页字段卡那块(`renderParamForm` + 本场景那句操作说明)。候选那一格由 `valuesOf` 出的 `pick` 给。 */
26
+ export declare function fieldCardOf(input: {
27
+ readonly description: string;
28
+ readonly slots: readonly FieldSlot[];
29
+ readonly params: Record<string, unknown>;
30
+ readonly marks: readonly PrefillMark[];
31
+ readonly pick: Record<string, readonly string[]>;
32
+ }): string;
33
+ /** 缺项那两处的原文,一次给全(两个名字合成一个粗入口):
34
+ * ① `command` 是缺项时那条写库指令原文——缺的值留成尖括号占位符,**只给看不给复制**(复制按钮在阻断条里被拿掉);
35
+ * ② `prompt` 是「照这句跟助手说一遍」那块话:说清缺什么、这一页先不写库、补齐之后说哪句——
36
+ * **不给可跑的写库指令**。本轮整改:缺项清单里不再印参数名(库列名不上屏),
37
+ * `重跑同一条命令` 换「跟助手说一遍」。
38
+ * `replaces` 给「按中文名占位」以外的写法(拍账单的要素名)。 */
39
+ export declare function blockedPromptOf(input: {
40
+ readonly key: string;
41
+ readonly params: Record<string, unknown>;
42
+ readonly blocked: readonly {
43
+ readonly name: string;
44
+ readonly label: string;
45
+ readonly why: string;
46
+ }[];
47
+ readonly replaces?: Readonly<Record<string, string>>;
48
+ }): {
49
+ readonly command: string;
50
+ readonly prompt: string;
51
+ };
52
+ export {};
53
+ //# sourceMappingURL=photoEscape.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"photoEscape.d.ts","sourceRoot":"","sources":["../../src/shared/photoEscape.ts"],"names":[],"mappings":"AAwCA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,gBAAgB,CAAC;AAE9C,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,oBAAoB,CAAC;AAEzD,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,kBAAkB,CAAC;AAEpD,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,iBAAiB,CAAC;AAkDpD;;2CAE2C;AAC3C,wBAAgB,QAAQ,CAAC,KAAK,EAAE;IAC9B,QAAQ,CAAC,MAAM,EAAE,SAAS,OAAO,EAAE,CAAC;IACpC,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IACzC,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;CACxB,GAAG;IACF,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,SAAS,MAAM,EAAE,CAAC,CAAC;IACjD,QAAQ,CAAC,KAAK,EAAE,cAAc,CAAC;IAC/B,QAAQ,CAAC,KAAK,EAAE,YAAY,CAAC;CAC9B,CAMA;AAED,2DAA2D;AAC3D,UAAU,SAAS;IACjB,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,QAAQ,EAAE,OAAO,CAAC;CAC5B;AAwBD,6EAA6E;AAC7E,wBAAgB,WAAW,CAAC,KAAK,EAAE;IACjC,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAC;IAC7B,QAAQ,CAAC,KAAK,EAAE,SAAS,SAAS,EAAE,CAAC;IACrC,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IACzC,QAAQ,CAAC,KAAK,EAAE,SAAS,WAAW,EAAE,CAAC;IACvC,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,SAAS,MAAM,EAAE,CAAC,CAAC;CAClD,GAAG,MAAM,CAKT;AAED;;;;;0CAK0C;AAC1C,wBAAgB,eAAe,CAAC,KAAK,EAAE;IACrC,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAC;IACrB,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IACzC,QAAQ,CAAC,OAAO,EAAE,SAAS;QAAE,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;QAAC,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;QAAC,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAA;KAAE,EAAE,CAAC;IACrG,QAAQ,CAAC,QAAQ,CAAC,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,CAAC;CACtD,GAAG;IAAE,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAA;CAAE,CASxD"}
@@ -0,0 +1,139 @@
1
+ /** 记账族四个场景件共用的采集页表单积木(**唯一定义地**):表单取值判定、字段卡、复制 prompt 区那段话
2
+ * 与缺项时那条写库指令原文。四个场景件(记收入/记报销/记一笔/拍账单)的采集页要**同一套积木**,
3
+ * 抄四份就会改一处漏三处,故收在一处。
4
+
5
+ * 本件对外的名字**三个**(照 `docs/agents/structure.md` 的「一个文件对外给的东西不多于五个」,
6
+ * 只数真被本目录之外的件引用的名字):
7
+ * `valuesOf`(采集页那几格取值:候选/重复检测探针/摘要行事实)、`fieldCardOf`(字段卡)、
8
+ * `blockedPromptOf`(缺项那条 + 复制 prompt 区那段话,一次给全)。
9
+ * 其余收在件内、不外给:`pickOf`(三枚选择器的候选,一行转发到共用位 `recentPicks.ts`)、
10
+ * `categorySideOf`(分类侧别的唯一落点)、`probeOf`、`factsOf`、`FieldSlot`(字段卡要的一格;只有本件
11
+ * `fieldCardOf` 的签名与件内的 `formFieldsOf` 认它,外面照形状给普通对象即可)、`isGiven`、`formFieldsOf`。
12
+ * **本次由 12 名收到 3 名**,两刀:① 外部识别那五样(拍账单的图片识别外置通道)搬去
13
+ * `src/shared/outsideScan.ts`;② 表单那六个名字并成三个粗入口(`pickOf`+`probeOf`+`factsOf` 合成
14
+ * `valuesOf`;`commandsOf` 与 `promptOf` 合成 `blockedPromptOf`)。
15
+
16
+ * 谁在用(四个调用点,指名;每个调用点后头写明它取哪几个名字):
17
+ * ① `src/record/scene-income.ts`——记收入:`valuesOf`(候选落收入侧)/`fieldCardOf`/`blockedPromptOf`;
18
+ * ② `src/record/scene-reimburse.ts`——记报销:同一套三个名字,只是 `kind` 换成 `reimburse`;
19
+ * ③ `src/record/scene-plain.ts`——记一笔:同一套三个名字,`kind` 给空串(分类候选两侧都给,方向按金额符号判);
20
+ * ④ `src/record/scene-photo.ts`——拍账单:同一套三个名字,`kind` 给 `photo`;
21
+ * 外部识别通道的五个名字走 `src/shared/outsideScan.ts`。
22
+
23
+ * **本件只吃普通数据、零跨目录引用**(与已冻的 `candidatePick.ts`/`rowEditorTable.ts`/`diffTable.ts` 同形状):
24
+ * 入参是「要展示的字段名与文案」「本次参数」「近期记录那几列」这类普通数据,**不引** `src/record/` 下的件,
25
+ * 也不认 `CollectInput`/`ReceiptInput`——那两张页的入参形状由 `src/record/scene.ts` 定义,由各场景件自己解成普通数据传进来。
26
+ * 本件可引的只有:`base-paint`/`base-paint/blocks`(现成组件)、`src/policy/category.ts`(口径层)、
27
+ * `src/fetch/db.ts`(记录行的数据形状)、`src/shared/` 同目录的共用件。
28
+ *
29
+ * 口径(一处定义,别处不许再写第二份):
30
+ * - **一个值算不算「给了」**:`undefined`/`null`/空白串都不算,0 算给了(金额 0 是合法值);
31
+ * - **候选取值**:按最近在先去重、取前十二个、分类一条历史都没有时退到本型的 L1 名单——
32
+ * 这一半的唯一定义地是 `src/shared/recentPicks.ts`,本件的 `pickOf` 只留一行转发;
33
+ * - **缺项即不出复制指令**:阻断判定在 `src/shared/blockedSlots.ts`,写库指令原文在本件的
34
+ * `blockedPromptOf`;复制 prompt 区那段话里**没有可跑的写库指令**。
35
+ *
36
+ * 本件不自造任何页面骨架与样式:字段卡走 `base-paint/blocks` 的 `renderParamForm`,其余块由各场景件
37
+ * 从代表页那套共用件里取。
38
+ */
39
+ import { renderParamForm } from 'base-paint/blocks';
40
+ import { ALL_L1, EXPENSE_L1, INCOME_L1 } from '../policy/category.js';
41
+ import { prefillHint } from './prefillNote.js';
42
+ import { optionsFor, pickOf as pickValues, textOf } from './recentPicks.js';
43
+ import { commandLine } from './writeParts.js';
44
+ /** 分类一侧的 L1 名单:收入词落收入侧、支出型词落支出侧、通用词两侧都给。**这一处是分类侧别的唯一落点**。 */
45
+ function categorySideOf(kind) {
46
+ if (kind === 'income')
47
+ return INCOME_L1;
48
+ if (kind === 'expense' || kind === 'reimburse' || kind === 'photo' || kind === 'refund')
49
+ return EXPENSE_L1;
50
+ return ALL_L1;
51
+ }
52
+ /** 三枚选择器的候选(**转发到 `recentPicks.ts`,本件不另写一份取数**):分类退到哪一侧由 `categorySideOf` 定。 */
53
+ function pickOf(recent, kind) {
54
+ return pickValues(recent, categorySideOf(kind));
55
+ }
56
+ /** 一个值算不算「给了」:`undefined`/`null`/空白串都不算,0 算给了(金额 0 是合法值)。
57
+ * 与 `src/record/slots.ts` 的 `isGiven` 同一口径;本件只吃普通数据,故照这条口径在本件内重写一遍,
58
+ * 不从能力目录里引件(`src/shared/` 与 `src/record/` 之间不互相引)。 */
59
+ function isGiven(v) {
60
+ if (v === undefined || v === null)
61
+ return false;
62
+ return !(typeof v === 'string' && v.trim() === '');
63
+ }
64
+ /** 重复检测的探针(四件同一口径:日期缺省取本页执行那天)。**收在件内**,对外由 `valuesOf` 一次给。 */
65
+ function probeOf(params, today) {
66
+ const raw = textOf(params['amount']);
67
+ const n = raw === '' ? Number.NaN : Number(raw);
68
+ const time = textOf(params['time']);
69
+ return {
70
+ amount: Number.isFinite(n) ? n : null,
71
+ category: textOf(params['category']),
72
+ date: time === '' ? today : time,
73
+ account: textOf(params['account']),
74
+ };
75
+ }
76
+ /** 摘要行的事实(四件同一口径:事实取自本次参数,缺的格写「未给」)。**收在件内**,对外由 `valuesOf` 一次给。 */
77
+ function factsOf(params, date) {
78
+ const raw = textOf(params['amount']);
79
+ const n = raw === '' ? Number.NaN : Number(raw);
80
+ const time = textOf(params['time']);
81
+ return {
82
+ amount: Number.isFinite(n) ? n : null,
83
+ category: textOf(params['category']),
84
+ account: textOf(params['account']),
85
+ ledger: textOf(params['ledger']),
86
+ time: time === '' ? date : time,
87
+ };
88
+ }
89
+ /** 采集页那几格取值,一次给全(`pickOf`/`probeOf`/`factsOf` 三个名字合成这一个粗入口):
90
+ * ① `pick` 三枚选择器的候选(分类退到哪一侧由 `kind` 定);② `probe` 重复检测的探针;
91
+ * ③ `facts` 摘要行的事实。三个都只读本次参数与近期记录,不碰库。 */
92
+ export function valuesOf(input) {
93
+ return {
94
+ pick: pickOf(input.recent, input.kind),
95
+ probe: probeOf(input.params, input.today),
96
+ facts: factsOf(input.params, input.today),
97
+ };
98
+ }
99
+ /** 字段卡的每一格:一律由 `renderParamForm` 出(标签与控件配对、每格带 `name`)。收在件内,对外只给 `fieldCardOf`。 */
100
+ function formFieldsOf(input) {
101
+ return input.slots.map((s) => {
102
+ const mark = input.marks.find((m) => m.name === s.name);
103
+ const value = isGiven(input.params[s.name]) ? String(input.params[s.name]) : (mark?.value ?? '');
104
+ const options = optionsFor(input.pick, s.name, value);
105
+ return {
106
+ name: s.name,
107
+ label: s.label,
108
+ hint: prefillHint(input.marks, s.name) ?? s.hint,
109
+ ...(options === undefined ? {} : { options }),
110
+ ...(s.required ? { required: true } : {}),
111
+ ...(value === '' ? {} : { value }),
112
+ };
113
+ });
114
+ }
115
+ /** 采集页字段卡那块(`renderParamForm` + 本场景那句操作说明)。候选那一格由 `valuesOf` 出的 `pick` 给。 */
116
+ export function fieldCardOf(input) {
117
+ return renderParamForm({
118
+ description: input.description,
119
+ fields: formFieldsOf({ slots: input.slots, params: input.params, marks: input.marks, pick: input.pick }),
120
+ });
121
+ }
122
+ /** 缺项那两处的原文,一次给全(两个名字合成一个粗入口):
123
+ * ① `command` 是缺项时那条写库指令原文——缺的值留成尖括号占位符,**只给看不给复制**(复制按钮在阻断条里被拿掉);
124
+ * ② `prompt` 是「照这句跟助手说一遍」那块话:说清缺什么、这一页先不写库、补齐之后说哪句——
125
+ * **不给可跑的写库指令**。本轮整改:缺项清单里不再印参数名(库列名不上屏),
126
+ * `重跑同一条命令` 换「跟助手说一遍」。
127
+ * `replaces` 给「按中文名占位」以外的写法(拍账单的要素名)。 */
128
+ export function blockedPromptOf(input) {
129
+ const filled = { ...input.params };
130
+ for (const b of input.blocked)
131
+ filled[b.name] = input.replaces?.[b.name] ?? '<' + b.label + '>';
132
+ return {
133
+ command: commandLine(input.key, filled),
134
+ prompt: '这一笔还差 ' + input.blocked.length + ' 项:'
135
+ + input.blocked.map((i) => i.label + '(' + i.why + ')').join('、')
136
+ + '。\n这一页先不写库;补齐之后跟助手说一遍,照这条说:' + input.key + '。',
137
+ };
138
+ }
139
+ //# sourceMappingURL=photoEscape.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"photoEscape.js","sourceRoot":"","sources":["../../src/shared/photoEscape.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,21 @@
1
+ import type { BillRow } from '../fetch/db.js';
2
+ /** 一条预填标注:哪一格/中文名/顶上去的值/来源。 */
3
+ export interface PrefillMark {
4
+ readonly name: string;
5
+ readonly label: string;
6
+ readonly value: string;
7
+ readonly from: string;
8
+ }
9
+ /** 预填判定:`params` 里没给的字段,按近期最近一笔顶;历史也没有就按缺省顶。`today`=本页执行那天(`YYYY-MM-DD`)。 */
10
+ export declare function prefillOf(input: {
11
+ readonly params: Record<string, unknown>;
12
+ readonly recent: readonly BillRow[];
13
+ readonly today: string;
14
+ }): PrefillMark[];
15
+ /** 某一格的来源一句(给表单字段的提示用);没有这一格=返回 `undefined`。
16
+ * 本轮整改:原来的 `预填 支付宝 · 来自记录编号 1` 里那个 `·` 落在选择器回显上(版式位),
17
+ * 改一句连读的「已经替你填上 支付宝,来自…」——一句话说清,不用分隔符。 */
18
+ export declare function prefillHint(marks: readonly PrefillMark[], name: string): string | undefined;
19
+ /** 预填标注表:字段/取值/来源三列。**空数组=没有预填,页上不出这一段**(返回空串)。 */
20
+ export declare function prefillNote(marks: readonly PrefillMark[]): string;
21
+ //# sourceMappingURL=prefillNote.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"prefillNote.d.ts","sourceRoot":"","sources":["../../src/shared/prefillNote.ts"],"names":[],"mappings":"AAoBA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,gBAAgB,CAAC;AAE9C,+BAA+B;AAC/B,MAAM,WAAW,WAAW;IAC1B,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;CACvB;AAeD,6EAA6E;AAC7E,wBAAgB,SAAS,CAAC,KAAK,EAAE;IAC/B,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IACzC,QAAQ,CAAC,MAAM,EAAE,SAAS,OAAO,EAAE,CAAC;IACpC,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;CACxB,GAAG,WAAW,EAAE,CAsBhB;AAED;;2CAE2C;AAC3C,wBAAgB,WAAW,CAAC,KAAK,EAAE,SAAS,WAAW,EAAE,EAAE,IAAI,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS,CAG3F;AAED,mDAAmD;AACnD,wBAAgB,WAAW,CAAC,KAAK,EAAE,SAAS,WAAW,EAAE,GAAG,MAAM,CAWjE"}
@@ -0,0 +1,78 @@
1
+ /** 预填标注(缺口块之一,**唯一定义地**):每个被历史数据预填的字段标出来源(老侧 `prefillBox` 的形态)。
2
+ *
3
+ * 谁在用(按实际写,别写名义调用点):
4
+ * ① `src/record/collect.ts`——过程型采集页:账户/账本/币种/时间这四格能由历史与缺省顶上,
5
+ * 顶上哪一格就在表单那一格的提示里写「预填·来源」,另出一张「预填标注」表把来源逐条列清(本件真调用点);
6
+ * ② **本票没有第二个调用点**:回执页报的是已写入的值,不预填,`src/record/receipt.ts` 不引本件
7
+ * (件头原来写它「会引但本件不出」,那是名义调用点,按实际改掉)。
8
+ * 第二个消费者:`src/query/`(随兄弟图 #403 的查询域一起到位,同一套采集页/回执页/复制区要同一条口径)。
9
+ * 本票实测:本包 `src/` 下真引用本件的只有 `collect.ts` 一处。
10
+ *
11
+ * 口径(三件事一处定义):
12
+ * - **只预填四项**:账户/账本/币种(来源=近期最近一笔的库内值)+ 时间(来源=本页执行那天的缺省时刻);
13
+ * 分类**一律不预填**(施工图第四节第 10 条:分类不许留空交给助手猜),备注是自由文本也不预填;
14
+ * - **缺省值不在本件另立一份**:账本「生活」/币种「人民币」引 `src/policy/category.ts` 的 `DEFAULTS`;
15
+ * 时间引同一件的 `defaultTimeOn`(`12:00:00` 的真源在口径层,本件不写第二份字面量);
16
+ * - **来源逐格可追**:库里顶来的写「来自记录编号 N(最近一笔)」,缺省顶的写「缺省值(库里还没有可用的…)」,
17
+ * 两种来源不许混成一句「自动填的」。
18
+ */
19
+ import { renderDataTable } from 'base-paint/blocks';
20
+ import { DEFAULTS, DEFAULT_TIME_SUFFIX, defaultTimeOn } from '../policy/category.js';
21
+ /** 采集页要的四格(值 + 中文名 + 来源后缀)。缺省值一处定义:账本/币种/账户引口径层的 `DEFAULTS`
22
+ * (账户缺省是空串=落库默认,不走「缺省值(账户)」那一岔)。 */
23
+ const PREFILL_FIELDS = [
24
+ { name: 'account', label: '账户', fallback: DEFAULTS.account, what: '账户' },
25
+ { name: 'ledger', label: '账本', fallback: DEFAULTS.ledger, what: '账本' },
26
+ { name: 'currency', label: '币种', fallback: DEFAULTS.currency, what: '币种' },
27
+ ];
28
+ /** 取一个字段的字符串值(非字符串/空串一律当没给)。 */
29
+ function textOf(v) {
30
+ return typeof v === 'string' ? v.trim() : '';
31
+ }
32
+ /** 预填判定:`params` 里没给的字段,按近期最近一笔顶;历史也没有就按缺省顶。`today`=本页执行那天(`YYYY-MM-DD`)。 */
33
+ export function prefillOf(input) {
34
+ const marks = [];
35
+ const last = input.recent.length > 0 ? input.recent[0] : undefined;
36
+ for (const f of PREFILL_FIELDS) {
37
+ if (textOf(input.params[f.name]) !== '')
38
+ continue;
39
+ const fromHistory = last === undefined ? '' : textOf(last[f.name]);
40
+ if (fromHistory !== '') {
41
+ marks.push({ name: f.name, label: f.label, value: fromHistory, from: '来自记录编号 ' + last?.id + '(最近一笔)' });
42
+ continue;
43
+ }
44
+ marks.push({
45
+ name: f.name, label: f.label, value: f.fallback,
46
+ from: f.fallback === '' ? '缺省值(库里还没有可用的' + f.what + ',留空=落库默认)' : '缺省值(' + f.what + ')',
47
+ });
48
+ }
49
+ if (textOf(input.params['time']) === '') {
50
+ marks.push({
51
+ name: 'time', label: '时间', value: defaultTimeOn(input.today),
52
+ from: '缺省值(本页执行那天 ' + DEFAULT_TIME_SUFFIX + ')',
53
+ });
54
+ }
55
+ return marks;
56
+ }
57
+ /** 某一格的来源一句(给表单字段的提示用);没有这一格=返回 `undefined`。
58
+ * 本轮整改:原来的 `预填 支付宝 · 来自记录编号 1` 里那个 `·` 落在选择器回显上(版式位),
59
+ * 改一句连读的「已经替你填上 支付宝,来自…」——一句话说清,不用分隔符。 */
60
+ export function prefillHint(marks, name) {
61
+ const hit = marks.find((m) => m.name === name);
62
+ return hit === undefined ? undefined : '已经替你填上 ' + hit.value + ',' + hit.from;
63
+ }
64
+ /** 预填标注表:字段/取值/来源三列。**空数组=没有预填,页上不出这一段**(返回空串)。 */
65
+ export function prefillNote(marks) {
66
+ if (marks.length === 0)
67
+ return '';
68
+ return renderDataTable({
69
+ columns: [
70
+ { key: 'label', label: '预填的格' },
71
+ { key: 'value', label: '顶上去的值' },
72
+ { key: 'from', label: '来源' },
73
+ ],
74
+ rows: marks.map((m) => ({ label: m.label, value: m.value === '' ? '(留空=落库默认)' : m.value, from: m.from })),
75
+ caption: '预填标注(每个被顶上的格都写清来源)',
76
+ });
77
+ }
78
+ //# sourceMappingURL=prefillNote.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"prefillNote.js","sourceRoot":"","sources":["../../src/shared/prefillNote.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,12 @@
1
+ import type { KpiCardInput } from 'base-paint/blocks';
2
+ import type { BillReceipt } from './writeParts.js';
3
+ /** 一格的状态值:值 + 一句说明(说明由调用方按本页措辞传入)。 */
4
+ export declare function statusCard(value: string, detail: string): KpiCardInput;
5
+ /** 回执页的状态卡:无改动/已改动 + 一句写入去向的说明。 */
6
+ export declare function receiptStatusCard(receipt: BillReceipt, writtenDetail: string): KpiCardInput;
7
+ /** 页尾「对账信息」折叠区:本次写入的**可核对信息**——记录编号/写入时间。
8
+ * 这次记了几笔与写进去的项已在上方卡片上,这里不重写。
9
+ * 本轮整改删掉两行内部话(照 `docs/skills/skill-bill/t407-文字审查.md` 第 54 条):
10
+ * `本地时钟` 与 `回执格式 / v1(写库回执)`——前者是实现细节,后者是版本自指,用户都拿它没动作可做。 */
11
+ export declare function reconcileDisclosure(receipt: BillReceipt): string;
12
+ //# sourceMappingURL=receiptParts.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"receiptParts.d.ts","sourceRoot":"","sources":["../../src/shared/receiptParts.ts"],"names":[],"mappings":"AAaA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAC;AACtD,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,iBAAiB,CAAC;AAGnD,sCAAsC;AACtC,wBAAgB,UAAU,CAAC,KAAK,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,YAAY,CAEtE;AAED,mCAAmC;AACnC,wBAAgB,iBAAiB,CAAC,OAAO,EAAE,WAAW,EAAE,aAAa,EAAE,MAAM,GAAG,YAAY,CAK3F;AAED;;;8DAG8D;AAC9D,wBAAgB,mBAAmB,CAAC,OAAO,EAAE,WAAW,GAAG,MAAM,CAWhE"}
@@ -0,0 +1,38 @@
1
+ /** 写后回执页与采集页的两块共用件:状态卡 + 页尾「对账信息」折叠区。
2
+ *
3
+ * 谁在用(两个调用点,指名):
4
+ * ① `src/record/receipt.ts`——结果型回执整页:`receiptStatusCard`(已改动/无改动)+ `reconcileDisclosure`;
5
+ * ② `src/record/collect.ts`——过程型采集页:`statusCard`(那一格写「待补槽位」)。
6
+ * 第二个消费者:`src/query/`(随兄弟图 #403 的查询域一起到位,出来的是同一套采集页/回执页/复制区)。
7
+ *
8
+ * 口径出处:照 `packages/skill-calorie/src/shared/receiptParts.ts` 的两块(状态卡+页尾对账折叠区),
9
+ * 分「块」与「整页」的分工也照它:整页装配住同目录 `docPage.ts`,本文件只出页内的两块。
10
+ * 一处由调用方给的措辞:**写入去向那句说明**(`writtenDetail`)——记一笔写的是账单、改记录改的是同一条,
11
+ * 两边说法不同,故它是必填参数,不给默认值,免得哪张页悄悄用了别处的说法。
12
+ */
13
+ import { renderDataTable, renderDisclosure } from 'base-paint/blocks';
14
+ /** 一格的状态值:值 + 一句说明(说明由调用方按本页措辞传入)。 */
15
+ export function statusCard(value, detail) {
16
+ return { label: '状态', value, detail };
17
+ }
18
+ /** 回执页的状态卡:无改动/已改动 + 一句写入去向的说明。 */
19
+ export function receiptStatusCard(receipt, writtenDetail) {
20
+ return statusCard(receipt.noChange ? '无改动' : '已改动', receipt.noChange ? '值与改前一致' : writtenDetail);
21
+ }
22
+ /** 页尾「对账信息」折叠区:本次写入的**可核对信息**——记录编号/写入时间。
23
+ * 这次记了几笔与写进去的项已在上方卡片上,这里不重写。
24
+ * 本轮整改删掉两行内部话(照 `docs/skills/skill-bill/t407-文字审查.md` 第 54 条):
25
+ * `本地时钟` 与 `回执格式 / v1(写库回执)`——前者是实现细节,后者是版本自指,用户都拿它没动作可做。 */
26
+ export function reconcileDisclosure(receipt) {
27
+ return renderDisclosure({
28
+ title: '对账信息',
29
+ contentHtml: renderDataTable({
30
+ columns: [{ key: 'k', label: '哪一项' }, { key: 'v', label: '记成什么' }],
31
+ rows: [
32
+ { k: '记录编号', v: receipt.recordId === null ? '还没有' : String(receipt.recordId) },
33
+ { k: '写入时间', v: receipt.actionAt },
34
+ ],
35
+ }),
36
+ });
37
+ }
38
+ //# sourceMappingURL=receiptParts.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"receiptParts.js","sourceRoot":"","sources":["../../src/shared/receiptParts.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AACH,OAAO,EAAE,eAAe,EAAE,gBAAgB,EAAE,MAAM,mBAAmB,CAAC;AAKtE,sCAAsC;AACtC,MAAM,UAAU,UAAU,CAAC,KAAa,EAAE,MAAc;IACtD,OAAO,EAAE,KAAK,EAAE,IAAI,EAAE,KAAK,EAAE,MAAM,EAAE,CAAC;AACxC,CAAC;AAED,mCAAmC;AACnC,MAAM,UAAU,iBAAiB,CAAC,OAAoB,EAAE,aAAqB;IAC3E,OAAO,UAAU,CACf,OAAO,CAAC,QAAQ,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,KAAK,EAChC,OAAO,CAAC,QAAQ,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,aAAa,CAC5C,CAAC;AACJ,CAAC;AAED;;;8DAG8D;AAC9D,MAAM,UAAU,mBAAmB,CAAC,OAAoB;IACtD,OAAO,gBAAgB,CAAC;QACtB,KAAK,EAAE,MAAM;QACb,WAAW,EAAE,eAAe,CAAC;YAC3B,OAAO,EAAE,CAAC,EAAE,GAAG,EAAE,GAAG,EAAE,KAAK,EAAE,KAAK,EAAE,EAAE,EAAE,GAAG,EAAE,GAAG,EAAE,KAAK,EAAE,MAAM,EAAE,CAAC;YAClE,IAAI,EAAE;gBACJ,EAAE,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,OAAO,CAAC,QAAQ,KAAK,IAAI,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC,QAAQ,CAAC,EAAE;gBAC9E,EAAE,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,OAAO,CAAC,QAAQ,EAAE;aACnC;SACF,CAAC;KACH,CAAC,CAAC;AACL,CAAC"}
@@ -0,0 +1,26 @@
1
+ /** 近期记录取候选值(**唯一定义地**):三枚选择器(分类/账户/账本)的候选怎么取——值转字符串、
2
+ * 按最近在先去重、剔掉没给的、取前十二个;再把本次已给的值并进那一格。
3
+
4
+ * 谁在用(两处,指名;两处原先各写一份同形同名的取数,本次提到本件一处):
5
+ * ① `src/shared/photoEscape.ts`——记收入/记报销/记一笔/拍账单四个场景件的字段卡,它的 `pickOf` 一行转发到本件;
6
+ * ② `src/record/collectBody.ts`——通用采集页装配体的那一格,它的 `pickOf` 同样一行转发到本件。
7
+
8
+ * 本件只吃普通数据、零跨目录引用:入参是「近期记录那几列」与「本次参数」这种普通数据,
9
+ * **不引** `src/record/` 下的件,也不认 `CollectInput` 这类页面入参形状。可引的只有
10
+ * `src/fetch/db.ts`(记录行的数据形状)与 `src/policy/category.ts`(缺省那一格)。
11
+
12
+ * 口径(一处定义,别处不许再写第二份):
13
+ * - 候选上限**十二个**(`PICK_LIMIT`):三枚选择器共用这一个数;
14
+ * - 取值口径:非字符串按空串用、数字写成十进制串、两头空白剪掉;空白串不算一个候选;
15
+ * - 分类一条历史都没有时退到**调用方给的 L1 名单**(哪一侧由调用方定,本件不判方向);
16
+ * - 一个字段的选项=候选 + 本次已给的值(已给的值不在候选里时并到队首,免得表单把它显示没了)。
17
+ */
18
+ import type { BillRow } from '../fetch/db.js';
19
+ /** 一个值的字符串形态(非字符串按空串用;数字写成十进制串)。 */
20
+ export declare function textOf(v: unknown): string;
21
+ /** 三枚选择器的候选:分类(近期有历史就用历史,一条历史都没有就退到 `fallbackCategory` 给的名单)/
22
+ * 账户/账本(缺省「生活」)。**分类退到哪一侧由调用方定**:本件不收方向这一格。 */
23
+ export declare function pickOf(recent: readonly BillRow[], fallbackCategory: readonly string[]): Record<string, readonly string[]>;
24
+ /** 一个字段的选项:选择器候选 + 本次已给的值(已给的值不在候选里时并到队首,免得表单把它显示没了)。 */
25
+ export declare function optionsFor(pick: Record<string, readonly string[]>, name: string, value: string): readonly string[] | undefined;
26
+ //# sourceMappingURL=recentPicks.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"recentPicks.d.ts","sourceRoot":"","sources":["../../src/shared/recentPicks.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;GAgBG;AACH,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,gBAAgB,CAAC;AAM9C,oCAAoC;AACpC,wBAAgB,MAAM,CAAC,CAAC,EAAE,OAAO,GAAG,MAAM,CAGzC;AAaD;gDACgD;AAChD,wBAAgB,MAAM,CACpB,MAAM,EAAE,SAAS,OAAO,EAAE,EAC1B,gBAAgB,EAAE,SAAS,MAAM,EAAE,GAClC,MAAM,CAAC,MAAM,EAAE,SAAS,MAAM,EAAE,CAAC,CASnC;AAED,yDAAyD;AACzD,wBAAgB,UAAU,CACxB,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,SAAS,MAAM,EAAE,CAAC,EACvC,IAAI,EAAE,MAAM,EACZ,KAAK,EAAE,MAAM,GACZ,SAAS,MAAM,EAAE,GAAG,SAAS,CAI/B"}
@@ -0,0 +1,41 @@
1
+ import { DEFAULTS } from '../policy/category.js';
2
+ /** 候选选择器的取数上限(三枚选择器:分类/账户/账本)。**收在件内**:外面不需要知道这个数。 */
3
+ const PICK_LIMIT = 12;
4
+ /** 一个值的字符串形态(非字符串按空串用;数字写成十进制串)。 */
5
+ export function textOf(v) {
6
+ if (typeof v === 'string')
7
+ return v.trim();
8
+ return typeof v === 'number' ? String(v) : '';
9
+ }
10
+ /** 近期记录里某个字段的取值(按最近在先去重,取前 `PICK_LIMIT` 个)——三枚选择器的候选。**收在件内**。 */
11
+ function distinctOf(recent, field) {
12
+ const out = [];
13
+ for (const r of recent) {
14
+ const v = textOf(r[field]);
15
+ if (v !== '' && !out.includes(v))
16
+ out.push(v);
17
+ if (out.length >= PICK_LIMIT)
18
+ break;
19
+ }
20
+ return out;
21
+ }
22
+ /** 三枚选择器的候选:分类(近期有历史就用历史,一条历史都没有就退到 `fallbackCategory` 给的名单)/
23
+ * 账户/账本(缺省「生活」)。**分类退到哪一侧由调用方定**:本件不收方向这一格。 */
24
+ export function pickOf(recent, fallbackCategory) {
25
+ const category = distinctOf(recent, 'category');
26
+ const account = distinctOf(recent, 'account');
27
+ const ledger = distinctOf(recent, 'ledger');
28
+ return {
29
+ category: category.length > 0 ? category : fallbackCategory,
30
+ account,
31
+ ledger: ledger.length > 0 ? ledger : [DEFAULTS.ledger],
32
+ };
33
+ }
34
+ /** 一个字段的选项:选择器候选 + 本次已给的值(已给的值不在候选里时并到队首,免得表单把它显示没了)。 */
35
+ export function optionsFor(pick, name, value) {
36
+ const list = pick[name];
37
+ if (list === undefined || list.length === 0)
38
+ return undefined;
39
+ return value !== '' && !list.includes(value) ? [value, ...list] : [...list];
40
+ }
41
+ //# sourceMappingURL=recentPicks.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"recentPicks.js","sourceRoot":"","sources":["../../src/shared/recentPicks.ts"],"names":[],"mappings":"AAkBA,OAAO,EAAE,QAAQ,EAAE,MAAM,uBAAuB,CAAC;AAEjD,sDAAsD;AACtD,MAAM,UAAU,GAAG,EAAE,CAAC;AAEtB,oCAAoC;AACpC,MAAM,UAAU,MAAM,CAAC,CAAU;IAC/B,IAAI,OAAO,CAAC,KAAK,QAAQ;QAAE,OAAO,CAAC,CAAC,IAAI,EAAE,CAAC;IAC3C,OAAO,OAAO,CAAC,KAAK,QAAQ,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC;AAChD,CAAC;AAED,kEAAkE;AAClE,SAAS,UAAU,CAAC,MAA0B,EAAE,KAAwC;IACtF,MAAM,GAAG,GAAa,EAAE,CAAC;IACzB,KAAK,MAAM,CAAC,IAAI,MAAM,EAAE,CAAC;QACvB,MAAM,CAAC,GAAG,MAAM,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC;QAC3B,IAAI,CAAC,KAAK,EAAE,IAAI,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC,CAAC;YAAE,GAAG,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;QAC9C,IAAI,GAAG,CAAC,MAAM,IAAI,UAAU;YAAE,MAAM;IACtC,CAAC;IACD,OAAO,GAAG,CAAC;AACb,CAAC;AAED;gDACgD;AAChD,MAAM,UAAU,MAAM,CACpB,MAA0B,EAC1B,gBAAmC;IAEnC,MAAM,QAAQ,GAAG,UAAU,CAAC,MAAM,EAAE,UAAU,CAAC,CAAC;IAChD,MAAM,OAAO,GAAG,UAAU,CAAC,MAAM,EAAE,SAAS,CAAC,CAAC;IAC9C,MAAM,MAAM,GAAG,UAAU,CAAC,MAAM,EAAE,QAAQ,CAAC,CAAC;IAC5C,OAAO;QACL,QAAQ,EAAE,QAAQ,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,gBAAgB;QAC3D,OAAO;QACP,MAAM,EAAE,MAAM,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,MAAM,CAAC;KACvD,CAAC;AACJ,CAAC;AAED,yDAAyD;AACzD,MAAM,UAAU,UAAU,CACxB,IAAuC,EACvC,IAAY,EACZ,KAAa;IAEb,MAAM,IAAI,GAAG,IAAI,CAAC,IAAI,CAAC,CAAC;IACxB,IAAI,IAAI,KAAK,SAAS,IAAI,IAAI,CAAC,MAAM,KAAK,CAAC;QAAE,OAAO,SAAS,CAAC;IAC9D,OAAO,KAAK,KAAK,EAAE,IAAI,CAAC,IAAI,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,KAAK,EAAE,GAAG,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,IAAI,CAAC,CAAC;AAC9E,CAAC"}
@@ -0,0 +1,32 @@
1
+ import type { BillRow } from '../fetch/db.js';
2
+ import type { DiffRow } from './diffTable.js';
3
+ /** `params.op` 落哪一种过筛条件(缺省=改字段那一条)。 */
4
+ export declare function pickModeOf(op: unknown): 'update' | 'undo' | 'restore';
5
+ /** 候选格整块:单选 + 候选记录表 +「为什么是它」+ 一行口径;候选为空或读不通都出空态(不拿最近一笔兜底)。 */
6
+ export declare function pickerBlock(input: {
7
+ readonly mode: 'update' | 'undo' | 'restore';
8
+ /** 本次已经认准的那条(不给=不预选)。 */
9
+ readonly selectedId?: number | null;
10
+ /** 换一句话说这一格(不给=按 `mode` 的缺省那句)。 */
11
+ readonly hint?: string;
12
+ }): string;
13
+ /** 按编号读一条记录(**含已打标撤销的**,`getById` 读不到软删行,故本件走 `fetchAll` 自己筛)。
14
+ * `deleted` 与 `row` 一次给全:软删口径只有 `isDeleted` 一处定义,调用方不再各判一次。 */
15
+ export declare function readRowById(id: number): {
16
+ readonly ok: boolean;
17
+ readonly reason: string;
18
+ readonly row: BillRow | null;
19
+ readonly deleted: boolean;
20
+ };
21
+ /** 一条记录的只读表(列名与 `renderDataTable` 的两列同形)。
22
+ * 表头说明里那个 `·` 改全角空格(本轮整改:表头说明是版式位,行内不再拿 `·` 当版式)。 */
23
+ export declare function snapshotTable(row: BillRow, caption?: string): string;
24
+ /** 本次打算改的那几个字段的对照:**只比给了的那些字段**。
25
+ * 没给的字段不许进这张表——拿「未设置」当新值比,会把「这一格没动」算成「把这一格清空了」。 */
26
+ export declare function diffRowsFor(input: {
27
+ readonly row: BillRow;
28
+ readonly params: Record<string, unknown>;
29
+ /** 允许改的字段名单(取自槽位表,本件不另抄一份)。 */
30
+ readonly fields: readonly string[];
31
+ }): readonly DiffRow[];
32
+ //# sourceMappingURL=recordPicker.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"recordPicker.d.ts","sourceRoot":"","sources":["../../src/shared/recordPicker.ts"],"names":[],"mappings":"AA4BA,OAAO,KAAK,EAAE,OAAO,EAAU,MAAM,gBAAgB,CAAC;AAMtD,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,gBAAgB,CAAC;AAoC9C,uCAAuC;AACvC,wBAAgB,UAAU,CAAC,EAAE,EAAE,OAAO,GAAG,QAAQ,GAAG,MAAM,GAAG,SAAS,CAErE;AAwED,8DAA8D;AAC9D,wBAAgB,WAAW,CAAC,KAAK,EAAE;IACjC,QAAQ,CAAC,IAAI,EAAE,QAAQ,GAAG,MAAM,GAAG,SAAS,CAAC;IAC7C,yBAAyB;IACzB,QAAQ,CAAC,UAAU,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACpC,mCAAmC;IACnC,QAAQ,CAAC,IAAI,CAAC,EAAE,MAAM,CAAC;CACxB,GAAG,MAAM,CA2BT;AAED;gEACgE;AAChE,wBAAgB,WAAW,CAAC,EAAE,EAAE,MAAM,GAAG;IACvC,QAAQ,CAAC,EAAE,EAAE,OAAO,CAAC;IACrB,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB,QAAQ,CAAC,GAAG,EAAE,OAAO,GAAG,IAAI,CAAC;IAC7B,QAAQ,CAAC,OAAO,EAAE,OAAO,CAAC;CAC3B,CAWA;AAqBD;sDACsD;AACtD,wBAAgB,aAAa,CAAC,GAAG,EAAE,OAAO,EAAE,OAAO,CAAC,EAAE,MAAM,GAAG,MAAM,CAMpE;AAQD;oDACoD;AACpD,wBAAgB,WAAW,CAAC,KAAK,EAAE;IACjC,QAAQ,CAAC,GAAG,EAAE,OAAO,CAAC;IACtB,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IACzC,+BAA+B;IAC/B,QAAQ,CAAC,MAAM,EAAE,SAAS,MAAM,EAAE,CAAC;CACpC,GAAG,SAAS,OAAO,EAAE,CAGrB"}