@agile-team/wl-skills-kit 1.0.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 (112) hide show
  1. package/CHANGELOG.md +13 -0
  2. package/README.md +328 -0
  3. package/bin/wl-skills.js +104 -0
  4. package/files/.github/copilot-instructions.md +211 -0
  5. package/files/.github/docs/SYS_MENU_INFO.md +247 -0
  6. package/files/.github/docs/menu-sync-design.md +265 -0
  7. package/files/.github/docs/use-skill.md +379 -0
  8. package/files/.github/docs/wl-skills-kit.md +266 -0
  9. package/files/.github/skills/api-contract/SKILL.md +247 -0
  10. package/files/.github/skills/convention-extract/SKILL.md +355 -0
  11. package/files/.github/skills/menu-sync/SKILL.md +255 -0
  12. package/files/.github/skills/menu-sync/env/guide.md +73 -0
  13. package/files/.github/skills/page-codegen/SKILL.md +825 -0
  14. package/files/.github/skills/page-codegen/TPL-CHANGE-HISTORY.md +281 -0
  15. package/files/.github/skills/page-codegen/TPL-DETAIL-TABS.md +1112 -0
  16. package/files/.github/skills/page-codegen/TPL-DRIVEN.md +124 -0
  17. package/files/.github/skills/page-codegen/TPL-FORM-ROUTE.md +441 -0
  18. package/files/.github/skills/page-codegen/TPL-LIST.md +196 -0
  19. package/files/.github/skills/page-codegen/TPL-MASTER-DETAIL.md +153 -0
  20. package/files/.github/skills/page-codegen/TPL-OPERATION-STATION.md +442 -0
  21. package/files/.github/skills/page-codegen/TPL-RECORD-FORM.md +376 -0
  22. package/files/.github/skills/page-codegen/TPL-TREE-LIST.md +191 -0
  23. package/files/.github/skills/prototype-scan/SKILL.md +414 -0
  24. package/files/demo/README.md +44 -0
  25. package/files/demo/produce/aiflow/mmwr-customer-apply-add/api.md +54 -0
  26. package/files/demo/produce/aiflow/mmwr-customer-apply-add/data.ts +346 -0
  27. package/files/demo/produce/aiflow/mmwr-customer-apply-add/index.scss +1 -0
  28. package/files/demo/produce/aiflow/mmwr-customer-apply-add/index.vue +28 -0
  29. package/files/demo/produce/aiflow/mmwr-customer-apply-add-form/data.ts +115 -0
  30. package/files/demo/produce/aiflow/mmwr-customer-apply-add-form/index.scss +44 -0
  31. package/files/demo/produce/aiflow/mmwr-customer-apply-add-form/index.vue +43 -0
  32. package/files/demo/produce/aiflow/mmwr-customer-apply-change/data.ts +338 -0
  33. package/files/demo/produce/aiflow/mmwr-customer-apply-change/index.scss +1 -0
  34. package/files/demo/produce/aiflow/mmwr-customer-apply-change/index.vue +28 -0
  35. package/files/demo/produce/aiflow/mmwr-customer-apply-change-form/data.ts +115 -0
  36. package/files/demo/produce/aiflow/mmwr-customer-apply-change-form/index.scss +44 -0
  37. package/files/demo/produce/aiflow/mmwr-customer-apply-change-form/index.vue +43 -0
  38. package/files/demo/produce/aiflow/mmwr-customer-apply-change-history/data.ts +196 -0
  39. package/files/demo/produce/aiflow/mmwr-customer-apply-change-history/index.scss +150 -0
  40. package/files/demo/produce/aiflow/mmwr-customer-apply-change-history/index.vue +79 -0
  41. package/files/demo/produce/aiflow/mmwr-customer-archive/api.md +88 -0
  42. package/files/demo/produce/aiflow/mmwr-customer-archive/data.ts +601 -0
  43. package/files/demo/produce/aiflow/mmwr-customer-archive/index.scss +1 -0
  44. package/files/demo/produce/aiflow/mmwr-customer-archive/index.vue +64 -0
  45. package/files/demo/produce/aiflow/mmwr-customer-detail/api.md +67 -0
  46. package/files/demo/produce/aiflow/mmwr-customer-detail/data.ts +286 -0
  47. package/files/demo/produce/aiflow/mmwr-customer-detail/index.scss +139 -0
  48. package/files/demo/produce/aiflow/mmwr-customer-detail/index.vue +318 -0
  49. package/files/demo/produce/aiflow/mmwr-temp-customer-archive/api.md +98 -0
  50. package/files/demo/produce/aiflow/mmwr-temp-customer-archive/data.ts +543 -0
  51. package/files/demo/produce/aiflow/mmwr-temp-customer-archive/index.scss +1 -0
  52. package/files/demo/produce/aiflow/mmwr-temp-customer-archive/index.vue +52 -0
  53. package/files/demo/sale/demo/add-demo/data.ts +518 -0
  54. package/files/demo/sale/demo/add-demo/index.scss +207 -0
  55. package/files/demo/sale/demo/add-demo/index.vue +167 -0
  56. package/files/demo/sale/demo/billet-flame-cut-plan/data.ts +524 -0
  57. package/files/demo/sale/demo/billet-flame-cut-plan/index.scss +155 -0
  58. package/files/demo/sale/demo/billet-flame-cut-plan/index.vue +117 -0
  59. package/files/demo/sale/demo/domestic-trade-order/data.ts +308 -0
  60. package/files/demo/sale/demo/domestic-trade-order/index.scss +99 -0
  61. package/files/demo/sale/demo/domestic-trade-order/index.vue +77 -0
  62. package/files/demo/sale/demo/heat-batch-return/data.ts +367 -0
  63. package/files/demo/sale/demo/heat-batch-return/index.scss +100 -0
  64. package/files/demo/sale/demo/heat-batch-return/index.vue +170 -0
  65. package/files/demo/sale/demo/heat-batch-return/meltDialog.vue +320 -0
  66. package/files/demo/sale/demo/metallurgical-spec/data.ts +825 -0
  67. package/files/demo/sale/demo/metallurgical-spec/index.scss +264 -0
  68. package/files/demo/sale/demo/metallurgical-spec/index.vue +309 -0
  69. package/files/docs/jh-date-range.md +257 -0
  70. package/files/docs/jh-date.md +222 -0
  71. package/files/docs/jh-dept-picker.md +190 -0
  72. package/files/docs/jh-drag-row.md +590 -0
  73. package/files/docs/jh-file-upload.md +216 -0
  74. package/files/docs/jh-pagination.md +505 -0
  75. package/files/docs/jh-picker.md +218 -0
  76. package/files/docs/jh-select.md +148 -0
  77. package/files/docs/jh-text.md +248 -0
  78. package/files/docs/jh-user-picker.md +197 -0
  79. package/files/docs/page-query-hook-best-practices.md +362 -0
  80. package/files/docs/request.md +925 -0
  81. package/files/src/components/global/C_ParentView/index.vue +3 -0
  82. package/files/src/components/global/C_RightToolbar/index.vue +459 -0
  83. package/files/src/components/global/C_Splitter/index.vue +195 -0
  84. package/files/src/components/global/C_SvgIcon/index.vue +61 -0
  85. package/files/src/components/global/C_SvgIcon/svgicon.js +10 -0
  86. package/files/src/components/global/C_TagStatus/README.md +264 -0
  87. package/files/src/components/global/C_TagStatus/config.ts +192 -0
  88. package/files/src/components/global/C_TagStatus/index.vue +127 -0
  89. package/files/src/components/global/C_TagStatus/types.ts +64 -0
  90. package/files/src/components/global/C_Tree/README.md +153 -0
  91. package/files/src/components/global/C_Tree/index.scss +42 -0
  92. package/files/src/components/global/C_Tree/index.vue +119 -0
  93. package/files/src/components/global/C_Tree/types.ts +59 -0
  94. package/files/src/components/local/c_formModal/README.md +235 -0
  95. package/files/src/components/local/c_formModal/data.ts +95 -0
  96. package/files/src/components/local/c_formModal/index.scss +8 -0
  97. package/files/src/components/local/c_formModal/index.vue +107 -0
  98. package/files/src/components/local/c_formSections/README.md +496 -0
  99. package/files/src/components/local/c_formSections/data.ts +175 -0
  100. package/files/src/components/local/c_formSections/index.scss +280 -0
  101. package/files/src/components/local/c_formSections/index.vue +429 -0
  102. package/files/src/components/local/c_listModal/data.ts +41 -0
  103. package/files/src/components/local/c_listModal/index.vue +136 -0
  104. package/files/src/components/local/c_spliterTitle/index.scss +25 -0
  105. package/files/src/components/local/c_spliterTitle/index.vue +21 -0
  106. package/files/src/components/remote/AGGrid/README.md +530 -0
  107. package/files/src/components/remote/BaseForm/README.md +508 -0
  108. package/files/src/components/remote/BaseQuery/README.md +865 -0
  109. package/files/src/components/remote/BaseTable/README.md +941 -0
  110. package/files/src/components/remote/BaseToolbar/README.md +496 -0
  111. package/files/src/types/page.ts +24 -0
  112. package/package.json +31 -0
@@ -0,0 +1,543 @@
1
+ import {
2
+ AbstractPageQueryHook,
3
+ BaseQueryItemDesc,
4
+ ActionButtonDesc,
5
+ TableColumnDesc
6
+ } from "@/types/page";
7
+ import type { BaseFormItemDesc } from "@jhlc/common-core/src/components/form/common/type";
8
+ import { postAction } from "@jhlc/common-core/src/api/action";
9
+ import envConfig from "@jhlc/common-core/src/store/env-config";
10
+ import * as XLSX from "xlsx";
11
+ import { h, resolveComponent } from "vue";
12
+
13
+ /** 状态色块映射 */
14
+ const STATUS_TAG_MAP: Record<string, Record<string, string>> = {
15
+ convertStatus: { 已转化: "success", 未转化: "info" },
16
+ customerStatus: { 临时客户: "warning", 正式客户: "success" },
17
+ verifyStatus: { 已核实: "success", 未核实: "info" }
18
+ };
19
+ function renderStatusTag(row: any, field: string) {
20
+ const val = row[field];
21
+ const type = STATUS_TAG_MAP[field]?.[val];
22
+ if (type === undefined) return val;
23
+ return h(
24
+ resolveComponent("ElTag") as any,
25
+ { type, effect: "light", size: "small" },
26
+ () => val
27
+ );
28
+ }
29
+
30
+ export const API_CONFIG = {
31
+ list: "/sale/tempCustomerArchive/list",
32
+ remove: "/sale/tempCustomerArchive/remove",
33
+ getById: "/sale/tempCustomerArchive/getById",
34
+ save: "/sale/tempCustomerArchive/save",
35
+ update: "/sale/tempCustomerArchive/update",
36
+ convert: "/sale/tempCustomerArchive/convert",
37
+ cancel: "/sale/tempCustomerArchive/cancel",
38
+ claim: "/sale/tempCustomerArchive/claim",
39
+ assign: "/sale/tempCustomerArchive/assign",
40
+ recycle: "/sale/tempCustomerArchive/recycle",
41
+ returnBack: "/sale/tempCustomerArchive/return",
42
+ export: "/sale/tempCustomerArchive/export"
43
+ } as const;
44
+
45
+ /** Tab 类型 */
46
+ export type TabType = "temp" | "formal" | "pool";
47
+
48
+ const OPTS = {
49
+ customerStatus: [
50
+ { label: "临时客户", value: "临时客户" },
51
+ { label: "正式客户", value: "正式客户" }
52
+ ],
53
+ customerType: [
54
+ { label: "SYCSR001-交易客户", value: "SYCSR001-交易客户" },
55
+ { label: "SYCSR002-直采客户", value: "SYCSR002-直采客户" }
56
+ ],
57
+ useOrg: [
58
+ { label: "不锈鋼接單中心", value: "不锈鋼接單中心" },
59
+ {
60
+ label: "江阴华新特殊合金材料有限公司",
61
+ value: "江阴华新特殊合金材料有限公司"
62
+ },
63
+ { label: "採瞒管理中心", value: "採瞒管理中心" },
64
+ { label: "烟台华鑫再生资源有限公司", value: "烟台华鑫再生资源有限公司" }
65
+ ],
66
+ businessDept: [
67
+ { label: "業務管理處", value: "業務管理處" },
68
+ { label: "線材銷售部", value: "線材銷售部" },
69
+ { label: "無縫管銷售處", value: "無縫管銷售處" },
70
+ { label: "華南銷售科", value: "華南銷售科" },
71
+ { label: "汽車產業銷售科", value: "汽車產業銷售科" },
72
+ { label: "大陸行銷部", value: "大陸行銷部" },
73
+ { label: "冷精棒業管部(台北)", value: "冷精棒業管部(台北)" },
74
+ { label: "業管科", value: "業管科" },
75
+ { label: "華東銷售科", value: "華東銷售科" }
76
+ ],
77
+ applicant: [
78
+ { label: "魏子明", value: "魏子明" },
79
+ { label: "龚辉鉴", value: "龚辉鉴" },
80
+ { label: "宋书迪", value: "宋书迪" },
81
+ { label: "李锋", value: "李锋" },
82
+ { label: "杨松", value: "杨松" },
83
+ { label: "王之勤", value: "王之勤" },
84
+ { label: "邹建军", value: "邹建军" },
85
+ { label: "龙成金", value: "龙成金" }
86
+ ],
87
+ product: [
88
+ { label: "热轧", value: "热轧" },
89
+ { label: "盘元", value: "盘元" },
90
+ { label: "冷精", value: "冷精" },
91
+ { label: "汽车", value: "汽车" }
92
+ ],
93
+ verifyStatus: [
94
+ { label: "未核实", value: "未核实" },
95
+ { label: "已核实", value: "已核实" }
96
+ ],
97
+ convertStatus: [
98
+ { label: "已转化", value: "已转化" },
99
+ { label: "未转化", value: "未转化" }
100
+ ]
101
+ };
102
+
103
+ export { OPTS };
104
+
105
+ /** c_formModal 配置 */
106
+ export const modalConfig = {
107
+ titlePrefix: "临时客户",
108
+ width: "850px",
109
+ columns: 2,
110
+ labelWidth: "110px",
111
+ formItems: [
112
+ {
113
+ name: "customerCode",
114
+ label: "客户编号",
115
+ disabled: true,
116
+ placeholder: "系统自动生成"
117
+ },
118
+ {
119
+ name: "customerName",
120
+ label: "客户名称",
121
+ required: true,
122
+ placeholder: "请输入客户名称"
123
+ },
124
+ {
125
+ name: "customerType",
126
+ label: "客户类型",
127
+ component: () => ({ tag: "jh-select", items: OPTS.customerType })
128
+ },
129
+ {
130
+ name: "product",
131
+ label: "产品别",
132
+ component: () => ({ tag: "jh-select", items: OPTS.product })
133
+ },
134
+ { name: "contactPerson", label: "联系人", placeholder: "请输入联系人" },
135
+ { name: "phone", label: "联系电话", placeholder: "请输入联系电话" },
136
+ { name: "businessPerson", label: "业务员", placeholder: "请输入业务员" },
137
+ { name: "applyReason", label: "申请原因", placeholder: "请输入申请原因" }
138
+ ] as BaseFormItemDesc<any>[],
139
+ api: {
140
+ getById: API_CONFIG.getById,
141
+ save: API_CONFIG.save,
142
+ update: API_CONFIG.update
143
+ }
144
+ };
145
+
146
+ let _editModalRef: any = null;
147
+
148
+ const DETAIL_ROUTE = "/aiflow/mmwrCustomerDetail";
149
+ /** 查看临时客户详情(跳转详情页) */
150
+ function handleCustomerCodeClick(row: any) {
151
+ const router = envConfig()?.router;
152
+ if (!router) {
153
+ ElMessage.error("路由未初始化,请刷新页面重试");
154
+ return;
155
+ }
156
+ location.href = router.resolve({
157
+ path: DETAIL_ROUTE,
158
+ query: { id: row.id }
159
+ }).href;
160
+ }
161
+
162
+ let PageRef: any = null;
163
+
164
+ export function createPage(editModalRef?: any) {
165
+ _editModalRef = editModalRef;
166
+ const activeTab = ref<TabType>("temp");
167
+
168
+ let Page = new (class extends AbstractPageQueryHook {
169
+ constructor() {
170
+ super({ url: { list: API_CONFIG.list, remove: API_CONFIG.remove } });
171
+ }
172
+
173
+ queryDef(): BaseQueryItemDesc<any>[] {
174
+ return [
175
+ { name: "customerCode", label: "客户编码", placeholder: "请输入" },
176
+ {
177
+ name: "customerStatus",
178
+ label: "客户状态",
179
+ component: () => ({ tag: "jh-select", items: OPTS.customerStatus })
180
+ },
181
+ {
182
+ name: "useOrg",
183
+ label: "使用组织",
184
+ component: () => ({ tag: "jh-select", items: OPTS.useOrg })
185
+ },
186
+ { name: "customerName", label: "客户名称", placeholder: "请输入" },
187
+ {
188
+ name: "businessDept",
189
+ label: "业务部门",
190
+ component: () => ({ tag: "jh-select", items: OPTS.businessDept })
191
+ },
192
+ {
193
+ name: "applicant",
194
+ label: "申请人",
195
+ component: () => ({ tag: "jh-select", items: OPTS.applicant })
196
+ },
197
+ {
198
+ name: "convertStatus",
199
+ label: "转换状态",
200
+ component: () => ({ tag: "jh-select", items: OPTS.convertStatus })
201
+ },
202
+ {
203
+ name: "product",
204
+ label: "产品别",
205
+ component: () => ({ tag: "jh-select", items: OPTS.product })
206
+ },
207
+ {
208
+ name: "businessPerson",
209
+ label: "业务员",
210
+ component: () => ({ tag: "jh-select", items: OPTS.applicant })
211
+ },
212
+ {
213
+ name: "verifyStatus",
214
+ label: "核实状态",
215
+ component: () => ({ tag: "jh-select", items: OPTS.verifyStatus })
216
+ },
217
+ {
218
+ name: "createDate",
219
+ startName: "createDateStart",
220
+ endName: "createDateEnd",
221
+ label: "建立日期",
222
+ component: () => ({
223
+ tag: "jh-date",
224
+ type: "daterange",
225
+ rangeSeparator: "至",
226
+ showFormat: "YYYY-MM-DD",
227
+ valueFormat: "YYYY-MM-DD"
228
+ })
229
+ },
230
+ {
231
+ name: "lastFollowDate",
232
+ startName: "lastFollowDateStart",
233
+ endName: "lastFollowDateEnd",
234
+ label: "最后跟进时间",
235
+ component: () => ({
236
+ tag: "jh-date",
237
+ type: "daterange",
238
+ rangeSeparator: "至",
239
+ showFormat: "YYYY-MM-DD",
240
+ valueFormat: "YYYY-MM-DD"
241
+ })
242
+ }
243
+ ];
244
+ }
245
+
246
+ toolbarDef(): ActionButtonDesc[] {
247
+ return [
248
+ {
249
+ name: "primary",
250
+ label: "新增",
251
+ onClick: () => _editModalRef?.value?.open()
252
+ },
253
+ {
254
+ label: "分配",
255
+ plain: true,
256
+ onClick: () => {
257
+ const rows = this.tableRef.value?.getSelectionRows();
258
+ if (!rows?.length) {
259
+ ElMessage.warning("请先选择数据");
260
+ return;
261
+ }
262
+ const ids = rows.map((r: any) => r.id);
263
+ ElMessageBox.confirm("确定分配选中客户?", "提示", { type: "info" })
264
+ .then(() => {
265
+ postAction(API_CONFIG.assign, { ids }).then(() => {
266
+ ElMessage.success("分配成功");
267
+ this.select();
268
+ });
269
+ })
270
+ .catch(() => {});
271
+ }
272
+ },
273
+ {
274
+ label: "作废",
275
+ type: "danger",
276
+ plain: true,
277
+ onClick: () => {
278
+ const rows = this.tableRef.value?.getSelectionRows();
279
+ if (!rows?.length) {
280
+ ElMessage.warning("请先选择数据");
281
+ return;
282
+ }
283
+ const ids = rows.map((r: any) => r.id);
284
+ ElMessageBox.confirm("确定作废选中客户?", "提示", {
285
+ type: "warning"
286
+ })
287
+ .then(() => {
288
+ postAction(API_CONFIG.cancel, { ids }).then(() => {
289
+ ElMessage.success("作废成功");
290
+ this.select();
291
+ });
292
+ })
293
+ .catch(() => {});
294
+ }
295
+ },
296
+ {
297
+ label: "导出",
298
+ plain: true,
299
+ onClick: async () => {
300
+ const data = this.list.value;
301
+ if (!data?.length) {
302
+ ElMessage.warning("无数据可导出");
303
+ return;
304
+ }
305
+ const exportData = data.map((row: any) => ({
306
+ 客户编号: row.customerCode,
307
+ 客户名称: row.customerName,
308
+ 客户类型: row.customerType,
309
+ 使用组织: row.useOrg,
310
+ 产品别: row.product,
311
+ 业务员: row.businessPerson,
312
+ 业务部门: row.businessDept,
313
+ 核实状态: row.verifyStatus,
314
+ 转换状态: row.convertStatus,
315
+ 创建时间: row.createTime
316
+ }));
317
+ const ws = XLSX.utils.json_to_sheet(exportData);
318
+ const wb = XLSX.utils.book_new();
319
+ XLSX.utils.book_append_sheet(wb, ws, "临时客户档案");
320
+ XLSX.writeFile(wb, "临时客户档案.xlsx");
321
+ ElMessage.success("导出成功");
322
+ }
323
+ },
324
+ {
325
+ label: "回收",
326
+ type: "warning",
327
+ plain: true,
328
+ onClick: () => {
329
+ const rows = this.tableRef.value?.getSelectionRows();
330
+ if (!rows?.length) {
331
+ ElMessage.warning("请先选择数据");
332
+ return;
333
+ }
334
+ const ids = rows.map((r: any) => r.id);
335
+ ElMessageBox.confirm("确定回收选中客户?", "提示", {
336
+ type: "warning"
337
+ })
338
+ .then(() => {
339
+ postAction(API_CONFIG.recycle, { ids }).then(() => {
340
+ ElMessage.success("回收成功");
341
+ this.select();
342
+ });
343
+ })
344
+ .catch(() => {});
345
+ }
346
+ },
347
+ {
348
+ label: "转化",
349
+ type: "success",
350
+ plain: true,
351
+ onClick: () => {
352
+ const rows = this.tableRef.value?.getSelectionRows();
353
+ if (!rows?.length) {
354
+ ElMessage.warning("请先选择数据");
355
+ return;
356
+ }
357
+ const ids = rows.map((r: any) => r.id);
358
+ ElMessageBox.confirm("确定将选中临时客户转化为正式客户?", "提示", {
359
+ type: "info"
360
+ })
361
+ .then(() => {
362
+ postAction(API_CONFIG.convert, { ids }).then(() => {
363
+ ElMessage.success("转化成功");
364
+ this.select();
365
+ });
366
+ })
367
+ .catch(() => {});
368
+ }
369
+ },
370
+ {
371
+ label: "认领",
372
+ type: "success",
373
+ plain: true,
374
+ onClick: () => {
375
+ const rows = this.tableRef.value?.getSelectionRows();
376
+ if (!rows?.length) {
377
+ ElMessage.warning("请先选择数据");
378
+ return;
379
+ }
380
+ const ids = rows.map((r: any) => r.id);
381
+ ElMessageBox.confirm("确定认领选中客户?", "提示", { type: "info" })
382
+ .then(() => {
383
+ postAction(API_CONFIG.claim, { ids }).then(() => {
384
+ ElMessage.success("认领成功");
385
+ this.select();
386
+ });
387
+ })
388
+ .catch(() => {});
389
+ }
390
+ },
391
+ {
392
+ label: "退回",
393
+ type: "warning",
394
+ plain: true,
395
+ onClick: () => {
396
+ const rows = this.tableRef.value?.getSelectionRows();
397
+ if (!rows?.length) {
398
+ ElMessage.warning("请先选择数据");
399
+ return;
400
+ }
401
+ const ids = rows.map((r: any) => r.id);
402
+ ElMessageBox.confirm("确定退回选中客户?", "提示", {
403
+ type: "warning"
404
+ })
405
+ .then(() => {
406
+ postAction(API_CONFIG.returnBack, { ids }).then(() => {
407
+ ElMessage.success("退回成功");
408
+ this.select();
409
+ });
410
+ })
411
+ .catch(() => {});
412
+ }
413
+ }
414
+ ];
415
+ }
416
+
417
+ columnsDef(): TableColumnDesc<any>[] {
418
+ return [
419
+ { type: "selection" },
420
+ { type: "index" },
421
+ {
422
+ label: "客户编号",
423
+ name: "customerCode",
424
+ minWidth: 140,
425
+ defaultSlot: ({ row }: any) => {
426
+ return h(
427
+ "span",
428
+ {
429
+ style:
430
+ "color: #409eff; cursor: pointer; text-decoration: underline;",
431
+ onClick: () => handleCustomerCodeClick(row)
432
+ },
433
+ row.customerCode
434
+ );
435
+ }
436
+ },
437
+ {
438
+ label: "使用组织",
439
+ name: "useOrg",
440
+ minWidth: 180,
441
+ showOverflowTooltip: true
442
+ },
443
+ { label: "产品别", name: "product", minWidth: 100 },
444
+ { label: "申请原因", name: "applyReason", minWidth: 120 },
445
+ { label: "业务员", name: "businessPerson", minWidth: 100 },
446
+ { label: "业务部门", name: "businessDept", minWidth: 140 },
447
+ {
448
+ label: "核实状态",
449
+ name: "verifyStatus",
450
+ minWidth: 100,
451
+ defaultSlot: ({ row }: any) => renderStatusTag(row, "verifyStatus")
452
+ },
453
+ { label: "创建人", name: "creator", minWidth: 100 },
454
+ { label: "创建时间", name: "createTime", minWidth: 160 },
455
+ { label: "最近跟进人", name: "lastFollowPerson", minWidth: 100 },
456
+ { label: "最近跟进日期", name: "lastFollowDate", minWidth: 130 },
457
+ {
458
+ label: "转化状态",
459
+ name: "convertStatus",
460
+ minWidth: 100,
461
+ fixed: "right",
462
+ defaultSlot: ({ row }: any) => renderStatusTag(row, "convertStatus")
463
+ },
464
+ {
465
+ label: "客户状态",
466
+ name: "customerStatus",
467
+ minWidth: 100,
468
+ fixed: "right",
469
+ defaultSlot: ({ row }: any) => renderStatusTag(row, "customerStatus")
470
+ },
471
+ {
472
+ label: "操作",
473
+ width: 140,
474
+ fixed: "right",
475
+ operations: [
476
+ {
477
+ name: "edit",
478
+ label: "修改",
479
+ show: (row: any) => row.verifyStatus === "已核实",
480
+ onClick: (row: any) => _editModalRef?.value?.edit(row.id)
481
+ },
482
+ {
483
+ name: "danger",
484
+ label: "作废",
485
+ show: (row: any) => row.verifyStatus === "已核实",
486
+ onClick: (row: any) => {
487
+ ElMessageBox.confirm("确定作废该客户?", "提示", {
488
+ type: "warning"
489
+ })
490
+ .then(() => {
491
+ postAction(API_CONFIG.cancel, { ids: [row.id] }).then(
492
+ () => {
493
+ ElMessage.success("作废成功");
494
+ PageRef?.select();
495
+ }
496
+ );
497
+ })
498
+ .catch(() => {});
499
+ }
500
+ },
501
+ {
502
+ name: "edit",
503
+ label: "编辑",
504
+ show: (row: any) => row.verifyStatus !== "已核实",
505
+ onClick: (row: any) => _editModalRef?.value?.edit(row.id)
506
+ },
507
+ {
508
+ name: "remove",
509
+ label: "删除",
510
+ show: (row: any) => row.verifyStatus !== "已核实",
511
+ onClick: (row: any) => {
512
+ ElMessageBox.confirm("确定删除该客户?", "提示", {
513
+ type: "warning"
514
+ })
515
+ .then(() => {
516
+ postAction(API_CONFIG.remove, { id: row.id }).then(() => {
517
+ ElMessage.success("删除成功");
518
+ PageRef?.select();
519
+ });
520
+ })
521
+ .catch(() => {});
522
+ }
523
+ }
524
+ ]
525
+ }
526
+ ];
527
+ }
528
+ })();
529
+
530
+ PageRef = Page;
531
+ let result = (Page as any).create() as any;
532
+
533
+ /** Tab 切换 */
534
+ const handleTabChange = (val: TabType) => {
535
+ activeTab.value = val;
536
+ result.queryParam.value.tabType = val;
537
+ result.select();
538
+ };
539
+
540
+ result.activeTab = activeTab;
541
+ result.handleTabChange = handleTabChange;
542
+ return result;
543
+ }
@@ -0,0 +1 @@
1
+ // 临时客户档案 - 页面样式
@@ -0,0 +1,52 @@
1
+ <template>
2
+ <div class="app-container app-page-container">
3
+ <el-tabs v-model="activeTab" @tab-change="handleTabChange">
4
+ <el-tab-pane label="临时客户" name="temp" />
5
+ <el-tab-pane label="正式客户" name="formal" />
6
+ <el-tab-pane label="公海池" name="pool" />
7
+ </el-tabs>
8
+ <BaseQuery
9
+ :form="queryParam"
10
+ :items="queryItems"
11
+ @select="select"
12
+ @reset="select"
13
+ />
14
+ <BaseToolbar :items="toolbars" />
15
+ <BaseTable ref="tableRef" :data="list" :columns="columns" showToolbar />
16
+ <jh-pagination
17
+ v-show="page.total && page.total > 0"
18
+ :total="page.total || 0"
19
+ v-model:currentPage="page.current"
20
+ v-model:pageSize="page.size"
21
+ @current-change="select"
22
+ @size-change="select"
23
+ />
24
+ <c_formModal ref="editModalRef" v-bind="modalConfig" @ok="select" />
25
+ </div>
26
+ </template>
27
+
28
+ <script setup lang="ts">
29
+ import { createPage, modalConfig } from "./data";
30
+ import c_formModal from "@/components/local/c_formModal/index.vue";
31
+
32
+ const editModalRef = ref();
33
+ const Page = createPage(editModalRef);
34
+ const {
35
+ tableRef,
36
+ page,
37
+ queryParam,
38
+ list,
39
+ queryItems,
40
+ columns,
41
+ toolbars,
42
+ select,
43
+ activeTab,
44
+ handleTabChange
45
+ } = Page;
46
+
47
+ onMounted(() => select());
48
+ </script>
49
+
50
+ <style scoped lang="scss">
51
+ @import "./index.scss";
52
+ </style>