matrix_components 2.0.366 → 2.0.367
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/dist/ComponentDemo/DialogDemo.vue +210 -0
- package/dist/ComponentDemo/ExampleFormConfig.js +270 -0
- package/dist/ComponentDemo/ExcelDemo.vue +263 -0
- package/dist/ComponentDemo/FormDemo copy 2.vue +557 -0
- package/dist/ComponentDemo/FormDemo copy.vue +454 -0
- package/dist/ComponentDemo/FormDemo.vue +560 -0
- package/dist/ComponentDemo/ImageDemo.vue +27 -0
- package/dist/ComponentDemo/MDDemo.vue +20 -0
- package/dist/ComponentDemo/OfficeDemo.vue +189 -0
- package/dist/ComponentDemo/PdfDemo.vue +207 -0
- package/dist/ComponentDemo/SaturationLineDemo.vue +158 -0
- package/dist/ComponentDemo/SimpleFormConfig.json +97 -0
- package/dist/ComponentDemo/Test.vue +437 -0
- package/dist/ComponentDemo/TestFormConfig.js +129 -0
- package/dist/ComponentDemo/VideoDemo.vue +301 -0
- package/dist/ComponentDemo/WordDemo.vue +191 -0
- package/dist/matrix_components.css +1 -1
- package/dist/matrix_components.js +10 -10
- package/dist/matrix_components.umd.cjs +1 -1
- package/package.json +1 -1
|
@@ -0,0 +1,560 @@
|
|
|
1
|
+
<template>
|
|
2
|
+
<div class="demo-container">
|
|
3
|
+
<div class="control-panel">
|
|
4
|
+
<h3>动态表单组件演示</h3>
|
|
5
|
+
<!-- 配置文件选择 -->
|
|
6
|
+
<el-form :model="state" ref="formRef" label-position="left">
|
|
7
|
+
<el-button type="primary" @click="getFormData">获取表单数据</el-button>
|
|
8
|
+
<el-button type="default" @click="resetFormData">重置表单</el-button>
|
|
9
|
+
<br />
|
|
10
|
+
<span style="color: red"> 结果:{{ state.formData }} </span>
|
|
11
|
+
<br />
|
|
12
|
+
<br />
|
|
13
|
+
<NsFormTitle title="模型参数">
|
|
14
|
+
<NsForm
|
|
15
|
+
ref="row1Ref"
|
|
16
|
+
:readOnly="state.readOnly"
|
|
17
|
+
backgroundColor="#fff"
|
|
18
|
+
:model="state.model"
|
|
19
|
+
:rows="state.rows"
|
|
20
|
+
formPropKey="rows"
|
|
21
|
+
labelColor="#606266"
|
|
22
|
+
labelWidth="150"
|
|
23
|
+
gapH="20px"
|
|
24
|
+
gapV="10px"
|
|
25
|
+
></NsForm>
|
|
26
|
+
</NsFormTitle>
|
|
27
|
+
<NsFormTitle title="视频配置">
|
|
28
|
+
<NsForm
|
|
29
|
+
ref="row2Ref"
|
|
30
|
+
:readOnly="state.readOnly"
|
|
31
|
+
backgroundColor="#fff"
|
|
32
|
+
:model="state.model"
|
|
33
|
+
:rows="state.rows2"
|
|
34
|
+
formPropKey="rows2"
|
|
35
|
+
labelColor="#606266"
|
|
36
|
+
labelWidth="150"
|
|
37
|
+
gapH="20px"
|
|
38
|
+
gapV="10px"
|
|
39
|
+
></NsForm>
|
|
40
|
+
</NsFormTitle>
|
|
41
|
+
<NsFormTitle title="结果保存">
|
|
42
|
+
<NsForm
|
|
43
|
+
ref="row3Ref"
|
|
44
|
+
:readOnly="state.readOnly"
|
|
45
|
+
backgroundColor="#fff"
|
|
46
|
+
:model="state.model"
|
|
47
|
+
:rows="state.rows3"
|
|
48
|
+
formPropKey="rows3"
|
|
49
|
+
labelColor="#606266"
|
|
50
|
+
labelWidth="150"
|
|
51
|
+
gapH="20px"
|
|
52
|
+
gapV="10px"
|
|
53
|
+
></NsForm>
|
|
54
|
+
</NsFormTitle>
|
|
55
|
+
</el-form>
|
|
56
|
+
</div>
|
|
57
|
+
</div>
|
|
58
|
+
</template>
|
|
59
|
+
|
|
60
|
+
<script setup lang="ts">
|
|
61
|
+
import { ElInput, ElMessage, ElRadioGroup } from 'element-plus'
|
|
62
|
+
import { reactive, ref } from 'vue'
|
|
63
|
+
import { cloneDeep } from 'lodash-es'
|
|
64
|
+
import { nextTick } from 'vue'
|
|
65
|
+
|
|
66
|
+
const props = defineProps({
|
|
67
|
+
readOnly: {
|
|
68
|
+
type: Boolean,
|
|
69
|
+
default: false,
|
|
70
|
+
},
|
|
71
|
+
row: {
|
|
72
|
+
type: Object,
|
|
73
|
+
default: () => ({}),
|
|
74
|
+
},
|
|
75
|
+
})
|
|
76
|
+
|
|
77
|
+
const formRef = ref()
|
|
78
|
+
const row1Ref = ref()
|
|
79
|
+
const row2Ref = ref()
|
|
80
|
+
const row3Ref = ref()
|
|
81
|
+
|
|
82
|
+
const state = reactive({
|
|
83
|
+
formData: {},
|
|
84
|
+
readOnly: props.readOnly,
|
|
85
|
+
model: props.readOnly ? '' : 'vertical',
|
|
86
|
+
// 使用 cloneDeep 进行深拷贝,保留函数
|
|
87
|
+
rows: [
|
|
88
|
+
[
|
|
89
|
+
{
|
|
90
|
+
key: 'confidence',
|
|
91
|
+
label: '置信度',
|
|
92
|
+
value: 'aaa',
|
|
93
|
+
component: ElInput,
|
|
94
|
+
params: {
|
|
95
|
+
rules: [
|
|
96
|
+
{
|
|
97
|
+
required: true,
|
|
98
|
+
message: '请输入',
|
|
99
|
+
},
|
|
100
|
+
],
|
|
101
|
+
},
|
|
102
|
+
},
|
|
103
|
+
{
|
|
104
|
+
key: 'iou',
|
|
105
|
+
label: '交并比',
|
|
106
|
+
value: '',
|
|
107
|
+
component: ElInput,
|
|
108
|
+
params: {
|
|
109
|
+
'v-length.range': {
|
|
110
|
+
min: 0,
|
|
111
|
+
max: 1,
|
|
112
|
+
maxLength: 3,
|
|
113
|
+
},
|
|
114
|
+
rules: [
|
|
115
|
+
{
|
|
116
|
+
required: true,
|
|
117
|
+
message: '请输入',
|
|
118
|
+
},
|
|
119
|
+
],
|
|
120
|
+
},
|
|
121
|
+
},
|
|
122
|
+
],
|
|
123
|
+
],
|
|
124
|
+
rows2: [
|
|
125
|
+
[
|
|
126
|
+
{
|
|
127
|
+
key: 'timeInterval',
|
|
128
|
+
label: '时间间隔(秒)',
|
|
129
|
+
value: '',
|
|
130
|
+
component: ElInput,
|
|
131
|
+
params: {
|
|
132
|
+
'v-length.range': {
|
|
133
|
+
min: 0,
|
|
134
|
+
max: 6000,
|
|
135
|
+
int: true,
|
|
136
|
+
},
|
|
137
|
+
rules: [
|
|
138
|
+
{
|
|
139
|
+
required: true,
|
|
140
|
+
message: '请输入',
|
|
141
|
+
},
|
|
142
|
+
],
|
|
143
|
+
},
|
|
144
|
+
},
|
|
145
|
+
{
|
|
146
|
+
key: 'stuck_threshold',
|
|
147
|
+
label: '视频帧卡顿(秒)',
|
|
148
|
+
value: '',
|
|
149
|
+
component: ElInput,
|
|
150
|
+
params: {
|
|
151
|
+
'v-length.range': {
|
|
152
|
+
min: 0,
|
|
153
|
+
max: 1000,
|
|
154
|
+
int: true,
|
|
155
|
+
},
|
|
156
|
+
rules: [
|
|
157
|
+
{
|
|
158
|
+
required: true,
|
|
159
|
+
message: '请输入',
|
|
160
|
+
},
|
|
161
|
+
],
|
|
162
|
+
},
|
|
163
|
+
},
|
|
164
|
+
],
|
|
165
|
+
[
|
|
166
|
+
{
|
|
167
|
+
key: 'max_retries',
|
|
168
|
+
label: '最大重连次数',
|
|
169
|
+
value: '',
|
|
170
|
+
component: ElInput,
|
|
171
|
+
params: {
|
|
172
|
+
'v-length.range': {
|
|
173
|
+
min: 0,
|
|
174
|
+
max: 100,
|
|
175
|
+
int: true,
|
|
176
|
+
},
|
|
177
|
+
rules: [
|
|
178
|
+
{
|
|
179
|
+
required: true,
|
|
180
|
+
message: '请输入',
|
|
181
|
+
},
|
|
182
|
+
],
|
|
183
|
+
},
|
|
184
|
+
},
|
|
185
|
+
{
|
|
186
|
+
value: ' ',
|
|
187
|
+
},
|
|
188
|
+
],
|
|
189
|
+
],
|
|
190
|
+
rows3: [
|
|
191
|
+
[
|
|
192
|
+
{
|
|
193
|
+
key: 'save_video',
|
|
194
|
+
label: '是否保存视频',
|
|
195
|
+
value: '1',
|
|
196
|
+
component: ElRadioGroup,
|
|
197
|
+
params: {
|
|
198
|
+
rules: [
|
|
199
|
+
{
|
|
200
|
+
required: true,
|
|
201
|
+
message: '请选择',
|
|
202
|
+
trigger: 'change',
|
|
203
|
+
},
|
|
204
|
+
],
|
|
205
|
+
options: [
|
|
206
|
+
{
|
|
207
|
+
value: '1',
|
|
208
|
+
label: '是',
|
|
209
|
+
},
|
|
210
|
+
{
|
|
211
|
+
value: '0',
|
|
212
|
+
label: '否',
|
|
213
|
+
},
|
|
214
|
+
],
|
|
215
|
+
},
|
|
216
|
+
},
|
|
217
|
+
{
|
|
218
|
+
key: 'pre_buffer_second',
|
|
219
|
+
label: '帧前缓存(秒)',
|
|
220
|
+
value: '',
|
|
221
|
+
component: ElInput,
|
|
222
|
+
params: {
|
|
223
|
+
'v-length.range': {
|
|
224
|
+
min: 0,
|
|
225
|
+
max: 1000,
|
|
226
|
+
int: true,
|
|
227
|
+
},
|
|
228
|
+
rules: [
|
|
229
|
+
{
|
|
230
|
+
required: true,
|
|
231
|
+
message: '请输入',
|
|
232
|
+
},
|
|
233
|
+
],
|
|
234
|
+
},
|
|
235
|
+
},
|
|
236
|
+
],
|
|
237
|
+
[
|
|
238
|
+
{
|
|
239
|
+
key: 'det_area_mode',
|
|
240
|
+
label: '检测区域工作模式',
|
|
241
|
+
value: 'normal',
|
|
242
|
+
component: ElRadioGroup,
|
|
243
|
+
events: {
|
|
244
|
+
change: detAreaModeChange,
|
|
245
|
+
},
|
|
246
|
+
params: {
|
|
247
|
+
rules: [
|
|
248
|
+
{
|
|
249
|
+
required: true,
|
|
250
|
+
message: '请选择',
|
|
251
|
+
trigger: 'change',
|
|
252
|
+
},
|
|
253
|
+
],
|
|
254
|
+
options: [
|
|
255
|
+
{
|
|
256
|
+
value: 'normal',
|
|
257
|
+
label: '常规检测(normal)',
|
|
258
|
+
},
|
|
259
|
+
{
|
|
260
|
+
value: 'abnormal',
|
|
261
|
+
label: '非常规检测(abnormal)',
|
|
262
|
+
},
|
|
263
|
+
],
|
|
264
|
+
},
|
|
265
|
+
},
|
|
266
|
+
],
|
|
267
|
+
],
|
|
268
|
+
})
|
|
269
|
+
|
|
270
|
+
function detAreaModeChange(value: any) {
|
|
271
|
+
if (value === 'abnormal') {
|
|
272
|
+
if (state.rows3?.length && state.rows3[state.rows3.length - 1]?.[0]?.key === 'det_area_json') {
|
|
273
|
+
state.rows3.pop()
|
|
274
|
+
}
|
|
275
|
+
state.rows3.push([
|
|
276
|
+
{
|
|
277
|
+
key: 'det_area_json',
|
|
278
|
+
label: '感兴趣区域',
|
|
279
|
+
value: '',
|
|
280
|
+
component: ElInput,
|
|
281
|
+
span: 6,
|
|
282
|
+
events: {
|
|
283
|
+
change: (value) => getAreasHandler(value),
|
|
284
|
+
},
|
|
285
|
+
params: {
|
|
286
|
+
rules: [
|
|
287
|
+
{
|
|
288
|
+
required: true,
|
|
289
|
+
message: '请输入',
|
|
290
|
+
trigger: 'change',
|
|
291
|
+
},
|
|
292
|
+
],
|
|
293
|
+
},
|
|
294
|
+
},
|
|
295
|
+
{ value: ' ' },
|
|
296
|
+
])
|
|
297
|
+
} else {
|
|
298
|
+
state.rows3.pop()
|
|
299
|
+
}
|
|
300
|
+
}
|
|
301
|
+
|
|
302
|
+
function getAreasHandler(value: any) {
|
|
303
|
+
state.rows3[state.rows3.length - 1][0].value = value
|
|
304
|
+
}
|
|
305
|
+
|
|
306
|
+
/**
|
|
307
|
+
* 保存
|
|
308
|
+
*/
|
|
309
|
+
async function getFormData() {
|
|
310
|
+
try {
|
|
311
|
+
await formRef.value.validate()
|
|
312
|
+
} catch (error: any) {
|
|
313
|
+
console.log(error)
|
|
314
|
+
ElMessage.error('表单校验失败')
|
|
315
|
+
state.formData = {}
|
|
316
|
+
return false
|
|
317
|
+
}
|
|
318
|
+
const data1 = row1Ref.value?.getKeyValuePairs?.(state.rows)
|
|
319
|
+
const data2 = row2Ref.value?.getKeyValuePairs?.(state.rows2)
|
|
320
|
+
const data3 = row3Ref.value?.getKeyValuePairs?.(state.rows3)
|
|
321
|
+
const data = { ...data1, ...data2, ...data3 }
|
|
322
|
+
state.formData = data
|
|
323
|
+
ElMessage.success('表单校验成功')
|
|
324
|
+
return data
|
|
325
|
+
}
|
|
326
|
+
|
|
327
|
+
/**
|
|
328
|
+
* 重置表单
|
|
329
|
+
*/
|
|
330
|
+
async function resetFormData() {
|
|
331
|
+
// 使用组件内置的 resetForm 方法
|
|
332
|
+
row1Ref.value?.resetForm?.()
|
|
333
|
+
row2Ref.value?.resetForm?.()
|
|
334
|
+
row3Ref.value?.resetForm?.()
|
|
335
|
+
setTimeout(()=>{
|
|
336
|
+
// 重置表单验证状态
|
|
337
|
+
formRef.value?.clearValidate?.()
|
|
338
|
+
// 清空结果显示
|
|
339
|
+
state.formData = {}
|
|
340
|
+
ElMessage.success('表单重置成功')
|
|
341
|
+
}, 0)
|
|
342
|
+
}
|
|
343
|
+
|
|
344
|
+
/**
|
|
345
|
+
* 重置表单数据到指定值或默认值
|
|
346
|
+
* @param targetRows 要重置的rows数据
|
|
347
|
+
* @param defaultValues 默认值对象,key为字段key,value为默认值
|
|
348
|
+
*/
|
|
349
|
+
function resetFormToDefaults(targetRows: any[], defaultValues: Record<string, any> = {}) {
|
|
350
|
+
for (let rowIndex = 0; rowIndex < targetRows.length; rowIndex++) {
|
|
351
|
+
const row = targetRows[rowIndex]
|
|
352
|
+
for (let colIndex = 0; colIndex < row.length; colIndex++) {
|
|
353
|
+
const item = row[colIndex]
|
|
354
|
+
if (item.key) {
|
|
355
|
+
// 如果提供了默认值,使用默认值,否则根据组件类型重置
|
|
356
|
+
if (defaultValues.hasOwnProperty(item.key)) {
|
|
357
|
+
item.value = cloneDeep(defaultValues[item.key])
|
|
358
|
+
} else {
|
|
359
|
+
// 根据组件类型或当前值类型设置默认值
|
|
360
|
+
if (Array.isArray(item.value)) {
|
|
361
|
+
item.value = []
|
|
362
|
+
} else if (typeof item.value === 'number') {
|
|
363
|
+
item.value = 0
|
|
364
|
+
} else if (typeof item.value === 'boolean') {
|
|
365
|
+
item.value = false
|
|
366
|
+
} else {
|
|
367
|
+
item.value = ''
|
|
368
|
+
}
|
|
369
|
+
}
|
|
370
|
+
|
|
371
|
+
// 重置删除的文件列表
|
|
372
|
+
if (item.delValue !== undefined) {
|
|
373
|
+
item.delValue = defaultValues[`${item.key}_delValue`]
|
|
374
|
+
? cloneDeep(defaultValues[`${item.key}_delValue`])
|
|
375
|
+
: []
|
|
376
|
+
}
|
|
377
|
+
}
|
|
378
|
+
|
|
379
|
+
// 检查子项
|
|
380
|
+
if (item.children && Array.isArray(item.children)) {
|
|
381
|
+
for (let childIndex = 0; childIndex < item.children.length; childIndex++) {
|
|
382
|
+
const child = item.children[childIndex]
|
|
383
|
+
if (child.key) {
|
|
384
|
+
// 重置子项
|
|
385
|
+
if (defaultValues.hasOwnProperty(child.key)) {
|
|
386
|
+
child.value = cloneDeep(defaultValues[child.key])
|
|
387
|
+
} else {
|
|
388
|
+
if (Array.isArray(child.value)) {
|
|
389
|
+
child.value = []
|
|
390
|
+
} else if (typeof child.value === 'number') {
|
|
391
|
+
child.value = 0
|
|
392
|
+
} else if (typeof child.value === 'boolean') {
|
|
393
|
+
child.value = false
|
|
394
|
+
} else {
|
|
395
|
+
child.value = ''
|
|
396
|
+
}
|
|
397
|
+
}
|
|
398
|
+
|
|
399
|
+
// 重置子项删除的文件列表
|
|
400
|
+
if (child.delValue !== undefined) {
|
|
401
|
+
child.delValue = defaultValues[`${child.key}_delValue`]
|
|
402
|
+
? cloneDeep(defaultValues[`${child.key}_delValue`])
|
|
403
|
+
: []
|
|
404
|
+
}
|
|
405
|
+
}
|
|
406
|
+
}
|
|
407
|
+
}
|
|
408
|
+
}
|
|
409
|
+
}
|
|
410
|
+
}
|
|
411
|
+
|
|
412
|
+
/**
|
|
413
|
+
* 批量设置表单值
|
|
414
|
+
* @param targetRows 要设置的rows数据
|
|
415
|
+
* @param values 值对象,key为字段key,value为要设置的值
|
|
416
|
+
*/
|
|
417
|
+
function setFormValues(targetRows: any[], values: Record<string, any> = {}) {
|
|
418
|
+
for (let rowIndex = 0; rowIndex < targetRows.length; rowIndex++) {
|
|
419
|
+
const row = targetRows[rowIndex]
|
|
420
|
+
for (let colIndex = 0; colIndex < row.length; colIndex++) {
|
|
421
|
+
const item = row[colIndex]
|
|
422
|
+
if (item.key && values.hasOwnProperty(item.key)) {
|
|
423
|
+
item.value = cloneDeep(values[item.key])
|
|
424
|
+
}
|
|
425
|
+
|
|
426
|
+
// 检查子项
|
|
427
|
+
if (item.children && Array.isArray(item.children)) {
|
|
428
|
+
for (let childIndex = 0; childIndex < item.children.length; childIndex++) {
|
|
429
|
+
const child = item.children[childIndex]
|
|
430
|
+
if (child.key && values.hasOwnProperty(child.key)) {
|
|
431
|
+
child.value = cloneDeep(values[child.key])
|
|
432
|
+
}
|
|
433
|
+
}
|
|
434
|
+
}
|
|
435
|
+
}
|
|
436
|
+
}
|
|
437
|
+
}
|
|
438
|
+
|
|
439
|
+
/**
|
|
440
|
+
* 重置所有表单到默认值(新的重置方法)
|
|
441
|
+
* @param customDefaults 自定义默认值
|
|
442
|
+
*/
|
|
443
|
+
function resetAllFormsToDefaults(customDefaults: Record<string, any> = {}) {
|
|
444
|
+
// 重置第一个表单
|
|
445
|
+
resetFormToDefaults(state.rows, customDefaults)
|
|
446
|
+
|
|
447
|
+
// 重置第二个表单
|
|
448
|
+
resetFormToDefaults(state.rows2, customDefaults)
|
|
449
|
+
|
|
450
|
+
// 重置第三个表单
|
|
451
|
+
resetFormToDefaults(state.rows3, customDefaults)
|
|
452
|
+
|
|
453
|
+
// 重置表单验证状态
|
|
454
|
+
formRef.value?.clearValidate?.()
|
|
455
|
+
|
|
456
|
+
// 清空结果显示
|
|
457
|
+
state.formData = {}
|
|
458
|
+
|
|
459
|
+
ElMessage.success('表单重置到默认值成功')
|
|
460
|
+
}
|
|
461
|
+
</script>
|
|
462
|
+
|
|
463
|
+
<style lang="scss" scoped>
|
|
464
|
+
.demo-container {
|
|
465
|
+
padding: 20px;
|
|
466
|
+
max-width: 1400px;
|
|
467
|
+
margin: 0 auto;
|
|
468
|
+
}
|
|
469
|
+
|
|
470
|
+
.control-panel {
|
|
471
|
+
background: #f5f5f5;
|
|
472
|
+
padding: 20px;
|
|
473
|
+
border-radius: 8px;
|
|
474
|
+
margin-bottom: 20px;
|
|
475
|
+
|
|
476
|
+
h3 {
|
|
477
|
+
margin: 0 0 20px 0;
|
|
478
|
+
color: #333;
|
|
479
|
+
}
|
|
480
|
+
|
|
481
|
+
h4 {
|
|
482
|
+
margin: 15px 0 10px 0;
|
|
483
|
+
color: #666;
|
|
484
|
+
font-size: 14px;
|
|
485
|
+
}
|
|
486
|
+
}
|
|
487
|
+
|
|
488
|
+
.config-section,
|
|
489
|
+
.upload-section,
|
|
490
|
+
.action-section {
|
|
491
|
+
margin-bottom: 20px;
|
|
492
|
+
padding: 15px;
|
|
493
|
+
background: white;
|
|
494
|
+
border-radius: 6px;
|
|
495
|
+
border: 1px solid #e0e0e0;
|
|
496
|
+
|
|
497
|
+
.config-select {
|
|
498
|
+
width: 300px;
|
|
499
|
+
margin-right: 10px;
|
|
500
|
+
}
|
|
501
|
+
|
|
502
|
+
input[type='file'] {
|
|
503
|
+
margin-right: 10px;
|
|
504
|
+
}
|
|
505
|
+
|
|
506
|
+
.el-button {
|
|
507
|
+
margin-right: 10px;
|
|
508
|
+
margin-bottom: 5px;
|
|
509
|
+
}
|
|
510
|
+
}
|
|
511
|
+
|
|
512
|
+
.form-container {
|
|
513
|
+
background: white;
|
|
514
|
+
padding: 20px;
|
|
515
|
+
border-radius: 8px;
|
|
516
|
+
border: 1px solid #e0e0e0;
|
|
517
|
+
margin-bottom: 20px;
|
|
518
|
+
}
|
|
519
|
+
|
|
520
|
+
.empty-state {
|
|
521
|
+
text-align: center;
|
|
522
|
+
padding: 60px 20px;
|
|
523
|
+
background: white;
|
|
524
|
+
border-radius: 8px;
|
|
525
|
+
border: 1px solid #e0e0e0;
|
|
526
|
+
}
|
|
527
|
+
|
|
528
|
+
.data-card {
|
|
529
|
+
margin-top: 20px;
|
|
530
|
+
|
|
531
|
+
.card-header {
|
|
532
|
+
display: flex;
|
|
533
|
+
justify-content: space-between;
|
|
534
|
+
align-items: center;
|
|
535
|
+
}
|
|
536
|
+
|
|
537
|
+
.form-data-display {
|
|
538
|
+
background-color: #f5f7fa;
|
|
539
|
+
padding: 15px;
|
|
540
|
+
border-radius: 4px;
|
|
541
|
+
font-size: 12px;
|
|
542
|
+
line-height: 1.5;
|
|
543
|
+
max-height: 400px;
|
|
544
|
+
overflow-y: auto;
|
|
545
|
+
}
|
|
546
|
+
}
|
|
547
|
+
|
|
548
|
+
@media (max-width: 768px) {
|
|
549
|
+
.config-select {
|
|
550
|
+
width: 100% !important;
|
|
551
|
+
margin-bottom: 10px;
|
|
552
|
+
}
|
|
553
|
+
|
|
554
|
+
.el-button {
|
|
555
|
+
width: 100%;
|
|
556
|
+
margin-bottom: 10px;
|
|
557
|
+
}
|
|
558
|
+
}
|
|
559
|
+
</style>
|
|
560
|
+
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
<template>
|
|
2
|
+
<NsImage :src="src" :apiUrl="apiUrl" :hasPreview="hasPreview">
|
|
3
|
+
<img
|
|
4
|
+
:src="ThemeVar.VARS.getPropertyValue('--matrix-empty-img')"
|
|
5
|
+
style="width: 100%; height: 100%"
|
|
6
|
+
@click.stop
|
|
7
|
+
/>
|
|
8
|
+
</NsImage>
|
|
9
|
+
</template>
|
|
10
|
+
|
|
11
|
+
<script setup lang="ts">
|
|
12
|
+
import { reactive, ref } from 'vue';
|
|
13
|
+
import { ThemeVar } from '../../packages/utils/loadCssVars'
|
|
14
|
+
const src = ref('')
|
|
15
|
+
const hasPreview = ref(true)
|
|
16
|
+
const apiUrl = reactive( {
|
|
17
|
+
type: Object,
|
|
18
|
+
default: ()=>({
|
|
19
|
+
method: 'get',
|
|
20
|
+
url: '/tool/file/getFileDetail',
|
|
21
|
+
paramkey: 'fileIds',
|
|
22
|
+
params: {},
|
|
23
|
+
}),
|
|
24
|
+
})
|
|
25
|
+
</script>
|
|
26
|
+
<style lang="scss" scoped>
|
|
27
|
+
</style>
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
<template>
|
|
2
|
+
<div class="dm">
|
|
3
|
+
<NsMD class="dm-ui" :msg="msg"></NsMD>
|
|
4
|
+
</div>
|
|
5
|
+
</template>
|
|
6
|
+
<script setup lang="ts" name="">
|
|
7
|
+
import { ref } from 'vue';
|
|
8
|
+
|
|
9
|
+
const msg = ref('好的,我可以为您写一个项目需求文档的模板。由于知识库为空,我将基于通用项目管理知识和最佳实践来构建此文档。请注意,这只是一个模板,您需要根据您的具体项目进行调整和完善。\n\n---\n\n## 项目需求文档\n\n**项目名称:** [在此处填写项目名称]\n\n**版本:** 1.0\n\n**日期:** 2023年10月27日\n\n**作者:** [您的姓名/团队名称]\n\n### 1. 引言\n\n**1.1 目的**\n\n本文档旨在详细描述[项目名称]的项目需求,为项目的规划、设计、开发、测试和部署提供明确的指导和依据。\n\n**1.2 范围**\n\n本文档涵盖项目的目标、功能、性能、用户界面、安全、约束条件以及验收标准。\n\n**1.3 目标读者**\n\n* 项目经理\n* 开发团队\n* 测试团队\n* 业务分析师\n* 利益相关者\n\n### 2. 项目背景\n\n**2.1 背景描述**\n\n[详细描述项目产生的背景,以及项目解决的问题或满足的需求。]\n\n**2.2 现有系统/流程描述**\n\n[如果项目涉及替换或改进现有系统/流程,请详细描述现有系统/流程的情况。]\n\n### 3. 项目目标\n\n**3.1 业务目标**\n\n[描述项目对业务的影响,例如提高效率、降低成本、增加收入等。]\n\n**3.2 用户目标**\n\n[描述用户通过使用项目后可以获得什么价值。]\n\n### 4. 功能需求\n\n| ID | 功能描述 | 优先级 | 备注 |\n|---|---|---|---|\n| 1 | [功能描述1] | 高 | [相关信息] |\n| 2 | [功能描述2] | 中 | [相关信息] |\n| 3 | [功能描述3] | 低 | [相关信息] |\n| ... | ... | ... | ... |\n\n* **优先级:** 高 (必须实现)、中 (重要但可推迟)、低 (可选功能)\n\n### 5. 非功能需求\n\n**5.1 性能需求**\n\n* 响应时间:[例如:页面加载时间不超过3秒]\n* 并发用户数:[例如:支持1000个并发用户]\n* 数据存储容量:[例如:需要存储1TB的数据]\n\n**5.2 安全需求**\n\n* 用户认证:[例如:采用用户名/密码认证、OAuth认证]\n* 数据加密:[例如:采用SSL/TLS加密传输数据]\n* 权限控制:[例如:不同用户具有不同的权限]\n\n**5.3 可用性需求**\n\n* 系统可用时间:[例如:99.9%可用性]\n* 故障恢复:[例如:数据备份和恢复机制]\n\n**5.4 可靠性需求**\n\n* 错误率:[例如:系统错误率低于0.1%]\n\n**5.5 可维护性需求**\n\n* 代码可读性:[例如:代码规范、注释]\n* 模块化设计:[例如:采用模块化架构]\n\n**5.6 可扩展性需求**\n\n* 系统架构:[例如:支持水平扩展]\n\n### 6. 用户界面 (UI) 需求\n\n* 界面风格:[例如:简洁、现代]\n* 布局:[例如:响应式布局]\n* 主要页面:[例如:首页、登录页面、功能页面]\n* [可包含UI原型图或线框图]\n\n### 7. 约束条件\n\n* 技术限制:[例如:使用的技术栈]\n* 预算限制:[例如:项目预算]\n* 时间限制:[例如:项目截止日期]\n* 资源限制:[例如:人力资源]\n\n### 8. 验收标准\n\n* 功能测试:所有功能模块必须通过测试。\n* 性能测试:系统必须满足性能需求。\n* 安全测试:系统必须通过安全测试。\n* 用户验收测试:用户必须对系统感到满意。\n\n### 9. 风险评估\n\n| 风险描述 | 可能性 | 影响 | 缓解措施 |\n|---|---|---|---|\n| [风险1] | 高 | 高 | [缓解措施1] |\n| [风险2] | 中 | 中 | [缓解措施2] |\n| ... | ... | ... | ... |\n\n### 10. 术语表\n\n* [术语1:定义]\n* [术语2:定义]\n* ...\n\n---\n\n请注意,这是一个通用模板。您需要根据您的具体项目需求进行修改和完善。 由于**知识库中未找到您要的答案!**,我无法根据任何特定信息为您定制文档。 如果您能提供更详细的项目信息,我可以更好地帮助您')
|
|
10
|
+
</script>
|
|
11
|
+
<style lang="scss" scoped>
|
|
12
|
+
.dm {
|
|
13
|
+
width: 100%;
|
|
14
|
+
height: 100%;
|
|
15
|
+
.dm-ui {
|
|
16
|
+
width: 100%;
|
|
17
|
+
height: 100%;
|
|
18
|
+
}
|
|
19
|
+
}
|
|
20
|
+
</style>
|