dsh-metaphysics 0.38.2 → 0.46.5
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.
- package/CHANGELOG.md +215 -8
- package/README.md +348 -342
- package/client.js +2134 -129
- package/engine/bazi-words.js +174 -0
- package/engine/classics.js +136 -7
- package/engine/fengshui.js +197 -11
- package/engine/followup.js +29 -5
- package/engine/geju.js +41 -0
- package/engine/index.js +96 -8
- package/engine/interpret-knowledge.js +31 -4
- package/engine/interpret-plain.js +367 -322
- package/engine/interpret.js +288 -32
- package/engine/liuyao.js +85 -0
- package/engine/name-data.js +229 -0
- package/engine/name.js +234 -9
- package/engine/ziwei-words.js +245 -0
- package/engine/ziwei.js +254 -26
- package/index.js +65 -9
- package/package.json +2 -2
- package//345/221/275/347/220/206/346/216/222/347/233/230.html +2933 -487
|
@@ -1,322 +1,367 @@
|
|
|
1
|
-
// 白话层:把「专业表述」翻译成「问的人能读懂的话」
|
|
2
|
-
//
|
|
3
|
-
// 设计原则:
|
|
4
|
-
// · 只从盘面已有字段推导,不编造盘上没有的东西;
|
|
5
|
-
// · 一律用倾向性措辞(避讳「一定/必然/注定」这类绝对化表述);
|
|
6
|
-
// · 每个字段都可能缺失(海外盘、静卦、缺资料),取不到就整句不出,绝不输出 undefined;
|
|
7
|
-
// · 与 interpret.js 无循环依赖:需要的外部常量(档位文案等)由调用方通过 ctx 传入。
|
|
8
|
-
|
|
9
|
-
const s = (v, fallback = '') => (v === undefined || v === null || v === '' ? fallback : String(v));
|
|
10
|
-
const join = (arr) => (Array.isArray(arr) ? arr.filter(Boolean).join('') : '');
|
|
11
|
-
const has = (v) => (Array.isArray(v) ? v.length > 0 : v !== undefined && v !== null && v !== '');
|
|
12
|
-
|
|
13
|
-
// 旺衰 → 生活化比喻(这是「说人话」的核心:把分数讲成体感)
|
|
14
|
-
const STRENGTH_PLAIN = {
|
|
15
|
-
身强: '底子偏足、抗压能力好,但容易自己给自己加码,学会收力比使劲更重要',
|
|
16
|
-
偏强: '底子略足,扛得住事,也容易把事都往自己身上揽',
|
|
17
|
-
中和: '力量比较匀,属于「给什么环境就长出什么样子」的类型',
|
|
18
|
-
偏弱: '底子偏薄,靠外部支援比硬扛有效,选对圈子与节奏很关键',
|
|
19
|
-
身弱: '底子偏薄,先修恢复力再谈冲刺,硬撑的性价比最低',
|
|
20
|
-
};
|
|
21
|
-
|
|
22
|
-
// 卦体关系 → 生活化一句话(六冲六合讲聚散,伏吟讲原地,反吟讲反复)
|
|
23
|
-
const PLAIN_BODY = {
|
|
24
|
-
六冲卦: '这一卦是「六冲」,事情起落快,急事反而好办,拖久了的人事容易散。',
|
|
25
|
-
六合卦: '这一卦是「六合」,容易谈成,也容易黏住不放。',
|
|
26
|
-
变六冲: '往下走会散,收尾别拖。',
|
|
27
|
-
变六合: '往下走会合,事情倾向于延续下去。',
|
|
28
|
-
内卦伏吟: '事情卡在原地打转,想动但动不了。',
|
|
29
|
-
外卦伏吟: '外面那层没变,看起来在动,其实格局照旧。',
|
|
30
|
-
内卦反吟: '反复在自己这一头,改了又改回来。',
|
|
31
|
-
外卦反吟: '外面反复,对方或环境会来回拉扯。',
|
|
32
|
-
化进神: '有一爻在往上走,顺着这股劲推比往回拉顺。',
|
|
33
|
-
化退神: '有一爻在往后退,别按原来的势头硬推。',
|
|
34
|
-
};
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
function
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
const
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
const
|
|
98
|
-
const
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
if (
|
|
102
|
-
return
|
|
103
|
-
}
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
const
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
}
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
return
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
return
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
const
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
1
|
+
// 白话层:把「专业表述」翻译成「问的人能读懂的话」
|
|
2
|
+
//
|
|
3
|
+
// 设计原则:
|
|
4
|
+
// · 只从盘面已有字段推导,不编造盘上没有的东西;
|
|
5
|
+
// · 一律用倾向性措辞(避讳「一定/必然/注定」这类绝对化表述);
|
|
6
|
+
// · 每个字段都可能缺失(海外盘、静卦、缺资料),取不到就整句不出,绝不输出 undefined;
|
|
7
|
+
// · 与 interpret.js 无循环依赖:需要的外部常量(档位文案等)由调用方通过 ctx 传入。
|
|
8
|
+
|
|
9
|
+
const s = (v, fallback = '') => (v === undefined || v === null || v === '' ? fallback : String(v));
|
|
10
|
+
const join = (arr) => (Array.isArray(arr) ? arr.filter(Boolean).join('') : '');
|
|
11
|
+
const has = (v) => (Array.isArray(v) ? v.length > 0 : v !== undefined && v !== null && v !== '');
|
|
12
|
+
|
|
13
|
+
// 旺衰 → 生活化比喻(这是「说人话」的核心:把分数讲成体感)
|
|
14
|
+
const STRENGTH_PLAIN = {
|
|
15
|
+
身强: '底子偏足、抗压能力好,但容易自己给自己加码,学会收力比使劲更重要',
|
|
16
|
+
偏强: '底子略足,扛得住事,也容易把事都往自己身上揽',
|
|
17
|
+
中和: '力量比较匀,属于「给什么环境就长出什么样子」的类型',
|
|
18
|
+
偏弱: '底子偏薄,靠外部支援比硬扛有效,选对圈子与节奏很关键',
|
|
19
|
+
身弱: '底子偏薄,先修恢复力再谈冲刺,硬撑的性价比最低',
|
|
20
|
+
};
|
|
21
|
+
|
|
22
|
+
// 卦体关系 → 生活化一句话(六冲六合讲聚散,伏吟讲原地,反吟讲反复)
|
|
23
|
+
const PLAIN_BODY = {
|
|
24
|
+
六冲卦: '这一卦是「六冲」,事情起落快,急事反而好办,拖久了的人事容易散。',
|
|
25
|
+
六合卦: '这一卦是「六合」,容易谈成,也容易黏住不放。',
|
|
26
|
+
变六冲: '往下走会散,收尾别拖。',
|
|
27
|
+
变六合: '往下走会合,事情倾向于延续下去。',
|
|
28
|
+
内卦伏吟: '事情卡在原地打转,想动但动不了。',
|
|
29
|
+
外卦伏吟: '外面那层没变,看起来在动,其实格局照旧。',
|
|
30
|
+
内卦反吟: '反复在自己这一头,改了又改回来。',
|
|
31
|
+
外卦反吟: '外面反复,对方或环境会来回拉扯。',
|
|
32
|
+
化进神: '有一爻在往上走,顺着这股劲推比往回拉顺。',
|
|
33
|
+
化退神: '有一爻在往后退,别按原来的势头硬推。',
|
|
34
|
+
};
|
|
35
|
+
|
|
36
|
+
// 伏神出伏的四档 → 一句白话;只讲条件,不把它说成应期
|
|
37
|
+
const FUSHEN_PLAIN = {
|
|
38
|
+
可出: '眼下的条件算是有助无压,属于「出得来」的一档——这是条件,不等于马上应验。',
|
|
39
|
+
有助有压: '眼下是一边有助、一边有压,出得来,但得费点劲。',
|
|
40
|
+
受压难出: '眼下被上面的力量压着,不太容易露头,先别急着硬推。',
|
|
41
|
+
未得助: '眼下暂时没借到力,还得等条件转过来。',
|
|
42
|
+
飞伏未知: '飞伏关系看不全,这一层先不下判断。',
|
|
43
|
+
};
|
|
44
|
+
|
|
45
|
+
/**
|
|
46
|
+
* 用神 → 一句白话。
|
|
47
|
+
* 只说「用神落在哪、有没有动、要不要往深处找」,不替人断成败。
|
|
48
|
+
*/
|
|
49
|
+
function usePlainOf(ug, fa) {
|
|
50
|
+
if (!ug || !ug.liuqin) return '';
|
|
51
|
+
if (ug.found.length) {
|
|
52
|
+
const pos = ug.found.map((f) => `第${f.position}爻`).join('、');
|
|
53
|
+
const moving = ug.found.some((f) => f.moving);
|
|
54
|
+
const who = ug.byShi ? '代表你自己' : `就是「${ug.liuqin}」这一类事`;
|
|
55
|
+
return `你问的这件事,在卦里对应${pos}${who}——${moving ? '这一爻还在动,说明事情正在推进' : '这一爻没动,先按现状看'}。`;
|
|
56
|
+
}
|
|
57
|
+
if (ug.fushen.length) {
|
|
58
|
+
const f = ug.fushen[0];
|
|
59
|
+
const hit = fa && Array.isArray(fa.items) ? fa.items.find((x) => x.position === f.position) : null;
|
|
60
|
+
const tail = hit ? ` ${FUSHEN_PLAIN[hit.verdict] || ''}` : '';
|
|
61
|
+
return `你问的这件事,卦面上没有直接露出来,得往深处找:它藏在第${f.position}爻下面(伏神),与上面的关系是「${f.relation || '—'}」,要借力才出得来。${tail}`;
|
|
62
|
+
}
|
|
63
|
+
return '';
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
/**
|
|
67
|
+
* 用神旺衰 → 一句白话。
|
|
68
|
+
*/
|
|
69
|
+
function useStrengthPlain(st) {
|
|
70
|
+
if (!st || !st.lines || !st.lines.length) return '';
|
|
71
|
+
const dead = st.lines.filter((l) => /死|囚/.test(l.monthState) || l.monthChong);
|
|
72
|
+
const live = st.lines.filter((l) => /旺|相/.test(l.monthState));
|
|
73
|
+
const when = st.month && st.month.branch ? `眼下这阵子(${st.month.branch}月)` : '起卦这段日子';
|
|
74
|
+
if (dead.length && !live.length) return `${when}对这件事不太帮忙,气有点被压着——先别急着硬推,等风向转。`;
|
|
75
|
+
if (live.length && !dead.length) return `${when}对这件事是帮着的,气正在往上走,能推就趁现在。`;
|
|
76
|
+
return `${when}对这件事有帮有压,一半的力要自己挣——结果更看你怎么走。`;
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
// 化进 / 化退的力重 → 一句白话:方向之外,时令托不托着
|
|
80
|
+
function jinTuiPlain(r) {
|
|
81
|
+
const jp = r && r.jinTuiPower;
|
|
82
|
+
if (!jp || !Array.isArray(jp.lines) || !jp.lines.length) return '';
|
|
83
|
+
const sayOf = (l) => (l.verdict === '后劲足' ? '时令托着,后劲足'
|
|
84
|
+
: l.verdict === '后劲有限' ? '时令不太托,后劲有限'
|
|
85
|
+
: l.verdict === '进得虚' ? '时令最背,进也是虚进'
|
|
86
|
+
: l.verdict === '退得缓' ? '时令还托着,退得慢'
|
|
87
|
+
: l.verdict === '退得实' ? '时令也不托,退得实'
|
|
88
|
+
: l.verdict === '月破失据' ? '又正好逢月破,进退都站不稳'
|
|
89
|
+
: '缺月建,先只当方向看');
|
|
90
|
+
return `动爻的进退还要看时令:${jp.lines.map((l) => `${l.position}爻${l.from}→${l.to}${l.type},${sayOf(l)}`).join(';')}。`;
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
// 全卦逐爻旺衰 → 一句白话:整张卦的气偏在哪一头(与用神那一句分开说)
|
|
94
|
+
function hexStrengthPlain(hs) {
|
|
95
|
+
if (!hs || !hs.counts) return '';
|
|
96
|
+
const up = (hs.counts.旺 || 0) + (hs.counts.相 || 0);
|
|
97
|
+
const down = (hs.counts.囚 || 0) + (hs.counts.死 || 0);
|
|
98
|
+
const when = hs.month && hs.month.branch ? `按${hs.month.branch}月这段时令看` : '按起卦这天看';
|
|
99
|
+
const shi = hs.shi && hs.shi.monthState !== 'unknown' ? `代表你的世爻在${hs.shi.monthState}` : '';
|
|
100
|
+
if (up >= 4 && down === 0) return `${when},整张卦六爻的气多数是顺的,${shi},眼下算是好推的时候。`;
|
|
101
|
+
if (down >= 4 && up === 0) return `${when},整张卦六爻的气多数被压着,${shi},这几天更适合等而不是冲。`;
|
|
102
|
+
return `${when},整张卦六爻有顺有逆(旺相 ${up} 爻、囚死 ${down} 爻)${shi ? `,${shi}` : ''},成不成要看具体哪一爻在动。`;
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
// 三方四正复合飞化 → 一句白话:四股力有没有挤到同一处
|
|
106
|
+
function flyCompositePlain(fc) {
|
|
107
|
+
if (!fc || !Array.isArray(fc.targets)) return '';
|
|
108
|
+
const hub = fc.targets.find((t) => t.count >= 2);
|
|
109
|
+
const self = fc.groups && fc.groups.selfHua && fc.groups.selfHua.length
|
|
110
|
+
? '其中有的宫自己化出去又落回自己,容易表现为「想得多、落得少」。'
|
|
111
|
+
: '';
|
|
112
|
+
if (!hub) return `把命宫连同对宫、两个三合宫一起看,四股力飞出去没有挤到同一处,这几件事之间牵连不深。${self}`;
|
|
113
|
+
return `把命宫连同对宫与两个三合宫一起看,${hub.incoming.length} 股力最后挤在「${String(hub.palace).replace(/宫$/, '')}」这件事上——这件事会把好几个方面的劲都吸过来。${self}`;
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
/**
|
|
117
|
+
* 六爻卦体 → 一句白话。
|
|
118
|
+
* 标签可能带爻位(「化进神 5」),所以按前缀匹配;
|
|
119
|
+
* 主句取标签顺序里第一个能说的,化进/化退作为补充句跟在后面(它们只说某一爻,不覆盖全局)。
|
|
120
|
+
*/
|
|
121
|
+
function bodyPlainOf(labels) {
|
|
122
|
+
const keyOf = (l) => Object.keys(PLAIN_BODY).find((k) => l === k || l.startsWith(`${k} `)) || '';
|
|
123
|
+
const primary = labels.find((l) => keyOf(l));
|
|
124
|
+
const main = primary ? PLAIN_BODY[keyOf(primary)] : '';
|
|
125
|
+
const extra = labels
|
|
126
|
+
.filter((l) => l !== primary && /^化[进退]神 /.test(l))
|
|
127
|
+
.map((l) => PLAIN_BODY[keyOf(l)])
|
|
128
|
+
.filter(Boolean);
|
|
129
|
+
return main + extra.join('');
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
// 询问方向 → 该往哪一节看
|
|
133
|
+
const DIR_SECTION = {
|
|
134
|
+
wealth: '「工作与职业选择」与「时间窗」',
|
|
135
|
+
career: '「事业发展」与「时间窗」',
|
|
136
|
+
love: '「爱情与感情」',
|
|
137
|
+
health: '「健康状况」',
|
|
138
|
+
study: '「事业发展」与「时间窗」',
|
|
139
|
+
travel: '「整体运势」与「时间窗」',
|
|
140
|
+
general: '「整体运势」与「看盘顺序」',
|
|
141
|
+
};
|
|
142
|
+
|
|
143
|
+
/** 一句话直答:先回答「你问的事」,再指路到具体小节 */
|
|
144
|
+
export function buildAnswer(r, ask, ctx = {}) {
|
|
145
|
+
if (!r || !r.system) return '';
|
|
146
|
+
const q = s(ask && ask.question).trim();
|
|
147
|
+
const dir = (ask && ask.direction) || 'general';
|
|
148
|
+
// 只有八字的维度与「时间窗」是固定名称,其余体系用中性说法,避免指向不存在的小节
|
|
149
|
+
const where = r.system === 'bazi'
|
|
150
|
+
? (DIR_SECTION[dir] || DIR_SECTION.general)
|
|
151
|
+
: '下面与你的问题最贴近的那一节';
|
|
152
|
+
const head = q ? `你问的是「${q}」。` : '';
|
|
153
|
+
|
|
154
|
+
if (r.system === 'bazi') {
|
|
155
|
+
const dm = r.dayMaster || {};
|
|
156
|
+
const st = r.strength || {};
|
|
157
|
+
const ys = (r.frame && r.frame.yongshen) || {};
|
|
158
|
+
const favor = join(ys.favor);
|
|
159
|
+
const avoid = join(ys.avoid);
|
|
160
|
+
const ln = (r.liunian || [])[0];
|
|
161
|
+
const parts = [
|
|
162
|
+
head + `先说结论:你是${s(dm.stem)}${s(dm.element)}日主,命局${s(st.level, '待定')}` +
|
|
163
|
+
`${favor ? `,顺${favor}、忌${avoid}——往${favor}的方向安排事情会更省力` : ''}。`,
|
|
164
|
+
ln && ln.ganzhi
|
|
165
|
+
? `${s(ln.year)} 年是${ln.ganzhi}年(${s(ln.luck && ln.luck.tier, '平')}),这是「大环境」这一层。`
|
|
166
|
+
: '',
|
|
167
|
+
`具体到你问的这件事,重点看${where}。`,
|
|
168
|
+
];
|
|
169
|
+
if (!q) parts[parts.length - 1] = `没指定问题,就按${where}的顺序往下看。`;
|
|
170
|
+
return parts.filter(Boolean).join('');
|
|
171
|
+
}
|
|
172
|
+
|
|
173
|
+
if (r.system === 'ziwei') {
|
|
174
|
+
const soul = r.soul || {};
|
|
175
|
+
const body = r.body || {};
|
|
176
|
+
const bureau = r.bureau || {};
|
|
177
|
+
const md = r.lifeMaster || '';
|
|
178
|
+
const ji = r.flyChains && r.flyChains.忌;
|
|
179
|
+
const plainFly = ji && ji.steps.length
|
|
180
|
+
? `还有一条线值得留意:${ji.path.map((p) => p.replace(/宫$/, '')).join(' → ')}——这几件事在你身上是连着转的,一件卡住,容易牵动下一件。`
|
|
181
|
+
: '';
|
|
182
|
+
return [
|
|
183
|
+
head + `先说结论:你的命宫落${s(soul.branch, '—')}宫` +
|
|
184
|
+
`${bureau.name ? `、${bureau.name}` : ''}${md ? `,命主${md}` : ''}` +
|
|
185
|
+
`${body.lands ? `,身宫落在「${body.lands}」——这张盘的重心在这件事上` : ''}。`,
|
|
186
|
+
plainFly,
|
|
187
|
+
flyCompositePlain(r.flyComposite),
|
|
188
|
+
q ? `具体到你问的这件事,重点看${where}。` : `没指定问题,就按${where}的顺序往下看。`,
|
|
189
|
+
].filter(Boolean).join('');
|
|
190
|
+
}
|
|
191
|
+
|
|
192
|
+
if (r.system === 'liuyao') {
|
|
193
|
+
const ben = r.ben || {};
|
|
194
|
+
const moving = (r.cast && r.cast.movingPositions) || [];
|
|
195
|
+
const bian = r.bian || {};
|
|
196
|
+
const labels = (r.body && Array.isArray(r.body.labels)) ? r.body.labels : [];
|
|
197
|
+
// 六冲六合伏吟反吟里挑最贴近当下局面的一句,避免四句叠着说
|
|
198
|
+
const plainBody = bodyPlainOf(labels);
|
|
199
|
+
return [
|
|
200
|
+
head + `先说结论:本卦是${s(ben.name, '—')}` +
|
|
201
|
+
`${ben.palace ? `(${ben.palace})` : ''}` +
|
|
202
|
+
`${moving.length ? `,第 ${moving.join('、')} 爻动,变为${s(bian.name, '—')}` : ',六爻安静没有动爻'}。` +
|
|
203
|
+
`${plainBody}${usePlainOf(r.useGod, r.fushenAccess)}${useStrengthPlain(r.useGodStrength)}${jinTuiPlain(r)}${hexStrengthPlain(r.hexStrength)}`,
|
|
204
|
+
'断卦的落点在「世爻」(代表你)和「动爻」(事情的推动点),下面「看盘顺序」就按这个次序展开。',
|
|
205
|
+
].join('');
|
|
206
|
+
}
|
|
207
|
+
|
|
208
|
+
// 其余体系没有固定小节名:有问才指路;没问就按顺序读,别假装知道「你的问题」
|
|
209
|
+
if (head) return `${head}下面按五个维度拆开看,重点看${where}。`;
|
|
210
|
+
// 奇门没有五维,内容按排盘事实/用神/宫位条件几节走,不能跟着说「五个维度」
|
|
211
|
+
if (r.system === 'qimen') {
|
|
212
|
+
const dirTip = dir !== 'general' && ask && ask.directionLabel ? `,取「${ask.directionLabel}」方向的用神` : '';
|
|
213
|
+
return `下面按排盘事实、用神、宫位条件几节展开${dirTip}。`;
|
|
214
|
+
}
|
|
215
|
+
if (dir !== 'general' && ask && ask.directionLabel) {
|
|
216
|
+
return `下面按五个维度拆开看,重点看与「${ask.directionLabel}」方向最贴近的那一节。`;
|
|
217
|
+
}
|
|
218
|
+
return '下面按五个维度拆开看,没指定问题,就从头依次读。';
|
|
219
|
+
}
|
|
220
|
+
|
|
221
|
+
/** 说人话整段:去掉术语,用生活语言讲这张盘的整体气质 */
|
|
222
|
+
export function buildPlain(r, ask, ctx = {}) {
|
|
223
|
+
if (!r || !r.system) return '';
|
|
224
|
+
if (r.system === 'bazi') {
|
|
225
|
+
const st = r.strength || {};
|
|
226
|
+
const ys = (r.frame && r.frame.yongshen) || {};
|
|
227
|
+
const favor = join(ys.favor);
|
|
228
|
+
const avoid = join(ys.avoid);
|
|
229
|
+
const strength = STRENGTH_PLAIN[st.level] || '力量偏中性';
|
|
230
|
+
const tiaohou = ys.tiaohou && ys.tiaohou.note ? `另外,${ys.tiaohou.note},所以「暖一点、亮一点」的环境通常更舒服。` : '';
|
|
231
|
+
const sy = (r.liunian || []).find((l) => l.suiyun && Array.isArray(l.suiyun.signals) && l.suiyun.signals.length);
|
|
232
|
+
const syPlain = sy
|
|
233
|
+
? `再往后看,${sy.year} 年${sy.ganzhi}是${sy.suiyun.signals.map((x) => x.type).join('、')}——传统上把它当作「变化感强一点」的提示,既不是好消息也不是坏消息,遇上时多留个心眼就好。`
|
|
234
|
+
: '';
|
|
235
|
+
return `你的命局属于「${s(st.level, '中性')}」:${strength}。` +
|
|
236
|
+
`${favor ? `能补${favor}的环境(行业、方位、作息、相处的人)会让你省力;${avoid ? `而${avoid}偏重的场合容易空耗,能绕就绕。` : ''}` : ''}` +
|
|
237
|
+
tiaohou + syPlain;
|
|
238
|
+
}
|
|
239
|
+
if (r.system === 'ziwei') {
|
|
240
|
+
const body = r.body || {};
|
|
241
|
+
const ji = r.flyChains && r.flyChains.忌;
|
|
242
|
+
// 只挑忌这一条白话:它最能说「你反复在哪几件事上使劲」
|
|
243
|
+
// 上面「先答所问」已经报过忌链与飞化的原句,这里换个说法只讲感受,避免同一句念两遍
|
|
244
|
+
const feltChain = ji && ji.steps.length
|
|
245
|
+
? '你身上有个绕不开的规律:几件事是连着转的,一件卡住,后面就跟着慢下来。'
|
|
246
|
+
: '';
|
|
247
|
+
const fc = r.flyComposite;
|
|
248
|
+
const hub = fc && Array.isArray(fc.targets) ? fc.targets.find((t) => t.count >= 2) : null;
|
|
249
|
+
const feltComposite = !fc || !Array.isArray(fc.targets)
|
|
250
|
+
? ''
|
|
251
|
+
: hub
|
|
252
|
+
? `再往深一层,四股力最后也压在「${String(hub.palace).replace(/宫$/, '')}」上——几个方面的劲都往这儿聚。`
|
|
253
|
+
: '再往深一层,四股的力没有全挤到一处,这几件事之间牵连不深。';
|
|
254
|
+
const focus = body.lands
|
|
255
|
+
? `真正让你上心的,多半是「${body.lands}」这件事,做别的总会分心。`
|
|
256
|
+
: '';
|
|
257
|
+
return [
|
|
258
|
+
`紫微讲的是「你与环境怎么互动」,不是谁好谁坏——同一件事换个环境、换个人配合,结果就不一样。`,
|
|
259
|
+
focus,
|
|
260
|
+
feltChain,
|
|
261
|
+
feltComposite,
|
|
262
|
+
].filter(Boolean).join('');
|
|
263
|
+
}
|
|
264
|
+
if (r.system === 'liuyao') {
|
|
265
|
+
const ben = r.ben || {};
|
|
266
|
+
const moving = (r.cast && r.cast.movingPositions) || [];
|
|
267
|
+
const labels = (r.body && Array.isArray(r.body.labels)) ? r.body.labels : [];
|
|
268
|
+
const plainBody = bodyPlainOf(labels);
|
|
269
|
+
return `${s(ben.name, '这一卦')}讲的是一个「${moving.length ? '正在动、还会变' : '暂时不动、先看清'}」的局面——` +
|
|
270
|
+
`${moving.length ? '有动爻,说明事情还有转圜空间,不是死局。' : '六爻安静,说明当下更该观察而不是硬推。'}` +
|
|
271
|
+
`${plainBody}${usePlainOf(r.useGod, r.fushenAccess)}${useStrengthPlain(r.useGodStrength)}${jinTuiPlain(r)}${hexStrengthPlain(r.hexStrength)}`;
|
|
272
|
+
}
|
|
273
|
+
return '';
|
|
274
|
+
}
|
|
275
|
+
|
|
276
|
+
/** 每维一句白话(仅在有盘面数据支撑时给出,避免空话) */
|
|
277
|
+
export function dimensionPlain(key, r, ctx = {}) {
|
|
278
|
+
if (!r || r.system !== 'bazi') return '';
|
|
279
|
+
const ys = (r.frame && r.frame.yongshen) || {};
|
|
280
|
+
const favor = join(ys.favor);
|
|
281
|
+
const avoid = join(ys.avoid);
|
|
282
|
+
const st = r.strength || {};
|
|
283
|
+
if (key === 'overall') return `一句话:底子${s(st.level, '中性')},往${favor || '有利方向'}走省力。`;
|
|
284
|
+
if (key === 'work') return `一句话:挑${favor || '喜用'}属性的活儿,比硬碰${avoid || '忌神'}省力。`;
|
|
285
|
+
if (key === 'career') return `一句话:你的上升方式,偏向把${favor || '长处'}做成看得见的成果。`;
|
|
286
|
+
if (key === 'love') return '一句话:关系里先看清自己要什么,再决定推进速度。';
|
|
287
|
+
if (key === 'health') return '一句话:作息稳定比任何调理都优先。';
|
|
288
|
+
return '';
|
|
289
|
+
}
|
|
290
|
+
|
|
291
|
+
// 术语白话表:只解释本篇真正出现的词
|
|
292
|
+
const GLOSSARY = [
|
|
293
|
+
['日主', '你出生那天对应的天干,代表「你自己」,整张盘都围着它转。'],
|
|
294
|
+
['用神', '这张盘里最需要补的那一类力量,顺着它做事更省力。'],
|
|
295
|
+
['忌神', '补得越多越别扭的那一类力量,不是坏东西,只是对你性价比低。'],
|
|
296
|
+
['调候', '按出生季节调温补缺:冬天的盘怕冷,夏天的盘怕燥。'],
|
|
297
|
+
['格局', '把整张盘的结构归成一个类型,用来看「你适合怎么打」。'],
|
|
298
|
+
['十神', '把五行关系翻译成人事:财=资源、官杀=规则与压力、印=支持、食伤=表达、比劫=同伴。'],
|
|
299
|
+
['月令', '出生的月份,是判断强弱最关键的一个位置。'],
|
|
300
|
+
['日支', '日柱的地支,也叫「配偶宫」,看亲密关系的第一落点。'],
|
|
301
|
+
['大运', '十年一换的大阶段,决定这十年顺不顺手。'],
|
|
302
|
+
['流年', '每一年的干支,看当年的具体环境。'],
|
|
303
|
+
['空亡', '落到空亡的字,力量打折,事情容易「看着有、抓不住」。'],
|
|
304
|
+
['伏神', '卦里没出现的六亲,藏在同宫首卦的对应爻下,用时才看得见。'],
|
|
305
|
+
['世应', '世爻代表你,应爻代表对方或外部环境。'],
|
|
306
|
+
['动爻', '会变的爻,是事情「往哪走」的推动点。'],
|
|
307
|
+
['纳甲', '给六个爻配上天干地支,六亲与生克才有依据。'],
|
|
308
|
+
['四化', '禄权科忌四种变化,标记星曜在这一步运里扮演什么角色。'],
|
|
309
|
+
['大限', '紫微里的十年阶段,作用类似八字的「大运」。'],
|
|
310
|
+
['庙旺', '星曜落在某宫时的力量档位:庙、旺最强,得、利、平居中,不、陷最弱。'],
|
|
311
|
+
['三方四正', '从命宫出发的三合三方加对宫,共四个宫位,是全盘最核心的势力范围。'],
|
|
312
|
+
['命主', '紫微里另有一颗命主星,补命宫看不到的那一层底色。'],
|
|
313
|
+
['身主', '紫微里另有一颗身主星,管后天的行动与身体那一面。'],
|
|
314
|
+
['五行局', '用纳音给整张盘定一个局(水二局、木三局等),大限的起法以此为准。'],
|
|
315
|
+
['自化', '宫干让本宫星曜自己生出四化,代表这一宫的事容易自己发酵。'],
|
|
316
|
+
['飞星', '拿一个宫的宫干去四化别的宫,看事情从哪来、往哪走。'],
|
|
317
|
+
['正曜', '十四主星。「无正曜」指命宫没有主星,要借对宫来看。'],
|
|
318
|
+
['借对宫', '命宫无主星时借对宫主星来读,性格更依赖环境与身边的人。'],
|
|
319
|
+
['双星', '两主星同宫,按组合读,不能只看其中一颗。'],
|
|
320
|
+
['墓库', '地支里的仓库。五行入墓代表这股力量收着,不是没有。'],
|
|
321
|
+
['伏吟', '干支重复出现,事情容易原地打转、反复。'],
|
|
322
|
+
['反吟', '天克地冲,变动与对撞的意味更明显。'],
|
|
323
|
+
];
|
|
324
|
+
|
|
325
|
+
/** 同一个术语在不同体系里含义不同,必须分体系解释,否则会给出错误定义 */
|
|
326
|
+
const GLOSSARY_BY_SYSTEM = {
|
|
327
|
+
liuyao: {
|
|
328
|
+
用神: '你问的这件事对应的那一类六亲,断卦先把它找出来。',
|
|
329
|
+
月令: '起卦时的月份,用来看各爻旺不旺。',
|
|
330
|
+
日支: '起卦当天的地支,与月建一起决定爻的力量。',
|
|
331
|
+
大运: '六爻不看大运,这里只取当前这一件事的象。',
|
|
332
|
+
流年: '六爻一般不看流年,看的是眼下这一卦的时段。',
|
|
333
|
+
},
|
|
334
|
+
ziwei: {
|
|
335
|
+
用神: '紫微斗数以「用神宫」的强弱看事情,不取五行喜忌那套。',
|
|
336
|
+
日主: '紫微斗数不看日主,看的是命宫与星曜组合。',
|
|
337
|
+
十神: '紫微斗数用四化与星情,不用十神。',
|
|
338
|
+
},
|
|
339
|
+
};
|
|
340
|
+
|
|
341
|
+
/** 术语白话:只列正文里真出现过的词;同名词按体系取对应释义 */
|
|
342
|
+
export function buildGlossary(texts, system) {
|
|
343
|
+
const body = (Array.isArray(texts) ? texts : [texts]).filter(Boolean).join('');
|
|
344
|
+
if (!body) return [];
|
|
345
|
+
const override = GLOSSARY_BY_SYSTEM[system] || {};
|
|
346
|
+
return GLOSSARY
|
|
347
|
+
.filter(([term]) => body.includes(term))
|
|
348
|
+
.map(([term, plain]) => ({ term, plain: override[term] || plain }))
|
|
349
|
+
.slice(0, 10);
|
|
350
|
+
}
|
|
351
|
+
|
|
352
|
+
const FOLLOWUPS = {
|
|
353
|
+
career: ['这份工作要不要动,明年哪几个月是窗口?', '和上级的关系该硬碰还是绕开?', '现在转方向,代价主要在哪儿?'],
|
|
354
|
+
wealth: ['这笔钱现在投出去合适吗?', '我的财主要来自工资还是副业?', '今年哪段时间最容易破财?'],
|
|
355
|
+
love: ['这段关系能走到哪一步?', '什么时候适合把关系定下来?', '我在关系里最容易忽略什么?'],
|
|
356
|
+
health: ['哪段时间身体最需要留意?', '作息怎么调最划算?', '查体和作息之外,还有什么是能自己控制的?'],
|
|
357
|
+
study: ['今年再考一次,胜算在哪、短板在哪?', '复习节奏该怎么排?', '要不要换目标院校或岗位?'],
|
|
358
|
+
travel: ['这次出门顺不顺,哪天走更好?', '换个城市生活,合不合适?'],
|
|
359
|
+
general: ['今年最该抓的一件事是什么?', '最该避开的坑在哪?', '接下来三个月,什么时间点值得留意?'],
|
|
360
|
+
};
|
|
361
|
+
|
|
362
|
+
/** 追问建议:把「还能问什么」具体化,降低二次提问的门槛 */
|
|
363
|
+
export function buildFollowups(r, ask) {
|
|
364
|
+
const dir = (ask && ask.direction) || 'general';
|
|
365
|
+
const list = FOLLOWUPS[dir] || FOLLOWUPS.general;
|
|
366
|
+
return list.slice(0, 3);
|
|
367
|
+
}
|