centaline-data-driven-v3 0.0.82 → 0.0.83

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": "centaline-data-driven-v3",
3
- "version": "0.0.82",
3
+ "version": "0.0.83",
4
4
  "private": false,
5
5
  "description": "centaline-data-driven-v3",
6
6
  "main": "dist/centaline-data-driven-v3.umd.js",
@@ -301,11 +301,9 @@ function clickHandler(routerKey, rowindex, forname, forrowindex, flagHaveAlert)
301
301
  if (typeof rowindex !== "undefined") {
302
302
  if (props.flagFormList) {
303
303
  emit("rolRouterclick", routerKey, rowindex, props.vmodel.$sourceIndex);
304
-
305
304
  }
306
305
  else {
307
- emit("rolRouterclick", routerKey, rowindex, forname, forrowindex, flagHaveAlert);
308
-
306
+ emit("rolRouterclick", routerKey, rowindex, forname, forrowindex, flagHaveAlert,props.vmodel,props.actionRouter);
309
307
  }
310
308
  }
311
309
  }
@@ -17,9 +17,22 @@
17
17
  <template v-for="message in model.messages">
18
18
  <div :key="message.id" class="message" v-if="message.content"
19
19
  :class="{ 'user-message': message.sender === 'user', 'ai-message': message.sender === 'ai' }">
20
- <div class="chat-message" :style="{ color: message.type == 'error' ? 'red' : '' }"
21
- v-html="htmlContent(message)">
22
- </div>
20
+ <template v-if="message.type == 'table'">
21
+ <div :style="{ 'width': tablewidth - 70 + 'px' }">
22
+ <div v-if="JSON.parse(message.content).title" style="margin-bottom: 10px;" v-html="JSON.parse(message.content).title"></div>
23
+ <template v-for="(row, rowindex) in JSON.parse(message.content).rows" :key="rowindex">
24
+ <ct-layout :vmodel="row" :cellLayout="JSON.parse(message.content).cellLayout" :rowindex="rowindex"
25
+ @rolRouterclick="rolRouterCellClickHandler"
26
+ :actionRouter="JSON.parse(message.content).actionRouters">
27
+ </ct-layout>
28
+ </template>
29
+ </div>
30
+ </template>
31
+ <template v-else>
32
+ <div class="chat-message" :style="{ color: message.type == 'error' ? 'red' : '' }"
33
+ v-html="htmlContent(message)">
34
+ </div>
35
+ </template>
23
36
  </div>
24
37
  <div v-else class="loading-container">
25
38
  <div class="loading-circle"></div>
@@ -30,8 +43,7 @@
30
43
  <!-- 输入区域 -->
31
44
  <div class="chat-editor" v-if="showAI">
32
45
  <div class="chat-input-editor-container">
33
- <textarea ref="textareaRef" class="chat-input"
34
- v-model="inputMessage" @keydown="handleKeydown"
46
+ <textarea ref="textareaRef" class="chat-input" v-model="inputMessage" @keydown="handleKeydown"
35
47
  :placeholder="model.placeholder"></textarea>
36
48
 
37
49
 
@@ -57,12 +69,13 @@
57
69
 
58
70
 
59
71
  <script setup lang="ts">
60
- import { ref, onActivated, nextTick, watch, computed } from 'vue'
72
+ import { ref, onActivated, nextTick, watch, computed, onMounted } from 'vue'
61
73
  import AIChat from '../../loader/src/AIChat'
62
74
  import common from '../../utils/common'
63
75
  import { marked } from 'marked';
64
76
  import DOMPurify from 'dompurify'
65
-
77
+ import Router from '../../loader/src/Router';
78
+ import { RouterClickHandler } from '../../utils/mixins';
66
79
 
67
80
  const emit = defineEmits(['loaded', "getRefFieldPara", "hideAI"])
68
81
  const props = defineProps({
@@ -70,6 +83,11 @@ const props = defineProps({
70
83
  router: Object,
71
84
  actionRouters: Array,
72
85
  form: Object,
86
+ tablewidth: Number,
87
+ isVisible: {
88
+ Boolean,
89
+ default: false,
90
+ },
73
91
  })
74
92
  interface StreamEventData {
75
93
  event: string
@@ -141,13 +159,7 @@ function load(data) {
141
159
  action();
142
160
  }
143
161
 
144
- onActivated(() => {
145
- nextTick(() => {
146
- if (inputMessage.value) {
147
- inputMessage.value.focus();
148
- }
149
- })
150
- })
162
+
151
163
  // Marked 配置
152
164
  marked.setOptions({
153
165
  breaks: true,
@@ -158,12 +170,20 @@ marked.setOptions({
158
170
  function htmlContent(message) {
159
171
  return DOMPurify.sanitize(marked(message.content) + '')
160
172
  };
161
- // 监听内容变化,调整 textarea 高度
162
- watch(inputMessage, () => {
173
+
174
+ // 监听多个值并执行不同逻辑
175
+ watch([() => inputMessage, () => props.isVisible], ([newVal1, newVal2], [oldVal1, oldVal2]) => {
163
176
  nextTick(() => {
164
- adjustTextareaHeight();
177
+ if (newVal1 !== oldVal1) {
178
+ adjustTextareaHeight();
179
+ }
180
+ if (newVal2) {
181
+ if (textareaRef.value) {
182
+ textareaRef.value.focus();
183
+ }
184
+ }
165
185
  });
166
- });
186
+ }, { flush: 'sync' }); // 控制监听的时机
167
187
 
168
188
  // 调整 textarea 高度
169
189
  const adjustTextareaHeight = () => {
@@ -314,7 +334,8 @@ const fetchAIResponse = async (params) => {
314
334
  })
315
335
  }).then(response => {
316
336
  if (!response.ok) {
317
- throw new Error('Network response was not ok');
337
+ common.message('网络响应不正常', 'error');
338
+ return;
318
339
  }
319
340
 
320
341
  // 获取响应的 ReadableStream
@@ -329,8 +350,6 @@ const fetchAIResponse = async (params) => {
329
350
  if (isStopped) {
330
351
  // 如果停止标志为 true,直接返回
331
352
  outtext.value += "\n\n用户停止"
332
- startTypingEffect(outtext.value);
333
- outtext.value = '';
334
353
  resolve();
335
354
  return;
336
355
  }
@@ -367,11 +386,28 @@ const fetchAIResponse = async (params) => {
367
386
  }).then(() => {
368
387
  // 在所有行处理完毕后执行 startTypingEffect
369
388
  if (outtext.value == '') {
370
- outtext.value = ' ';
389
+
371
390
  }
372
- UpdateMessageType('message');
373
- startTypingEffect(outtext.value);
374
- outtext.value = '';
391
+ let TemplateType = getTemplateType(outtext.value);
392
+ UpdateMessageType(TemplateType);
393
+
394
+ let type = model.value.messages[model.value.messages.length - 1].type;
395
+ if (type == "table" || type == "form") {
396
+ var data = JSON.parse(outtext.value).content;
397
+ if (type == "table") {
398
+ var actionRouters = [];
399
+ data.actionRouters.forEach((v) => {
400
+ var router = Router(v);
401
+ router.is = "ct-button";
402
+ actionRouters.push(router);
403
+ });
404
+ data.actionRouters = actionRouters
405
+ }
406
+ appendMessage(JSON.stringify(data));
407
+ } else {
408
+ startTypingEffect(outtext.value);
409
+ }
410
+ afoot.value = false;
375
411
  }).catch(error => {
376
412
  UpdateMessageType('error');
377
413
  if (error.name === 'AbortError') {
@@ -395,7 +431,7 @@ function stopRequest() {
395
431
  }).then(response => response.json()) // 将响应转换为 JSON
396
432
  .then(data => {
397
433
  if (data.result == 'success') {
398
- afoot.value = true;
434
+ afoot.value = false;
399
435
  }
400
436
 
401
437
  // 如果服务器返回 { result: "success" },这里会输出这个对象
@@ -459,13 +495,29 @@ const handleStreamEvent = (eventData: StreamEventData) => {
459
495
  }
460
496
 
461
497
  const getTemplateType = (fullText) => {
498
+ var rtn = "message";
499
+ try {
500
+ const eventData = JSON.parse(fullText)
501
+ if (eventData) {
502
+ if (eventData.content?.rows) {
503
+ rtn = 'table';
504
+ }
505
+ else if (eventData.content?.fields) {
506
+ rtn = 'form';
507
+ }
508
+ }
462
509
 
510
+ } catch (error) {
463
511
 
512
+ }
513
+
514
+ return rtn;
464
515
 
465
516
  }
466
517
 
467
518
 
468
519
  function startTypingEffect(fullText) {
520
+
469
521
  let index = 0;
470
522
  let timer = setInterval(() => {
471
523
  // 检查索引是否超出字符串长度
@@ -490,13 +542,39 @@ function startTypingEffect(fullText) {
490
542
  clearInterval(timer); // 清除定时器
491
543
  }
492
544
  }, 100); // 每100毫秒加载10个字符
493
- afoot.value = false;
545
+ outtext.value = '';
546
+
494
547
  }
495
548
 
496
549
  function hideAI() {
497
550
  emit("hideAI", false);
498
551
 
499
552
  }
553
+ //layout组件 路由操作
554
+ function rolRouterCellClickHandler(routerKey, rowindex, forname, forrowindex, flagHaveAlert, rowData, actionRouter) {
555
+ var submitData = {};
556
+ let field = actionRouter.find((b) => {
557
+ return b.key === routerKey;
558
+ });
559
+ field = Router(field);
560
+ if (typeof forname !== "undefined") {
561
+ field.submitListField.forEach((k) => {
562
+ submitData[k] = rowData[forname][forrowindex][k];
563
+ });
564
+ } else {
565
+ field.submitListField.forEach((k) => {
566
+ submitData[k] = rowData[k];
567
+ });
568
+ }
569
+ if (field.isCallTel) {
570
+ submitData.flagHaveAlert = flagHaveAlert || false;
571
+ }
572
+ let action = field.action;
573
+ if (field.actionField) {
574
+ action = rowData[field.actionField];
575
+ }
576
+ RouterClickHandler(field, submitData, action, model.value, 'table')
577
+ }
500
578
  </script>
501
579
 
502
580
  <style scoped>
@@ -532,6 +610,7 @@ function hideAI() {
532
610
  display: flex;
533
611
  flex-direction: column;
534
612
  gap: 1rem;
613
+
535
614
  }
536
615
 
537
616
  /* 隐藏滚动条 */
@@ -554,6 +633,10 @@ function hideAI() {
554
633
  max-height: none;
555
634
  /* 不限制子级高度 */
556
635
  border-radius: 10px;
636
+ word-wrap: break-word;
637
+ /* 确保内容自动换行 */
638
+ word-break: break-word;
639
+ /* 长单词或连续字符也能换行 */
557
640
 
558
641
  }
559
642
 
@@ -567,6 +650,10 @@ function hideAI() {
567
650
  align-self: flex-start;
568
651
  background-color: white;
569
652
  border: 1px solid #e0e0e0;
653
+ max-width: 100%;
654
+ /* 确保不超出父级宽度 */
655
+ width: auto;
656
+ /* 去掉固定宽度 */
570
657
  }
571
658
 
572
659
  .chat-message {
@@ -657,9 +744,10 @@ function hideAI() {
657
744
  }
658
745
 
659
746
  .chat-input::placeholder {
660
- color: #a8abb2;
661
- opacity: 1;
747
+ color: #a8abb2;
748
+ opacity: 1;
662
749
  }
750
+
663
751
  .chat-editor-action {
664
752
  display: flex;
665
753
  justify-content: space-between;
@@ -48,6 +48,7 @@ import Axios from 'axios';
48
48
  import { ref, nextTick } from 'vue'
49
49
  import { Search } from '@element-plus/icons-vue'
50
50
  import { initData, changeHandler } from '../../utils/mixins';
51
+ import common from '../../utils/common'
51
52
  import ComboBox from '../../loader/src/ComboBox';
52
53
  const emit = defineEmits(['click', 'input', 'change', 'popupSearchList', 'search'])
53
54
  const props = defineProps({
@@ -125,7 +126,7 @@ function getOptions(key) {
125
126
  }
126
127
 
127
128
  if(data.length==0){
128
- nodatatext.value = '无数据';
129
+ nodatatext.value = common.LocalizedString('无数据', '無數據');
129
130
  }
130
131
 
131
132
  nextTick(function () {
@@ -133,7 +134,7 @@ function getOptions(key) {
133
134
  });
134
135
  }
135
136
  else{
136
- nodatatext.value = '无数据';
137
+ nodatatext.value = common.LocalizedString('无数据', '無數據');
137
138
  }
138
139
  })
139
140
  }
@@ -157,14 +157,14 @@
157
157
 
158
158
  </div>
159
159
  <template v-if="model?.aiAttr?.showAI">
160
- <div :style="{ flex: ' 0 0 ' + model.aiAttr.width + 'px', position: 'sticky', top: '0' ,'margin-left': '10px'}"
160
+ <div :style="{ flex: ' 0 0 ' + model.aiAttr.width + 'px', position: 'sticky', top: '0' ,'box-shadow': '-10px 0 5px -9px rgba(0, 0, 0, 0.3)' }"
161
161
  v-show="showAI">
162
162
  <div
163
163
  :style="{ position: 'sticky', top: '0', height: dialogHeight + 'px', overflow: 'hidden', 'border-bottom-right-radius': '4px' }">
164
164
  <AIChat :height="dialogHeight"
165
165
  :style="{ position: 'sticky', top: '0', height: dialogHeight + 'px' }"
166
166
  :field="model.aiChat" :router="model.aiRouter" :actionRouter="model.actionRouters" :form="model"
167
- @hideAI="AIToggle">
167
+ @hideAI="AIToggle" :isVisible="showAI" :tablewidth="model.aiAttr.width">
168
168
 
169
169
  </AIChat>
170
170
  </div>
@@ -19,7 +19,7 @@ onActivated(() => {
19
19
  })
20
20
  function close() {
21
21
  emit('close', props);
22
- if (props.vmodel.content[0].attrs && typeof props.vmodel.content[0].attrs["onCloseDialog"] === "function") {
22
+ if (props.vmodel.content[0].component != 'ct-iframe' && props.vmodel.content[0].attrs && typeof props.vmodel.content[0].attrs["onCloseDialog"] === "function") {
23
23
  props.vmodel.content[0].attrs["onCloseDialog"]();
24
24
  }
25
25
  }
@@ -145,11 +145,11 @@ const render = () => {
145
145
  //AI弹框宽度自适应
146
146
  if (!item.attrs.onAIToggle) {
147
147
  item.attrs.onAIToggle = (newWidth) => {
148
-
148
+
149
149
  item.width = parseFloat(item.width) + newWidth + 'px';
150
150
  }
151
151
  }
152
-
152
+
153
153
  //加载失败关闭弹框
154
154
  if (!item.attrs.onFailLoad) {
155
155
  item.attrs.onFailLoad = () => {
@@ -195,8 +195,8 @@ const render = () => {
195
195
  item.documentWidth = (props.vmodel.pane.clientWidth - 20) + 'px';
196
196
  }
197
197
  }
198
- item.attrs.dialoWidth = parseInt((item.width||0).replace('px', ''));
199
- item.attrs.dialogHeight = parseInt((item.height||0).replace('px', ''));
198
+ item.attrs.dialoWidth = parseInt((item.width || 0).replace('px', ''));
199
+ item.attrs.dialogHeight = parseInt((item.height || 0).replace('px', ''));
200
200
  return h('div', {
201
201
  style: {
202
202
  width: item.width,
@@ -13,6 +13,9 @@ const Router = function (source) {
13
13
  get controlLabel() {
14
14
  return source.text;
15
15
  },
16
+ set controlLabel(v) {
17
+ return source.text=v;
18
+ },
16
19
  //动作对应的 控制器
17
20
  get action() {
18
21
  return source.action;
package/src/main.js CHANGED
@@ -22,16 +22,18 @@ for (const [key, component] of Object.entries(ElementPlusIconsVue)) {
22
22
 
23
23
  app.use(centaline, {
24
24
  baseUrl:"http://10.88.22.66/IBS.Mvc/api/",
25
+ //baseUrl: "https://kq-api.centaline.com.cn/onecard-api/",
26
+ //baseUrl: "http://10.88.22.13:6060/onecard-api/",
25
27
  //baseUrl: "http://10.88.22.66:6060/xian/",
26
28
  //baseUrl: "http://10.1.245.50:38735/max-uplink-api/",
27
29
  //baseUrl: "http://10.1.245.111:38028/",
28
-
30
+
29
31
  flagRouterSelf: true,
30
- flagApp: false,//是否app端
32
+ flagApp: true,//是否app端
31
33
  zindex: 999,
32
34
  showRequestSuccessMessage: true,
33
35
  showRequestErrorMessage: true,
34
- language:'HK',
36
+ language: 'HK',
35
37
  handler: {
36
38
  // 打开tab页
37
39
  openTab: function (action) {
@@ -64,10 +66,13 @@ app.use(centaline, {
64
66
  return {
65
67
  //authObject: '{token:"aplus eyJhbGciOiJIUzI1NiIsInppcCI6IkRFRiJ9.eNrEjjsOwjAQBe-ydVay1xvvOl3sJA2HiPIxElSIJBIIcXdAQEfPFK-YZt4Nlm2EChqtDafOYWqpRG6kxLoTxZhUTSRxHLUPH_DHfOmt5SDWt1gHScieHapNiol94q5pXYoNFJAvJ6isGHWmNMYVcBjWtyCr_iW2JZ93-fqPc8f18MwGIqFRCIO1GXmWGYd9npCZJ6N5JjYZ7g8AAAD__w.HgtNKtHWooj8c9Hy_vB8CfKq-qOeHMp0irnW0DfXtHo"}',
66
68
  //oldToken: 'd92d4a3b-2274-42e8-96f0-100ffb579b6e',
67
- //authObject: '{token:"1-a7289bb2-9f1e-4a04-9016-1e555bf39188"}',
68
- authObject: '{EmpID:"Token_43406e81-3337-4d1f-8917-edc5bfec9c9f",MachineCode:"e1f39b75-7069-4c4f-b5d5-c590da2d9aa2",SSO_Token:"SSOToken_43406e81-3337-4d1f-8917-edc5bfec9c9f",Platform:"web"}',
69
+ //authObject: '{token:"1647-1907352839429165056",platform:"WEB"}',
70
+ authObject: '{EmpID:"Token_2fa5c93f-ae55-4e77-98a4-ef9c8b3bec34",MachineCode:"7c4b2ffd-920a-462c-a586-37bbfb45c4fe",SSO_Token:"SSOToken_2fa5c93f-ae55-4e77-98a4-ef9c8b3bec34",Platform:"IOS"}',
69
71
  };
70
72
  },
73
+ getToken() {
74
+ return "1647-1907319603235786752"
75
+ },
71
76
  // 请求完成事件,可判断是否登录过期执行响应操作
72
77
  requestComplete: function (response) {
73
78
  // console.log(response);
@@ -6,6 +6,10 @@
6
6
 
7
7
  <ct-searchlist :apiParam="apiParam" :searchConditionApi="'/propertyTenderList/getLayoutOfSearch'"
8
8
  :searchDataApi="'/propertyTenderList/getListOfSearchModel'"></ct-searchlist>
9
+
10
+
11
+ <!-- <ct-searchlist :apiParam="apiParam" :searchConditionApi="'/EmployeeAttendanceBillList/getLayoutOfSearchForMy'"
12
+ :searchDataApi="'/EmployeeAttendanceBillList/getListOfSearchModelForMy'"></ct-searchlist> -->
9
13
  <ct-dialoglist ref="dialogList"></ct-dialoglist>
10
14
 
11
15
  </div>