create-jnrs-vue 2.0.2 → 2.0.4

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 (50) hide show
  1. package/jnrs-vue/components.d.ts +1 -0
  2. package/jnrs-vue/package.json +4 -4
  3. package/jnrs-vue/src/api/examples/playground.ts +51 -0
  4. package/jnrs-vue/src/api/examples/portfolio-management/portfolio.ts +10 -10
  5. package/jnrs-vue/src/api/examples/portfolio-management/program.ts +5 -5
  6. package/jnrs-vue/src/api/examples/portfolio-management/project.ts +4 -4
  7. package/jnrs-vue/src/api/examples/program-management/index.ts +5 -5
  8. package/jnrs-vue/src/api/examples/program-management/sub-project.ts +4 -4
  9. package/jnrs-vue/src/api/examples/project-management/index.ts +19 -51
  10. package/jnrs-vue/src/api/examples/project-management/manager.ts +1 -1
  11. package/jnrs-vue/src/components/common/DictSelector.vue +70 -0
  12. package/jnrs-vue/src/components/common/DictTag.vue +8 -2
  13. package/jnrs-vue/src/utils/index.ts +1 -1
  14. package/jnrs-vue/src/views/examples/playground/RequestPage.vue +97 -38
  15. package/jnrs-vue/src/views/examples/playground/index.vue +203 -63
  16. package/jnrs-vue/src/views/examples/portfolio-management/programList/editDialog.vue +10 -0
  17. package/jnrs-vue/src/views/examples/portfolio-management/programList/index.vue +1 -1
  18. package/jnrs-vue/src/views/examples/portfolio-management/projectList/editDialog.vue +12 -9
  19. package/jnrs-vue/src/views/examples/program-management/mainPage/editDialog.vue +15 -19
  20. package/jnrs-vue/src/views/examples/program-management/subPage/editDialog.vue +15 -19
  21. package/jnrs-vue/src/views/examples/project-management/EditDialog.vue +54 -24
  22. package/jnrs-vue/src/views/examples/project-management/index.vue +4 -18
  23. package/jnrs-vue/viteMockServe/auth.mock.ts +41 -0
  24. package/jnrs-vue/viteMockServe/details.mock.ts +12 -0
  25. package/jnrs-vue/viteMockServe/dict.mock.ts +21 -0
  26. package/jnrs-vue/viteMockServe/index.ts +22 -370
  27. package/jnrs-vue/viteMockServe/manager.mock.ts +12 -0
  28. package/jnrs-vue/viteMockServe/portfolio-program.mock.ts +36 -0
  29. package/jnrs-vue/viteMockServe/portfolio-project.mock.ts +28 -0
  30. package/jnrs-vue/viteMockServe/portfolio.mock.ts +109 -0
  31. package/jnrs-vue/viteMockServe/program.mock.ts +45 -0
  32. package/jnrs-vue/viteMockServe/project.mock.ts +58 -0
  33. package/jnrs-vue/viteMockServe/role.mock.ts +12 -0
  34. package/jnrs-vue/viteMockServe/sub-project.mock.ts +34 -0
  35. package/package.json +1 -1
  36. package/jnrs-vue/src/api/business/index.ts +0 -69
  37. package/jnrs-vue/src/utils/field.ts +0 -73
  38. package/jnrs-vue/src/views/businessPlayground/EditDialog.vue +0 -137
  39. package/jnrs-vue/src/views/businessPlayground/index.vue +0 -90
  40. package/jnrs-vue/viteMockServe/json/tableRes.json +0 -390
  41. /package/jnrs-vue/viteMockServe/json/{loginResAdmin.json → auth-login-admin.json} +0 -0
  42. /package/jnrs-vue/viteMockServe/json/{loginResUser.json → auth-login-user.json} +0 -0
  43. /package/jnrs-vue/viteMockServe/json/{detailsRes.json → details.json} +0 -0
  44. /package/jnrs-vue/viteMockServe/json/{dictItemRes.json → dict-detail.json} +0 -0
  45. /package/jnrs-vue/viteMockServe/json/{dictRes.json → dict-list.json} +0 -0
  46. /package/jnrs-vue/viteMockServe/json/{managerRes.json → manager-list.json} +0 -0
  47. /package/jnrs-vue/viteMockServe/json/{programListRes.json → program-list.json} +0 -0
  48. /package/jnrs-vue/viteMockServe/json/{projectListRes.json → project-list.json} +0 -0
  49. /package/jnrs-vue/viteMockServe/json/{roleRes.json → role-list.json} +0 -0
  50. /package/jnrs-vue/viteMockServe/json/{subProjectListRes.json → sub-project-list.json} +0 -0
@@ -0,0 +1,34 @@
1
+ import subProjectListRes from './json/sub-project-list.json'
2
+
3
+ export default [
4
+ // 获取子项目列表
5
+ {
6
+ url: '/api/mock/examples/sub-project/list',
7
+ method: 'get',
8
+ response: () => {
9
+ return subProjectListRes
10
+ }
11
+ },
12
+ // 保存子项目数据
13
+ {
14
+ url: '/api/mock/examples/sub-project/save',
15
+ method: 'post',
16
+ response: () => {
17
+ return {
18
+ code: 0,
19
+ msg: '子项目已保存'
20
+ }
21
+ }
22
+ },
23
+ // 删除子项目数据
24
+ {
25
+ url: /\/api\/mock\/agentic\/sub-project\/delete\/\w+/,
26
+ method: 'delete',
27
+ response: () => {
28
+ return {
29
+ code: 0,
30
+ msg: '子项目已删除'
31
+ }
32
+ }
33
+ }
34
+ ]
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "create-jnrs-vue",
3
- "version": "2.0.2",
3
+ "version": "2.0.4",
4
4
  "description": "巨能(JNRS)前端工程化开发,Vue 项目模板脚手架",
5
5
  "keywords": [
6
6
  "vue",
@@ -1,69 +0,0 @@
1
- /**
2
- * @Author : TanRui
3
- * @WeChat : Tan578853789
4
- * @File : business/index.ts
5
- * @Date : 2026/05/25
6
- * @Desc. : 业务功能测试模块接口文档
7
- */
8
-
9
- import type { IBlobItem } from '@jnrs/shared'
10
- import type { IPagination, IPageTableData, IFile } from '@/types'
11
- import { axiosRequest } from '../request'
12
- import { objectToFormData } from '@/utils'
13
-
14
- export interface ProcessItem extends IFile {
15
- id?: number
16
- productName?: string
17
- productCode?: string
18
- height?: number
19
- isProcessCompleteness?: boolean
20
- imageDocumentId?: unknown
21
- attachmentDocumentId?: unknown
22
- }
23
-
24
- export interface SaveProcessRequest {
25
- /** ID 编号 */
26
- id?: number
27
- productName: string
28
- productCode: string
29
- height: number
30
- orginAttachmentName?: string
31
- /** 文件 */
32
- newAttachmentFile: []
33
- orginImageNames?: string[]
34
- /** 图片 */
35
- newImageFiles: []
36
- }
37
-
38
- /**
39
- * 列表
40
- */
41
- export const getProductManagementProcessListApi = (params: IPagination): Promise<IPageTableData<ProcessItem>> => {
42
- return axiosRequest({
43
- url: '/product/process',
44
- method: 'get',
45
- params
46
- })
47
- }
48
-
49
- /**
50
- * 新建/编辑
51
- */
52
- export const saveProductManagementProcessApi = (data: SaveProcessRequest): Promise<void> => {
53
- return axiosRequest({
54
- url: '/product/process',
55
- method: 'post',
56
- data: objectToFormData(data)
57
- })
58
- }
59
-
60
- /**
61
- * 齐套检查 导出
62
- */
63
- export const getStandardLoadKitCheckExportApi = (): Promise<IBlobItem> => {
64
- return axiosRequest({
65
- url: '/order/completeness-check/export',
66
- method: 'get',
67
- responseType: 'blob'
68
- })
69
- }
@@ -1,73 +0,0 @@
1
- /**
2
- * @Author : Talia
3
- * @WeChat : Tan578853789
4
- * @File : field.ts
5
- * @Date : 2026/07/09
6
- * @Desc. : 字段处理相关函数(通用版:支持任意对象/数组镜像提取)
7
- */
8
-
9
- /** 原始 ID 类型 */
10
- type PrimitiveId = string | number
11
-
12
- /** 从对象中提取指定字段的类型,若字段不存在或类型不合法则回退到 undefined */
13
- type ExtractFieldType<T, K extends PropertyKey> =
14
- T extends Record<PropertyKey, unknown>
15
- ? K extends keyof T
16
- ? T[K] extends PrimitiveId
17
- ? T[K]
18
- : undefined
19
- : undefined
20
- : never
21
-
22
- // ============ 函数重载签名区 ============
23
-
24
- /** 重载1:传入数组 → 返回对应字段类型的数组 */
25
- export function extractFieldId<T extends Record<string, unknown>, K extends keyof T & PropertyKey = 'id'>(
26
- value: T[],
27
- fieldName?: K
28
- ): ExtractFieldType<T, K>[]
29
-
30
- /** 重载2:传入单个对象 → 返回对应字段类型 */
31
- export function extractFieldId<T extends Record<string, unknown>, K extends keyof T & PropertyKey = 'id'>(
32
- value: T,
33
- fieldName?: K
34
- ): ExtractFieldType<T, K>
35
-
36
- /** 重载3:传入 null / undefined → 返回 undefined */
37
- export function extractFieldId(value: null | undefined, fieldName?: string): undefined
38
-
39
- // ============ 实现签名区 ============
40
- export function extractFieldId(
41
- value: Record<string, unknown> | Record<string, unknown>[] | null | undefined,
42
- fieldName: string = 'id'
43
- ): unknown {
44
- // 1. 排除 null 和 undefined
45
- if (value == null) return undefined
46
-
47
- // 2. 数组形态:递归提取每个元素,过滤掉非法值
48
- if (Array.isArray(value)) {
49
- return value
50
- .map((item) => extractFieldId(item, fieldName))
51
- .filter((v): v is NonNullable<typeof v> => v !== undefined)
52
- }
53
-
54
- // 3. 必须是普通对象(防御性检查)
55
- if (typeof value !== 'object') {
56
- return undefined
57
- }
58
-
59
- // 4. 检查对象是否包含目标字段
60
- if (!(fieldName in value)) {
61
- return undefined
62
- }
63
-
64
- // 5. 安全获取字段值
65
- const fieldValue = (value as Record<string, unknown>)[fieldName]
66
-
67
- // 6. 只接受 string 或 number 类型
68
- if (typeof fieldValue === 'string' || typeof fieldValue === 'number') {
69
- return fieldValue
70
- }
71
-
72
- return undefined
73
- }
@@ -1,137 +0,0 @@
1
- <!--
2
- @Author : TanRui
3
- @WeChat : Tan578853789
4
- @Title : 项目编辑组件
5
- @File : /agentic/crud/EditDialog.vue
6
- @Date : 2026/01/01
7
- @Desc. : 该页面为增删改查类业务功能的页面模板,包含了常见的功能如表单控件、components/common 通用功能组件、导入导出、图片附件、附件上传等功能。开发者可以在此基础上进行修改和扩展,以适应具体的业务需求。
8
- -->
9
-
10
- <script setup lang="ts">
11
- import type { FormInstance } from 'element-plus'
12
- import { type SaveProcessRequest, saveProductManagementProcessApi } from '@/api/business/index'
13
- import { ref, nextTick } from 'vue'
14
- import { ElMessage } from 'element-plus'
15
- import { objectMatchAssign } from '@jnrs/shared'
16
- import { downloadFile } from '@/utils'
17
- import { JnDialog, JnFileUpload } from '@jnrs/vue-core/components'
18
-
19
- const emit = defineEmits<{
20
- success: []
21
- }>()
22
-
23
- const loading = ref(false)
24
- const editDialogRef = ref()
25
- const ruleFormRef = ref<FormInstance>()
26
- const ruleForm = ref<SaveProcessRequest>({
27
- id: 0,
28
- productName: '',
29
- productCode: '',
30
- height: 0,
31
- orginAttachmentName: '',
32
- newAttachmentFile: [],
33
- orginImageNames: [],
34
- newImageFiles: []
35
- })
36
-
37
- // 打开弹窗
38
- const open = (row?: SaveProcessRequest) => {
39
- editDialogRef.value.open()
40
- nextTick(() => {
41
- ruleFormRef.value?.resetFields()
42
- const matched = objectMatchAssign(ruleForm.value, row)
43
- ruleForm.value = matched
44
- })
45
- }
46
-
47
- // 关闭弹窗
48
- const close = () => {
49
- editDialogRef.value.close()
50
- }
51
-
52
- // 提交表单
53
- const submitForm = () => {
54
- ruleFormRef.value?.validate(async (valid) => {
55
- if (valid) {
56
- loading.value = true
57
- try {
58
- const baseData = {
59
- productName: ruleForm.value.productName,
60
- productCode: ruleForm.value.productCode,
61
- height: ruleForm.value.height,
62
- orginAttachmentName: ruleForm.value.orginAttachmentName,
63
- newAttachmentFile: ruleForm.value.newAttachmentFile,
64
- orginImageNames: ruleForm.value.orginImageNames,
65
- newImageFiles: ruleForm.value.newImageFiles
66
- }
67
-
68
- if ('id' in ruleForm.value && ruleForm.value.id) {
69
- await saveProductManagementProcessApi({ ...baseData, id: ruleForm.value.id })
70
- } else {
71
- await saveProductManagementProcessApi(baseData)
72
- }
73
-
74
- ElMessage({
75
- message: '数据已保存',
76
- grouping: true,
77
- showClose: true,
78
- type: 'success'
79
- })
80
- close()
81
- emit('success')
82
- } catch (err) {
83
- console.error(err)
84
- } finally {
85
- loading.value = false
86
- }
87
- }
88
- })
89
- }
90
-
91
- // 暴露方法给父组件
92
- defineExpose({
93
- open,
94
- close
95
- })
96
- </script>
97
-
98
- <template>
99
- <!-- 编辑弹窗 -->
100
- <JnDialog ref="editDialogRef" title="项目管理" width="800px">
101
- <el-form ref="ruleFormRef" :model="ruleForm" label-width="auto" v-loading="loading">
102
- <el-form-item prop="id"></el-form-item>
103
- <el-form-item label="产品名称" prop="productName">
104
- <el-input v-model.trim="ruleForm.productName" maxlength="50" show-word-limit />
105
- </el-form-item>
106
- <el-form-item label="产品编码" prop="productCode">
107
- <el-input v-model.trim="ruleForm.productCode" maxlength="50" show-word-limit />
108
- </el-form-item>
109
- <el-form-item label="高度(mm)" prop="height">
110
- <el-input-number v-model="ruleForm.height" :min="0" :precision="2" :step-strictly="true" style="width: 150px" />
111
- </el-form-item>
112
- <el-form-item label="上传图片" prop="newImageFiles">
113
- <JnFileUpload
114
- v-model="ruleForm.newImageFiles"
115
- :formRef="ruleFormRef"
116
- validateFieldName="newImageFiles"
117
- accept=".png,.jpg,.bmp,.gif"
118
- :fileSizeMb="50"
119
- :limit="1"
120
- drag
121
- :downloadFileFn="(file) => downloadFile(file.uniqueFileName, file.fileName)"
122
- />
123
- </el-form-item>
124
- <el-form-item label="上传文件" prop="newAttachmentFile">
125
- <JnFileUpload
126
- v-model="ruleForm.newAttachmentFile"
127
- accept=".pdf"
128
- :limit="1"
129
- :downloadFileFn="(file) => downloadFile(file.uniqueFileName, file.fileName)"
130
- />
131
- </el-form-item>
132
- </el-form>
133
- <template #footer>
134
- <el-button type="success" icon="Select" :loading="loading" @click="submitForm()">提交</el-button>
135
- </template>
136
- </JnDialog>
137
- </template>
@@ -1,90 +0,0 @@
1
- <script setup lang="ts">
2
- import {
3
- getStandardLoadKitCheckExportApi,
4
- getProductManagementProcessListApi,
5
- type ProcessItem
6
- } from '@/api/business/index'
7
- import { JnImportAndExport, JnTable, JnPagination } from '@jnrs/vue-core/components'
8
- import { debounce } from '@jnrs/shared/lodash'
9
- import { ref, onActivated } from 'vue'
10
- import EditDialog from './EditDialog.vue'
11
- import ImageView from '@/components/common/ImageView.vue'
12
- import PdfView from '@/components/common/PdfView.vue'
13
-
14
- const loading = ref(false)
15
- const tableData = ref<ProcessItem[]>([])
16
- const total = ref(0)
17
- const pagination = ref({ pageNo: 1, pageSize: 20 })
18
- // 编辑弹窗引用
19
- const editDialogRef = ref()
20
-
21
- // 获取表格数据
22
- const getTable = debounce(async () => {
23
- loading.value = true
24
- try {
25
- const res = await getProductManagementProcessListApi({
26
- ...pagination.value
27
- })
28
- tableData.value = res.list.map((item) => ({
29
- ...item,
30
- newImageFiles: item.imageDocument?.attachments,
31
- newAttachmentFile: item.attachmentDocument?.attachments
32
- }))
33
- total.value = res.count
34
- } catch (error) {
35
- console.error(error)
36
- } finally {
37
- loading.value = false
38
- }
39
- }, 300)
40
-
41
- // 新增和修改
42
- const handleEdit = (row?: ProcessItem) => {
43
- editDialogRef.value.open(row)
44
- }
45
-
46
- onActivated(() => {
47
- getTable()
48
- })
49
- </script>
50
-
51
- <template>
52
- <!-- 编辑弹窗组件 -->
53
- <EditDialog ref="editDialogRef" @success="getTable()" />
54
-
55
- <JnImportAndExport :exportApi="getStandardLoadKitCheckExportApi" size="small" />
56
- <!-- 数据列表 -->
57
- <JnTable
58
- :data="tableData"
59
- :pagination="pagination"
60
- :autoHeight="true"
61
- :showScrollbar="true"
62
- :showIndexColumn="true"
63
- highlight-current-row
64
- >
65
- <el-table-column prop="productName" label="产品名称" min-width="100" show-overflow-tooltip />
66
- <el-table-column prop="productCode" label="产品编码" min-width="100" show-overflow-tooltip />
67
- <el-table-column prop="height" label="高度(mm)" width="100" align="center" />
68
- <el-table-column prop="imageDocument" label="图片" width="120" align="center">
69
- <template #default="{ row }">
70
- <ImageView :loadKeys="row.newImageFiles" preview />
71
- </template>
72
- </el-table-column>
73
- <el-table-column prop="isProcessCompleteness" label="工艺是否齐套" width="100" align="center">
74
- <template #default="{ row }">
75
- <el-tag :type="row.isProcessCompleteness ? 'success' : 'warning'">
76
- {{ row.isProcessCompleteness ? '是' : '否' }}
77
- </el-tag>
78
- </template>
79
- </el-table-column>
80
- <el-table-column label="操作" width="100" align="center" fixed="right">
81
- <template #default="{ row }">
82
- <div><PdfView :loadKeys="row.newAttachmentFile" isPdf :showFileName="false" /></div>
83
- <div><el-button link type="primary" @click.stop="handleEdit(row)">编辑</el-button></div>
84
- </template>
85
- </el-table-column>
86
- </JnTable>
87
-
88
- <!-- 表格分页 -->
89
- <JnPagination :total="total" v-model="pagination" @change="getTable" />
90
- </template>