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
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "n20-common-lib",
3
- "version": "2.13.8",
3
+ "version": "2.13.10",
4
4
  "private": false,
5
5
  "scripts": {
6
6
  "serve": "vue-cli-service serve",
@@ -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="el-icon-view"
173
+ icon="n20-icon-query"
172
174
  :disabled="!row[keys.url]"
173
- @click="seeFile(row)"
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
- IWSADetachedSignAdvDefaultDN,
8
+ IWSADetachedSign,
9
9
  IWSAAttachedVerify,
10
10
  IWSASendAvailable,
11
11
  IWSAGetAvailable,
12
12
  IWSAGetAllCertsListInfo
13
13
  } = new IWSAgent()
14
14
  IWSASetTimeOut(6000)
15
- let certType = 'RSA'
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
- IWSAGetAllCertsListInfo('infosec.sm2', 'Sign', 2, (dnList2) => {
107
- if (!dn) {
108
- Message.error('没有获取到签名参数DN!')
109
- reject()
110
- }
111
- if (!dnList && !dnList2) {
112
- Message.error('没有获取到证书列表!')
113
- reject()
114
- }
115
- if (dnList.length === 0 && dnList2.length === 0) {
116
- Message.error('用户证书信息与当前用户不匹配!')
117
- reject()
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
- certInfo = verifyDn([...dnList, ...dnList2], dn)
121
- resolve(certInfo)
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 = IWSADetachedSignAdvDefaultDN
134
+ signMethod = IWSADetachedSign
141
135
  }
142
136
  return new Promise((resolve, reject) => {
143
- signMethod(plain, 'infosec.sm2', certStoreType, certDN, '1', 'SHA1', (errorCode, signedData) => {
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
- dnList.find((C, i) => {
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
- certType = C.CertType
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 dnListA = dnList?.map((res) => res.certDN)?.join(',')
176
+ let dnListB = dnList?.map((res) => res.certDN)?.join(',')
175
177
  Message({
176
178
  type: 'error',
177
- text: `证书Dn不匹配:${dnListA}里面无法匹配===>${dn}`,
179
+ text: `证书Dn不匹配:${dnListB}里面无法匹配===>${dn}`,
178
180
  duration: 5000
179
181
  })
180
182
  return index