dlzn-ui 2.0.26 → 2.0.28
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/chunks/{AssignUser-B8KO6qit.mjs → AssignUser-DZvNJ6_v.mjs} +2 -2
- package/chunks/{DictTypeDetail-DDv2c9JG.mjs → DictTypeDetail--OE6JJ5s.mjs} +1 -1
- package/chunks/{Log-CPni6oj5.mjs → Log-DTQeRVz1.mjs} +1 -1
- package/chunks/{SelectUser-Ce69wfaR.mjs → SelectUser-Y-2MCvw3.mjs} +1 -1
- package/chunks/{custom-page-list-DNONwY-V.mjs → custom-page-list-Dkjf1nLR.mjs} +2 -2
- package/chunks/{page-list-DMDDWHTe.mjs → page-list-DUYDkWcj.mjs} +4 -4
- package/chunks/{page-query-CRbcQbQW.mjs → page-query-oFiHpSCX.mjs} +9 -6
- package/components/custom-page-list/index.mjs +1 -1
- package/components/custom-page-list/src/custom-page-list.mjs +1 -1
- package/components/index.mjs +3 -3
- package/components/page-list/index.mjs +1 -1
- package/components/page-list/src/page-list.d.ts +1 -1
- package/components/page-list/src/page-list.mjs +1 -1
- package/components/page-query/index.mjs +1 -1
- package/components/page-query/src/page-query.mjs +1 -1
- package/components/page-query/src/page-query.vue.d.ts +2 -2
- package/components/select-sys-user/src/Picker.mjs +1 -1
- package/package.json +1 -1
- package/proj-template/.cursor/skills/refactor-page-list/SKILL.md +314 -0
- package/proj-template/.cursor/skills/refactor-page-list/examples.md +261 -0
- package/proj-template/.vscode/settings.json +1 -0
- package/views/index.mjs +4 -0
- package/views/monitor/logininfor/index.mjs +151 -0
- package/views/monitor/logininfor/index.vue.d.ts +3 -0
- package/views/monitor/operlog/index.mjs +231 -0
- package/views/monitor/operlog/index.vue.d.ts +3 -0
- package/views/system/config/index.mjs +192 -0
- package/views/system/config/index.vue.d.ts +3 -0
- package/views/system/dept/index.mjs +1 -1
- package/views/system/dict/index.mjs +2 -2
- package/views/system/dict/modules/DictTypeDetail.mjs +1 -1
- package/views/system/menu/index.mjs +1 -1
- package/views/system/notice/index.mjs +151 -0
- package/views/system/notice/index.vue.d.ts +3 -0
- package/views/system/post/index.mjs +1 -1
- package/views/system/role/index.mjs +2 -2
- package/views/system/role/modules/AssignUser.mjs +1 -1
- package/views/system/role/modules/SelectUser.mjs +1 -1
- package/views/system/user/index.mjs +1 -1
- package/views/tool/job/index.mjs +2 -2
- package/views/tool/job/modules/Log.mjs +1 -1
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import { F as e, S as t } from "./provider-BhFm5rvy.mjs";
|
|
2
2
|
import n from "../plugins/autoImport/$msg/index.mjs";
|
|
3
|
-
import { t as r } from "./page-list-
|
|
3
|
+
import { t as r } from "./page-list-DUYDkWcj.mjs";
|
|
4
4
|
import "../components/page-list/index.mjs";
|
|
5
|
-
import { t as i } from "./SelectUser-
|
|
5
|
+
import { t as i } from "./SelectUser-Y-2MCvw3.mjs";
|
|
6
6
|
import { computed as a, createBlock as o, defineComponent as s, h as c, mergeProps as l, openBlock as u, reactive as d, ref as f, unref as p, useTemplateRef as m } from "vue";
|
|
7
7
|
//#endregion
|
|
8
8
|
//#region ../../packages/dlzn-ui/views/system/role/modules/AssignUser.vue
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { F as e, S as t, o as n } from "./provider-BhFm5rvy.mjs";
|
|
2
2
|
import r from "../plugins/autoImport/$msg/index.mjs";
|
|
3
|
-
import { t as i } from "./page-list-
|
|
3
|
+
import { t as i } from "./page-list-DUYDkWcj.mjs";
|
|
4
4
|
import "../components/page-list/index.mjs";
|
|
5
5
|
import { createBlock as a, defineComponent as o, h as s, mergeProps as c, openBlock as l, reactive as u, ref as d, unref as f, useTemplateRef as p, watch as m } from "vue";
|
|
6
6
|
//#endregion
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { F as e, S as t, o as n } from "./provider-BhFm5rvy.mjs";
|
|
2
2
|
import r from "../plugins/autoImport/$msg/index.mjs";
|
|
3
|
-
import { t as i } from "./page-list-
|
|
3
|
+
import { t as i } from "./page-list-DUYDkWcj.mjs";
|
|
4
4
|
import "../components/page-list/index.mjs";
|
|
5
5
|
import { computed as a, createBlock as o, defineComponent as s, h as c, mergeProps as l, nextTick as u, openBlock as d, reactive as f, ref as p, unref as m, useTemplateRef as h, watch as g } from "vue";
|
|
6
6
|
import { useRequest as _ } from "alova/client";
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { S as e } from "./provider-BhFm5rvy.mjs";
|
|
2
2
|
import t from "../plugins/autoImport/$msg/index.mjs";
|
|
3
|
-
import { t as n } from "./page-list-
|
|
3
|
+
import { t as n } from "./page-list-DUYDkWcj.mjs";
|
|
4
4
|
import "../components/page-list/index.mjs";
|
|
5
5
|
import { createBlock as r, defineComponent as i, mergeProps as a, openBlock as o, unref as s, useTemplateRef as c } from "vue";
|
|
6
6
|
//#endregion
|
|
@@ -4,8 +4,8 @@ import { t as n } from "./card-Domqu1Hz.mjs";
|
|
|
4
4
|
import "../components/card/index.mjs";
|
|
5
5
|
import { t as r } from "./custom-page-table-y7emjJnS.mjs";
|
|
6
6
|
import "../components/custom-page-table/index.mjs";
|
|
7
|
-
import { n as i, r as a } from "./page-list-
|
|
8
|
-
import { t as o } from "./page-query-
|
|
7
|
+
import { n as i, r as a } from "./page-list-DUYDkWcj.mjs";
|
|
8
|
+
import { t as o } from "./page-query-oFiHpSCX.mjs";
|
|
9
9
|
import "../components/page-query/index.mjs";
|
|
10
10
|
import "../components/page-list/index.mjs";
|
|
11
11
|
import { Fragment as s, createBlock as c, createCommentVNode as l, createElementBlock as u, createElementVNode as d, createSlots as f, createVNode as p, defineComponent as m, guardReactiveProps as h, mergeDefaults as g, mergeProps as _, normalizeProps as v, openBlock as y, renderList as b, renderSlot as x, unref as S, useTemplateRef as C, withCtx as w } from "vue";
|
|
@@ -6,7 +6,7 @@ import { t as a } from "./card-Domqu1Hz.mjs";
|
|
|
6
6
|
import "../components/card/index.mjs";
|
|
7
7
|
import { t as o } from "./page-table-C1hMMXID.mjs";
|
|
8
8
|
import "../components/page-table/index.mjs";
|
|
9
|
-
import { t as s } from "./page-query-
|
|
9
|
+
import { t as s } from "./page-query-oFiHpSCX.mjs";
|
|
10
10
|
import "../components/page-query/index.mjs";
|
|
11
11
|
import { Fragment as c, computed as l, createBlock as u, createCommentVNode as d, createElementBlock as f, createSlots as p, createVNode as m, defineComponent as h, guardReactiveProps as g, mergeDefaults as _, mergeProps as v, nextTick as y, normalizeProps as b, openBlock as x, ref as S, renderList as C, renderSlot as w, unref as T, useTemplateRef as E, withCtx as D } from "vue";
|
|
12
12
|
import { cloneDeep as O } from "lodash-es";
|
|
@@ -16,13 +16,13 @@ var A = { isFirstQueryByParent: !1 };
|
|
|
16
16
|
function j({ pageQueryRef: t, pageTableRef: n, props: r, route: a }) {
|
|
17
17
|
let o = S({});
|
|
18
18
|
function s() {
|
|
19
|
-
t.value === null ? (o.value = {}, n.value.query(
|
|
19
|
+
t.value === null ? (o.value = {}, n.value.query()) : t.value.query();
|
|
20
20
|
}
|
|
21
21
|
function c() {
|
|
22
22
|
t.value === null ? (o.value = {}, n.value.reset()) : t.value.reset();
|
|
23
23
|
}
|
|
24
|
-
function u(e) {
|
|
25
|
-
o.value = O(e), n.value.query(
|
|
24
|
+
function u(e, t) {
|
|
25
|
+
o.value = O(e), n.value.query(t);
|
|
26
26
|
}
|
|
27
27
|
function d(e) {
|
|
28
28
|
o.value = O(e), n.value.reset();
|
|
@@ -62,12 +62,15 @@ var D = /* @__PURE__ */ l({
|
|
|
62
62
|
}
|
|
63
63
|
S([N, () => A.value.length], I);
|
|
64
64
|
function L() {
|
|
65
|
-
O("query", k.value);
|
|
65
|
+
O("query", k.value, !1);
|
|
66
66
|
}
|
|
67
67
|
function R() {
|
|
68
|
-
|
|
68
|
+
O("query", k.value, !0);
|
|
69
69
|
}
|
|
70
70
|
function z() {
|
|
71
|
+
B(), O("reset", k.value);
|
|
72
|
+
}
|
|
73
|
+
function B() {
|
|
71
74
|
Object.keys(k.value).forEach((e) => {
|
|
72
75
|
if (Object.hasOwn(D.data, e)) {
|
|
73
76
|
k.value[e] = D.data[e];
|
|
@@ -79,8 +82,8 @@ var D = /* @__PURE__ */ l({
|
|
|
79
82
|
return l({
|
|
80
83
|
formData: k,
|
|
81
84
|
query: L,
|
|
82
|
-
reset:
|
|
83
|
-
resetFormData:
|
|
85
|
+
reset: z,
|
|
86
|
+
resetFormData: B
|
|
84
87
|
}), (e, r) => (h(), i(b(n), f({
|
|
85
88
|
ref_key: "formRef",
|
|
86
89
|
ref: M,
|
|
@@ -90,7 +93,7 @@ var D = /* @__PURE__ */ l({
|
|
|
90
93
|
_btn: C(() => [
|
|
91
94
|
c(b(t), {
|
|
92
95
|
class: "shrink",
|
|
93
|
-
onClick:
|
|
96
|
+
onClick: R
|
|
94
97
|
}, {
|
|
95
98
|
default: C(() => [...r[1] ||= [s("查询", -1)]]),
|
|
96
99
|
_: 1
|
|
@@ -98,7 +101,7 @@ var D = /* @__PURE__ */ l({
|
|
|
98
101
|
c(b(t), {
|
|
99
102
|
class: "shrink",
|
|
100
103
|
theme: "default",
|
|
101
|
-
onClick:
|
|
104
|
+
onClick: z
|
|
102
105
|
}, {
|
|
103
106
|
default: C(() => [...r[2] ||= [s("重置", -1)]]),
|
|
104
107
|
_: 1
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import { t as e } from "../../chunks/custom-page-list-
|
|
1
|
+
import { t as e } from "../../chunks/custom-page-list-Dkjf1nLR.mjs";
|
|
2
2
|
export { e as TCustomPageList };
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import { t as e } from "../../../chunks/custom-page-list-
|
|
1
|
+
import { t as e } from "../../../chunks/custom-page-list-Dkjf1nLR.mjs";
|
|
2
2
|
export { e as default };
|
package/components/index.mjs
CHANGED
|
@@ -45,11 +45,11 @@ import "./table/index.mjs";
|
|
|
45
45
|
import "./page-table/index.mjs";
|
|
46
46
|
import { t as Z } from "../chunks/custom-page-table-y7emjJnS.mjs";
|
|
47
47
|
import "./custom-page-table/index.mjs";
|
|
48
|
-
import { n as Q, r as $, t as ee } from "../chunks/page-list-
|
|
49
|
-
import { t as te } from "../chunks/page-query-
|
|
48
|
+
import { n as Q, r as $, t as ee } from "../chunks/page-list-DUYDkWcj.mjs";
|
|
49
|
+
import { t as te } from "../chunks/page-query-oFiHpSCX.mjs";
|
|
50
50
|
import "./page-query/index.mjs";
|
|
51
51
|
import "./page-list/index.mjs";
|
|
52
|
-
import { t as ne } from "../chunks/custom-page-list-
|
|
52
|
+
import { t as ne } from "../chunks/custom-page-list-Dkjf1nLR.mjs";
|
|
53
53
|
import "./custom-page-list/index.mjs";
|
|
54
54
|
import { t as re } from "../chunks/overview-BvLGalk-.mjs";
|
|
55
55
|
import { t as ie } from "../chunks/overview-YqvRmr0O.mjs";
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import { n as e, r as t, t as n } from "../../chunks/page-list-
|
|
1
|
+
import { n as e, r as t, t as n } from "../../chunks/page-list-DUYDkWcj.mjs";
|
|
2
2
|
export { n as TPageList, e as baseCustomPageListPropsInit, t as useBaseCustomPageListMixin };
|
|
@@ -1411,7 +1411,7 @@ export declare function useBaseCustomPageListMixin({ pageQueryRef, pageTableRef,
|
|
|
1411
1411
|
_help?: string | ((h: typeof import('vue').h) => import('tdesign-vue-next').TNodeReturnValue) | undefined;
|
|
1412
1412
|
})[]>;
|
|
1413
1413
|
finallyQueryParams: import('vue').ComputedRef<Record<string, any> | undefined>;
|
|
1414
|
-
onQuery: (formData: Record<string, any
|
|
1414
|
+
onQuery: (formData: Record<string, any>, isClick: boolean) => void;
|
|
1415
1415
|
onReset: (formData: Record<string, any>) => void;
|
|
1416
1416
|
queryParams: Ref<Record<string, any>, Record<string, any>>;
|
|
1417
1417
|
resetCurrentQueryParams: () => void;
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import { t as e } from "../../../chunks/page-list-
|
|
1
|
+
import { t as e } from "../../../chunks/page-list-DUYDkWcj.mjs";
|
|
2
2
|
export { e as default };
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import { t as e } from "../../chunks/page-query-
|
|
1
|
+
import { t as e } from "../../chunks/page-query-oFiHpSCX.mjs";
|
|
2
2
|
export { e as TPageQuery };
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import { t as e } from "../../../chunks/page-query-
|
|
1
|
+
import { t as e } from "../../../chunks/page-query-oFiHpSCX.mjs";
|
|
2
2
|
export { e as default };
|
|
@@ -13,10 +13,10 @@ declare const __VLS_base: import('vue').DefineComponent<FormProps, {
|
|
|
13
13
|
resetFormData: typeof resetFormData;
|
|
14
14
|
}, {}, {}, {}, import('vue').ComponentOptionsMixin, import('vue').ComponentOptionsMixin, {
|
|
15
15
|
reset: (formData: Record<string, any>) => any;
|
|
16
|
-
query: (formData: Record<string, any
|
|
16
|
+
query: (formData: Record<string, any>, isClick: boolean) => any;
|
|
17
17
|
}, string, import('vue').PublicProps, Readonly<FormProps> & Readonly<{
|
|
18
18
|
onReset?: ((formData: Record<string, any>) => any) | undefined;
|
|
19
|
-
onQuery?: ((formData: Record<string, any
|
|
19
|
+
onQuery?: ((formData: Record<string, any>, isClick: boolean) => any) | undefined;
|
|
20
20
|
}>, {
|
|
21
21
|
data: import('../../form').FormPropsData;
|
|
22
22
|
disabled: boolean;
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { S as e } from "../../../chunks/provider-BhFm5rvy.mjs";
|
|
2
|
-
import { t } from "../../../chunks/page-list-
|
|
2
|
+
import { t } from "../../../chunks/page-list-DUYDkWcj.mjs";
|
|
3
3
|
import "../../page-list/index.mjs";
|
|
4
4
|
import { createBlock as n, createSlots as r, createVNode as i, defineComponent as a, mergeProps as o, openBlock as s, unref as c, useTemplateRef as l, withCtx as u } from "vue";
|
|
5
5
|
import { Alert as d } from "tdesign-vue-next";
|
package/package.json
CHANGED
|
@@ -0,0 +1,314 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: refactor-page-list
|
|
3
|
+
description: >-
|
|
4
|
+
将 yq-monitor-front 的 CPageList 列表页重构到 qc-ui 的 TPageList 模式。
|
|
5
|
+
用于页面迁移、列表页重构、CPageList 转 TPageList、yq-monitor-front 到 qc-ui 的 views 迁移。
|
|
6
|
+
---
|
|
7
|
+
|
|
8
|
+
# PageList 页面重构(yq-monitor-front → qc-ui)
|
|
9
|
+
|
|
10
|
+
## 项目约定
|
|
11
|
+
|
|
12
|
+
| 角色 | 路径 | 说明 |
|
|
13
|
+
|------|------|------|
|
|
14
|
+
| 原项目 | `e:\code\yq-monitor-front` | 业务行为基准,不做重构性改动 |
|
|
15
|
+
| 目标项目 | `e:\code\qc-ui` | 迁移落地目录,保持 `src/views/...` 路径一致 |
|
|
16
|
+
|
|
17
|
+
路由由后端菜单驱动,组件路径如 `system/config/index` 映射到 `qc-ui/src/views/system/config/index.vue`(`src/views/index.ts` glob),**无需手动注册路由**。
|
|
18
|
+
|
|
19
|
+
## 实现方式选择
|
|
20
|
+
|
|
21
|
+
迁移前先确认实现位置:
|
|
22
|
+
|
|
23
|
+
| 场景 | 做法 | 参考 |
|
|
24
|
+
|------|------|------|
|
|
25
|
+
| 通用系统模块(user/role/dict/post)且 dlzn-ui 已有 | qc-ui 薄封装,引用 `dlzn-ui/views/system/...` | `src/views/system/user/index.vue` |
|
|
26
|
+
| 通用系统模块但 dlzn-ui 尚无 | 在 qc-ui 内完整实现(默认) | `src/views/system/config/index.vue` |
|
|
27
|
+
| 舆情业务页(yq/* API) | 在 qc-ui 内完整实现 | `src/views/system/wbTaskCfg/index.vue` |
|
|
28
|
+
|
|
29
|
+
用户未指定时,**默认在 qc-ui 内完整实现**。
|
|
30
|
+
|
|
31
|
+
## 迁移工作流
|
|
32
|
+
|
|
33
|
+
```
|
|
34
|
+
Task Progress:
|
|
35
|
+
- [ ] 1. 读取原项目页面及 modules/PageListItemForm.vue(如有)
|
|
36
|
+
- [ ] 2. 读取原项目 `@/api/*.ts` 中**每个**接口的 `method`(未写则默认为 `get`,见 yq-monitor-front `$api`)
|
|
37
|
+
- [ ] 3. 在 qc-ui 同路径创建 index.vue
|
|
38
|
+
- [ ] 4. 按映射表转换配置
|
|
39
|
+
- [ ] 5. 内联新增/编辑表单(不迁移 PageListItemForm)
|
|
40
|
+
- [ ] 6. 对**本次修改的文件**执行 `pnpm eslint <路径>` 与 `pnpm vue-tsc --noEmit`,确认无 ESLint/TS 报错后再结束
|
|
41
|
+
```
|
|
42
|
+
|
|
43
|
+
### Step 1:分析原页面
|
|
44
|
+
|
|
45
|
+
原项目典型结构:
|
|
46
|
+
|
|
47
|
+
- `CPageList` + `config.urls`(list/delete/export)
|
|
48
|
+
- `config.formItems` + `config.columns`(vxe-table 字段名 `field`)
|
|
49
|
+
- `config.btns` 自定义操作
|
|
50
|
+
- `modules/PageListItemForm.vue` 负责新增/编辑
|
|
51
|
+
|
|
52
|
+
### Step 2:建立 formItemMap
|
|
53
|
+
|
|
54
|
+
将所有表单字段(筛选 + 弹窗)集中到 `formItemMap`:
|
|
55
|
+
|
|
56
|
+
```typescript
|
|
57
|
+
const formItemMap = {
|
|
58
|
+
fieldName: {
|
|
59
|
+
_label: '标签',
|
|
60
|
+
_required: true, // 弹窗必填
|
|
61
|
+
component: 'TInput', // 见组件映射表
|
|
62
|
+
model: 'fieldName',
|
|
63
|
+
dicCode: 'dict_code', // 字典字段
|
|
64
|
+
},
|
|
65
|
+
dateRange: {
|
|
66
|
+
_class: 'col-span-2', // 仅用于 TPageList 筛选区;vertical TForm 不加
|
|
67
|
+
_label: '创建时间',
|
|
68
|
+
component: 'TDatePicker',
|
|
69
|
+
model: 'dateRange',
|
|
70
|
+
type: 'daterange',
|
|
71
|
+
},
|
|
72
|
+
} satisfies Record<string, FormItem>
|
|
73
|
+
```
|
|
74
|
+
|
|
75
|
+
筛选用 `TSelect`,弹窗用 `TRadioGroup` 时,通过展开覆盖 component:
|
|
76
|
+
|
|
77
|
+
`formItemMap` 若同时用于筛选区和 vertical 弹窗,详情专用字段不要带 `_class: 'col-span-2'`;或弹窗 items 里单独定义不带 `_class` 的项。
|
|
78
|
+
|
|
79
|
+
```typescript
|
|
80
|
+
formItems: [{ ...formItemMap.status, component: 'TSelect' }]
|
|
81
|
+
// 弹窗内: { ...formItemMap.status, component: 'TRadioGroup' }
|
|
82
|
+
```
|
|
83
|
+
|
|
84
|
+
### Step 3:配置 PageListProps
|
|
85
|
+
|
|
86
|
+
```typescript
|
|
87
|
+
const pageListRef = useTemplateRef('pageListRef')
|
|
88
|
+
const config: PageListProps = {
|
|
89
|
+
apis: { /* 见 API 映射 */ },
|
|
90
|
+
columns: [ /* 见列映射 */ ],
|
|
91
|
+
formItems: [ /* 筛选项 */ ],
|
|
92
|
+
operations: [ /* 新增、刷新缓存等 */ ],
|
|
93
|
+
tableOtherProps: { rowKey: '主键字段' },
|
|
94
|
+
}
|
|
95
|
+
```
|
|
96
|
+
|
|
97
|
+
### Step 4:内联新增/编辑
|
|
98
|
+
|
|
99
|
+
**不要**迁移 `PageListItemForm.vue`,改用 `$confirm` + `h(TForm, ...)`:
|
|
100
|
+
|
|
101
|
+
```typescript
|
|
102
|
+
// 编辑
|
|
103
|
+
const formRef = ref<FormInstance | null>(null)
|
|
104
|
+
watch(formRef, () => { formRef.value!.setFormData(row) }, { once: true })
|
|
105
|
+
$confirm({
|
|
106
|
+
body: () => h(TForm, { items: [...], labelAlign: 'right', layout: 'vertical', ref: formRef }),
|
|
107
|
+
header: '修改xxx',
|
|
108
|
+
width: 460,
|
|
109
|
+
onConfirmCallback: async () => {
|
|
110
|
+
await $alova.Put('module/path', { ...(await formRef.value!.validate()), id: row.id })
|
|
111
|
+
$msg.success('修改成功')
|
|
112
|
+
pageListRef.value!.query()
|
|
113
|
+
},
|
|
114
|
+
})
|
|
115
|
+
|
|
116
|
+
// 新增
|
|
117
|
+
$confirm({
|
|
118
|
+
body: () => h(TForm, {
|
|
119
|
+
data: reactive({ status: '0' }), // 默认值
|
|
120
|
+
items: [...],
|
|
121
|
+
ref: formRef,
|
|
122
|
+
}),
|
|
123
|
+
onConfirmCallback: async () => {
|
|
124
|
+
await $alova.Post('module/path', await formRef.value!.validate())
|
|
125
|
+
$msg.success('添加成功')
|
|
126
|
+
pageListRef.value!.query()
|
|
127
|
+
},
|
|
128
|
+
})
|
|
129
|
+
```
|
|
130
|
+
|
|
131
|
+
### Step 5:模板
|
|
132
|
+
|
|
133
|
+
```vue
|
|
134
|
+
<template>
|
|
135
|
+
<TPageList ref="pageListRef" v-bind="config"></TPageList>
|
|
136
|
+
</template>
|
|
137
|
+
```
|
|
138
|
+
|
|
139
|
+
## 映射表
|
|
140
|
+
|
|
141
|
+
### 组件映射
|
|
142
|
+
|
|
143
|
+
| 原项目 (C*) | 目标项目 (T*) | 说明 |
|
|
144
|
+
|-------------|---------------|------|
|
|
145
|
+
| `CInput` / 默认 | `TInput` | 文本 |
|
|
146
|
+
| `CSelect` | `TSelect` | 筛选下拉 |
|
|
147
|
+
| `CRadio` | `TRadioGroup` | 弹窗单选 |
|
|
148
|
+
| `CDate` type=daterange | `TDatePicker` type=daterange | 筛选表单加 `_class: 'col-span-2'`;`layout: 'vertical'` 的 TForm 不加 |
|
|
149
|
+
| textarea | `TTextarea` | 备注 |
|
|
150
|
+
| append slot | `adornment: { append: () => '单位' }` | TInput 后缀须用函数形式 |
|
|
151
|
+
| `c:dicLabel` | `{ component: 'DicLabel', dicCode }` | 表格字典列 |
|
|
152
|
+
| `c:btns` | `{ component: 'Buttons', buttons: [...] }` | 操作列 |
|
|
153
|
+
|
|
154
|
+
### API 映射
|
|
155
|
+
|
|
156
|
+
**迁移前必查原项目 api 定义**(`yq-monitor-front/src/api/system.ts` 或 `monitor.ts` 等)。原项目 `$api` 默认 `method = 'get'`,**未显式声明 method 的接口一律是 GET**,不能凭语义猜测(如 unlock 不是 DELETE)。
|
|
157
|
+
|
|
158
|
+
| 原 apiConfig | 目标调用 |
|
|
159
|
+
|--------------|----------|
|
|
160
|
+
| 无 `method` 或 `method` 省略 | `$alova.Get('...')` |
|
|
161
|
+
| `url: 'system/xxx/list'` | `apis.list.method: 'system/xxx/list'` 或 `$alova.Get` |
|
|
162
|
+
| `method: 'post'` | `$alova.Post('...', data)` |
|
|
163
|
+
| `method: 'put'` | `$alova.Put('...', data)` |
|
|
164
|
+
| `method: 'delete'` + `{id}` | `$alova.Delete('...')` 或 `apis.delete.method`(TPageList 自动拼接 id) |
|
|
165
|
+
| `responseType: 'blob'` 导出 | `apis.export.method: '.../export'`(POST) |
|
|
166
|
+
| `refreshCache` 且原定义为 delete | `$alova.Delete('.../refreshCache', ...)` |
|
|
167
|
+
| `unlock/{userName}` 且无 method | `$alova.Get('monitor/logininfor/unlock/${userName}', ...)` |
|
|
168
|
+
|
|
169
|
+
路径占位符 `{userName}`、`{id}` 在目标项目中通常拼进 URL 字符串,如 `` `monitor/logininfor/unlock/${row.userName}` ``。
|
|
170
|
+
|
|
171
|
+
**`$alova` 参数个数**(勿与 axios 混用;写完后对照项目内已有调用):
|
|
172
|
+
|
|
173
|
+
| 方法 | 签名 | 仅 meta / params 时 |
|
|
174
|
+
|------|------|---------------------|
|
|
175
|
+
| `Get` | `(url, config?)` | `$alova.Get(url, { meta: { useSuccessMsg: true } })` |
|
|
176
|
+
| `Post` | `(url, data?, config?)` | 无 body 时第二参可省略 |
|
|
177
|
+
| `Put` | `(url, data?, config?)` | |
|
|
178
|
+
| `Delete` | `(url, data?, config?)` | 无 body 时用 `$alova.Delete(url, undefined, { meta })` |
|
|
179
|
+
|
|
180
|
+
`Get` **只有两个参数**,不要把 `undefined` 插在中间;`params` 与 `meta` 同放在第二个 config 对象里。
|
|
181
|
+
|
|
182
|
+
**dateRange 参数转换**(list 与 export 共用 finallyQueryParams;`dateRange` 恒为数组,空数组时 `[0]`/`[1]` 为 `undefined` 可直接传递):
|
|
183
|
+
|
|
184
|
+
```typescript
|
|
185
|
+
list: {
|
|
186
|
+
method: (o: Record<string, any>) =>
|
|
187
|
+
$alova.Get('system/xxx/list', {
|
|
188
|
+
params: {
|
|
189
|
+
...o,
|
|
190
|
+
dateRange: undefined,
|
|
191
|
+
'params[beginTime]': o.dateRange[0],
|
|
192
|
+
'params[endTime]': o.dateRange[1],
|
|
193
|
+
},
|
|
194
|
+
}),
|
|
195
|
+
},
|
|
196
|
+
```
|
|
197
|
+
|
|
198
|
+
**批量删除**:原 `handleParams` 拼接 id → 目标设置 `showBatch: true` + `tableOtherProps.rowKey`。
|
|
199
|
+
|
|
200
|
+
### 列映射
|
|
201
|
+
|
|
202
|
+
| 原 columns | 目标 columns |
|
|
203
|
+
|------------|--------------|
|
|
204
|
+
| `field: 'xxx'` | `colKey: 'xxx'` |
|
|
205
|
+
| `title: 'xxx'` | `title: 'xxx'`(不变) |
|
|
206
|
+
| `type: 'checkbox'` | 由 `apis.delete.showBatch: true` 自动处理 |
|
|
207
|
+
| `field: 'c-action'` | `colKey: '_operation'` |
|
|
208
|
+
| 删除按钮 | 由 TPageList 根据 `apis.delete` 自动追加 |
|
|
209
|
+
| `field: 'remark'` / `title: '备注'` | 加 `resize: { maxWidth: 300 }`(内容可能很长) |
|
|
210
|
+
|
|
211
|
+
### 权限
|
|
212
|
+
|
|
213
|
+
原 `permission` 字段**原样保留**,如 `system:config:add/edit/remove/export`。
|
|
214
|
+
|
|
215
|
+
### 即时请求操作需 popconfirm
|
|
216
|
+
|
|
217
|
+
`operations` 中点击即发请求的操作(刷新缓存、同步、重置等),**必须**用 `popconfirm` 二次确认,不用 `onClick` 直接请求:
|
|
218
|
+
|
|
219
|
+
```typescript
|
|
220
|
+
{
|
|
221
|
+
default: '刷新缓存',
|
|
222
|
+
permission: 'system:config:remove',
|
|
223
|
+
popconfirm: {
|
|
224
|
+
content: '确定要刷新缓存吗?',
|
|
225
|
+
onConfirm: async () => {
|
|
226
|
+
await $alova.Delete('system/config/refreshCache', undefined, {
|
|
227
|
+
meta: { useSuccessMsg: true },
|
|
228
|
+
})
|
|
229
|
+
},
|
|
230
|
+
},
|
|
231
|
+
}
|
|
232
|
+
```
|
|
233
|
+
|
|
234
|
+
新增/编辑等打开弹窗的操作不需要 popconfirm。
|
|
235
|
+
|
|
236
|
+
### 只读详情弹窗($dialog)
|
|
237
|
+
|
|
238
|
+
原项目用旧式 `$dialog({ title, showCancel: false, confirmText: '关闭' }, Component)` 展示只读详情时,目标项目**直接用 `h(TForm, ...)` 内联**,与 `formItemMap` 共用,**不单独建 `modules/Detail.vue`**:
|
|
239
|
+
|
|
240
|
+
```typescript
|
|
241
|
+
onClick: () => {
|
|
242
|
+
const formRef = ref<FormInstance | null>(null)
|
|
243
|
+
|
|
244
|
+
watch(formRef, () => {
|
|
245
|
+
formRef.value!.setFormData(row, {
|
|
246
|
+
override: {
|
|
247
|
+
loginInfo: `${row.operName}/${row.operIp}/${row.operLocation}`,
|
|
248
|
+
},
|
|
249
|
+
})
|
|
250
|
+
}, { once: true })
|
|
251
|
+
|
|
252
|
+
$dialog({
|
|
253
|
+
body: () =>
|
|
254
|
+
h(TForm, {
|
|
255
|
+
items: [formItemMap.title, formItemMap.businessType, /* ... */],
|
|
256
|
+
labelAlign: 'right',
|
|
257
|
+
layout: 'vertical',
|
|
258
|
+
readonly: true,
|
|
259
|
+
ref: formRef,
|
|
260
|
+
}),
|
|
261
|
+
cancelBtn: '关闭',
|
|
262
|
+
confirmBtn: null,
|
|
263
|
+
header: '操作日志详细',
|
|
264
|
+
width: 700,
|
|
265
|
+
})
|
|
266
|
+
}
|
|
267
|
+
```
|
|
268
|
+
|
|
269
|
+
- 用 `cancelBtn: '关闭'` + `confirmBtn: null` 实现仅关闭按钮,**不要用** `footer: false`
|
|
270
|
+
- 详情字段并入 `formItemMap`,筛选与详情共用;用 `setFormData(row)` 赋值,字段转换走 `override`,避免手写 `row.xxx`(Select 等组件内部已处理 number/string,无需 `numberToStringKeys`)
|
|
271
|
+
- `items` 直接内联,无复用时不在函数体内单独声明变量
|
|
272
|
+
- `layout: 'vertical'` 的 TForm 不是 grid 布局,其 `items` 上**不要**写 `_class: 'col-span-2'`(筛选区 inline 表单仍可用)
|
|
273
|
+
- 对应原项目 `showCancel: false` + `confirmText: '关闭'`
|
|
274
|
+
|
|
275
|
+
### 字典
|
|
276
|
+
|
|
277
|
+
| 原项目 | 目标项目 |
|
|
278
|
+
|--------|----------|
|
|
279
|
+
| `$dicStore('sys_yes_no')` | `dicCode: 'sys_yes_no'` |
|
|
280
|
+
|
|
281
|
+
## 不在迁移范围
|
|
282
|
+
|
|
283
|
+
- 不修改 yq-monitor-front
|
|
284
|
+
- 不创建 `modules/PageListItemForm.vue`
|
|
285
|
+
- 不新增 `src/api/*.ts`(qc-ui 无独立 API 层)
|
|
286
|
+
- 不修改 `folder-alias.json`(通常已有描述)
|
|
287
|
+
- 不遗留调试代码(如 `console.log`)
|
|
288
|
+
|
|
289
|
+
## 参考文件
|
|
290
|
+
|
|
291
|
+
| 用途 | 路径 |
|
|
292
|
+
|------|------|
|
|
293
|
+
| 迁移成果示例 | `qc-ui/src/views/system/config/index.vue` |
|
|
294
|
+
| 原项目示例 | `yq-monitor-front/src/views/system/config/index.vue` |
|
|
295
|
+
| 业务页参考 | `qc-ui/src/views/system/wbTaskCfg/index.vue` |
|
|
296
|
+
| 系统页参考(dlzn-ui) | `dlzn-ui/packages/dlzn-ui/views/system/post/index.vue` |
|
|
297
|
+
| 含 dateRange + 刷新缓存 | `dlzn-ui/packages/dlzn-ui/views/system/dict/index.vue` |
|
|
298
|
+
| 只读详情弹窗 | `qc-ui/src/views/monitor/operlog/index.vue` |
|
|
299
|
+
|
|
300
|
+
更多 before/after 片段见 [examples.md](examples.md)。
|
|
301
|
+
|
|
302
|
+
## 验证清单
|
|
303
|
+
|
|
304
|
+
- [ ] 路径与原项目一致(`src/views/.../index.vue`)
|
|
305
|
+
- [ ] 筛选、分页列表正常
|
|
306
|
+
- [ ] 新增、编辑、单删、批量删、导出
|
|
307
|
+
- [ ] 自定义 operations(如刷新缓存)
|
|
308
|
+
- [ ] 权限码与后端一致
|
|
309
|
+
- [ ] 每个非 CRUD 操作(unlock、clean、refreshCache 等)的 HTTP 方法已与原 `@/api` 定义逐项核对
|
|
310
|
+
- [ ] 无路由组件缺失报错
|
|
311
|
+
- [ ] 修改文件 ESLint 通过(`pnpm eslint <文件路径>`)
|
|
312
|
+
- [ ] 修改文件 TS 通过(`pnpm vue-tsc --noEmit`,或至少无本次文件相关报错)
|
|
313
|
+
- [ ] `$alova.Get` 仅两参;带 meta 时写在第二参 config 对象内
|
|
314
|
+
- [ ] `formItemMap` 使用 `satisfies Record<string, FormItem>`;条件显示用 `__others`
|