n20-common-lib 2.13.8 → 2.13.10
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/package.json
CHANGED
|
@@ -0,0 +1,90 @@
|
|
|
1
|
+
<template>
|
|
2
|
+
<span>
|
|
3
|
+
<slot :customEvent="aiFn">
|
|
4
|
+
<el-button v-title="'AI识别'" type="text" icon="n20-icon-query" @click="aiFn" />
|
|
5
|
+
</slot>
|
|
6
|
+
<cl-dialog v-drag :visible.sync="visible" title="AI识别" :destroy-on-open="true" width="690px">
|
|
7
|
+
<cl-upload
|
|
8
|
+
:drag="true"
|
|
9
|
+
:file-name.sync="fileName"
|
|
10
|
+
:file-url.sync="fileUrl"
|
|
11
|
+
action="/api/neams/eamsbaserecord/batchSavejson"
|
|
12
|
+
:on-success="onSuccess"
|
|
13
|
+
:msg-type="null"
|
|
14
|
+
:data="dataPorp"
|
|
15
|
+
>
|
|
16
|
+
<template slot="trigger">
|
|
17
|
+
<i class="drag-icon n20-icon-shangchuan"></i>
|
|
18
|
+
<span class="drag-text">点击或将文件拖拽到这里上传</span>
|
|
19
|
+
</template>
|
|
20
|
+
</cl-upload>
|
|
21
|
+
</cl-dialog>
|
|
22
|
+
</span>
|
|
23
|
+
</template>
|
|
24
|
+
|
|
25
|
+
<script>
|
|
26
|
+
export default {
|
|
27
|
+
name: 'AiButton',
|
|
28
|
+
components: {},
|
|
29
|
+
props: {
|
|
30
|
+
AIOptions: {
|
|
31
|
+
type: Object,
|
|
32
|
+
default: () => ({})
|
|
33
|
+
},
|
|
34
|
+
dataPorp: {
|
|
35
|
+
type: Object,
|
|
36
|
+
default: () => {
|
|
37
|
+
return {
|
|
38
|
+
data: JSON.stringify({
|
|
39
|
+
syscode: '010000000',
|
|
40
|
+
appno: 'abcd',
|
|
41
|
+
bussValue: '006001001',
|
|
42
|
+
cltno: '001',
|
|
43
|
+
creator: 'jz'
|
|
44
|
+
})
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
},
|
|
49
|
+
data() {
|
|
50
|
+
return {
|
|
51
|
+
visible: false,
|
|
52
|
+
fileName: '',
|
|
53
|
+
fileUrl: ''
|
|
54
|
+
}
|
|
55
|
+
},
|
|
56
|
+
computed: {},
|
|
57
|
+
watch: {},
|
|
58
|
+
created() {},
|
|
59
|
+
mounted() {},
|
|
60
|
+
methods: {
|
|
61
|
+
aiFn() {
|
|
62
|
+
this.visible = true
|
|
63
|
+
},
|
|
64
|
+
onSuccess({ data }) {
|
|
65
|
+
this.AiFn(data)
|
|
66
|
+
},
|
|
67
|
+
// ai识别
|
|
68
|
+
async AiFn(beid) {
|
|
69
|
+
if (!this.AIOptions.bussType) {
|
|
70
|
+
this.$message.error('请先配置bussType')
|
|
71
|
+
return false
|
|
72
|
+
}
|
|
73
|
+
const { data, code } = await this.$axios.post(
|
|
74
|
+
this.apiPrefix ? `${this.apiPrefix}neams/eamsbaserecord/aiAttaFile` : `/neams/eamsbaserecord/aiAttaFile`,
|
|
75
|
+
{
|
|
76
|
+
beid: beid,
|
|
77
|
+
bussType: this.AIOptions.bussType,
|
|
78
|
+
extendPrompt: ''
|
|
79
|
+
}
|
|
80
|
+
)
|
|
81
|
+
if (code === 200) {
|
|
82
|
+
this.$emit('aiFn', data)
|
|
83
|
+
this.visible = false
|
|
84
|
+
this.$message.success('识别成功')
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
</script>
|
|
90
|
+
<style lang="scss" scoped></style>
|
|
@@ -165,12 +165,14 @@
|
|
|
165
165
|
<el-table-column :label="'操作' | $lc" align="center" width="90" fixed="right">
|
|
166
166
|
<slot slot="header" slot-scope="scope" name="handle-header" :column="scope.column">{{ '操作' | $lc }}</slot>
|
|
167
167
|
<slot slot-scope="{ row }" name="handle" :row="row">
|
|
168
|
+
<el-button type="text" icon="el-icon-view" :disabled="!row[keys.url]" @click="seeFile(row)" />
|
|
168
169
|
<el-button
|
|
169
|
-
v-if="getOfficeStatus"
|
|
170
|
+
v-if="getOfficeStatus && openAI"
|
|
171
|
+
v-title="'ai识别'"
|
|
170
172
|
type="text"
|
|
171
|
-
icon="
|
|
173
|
+
icon="n20-icon-query"
|
|
172
174
|
:disabled="!row[keys.url]"
|
|
173
|
-
@click="
|
|
175
|
+
@click="AiFn(row)"
|
|
174
176
|
/>
|
|
175
177
|
<el-button
|
|
176
178
|
v-if="readonly"
|
|
@@ -334,6 +336,14 @@ export default {
|
|
|
334
336
|
}
|
|
335
337
|
},
|
|
336
338
|
props: {
|
|
339
|
+
AIOptions: {
|
|
340
|
+
type: Object,
|
|
341
|
+
default: () => ({})
|
|
342
|
+
},
|
|
343
|
+
openAI: {
|
|
344
|
+
type: Boolean,
|
|
345
|
+
default: false
|
|
346
|
+
},
|
|
337
347
|
readonly: {
|
|
338
348
|
type: Boolean,
|
|
339
349
|
default: false
|
|
@@ -466,6 +476,24 @@ export default {
|
|
|
466
476
|
this.getConfiguration()
|
|
467
477
|
},
|
|
468
478
|
methods: {
|
|
479
|
+
// ai识别
|
|
480
|
+
async AiFn(row) {
|
|
481
|
+
if (!this.AIOptions.bussType) {
|
|
482
|
+
this.$message.error('请先配置bussType')
|
|
483
|
+
return false
|
|
484
|
+
}
|
|
485
|
+
const { data, code } = await this.$axios.post(
|
|
486
|
+
this.apiPrefix ? `${this.apiPrefix}neams/eamsbaserecord/aiAttaFile` : `/neams/eamsbaserecord/aiAttaFile`,
|
|
487
|
+
{
|
|
488
|
+
beid: row.beid,
|
|
489
|
+
bussType: this.AIOptions.bussType,
|
|
490
|
+
extendPrompt: ''
|
|
491
|
+
}
|
|
492
|
+
)
|
|
493
|
+
if (code === 200) {
|
|
494
|
+
this.$emit('aiFn', data)
|
|
495
|
+
}
|
|
496
|
+
},
|
|
469
497
|
getConfiguration() {
|
|
470
498
|
getJsonc('portal/server-config.jsonc', null, true)
|
|
471
499
|
.then(({ loginConf }) => {
|
|
@@ -536,7 +564,7 @@ export default {
|
|
|
536
564
|
$uploadwrap.submit()
|
|
537
565
|
},
|
|
538
566
|
batchSuccess(response, file, fileList) {
|
|
539
|
-
let row = {...this.dataPorp.keys}
|
|
567
|
+
let row = { ...this.dataPorp.keys }
|
|
540
568
|
this.tableData.splice(0, 0, row)
|
|
541
569
|
this.$nextTick(() => {
|
|
542
570
|
this.onSuccessFn(response, file, fileList, row)
|
package/src/index.js
CHANGED
|
@@ -66,6 +66,7 @@ import WornPagination from './components/WornPagination/index.vue'
|
|
|
66
66
|
|
|
67
67
|
import AdvancedFilter from './components/AdvancedFilter/index.vue'
|
|
68
68
|
import AttachmentPass from './components/AttachmentPass/index.vue'
|
|
69
|
+
import AIButton from './components/AIButton/index.vue'
|
|
69
70
|
import DateChoose from './components/DateChoose/index.vue'
|
|
70
71
|
import ElectronicArchive from './components/ElectronicArchive/index.vue'
|
|
71
72
|
import HandlingAdvice from './components/HandlingAdvice/index.vue'
|
|
@@ -232,6 +233,7 @@ const components = [
|
|
|
232
233
|
ElectronicArchive,
|
|
233
234
|
Preview,
|
|
234
235
|
AttachmentPass,
|
|
236
|
+
AIButton,
|
|
235
237
|
HandlingAdvice,
|
|
236
238
|
/* old */
|
|
237
239
|
TableO,
|
|
@@ -303,6 +305,7 @@ export {
|
|
|
303
305
|
ApproveCard,
|
|
304
306
|
ApproveCardZjk,
|
|
305
307
|
AttachmentPass,
|
|
308
|
+
AIButton,
|
|
306
309
|
BusiDatePicker,
|
|
307
310
|
Button,
|
|
308
311
|
ButtonGroup,
|
|
@@ -5,14 +5,14 @@ import { IWSAgent } from './InfosecNetSignCNGAgent.min.js'
|
|
|
5
5
|
const {
|
|
6
6
|
IWSASetTimeOut,
|
|
7
7
|
IWSAAttachedSignAdvDefaultDN,
|
|
8
|
-
|
|
8
|
+
IWSADetachedSign,
|
|
9
9
|
IWSAAttachedVerify,
|
|
10
10
|
IWSASendAvailable,
|
|
11
11
|
IWSAGetAvailable,
|
|
12
12
|
IWSAGetAllCertsListInfo
|
|
13
13
|
} = new IWSAgent()
|
|
14
14
|
IWSASetTimeOut(6000)
|
|
15
|
-
let
|
|
15
|
+
let certIndex = 0
|
|
16
16
|
let certDN = ''
|
|
17
17
|
function getDN() {
|
|
18
18
|
let dn
|
|
@@ -103,23 +103,21 @@ export function getCertInfo(dn) {
|
|
|
103
103
|
return new Promise((resolve, reject) => {
|
|
104
104
|
let certInfo
|
|
105
105
|
IWSAGetAllCertsListInfo('infosec.sm2', 'Sign', 0, (dnList) => {
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
}
|
|
106
|
+
if (!dn) {
|
|
107
|
+
Message.error('没有获取到签名参数DN!')
|
|
108
|
+
reject()
|
|
109
|
+
}
|
|
110
|
+
if (!dnList) {
|
|
111
|
+
Message.error('没有获取到证书列表!')
|
|
112
|
+
reject()
|
|
113
|
+
}
|
|
114
|
+
if (dnList.length === 0) {
|
|
115
|
+
Message.error('用户证书信息与当前用户不匹配!')
|
|
116
|
+
reject()
|
|
117
|
+
}
|
|
119
118
|
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
})
|
|
119
|
+
certInfo = verifyDn(dnList, dn)
|
|
120
|
+
resolve(certInfo)
|
|
123
121
|
})
|
|
124
122
|
})
|
|
125
123
|
}
|
|
@@ -131,16 +129,12 @@ export function getCertInfo(dn) {
|
|
|
131
129
|
* @returns {Promise<string>} 签名后的密文信息
|
|
132
130
|
*/
|
|
133
131
|
export async function performSign(plain, index) {
|
|
134
|
-
let certStoreType = 2
|
|
135
|
-
if (certType === 'RSA') {
|
|
136
|
-
certStoreType = 1
|
|
137
|
-
}
|
|
138
132
|
let signMethod = IWSAAttachedSignAdvDefaultDN
|
|
139
133
|
if (window.NetSignMethod === 'Detached') {
|
|
140
|
-
signMethod =
|
|
134
|
+
signMethod = IWSADetachedSign
|
|
141
135
|
}
|
|
142
136
|
return new Promise((resolve, reject) => {
|
|
143
|
-
signMethod(
|
|
137
|
+
signMethod(2, plain, certIndex, 'SHA1', (errorCode, signedData) => {
|
|
144
138
|
if (errorCode === 0 || errorCode === '0') {
|
|
145
139
|
resolve(signedData)
|
|
146
140
|
} else {
|
|
@@ -159,22 +153,30 @@ export async function performSign(plain, index) {
|
|
|
159
153
|
*/
|
|
160
154
|
function verifyDn(dnList, dn) {
|
|
161
155
|
let userDnAttrsArr = dn.split(',').map((c) => c.trim())
|
|
162
|
-
|
|
163
156
|
let index = -1
|
|
164
|
-
|
|
157
|
+
// 先过滤满足证书的条件
|
|
158
|
+
let dnListA = JSON.parse(JSON.stringify(dnList)).filter((C, i) => {
|
|
165
159
|
let dnAttrsArr = C.certDN.split(',').map((c) => c.trim())
|
|
166
160
|
if (dnAttrsArr.every((dnAttr) => userDnAttrsArr.includes(dnAttr))) {
|
|
167
|
-
index = i
|
|
168
|
-
|
|
169
|
-
certDN = C.certDN // 保存证书DN到全局变量中 =
|
|
170
|
-
return true
|
|
161
|
+
C.index = i
|
|
162
|
+
return C
|
|
171
163
|
}
|
|
172
164
|
})
|
|
165
|
+
if (dnListA.length > 0) {
|
|
166
|
+
dnListA.forEach((item) => {
|
|
167
|
+
if (item.certType === 'SM2' && item.keyUsage === 'signature') {
|
|
168
|
+
index = item.index
|
|
169
|
+
} else {
|
|
170
|
+
index = dnListA[0].index
|
|
171
|
+
}
|
|
172
|
+
certIndex = item.index
|
|
173
|
+
})
|
|
174
|
+
}
|
|
173
175
|
if (index === -1) {
|
|
174
|
-
let
|
|
176
|
+
let dnListB = dnList?.map((res) => res.certDN)?.join(',')
|
|
175
177
|
Message({
|
|
176
178
|
type: 'error',
|
|
177
|
-
text: `证书Dn不匹配:${
|
|
179
|
+
text: `证书Dn不匹配:${dnListB}里面无法匹配===>${dn}`,
|
|
178
180
|
duration: 5000
|
|
179
181
|
})
|
|
180
182
|
return index
|