mvframe 1.0.73 → 1.0.75
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/README.cn.md +64 -1
- package/README.md +51 -1
- package/dist/index.js +11 -10
- package/dist/notify.js +80 -0
- package/dist/vendor.js +434 -425
- package/package.json +13 -4
- package/scripts/dev-with-notify.js +92 -0
- package/scripts/notify-server.js +405 -0
- package/scripts/scaffold-app.js +121 -1
package/README.cn.md
CHANGED
|
@@ -19,6 +19,7 @@
|
|
|
19
19
|
- `"."` → `dist/index.js`(主插件,默认导出 `install` 函数)
|
|
20
20
|
- `"./composition"` → `dist/composition.js`(`import { useMap, … } from 'mvframe/composition'`)
|
|
21
21
|
- `"./store"`、`"./directive"`、`"./util"` → 对应 `dist` 下分包
|
|
22
|
+
- `"./notify"` → `dist/notify.js`(浏览器端请求本地 `mvframe-notify` 服务的通知 helper)
|
|
22
23
|
- `"./style"` → `dist/css/style.css`(由 `src/style/index.scss` 单独入口打包的全量工具类/变量)
|
|
23
24
|
- `"./style/cpt"` → `dist/css/cpt.css`(随组件抽取的样式;一般用 `mvframe/style` 即可)
|
|
24
25
|
|
|
@@ -153,6 +154,59 @@ yarn build
|
|
|
153
154
|
|
|
154
155
|
---
|
|
155
156
|
|
|
157
|
+
## 钉钉通知服务
|
|
158
|
+
|
|
159
|
+
MVFrame 提供只支持钉钉机器人的本地 Node 服务,命令由框架包提供:
|
|
160
|
+
|
|
161
|
+
```bash
|
|
162
|
+
# 仅启动钉钉通知服务
|
|
163
|
+
yarn notify
|
|
164
|
+
# 或发布包命令
|
|
165
|
+
yarn exec mvframe-notify
|
|
166
|
+
|
|
167
|
+
# 同时启动 yarn dev 与通知服务
|
|
168
|
+
yarn d
|
|
169
|
+
# 或发布包命令
|
|
170
|
+
yarn exec mvframe-d
|
|
171
|
+
```
|
|
172
|
+
|
|
173
|
+
服务读取宿主项目根目录的 `.env.mvframe-notify`(可用 `--env` 指定):
|
|
174
|
+
|
|
175
|
+
```env
|
|
176
|
+
MVFRAME_NOTIFY_PORT=3300
|
|
177
|
+
MVFRAME_NOTIFY_HOST=127.0.0.1
|
|
178
|
+
MVFRAME_NOTIFY_TOKEN=
|
|
179
|
+
DINGTALK_WEBHOOK="https://oapi.dingtalk.com/robot/send?access_token=xxxxxxxx"
|
|
180
|
+
DINGTALK_SECRET="SECxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
|
|
181
|
+
```
|
|
182
|
+
|
|
183
|
+
浏览器端只配置本地服务地址和访问 token:
|
|
184
|
+
|
|
185
|
+
```js
|
|
186
|
+
app.use(mvframe, {
|
|
187
|
+
config: {
|
|
188
|
+
notify: {
|
|
189
|
+
enabled: true,
|
|
190
|
+
endpoint: import.meta.env.VITE_MVFRAME_NOTIFY_ENDPOINT || "http://127.0.0.1:3300",
|
|
191
|
+
token: import.meta.env.VITE_MVFRAME_NOTIFY_TOKEN || "",
|
|
192
|
+
},
|
|
193
|
+
},
|
|
194
|
+
});
|
|
195
|
+
```
|
|
196
|
+
|
|
197
|
+
发送消息:
|
|
198
|
+
|
|
199
|
+
```js
|
|
200
|
+
await globalThis.$notify.send("需要发送到钉钉的消息");
|
|
201
|
+
|
|
202
|
+
import { notify } from "mvframe/notify";
|
|
203
|
+
await notify("需要发送到钉钉的消息");
|
|
204
|
+
```
|
|
205
|
+
|
|
206
|
+
钉钉 webhook / secret 必须留在 Node 服务环境变量里,不要写进 `main.js`、`src/config/index.js` 或其它会被 Vite 打包到浏览器的文件。
|
|
207
|
+
|
|
208
|
+
---
|
|
209
|
+
|
|
156
210
|
## 设计取向与注意
|
|
157
211
|
|
|
158
212
|
- 布局、路由守卫、Tab、菜单等 **强绑定一套交互模型**;深度定制时可局部 fork `src/router`、`src/store/tab.js` 或外层包一层封装。
|
|
@@ -163,7 +217,7 @@ yarn build
|
|
|
163
217
|
|
|
164
218
|
## 命令行:项目目录雏形(推荐)
|
|
165
219
|
|
|
166
|
-
在**空目录或已有 Vite 工程根目录**执行,生成 `src/views`、`src/component`、`src/api`、`src/assets/img`、`src/assets/style`、`src/router`、`src/pinia/chip`、`src/config` 及示例 `main.js` / `App.vue`(已 `app.use(mvframe, …)` 挂好路由、Pinia `storeChips`、config),同时写入/更新宿主项目 **`AGENTS.md`** 的 MVFrame Codex 规则,并复制 **`/.cursor/rules/*.mdc`**(与 mvframe 仓库内 Cursor 规则一致)。若不存在则附带 `index.html` 与 `vite.config.js`。会**合并** `package.json` 的 `scripts` / `dependencies` / `devDependencies`(与 Vite
|
|
220
|
+
在**空目录或已有 Vite 工程根目录**执行,生成 `src/views`、`src/component`、`src/api`、`src/assets/img`、`src/assets/style`、`src/router`、`src/pinia/chip`、`src/config` 及示例 `main.js` / `App.vue`(已 `app.use(mvframe, …)` 挂好路由、Pinia `storeChips`、config),同时写入/更新宿主项目 **`AGENTS.md`** 的 MVFrame Codex 规则,并复制 **`/.cursor/rules/*.mdc`**(与 mvframe 仓库内 Cursor 规则一致)。若不存在则附带 `index.html` 与 `vite.config.js`。会**合并** `package.json` 的 `scripts` / `dependencies` / `devDependencies`(与 Vite 模板一致;**同名脚本和包保留你原有值**),初始化 `.env.mvframe-notify.example` / `.env.local.example` 与 `config.notify`,并自动执行 **`yarn install`**,最后请执行 **`yarn dev`**;需要同时启动通知服务时显式执行 **`yarn exec mvframe-d`**。加 `--no-package-json` 可不改动 `package.json` 且跳过安装。
|
|
167
221
|
|
|
168
222
|
```bash
|
|
169
223
|
cd /path/to/your-app
|
|
@@ -220,6 +274,15 @@ yarn exec mvframe-install-cursor-skill
|
|
|
220
274
|
|
|
221
275
|
---
|
|
222
276
|
|
|
277
|
+
## 迭代记录
|
|
278
|
+
|
|
279
|
+
- 新增 `mvframe-notify`:只支持钉钉机器人的本地通知服务,钉钉 webhook / secret 留在 Node 环境变量。
|
|
280
|
+
- 新增 `mvframe/notify` 与全局 `$notify`:前端通过 `config.notify` 请求本地通知服务。
|
|
281
|
+
- 新增框架命令 `yarn d` / `mvframe-d`:同时启动 `yarn dev` 与钉钉通知服务。
|
|
282
|
+
- `mvframe-init-app` 初始化 `config.notify`、带测试钉钉机器人的 `.env.mvframe-notify` / `.env.mvframe-notify.example` 与 `.env.local.example`,不自动覆盖宿主 `d` 脚本。
|
|
283
|
+
|
|
284
|
+
---
|
|
285
|
+
|
|
223
286
|
## 协议
|
|
224
287
|
|
|
225
288
|
ISC(见 `package.json`)。
|
package/README.md
CHANGED
|
@@ -19,6 +19,7 @@ A Vue 3 + Vite oriented admin-shell toolkit: **Frame layout**, **common business
|
|
|
19
19
|
- `"."` → `dist/index.js` (main plugin; default export is the `install` function)
|
|
20
20
|
- `"./composition"` → `dist/composition.js` (e.g. `import { useMap } from 'mvframe/composition'`)
|
|
21
21
|
- `"./store"`, `"./directive"`, `"./util"` → matching chunks under `dist`
|
|
22
|
+
- `"./notify"` → `dist/notify.js` (browser helper for the local `mvframe-notify` service)
|
|
22
23
|
- `"./style"` → `dist/css/style.css` (full toolkit CSS from `src/style/index.scss` entry)
|
|
23
24
|
- `"./style/cpt"` → `dist/css/cpt.css` (component-extracted CSS; usually `import 'mvframe/style'` is enough)
|
|
24
25
|
|
|
@@ -153,6 +154,46 @@ Production uses **library mode** with entry `src/index.js` and obfuscation-relat
|
|
|
153
154
|
|
|
154
155
|
---
|
|
155
156
|
|
|
157
|
+
## DingTalk Notify Service
|
|
158
|
+
|
|
159
|
+
MVFrame ships a local Node service for DingTalk robot messages only:
|
|
160
|
+
|
|
161
|
+
```bash
|
|
162
|
+
yarn notify
|
|
163
|
+
yarn exec mvframe-notify
|
|
164
|
+
|
|
165
|
+
yarn d
|
|
166
|
+
yarn exec mvframe-d
|
|
167
|
+
```
|
|
168
|
+
|
|
169
|
+
The service reads `.env.mvframe-notify` from the host root:
|
|
170
|
+
|
|
171
|
+
```env
|
|
172
|
+
MVFRAME_NOTIFY_PORT=3300
|
|
173
|
+
MVFRAME_NOTIFY_HOST=127.0.0.1
|
|
174
|
+
MVFRAME_NOTIFY_TOKEN=
|
|
175
|
+
DINGTALK_WEBHOOK="https://oapi.dingtalk.com/robot/send?access_token=xxxxxxxx"
|
|
176
|
+
DINGTALK_SECRET="SECxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
|
|
177
|
+
```
|
|
178
|
+
|
|
179
|
+
Browser code should only configure the local endpoint/token:
|
|
180
|
+
|
|
181
|
+
```js
|
|
182
|
+
app.use(mvframe, {
|
|
183
|
+
config: {
|
|
184
|
+
notify: {
|
|
185
|
+
enabled: true,
|
|
186
|
+
endpoint: import.meta.env.VITE_MVFRAME_NOTIFY_ENDPOINT || "http://127.0.0.1:3300",
|
|
187
|
+
token: import.meta.env.VITE_MVFRAME_NOTIFY_TOKEN || "",
|
|
188
|
+
},
|
|
189
|
+
},
|
|
190
|
+
});
|
|
191
|
+
```
|
|
192
|
+
|
|
193
|
+
Send messages with `globalThis.$notify.send("message")` or `import { notify } from "mvframe/notify"`. Keep DingTalk webhook/secret out of browser-bundled files.
|
|
194
|
+
|
|
195
|
+
---
|
|
196
|
+
|
|
156
197
|
## Design notes
|
|
157
198
|
|
|
158
199
|
- Layout, guards, tabs, and menu behavior are **opinionated**; heavy customization may mean forking `src/router`, `src/store/tab.js`, or wrapping from the app.
|
|
@@ -163,7 +204,7 @@ Production uses **library mode** with entry `src/index.js` and obfuscation-relat
|
|
|
163
204
|
|
|
164
205
|
## CLI: project skeleton
|
|
165
206
|
|
|
166
|
-
From an **empty folder or existing Vite root**, generates `src/views`, `src/component`, `src/api`, `src/assets/img`, `src/assets/style`, `src/router`, `src/pinia/chip`, `src/config`, plus starter `main.js` / `App.vue` with `app.use(mvframe, …)` (routes, Pinia `storeChips`, config). It also writes/updates host-project **`AGENTS.md`** with MVFrame Codex rules, and copies **`/.cursor/rules/*.mdc`** from the package (same as this repo’s Cursor rules). Adds `index.html` and `vite.config.js` only if missing (use `--force` to overwrite). **Merges** `scripts` / `dependencies` / `devDependencies` into `package.json` (existing values win for shared keys), then runs **`yarn install`**; use `--no-package-json` to skip package changes and install. Then run **`yarn dev
|
|
207
|
+
From an **empty folder or existing Vite root**, generates `src/views`, `src/component`, `src/api`, `src/assets/img`, `src/assets/style`, `src/router`, `src/pinia/chip`, `src/config`, plus starter `main.js` / `App.vue` with `app.use(mvframe, …)` (routes, Pinia `storeChips`, config). It also writes/updates host-project **`AGENTS.md`** with MVFrame Codex rules, and copies **`/.cursor/rules/*.mdc`** from the package (same as this repo’s Cursor rules). Adds `index.html` and `vite.config.js` only if missing (use `--force` to overwrite). **Merges** `scripts` / `dependencies` / `devDependencies` into `package.json` (existing values win for shared keys), initializes `.env.mvframe-notify.example` / `.env.local.example` and `config.notify`, then runs **`yarn install`**; use `--no-package-json` to skip package changes and install. Then run **`yarn dev`** or explicitly run **`yarn exec mvframe-d`** to start Vite with the notify service.
|
|
167
208
|
|
|
168
209
|
```bash
|
|
169
210
|
cd /path/to/your-app
|
|
@@ -218,6 +259,15 @@ Default target is **`./.cursor/skills/mvframe-app-init`** under the current work
|
|
|
218
259
|
|
|
219
260
|
---
|
|
220
261
|
|
|
262
|
+
## Changelog
|
|
263
|
+
|
|
264
|
+
- Added `mvframe-notify`, a DingTalk-only local Node notification service.
|
|
265
|
+
- Added `mvframe/notify` and global `$notify` for browser calls through `config.notify`.
|
|
266
|
+
- Added framework command `yarn d` / `mvframe-d` to run `yarn dev` with the notify service.
|
|
267
|
+
- `mvframe-init-app` now initializes `config.notify`, `.env.mvframe-notify` / `.env.mvframe-notify.example` with the MVFrame test DingTalk robot, and `.env.local.example` without forcing host `d` scripts.
|
|
268
|
+
|
|
269
|
+
---
|
|
270
|
+
|
|
221
271
|
## License
|
|
222
272
|
|
|
223
273
|
ISC (see `package.json`).
|
package/dist/index.js
CHANGED
|
@@ -1,17 +1,18 @@
|
|
|
1
1
|
import "./util.js";
|
|
2
2
|
import "./directive.js";
|
|
3
3
|
import "./store-shared.js";
|
|
4
|
-
import { j as
|
|
4
|
+
import { j as o, k as r, g as n, a as g, m as l, b as u, c as L, n as M, p as c, u as b } from "./vendor.js";
|
|
5
|
+
import "./notify.js";
|
|
5
6
|
import "./composition.js";
|
|
6
7
|
export {
|
|
7
|
-
|
|
8
|
-
|
|
8
|
+
o as builtinLocales,
|
|
9
|
+
r as default,
|
|
9
10
|
n as getBuiltinLangMaps,
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
11
|
+
g as getMaps,
|
|
12
|
+
l as mapLang,
|
|
13
|
+
u as mapLangPath,
|
|
14
|
+
L as mergeMaps,
|
|
15
|
+
M as normalizeBuiltinLocale,
|
|
16
|
+
c as patchMaps,
|
|
17
|
+
b as useMap
|
|
17
18
|
};
|
package/dist/notify.js
ADDED
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
const y = {
|
|
2
|
+
endpoint: "",
|
|
3
|
+
path: "/notify",
|
|
4
|
+
token: "",
|
|
5
|
+
timeout: 5e3
|
|
6
|
+
};
|
|
7
|
+
function d(n) {
|
|
8
|
+
return String(n || "").replace(/\/+$/, "");
|
|
9
|
+
}
|
|
10
|
+
function m(n) {
|
|
11
|
+
const t = String(n || "/notify");
|
|
12
|
+
return t.startsWith("/") ? t : `/${t}`;
|
|
13
|
+
}
|
|
14
|
+
function p(n = {}) {
|
|
15
|
+
var t;
|
|
16
|
+
return {
|
|
17
|
+
...y,
|
|
18
|
+
...((t = globalThis.$config) == null ? void 0 : t.notify) || {},
|
|
19
|
+
...n || {}
|
|
20
|
+
};
|
|
21
|
+
}
|
|
22
|
+
function l(n = {}) {
|
|
23
|
+
const t = async (s, r = {}) => {
|
|
24
|
+
var f;
|
|
25
|
+
const o = p({
|
|
26
|
+
...n,
|
|
27
|
+
...r.config || {}
|
|
28
|
+
});
|
|
29
|
+
if (o.enabled === !1)
|
|
30
|
+
return {
|
|
31
|
+
ok: !0,
|
|
32
|
+
skipped: !0,
|
|
33
|
+
message: "notify disabled"
|
|
34
|
+
};
|
|
35
|
+
if (!o.endpoint)
|
|
36
|
+
throw new Error("missing notify.endpoint");
|
|
37
|
+
const c = new AbortController(), g = Number(o.timeout || 5e3), u = setTimeout(() => c.abort(), g);
|
|
38
|
+
try {
|
|
39
|
+
const i = await fetch(`${d(o.endpoint)}${m(o.path)}`, {
|
|
40
|
+
method: "POST",
|
|
41
|
+
headers: {
|
|
42
|
+
"Content-Type": "application/json",
|
|
43
|
+
...o.token ? { "x-mvframe-notify-token": o.token } : {}
|
|
44
|
+
},
|
|
45
|
+
body: JSON.stringify({
|
|
46
|
+
message: s,
|
|
47
|
+
atMobiles: r.atMobiles,
|
|
48
|
+
atUserIds: r.atUserIds,
|
|
49
|
+
atAll: r.atAll
|
|
50
|
+
}),
|
|
51
|
+
signal: c.signal
|
|
52
|
+
}), e = (i.headers.get("content-type") || "").includes("application/json") ? await i.json() : { message: await i.text() };
|
|
53
|
+
if (!i.ok || (e == null ? void 0 : e.ok) === !1) {
|
|
54
|
+
const a = new Error((e == null ? void 0 : e.message) || ((f = e == null ? void 0 : e.push) == null ? void 0 : f.message) || "notify failed");
|
|
55
|
+
throw a.response = i, a.payload = e, a;
|
|
56
|
+
}
|
|
57
|
+
return e;
|
|
58
|
+
} finally {
|
|
59
|
+
clearTimeout(u);
|
|
60
|
+
}
|
|
61
|
+
};
|
|
62
|
+
return {
|
|
63
|
+
send: t,
|
|
64
|
+
ding: t,
|
|
65
|
+
dingtalk: t
|
|
66
|
+
};
|
|
67
|
+
}
|
|
68
|
+
async function b(n, t) {
|
|
69
|
+
return l().send(n, t);
|
|
70
|
+
}
|
|
71
|
+
const T = (n, t = {}) => {
|
|
72
|
+
const s = l(t);
|
|
73
|
+
n.config.globalProperties.$notify = s, globalThis.$notify = s;
|
|
74
|
+
};
|
|
75
|
+
export {
|
|
76
|
+
l as createNotifyClient,
|
|
77
|
+
T as default,
|
|
78
|
+
p as getNotifyConfig,
|
|
79
|
+
b as notify
|
|
80
|
+
};
|