vue2-client 1.8.46 → 1.8.48

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 (31) hide show
  1. package/CHANGELOG.md +3 -0
  2. package/package.json +1 -1
  3. package/public/img/dynamicStatistics/dynamicStatisticsBack.jpg +0 -0
  4. package/public/img/service/sendword.png +0 -0
  5. package/src/App.vue +1 -0
  6. package/src/assets/img/logo.png +0 -0
  7. package/src/assets/img/querySlotDemo.svg +15 -15
  8. package/src/base-client/components/common/CitySelect/index.js +3 -3
  9. package/src/base-client/components/common/CitySelect/index.md +109 -109
  10. package/src/base-client/components/common/PersonSetting/index.js +3 -3
  11. package/src/base-client/components/common/Upload/index.js +3 -3
  12. package/src/font-style/PingFang.ttf +0 -0
  13. package/src/font-style/font.css +6 -0
  14. package/src/pages/DynamicStatistics/ChartSelector.vue +155 -0
  15. package/src/pages/DynamicStatistics/DataTabs.vue +112 -0
  16. package/src/pages/DynamicStatistics/DynamicTable.vue +76 -0
  17. package/src/pages/DynamicStatistics/EvaluationArea.vue +54 -0
  18. package/src/pages/DynamicStatistics/FavoriteList.vue +51 -0
  19. package/src/pages/DynamicStatistics/SearchBar.vue +130 -0
  20. package/src/pages/DynamicStatistics/index.vue +201 -0
  21. package/src/pages/ServiceReview/index.vue +284 -0
  22. package/src/pages/login/Login.vue +11 -2
  23. package/src/router/async/config.async.js +2 -0
  24. package/src/router/async/router.map.js +4 -0
  25. package/src/router/index.js +1 -1
  26. package/src/router.js +1 -0
  27. package/src/services/api/restTools.js +24 -24
  28. package/src/utils/indexedDB.js +16 -0
  29. package/src/utils/routerUtil.js +3 -3
  30. package/src/utils/waterMark.js +31 -31
  31. package/vue.config.js +6 -1
@@ -0,0 +1,76 @@
1
+ <template>
2
+ <div class="table-main">
3
+ <a-table
4
+ :scroll="{ x: scrollXWidth, y: scrollYHeight }"
5
+ size="middle"
6
+ :columns="tableColumns"
7
+ :dataSource="tableData"
8
+ :rowKey="record => record.id">
9
+ </a-table>
10
+ </div>
11
+ </template>
12
+
13
+ <script>
14
+
15
+ export default {
16
+ name: 'DynamicTable',
17
+ data () {
18
+ return {
19
+ tableColumns: [],
20
+ // x滚动条宽度
21
+ scrollXWidth: 1600,
22
+ scrollYHeight: 400
23
+ }
24
+ },
25
+ mounted () {
26
+ this.initData()
27
+ },
28
+ props: {
29
+ tableData: {
30
+ type: Array,
31
+ required: true
32
+ }
33
+ },
34
+ watch: {
35
+ tableData: {
36
+ deep: true,
37
+ handler (newVal) {
38
+ this.initData()
39
+ }
40
+ }
41
+ },
42
+ methods: {
43
+ async initData () {
44
+ try {
45
+ // 从数据第一项推断列信息
46
+ const sample = this.tableData[0]
47
+ this.tableColumns = Object.keys(sample).map(key => ({
48
+ title: key, // 使用键名作为列标题
49
+ dataIndex: key, // 数据索引与键名相同
50
+ key: key,
51
+ ellipsis: true,
52
+ }))
53
+ let totalWidth = 0
54
+ // 设置表格宽度
55
+ for (let i = 0; i < this.tableColumns.length; i++) {
56
+ totalWidth = totalWidth + 180
57
+ }
58
+ // 设置表格高度为固定值
59
+ this.scrollYHeight = 'calc(100vh - 40rem)'
60
+ // 横向滚动长度大于所有宽度,才能实现固定表头
61
+ this.scrollXWidth = totalWidth
62
+ } catch (error) {
63
+ console.error('Fetching data failed:', error)
64
+ }
65
+ },
66
+ }
67
+ }
68
+ </script>
69
+ <style lang="less" scoped>
70
+ .table-main {
71
+ margin-top: 8px;
72
+ :deep(.ant-table) {
73
+ background-color: #fff;
74
+ }
75
+ }
76
+ </style>
@@ -0,0 +1,54 @@
1
+ <template>
2
+ <div class="evaluation-card">
3
+ <div v-if="!action">
4
+ <p>您对这次搜索结果满意吗?</p>
5
+ <a-button-group>
6
+ <a-button type="primary" @click="submitEvaluation(true)">满意</a-button>
7
+ <a-button type="danger" @click="submitEvaluation(false)">不满意</a-button>
8
+ </a-button-group>
9
+ </div>
10
+ </div>
11
+ </template>
12
+
13
+ <script>
14
+ import { post } from '@vue2-client/services/api'
15
+ import { indexedDB } from '@vue2-client/utils/indexedDB'
16
+
17
+ export default {
18
+ data () {
19
+ return {
20
+ action: false
21
+ }
22
+ },
23
+ props: {
24
+ uuid: {
25
+ type: String,
26
+ required: true
27
+ }
28
+ },
29
+ methods: {
30
+ submitEvaluation (result) {
31
+ const key = 'question-' + this.uuid
32
+ indexedDB.get(key, (item) => {
33
+ const content = Object.assign(item, {
34
+ evaluation: result
35
+ })
36
+ post('/api/af-system/logic/openapi/addCommonData', {
37
+ type: 'ai-evaluation',
38
+ content: content
39
+ }).then(res => {
40
+ this.action = true
41
+ this.$message.success('评论成功')
42
+ })
43
+ })
44
+ }
45
+ }
46
+ }
47
+ </script>
48
+ <style lang="less" scoped>
49
+ .evaluation-card {
50
+ width: 50%;
51
+ text-align: center;
52
+ margin: 20px auto 0 auto;
53
+ }
54
+ </style>
@@ -0,0 +1,51 @@
1
+ <template>
2
+ <div>
3
+ <a-list v-show="!loading" size="small" :data-source="data">
4
+ <a-list-item slot="renderItem" slot-scope="item">
5
+ <div>
6
+ <p><a @click="$emit('openFavorites', item.uuid)">{{ item.question }} </a></p>
7
+ <p>{{ item.date }}</p>
8
+ </div>
9
+ <a class="delete_item">
10
+ <a-icon type="close" @click="$emit('saveToFavorites', item.uuid)"/>
11
+ </a>
12
+ </a-list-item>
13
+ </a-list>
14
+ </div>
15
+ </template>
16
+
17
+ <script>
18
+ import { indexedDB } from '@vue2-client/utils/indexedDB'
19
+
20
+ export default {
21
+ name: 'FavoriteList',
22
+ data () {
23
+ return {
24
+ data: [],
25
+ loading: false
26
+ }
27
+ },
28
+ mounted () {
29
+ this.loadData()
30
+ },
31
+ methods: {
32
+ loadData () {
33
+ console.warn(123)
34
+ indexedDB.getAll((data) => {
35
+ const realData = data.filter(item => item.data && item.data.uuid)
36
+ .map(item => item.data)
37
+ this.data = realData
38
+ })
39
+ }
40
+ }
41
+ }
42
+ </script>
43
+ <style lang="less" scoped>
44
+ .delete_item {
45
+ margin-left: 8px;
46
+ color: #333;
47
+ }
48
+ p {
49
+ margin: 0
50
+ }
51
+ </style>
@@ -0,0 +1,130 @@
1
+ <template>
2
+ <div class="search-bar">
3
+ <a-input
4
+ class="search-input"
5
+ v-model="searchInput"
6
+ placeholder="请输入查询的内容"
7
+ @pressEnter="onSearch(searchInput)">
8
+ </a-input>
9
+ <a-button-group size="large" class="btn_group">
10
+ <a-button @click="onSearch(searchInput)" :loading="loading">
11
+ <a-icon type="search" />搜索
12
+ </a-button>
13
+ <a-tooltip>
14
+ <template slot="title">
15
+ 将该结果收藏到收藏夹
16
+ </template>
17
+ <a-button class="star_button" @click="onSaveToFavorites(undefined)">
18
+ <a-icon type="star" v-show="!favoriteState"/>
19
+ <a-icon type="star" v-show="favoriteState" theme="filled"/>
20
+ </a-button>
21
+ </a-tooltip>
22
+ <a-tooltip>
23
+ <template slot="title">
24
+ 收藏夹
25
+ </template>
26
+ <a-popover @visibleChange="favoriteListVisibleAction" title="收藏夹" placement="bottomRight" trigger="click">
27
+ <template slot="content">
28
+ <FavoriteList ref="favoriteList" @saveToFavorites="onSaveToFavorites" @openFavorites="openFavorites"/>
29
+ </template>
30
+ <a-button>
31
+ <a-icon type="menu" />
32
+ </a-button>
33
+ </a-popover>
34
+ </a-tooltip>
35
+ </a-button-group>
36
+ </div>
37
+ </template>
38
+
39
+ <script>
40
+ import FavoriteList from './FavoriteList.vue'
41
+
42
+ export default {
43
+ name: 'SearchBar',
44
+ components: { FavoriteList },
45
+ data () {
46
+ return {
47
+ searchInput: '', // 绑定搜索输入框的数据,
48
+ favoriteState: false, // 是否收藏
49
+ obj: undefined,
50
+ favoriteListVisible: false,
51
+ loading: false
52
+ }
53
+ },
54
+ methods: {
55
+ // 处理搜索操作
56
+ onSearch (value) {
57
+ this.loading = true
58
+ // 触发父组件的搜索事件,传递搜索输入的值
59
+ this.$emit('search', value, () => { this.loading = false })
60
+ },
61
+ // 处理打开收藏操作
62
+ openFavorites (uuid) {
63
+ this.$emit('openFavorites', uuid)
64
+ },
65
+ // 处理收藏操作
66
+ onSaveToFavorites (uuid) {
67
+ // 触发父组件的保存到收藏夹事件,传递当前搜索的uuid
68
+ let thisUUid
69
+ if (uuid) {
70
+ thisUUid = uuid
71
+ } else if (this.obj) {
72
+ thisUUid = this.obj.uuid
73
+ } else {
74
+ thisUUid = undefined
75
+ }
76
+ this.$emit('saveToFavorites', thisUUid)
77
+ },
78
+ // 收藏夹显示隐藏的回调
79
+ favoriteListVisibleAction (visible) {
80
+ if (this.$refs.favoriteList && visible) {
81
+ this.$refs.favoriteList.loadData()
82
+ }
83
+ },
84
+ init () {
85
+ this.searchInput = ''
86
+ this.obj = undefined
87
+ this.favoriteState = false
88
+ },
89
+ setObj (obj) {
90
+ this.obj = obj
91
+ this.searchInput = obj.question
92
+ this.favoriteState = obj.isFavorite
93
+ },
94
+ setFavorite (uuid, isFavorite) {
95
+ if (this.obj && uuid === this.obj.uuid) {
96
+ this.favoriteState = isFavorite
97
+ }
98
+ this.favoriteListVisibleAction(true)
99
+ }
100
+ }
101
+ }
102
+ </script>
103
+
104
+ <style lang="less" scoped>
105
+ .search-bar {
106
+ display: flex;
107
+ justify-content: center;
108
+ padding: 25px 0;
109
+ margin-bottom: 20px;
110
+ :deep(.ant-input) {
111
+ padding: 4px 80px 4px 40px;
112
+ height: 48px;
113
+ font-size: 16px;
114
+ }
115
+ .btn_group {
116
+ padding-left: 6px;
117
+ :deep(.ant-btn) {
118
+ height: 100%;
119
+ color: #4F93FE;
120
+ }
121
+ .star_button {
122
+ color: #ffba00;
123
+ }
124
+ }
125
+ }
126
+
127
+ .search-input {
128
+ width: 40%;
129
+ }
130
+ </style>
@@ -0,0 +1,201 @@
1
+ <template>
2
+ <div class="dynamic-statistics">
3
+ <div class="data-nav-card-back">
4
+ <div class="data-nav-card">
5
+ <a-row type="flex" align="middle" class="search-title-card">
6
+ <img class="search-title-logo" src="@vue2-client/assets/img/logo.png"/>
7
+ <span class="search-title-text">数据检索平台</span>
8
+ </a-row>
9
+ <div class="search-card">
10
+ <div class="blue-overlay"></div>
11
+ <div class="search-card-main">
12
+ <!-- 搜索栏组件 -->
13
+ <search-bar ref="searchBar" @search="handleSearch" @saveToFavorites="handleSaveToFavorites" @openFavorites="handleOpenFavorite"></search-bar>
14
+ </div>
15
+ </div>
16
+ </div>
17
+ </div>
18
+ <div class="data-main-card">
19
+ <!-- 数据展示Tabs -->
20
+ <data-tabs
21
+ ref="tabs"
22
+ @tab-change="handleTabChange"
23
+ @remove-cache="remove"
24
+ ></data-tabs>
25
+ </div>
26
+ </div>
27
+ </template>
28
+
29
+ <script>
30
+ import SearchBar from './SearchBar.vue'
31
+ import DataTabs from './DataTabs.vue'
32
+ import { indexedDB } from '@vue2-client/utils/indexedDB'
33
+ import { post } from '@vue2-client/services/api'
34
+ import { formatDate } from '@vue2-client/utils/util'
35
+
36
+ export default {
37
+ name: 'DynamicStatistics',
38
+ components: {
39
+ SearchBar,
40
+ DataTabs
41
+ },
42
+ data () {
43
+ return {
44
+ cacheSearchArray: {},
45
+ panes: []
46
+ }
47
+ },
48
+ methods: {
49
+ // 处理搜索逻辑,这里简化为直接赋值,实际应调用API
50
+ handleSearch (value, callback) {
51
+ if (!value) {
52
+ this.$message.warn('请先输入查询的数据')
53
+ return
54
+ }
55
+ const uuid = this.uuid()
56
+ post('/ai/question/', {
57
+ messages: [{
58
+ content: value,
59
+ role: 'user'
60
+ }]
61
+ }).then(res => {
62
+ if (Array.isArray(res)) {
63
+ this.addTab(uuid, value, res, false)
64
+ } else {
65
+ this.$message.warning(res)
66
+ }
67
+ }).finally(() => {
68
+ callback()
69
+ })
70
+ },
71
+ addTab (uuid, question, searchResults, isFavorite) {
72
+ this.cacheSearchArray[uuid] = {
73
+ uuid: uuid,
74
+ question: question,
75
+ data: searchResults,
76
+ isFavorite: isFavorite
77
+ }
78
+ this.$refs.tabs.add(this.cacheSearchArray[uuid])
79
+ this.$refs.searchBar.setObj(this.cacheSearchArray[uuid])
80
+ },
81
+ // 处理保存到收藏夹的逻辑
82
+ handleSaveToFavorites (uuid) {
83
+ if (!uuid) {
84
+ this.$message.warn('请先输入查询的数据')
85
+ return
86
+ }
87
+ const key = 'question-' + uuid
88
+ if (!this.cacheSearchArray[uuid]) {
89
+ indexedDB.get(key, (item) => {
90
+ this.cacheSearchArray[uuid] = item
91
+ this.setFavorite(key, uuid)
92
+ delete this.cacheSearchArray[uuid]
93
+ })
94
+ } else {
95
+ this.setFavorite(key, uuid)
96
+ }
97
+ },
98
+ setFavorite (key, uuid) {
99
+ const isFavorite = this.cacheSearchArray[uuid].isFavorite
100
+ this.cacheSearchArray[uuid].isFavorite = !isFavorite
101
+ if (isFavorite) {
102
+ indexedDB.delete(key)
103
+ this.$message.success('取消收藏成功')
104
+ } else {
105
+ indexedDB.add(key, Object.assign({
106
+ date: formatDate('now')
107
+ }, this.cacheSearchArray[uuid]))
108
+ this.$message.success('收藏成功')
109
+ }
110
+ this.$refs.searchBar.setFavorite(uuid, !isFavorite)
111
+ },
112
+ // 处理Tab变更,可以在这里进行额外的逻辑处理
113
+ handleTabChange (uuid) {
114
+ if (uuid) {
115
+ this.$refs.searchBar.setObj(this.cacheSearchArray[uuid])
116
+ } else {
117
+ this.cacheSearchArray = []
118
+ this.$refs.searchBar.init()
119
+ }
120
+ },
121
+ // 处理从收藏夹打开收藏项
122
+ handleOpenFavorite (uuid) {
123
+ if (this.cacheSearchArray[uuid]) {
124
+ this.$message.success('已切换至搜索结果页')
125
+ this.$refs.tabs.set(uuid)
126
+ return
127
+ }
128
+ // 这里应根据data从indexedDB中查询数据并展示
129
+ const key = 'question-' + uuid
130
+ indexedDB.get(key, (item) => {
131
+ this.addTab(uuid, item.question, item.data, item.isFavorite)
132
+ })
133
+ },
134
+ uuid () {
135
+ const tempUrl = URL.createObjectURL(new Blob())
136
+ const uuid = tempUrl.toString() // blob:https://xxx.com/b250d159-e1b6-4a87-9002-885d90033be3
137
+ URL.revokeObjectURL(tempUrl)
138
+ return uuid.substr(uuid.lastIndexOf('/') + 1)
139
+ },
140
+ remove (uuid) {
141
+ delete this.cacheSearchArray[uuid]
142
+ }
143
+ }
144
+ }
145
+ </script>
146
+
147
+ <style lang="less" scoped>
148
+ .dynamic-statistics {
149
+ position: relative;
150
+ overflow: auto;
151
+ height: 100vh;
152
+ background-color: #f5f7fb;
153
+ min-width: 1400px;
154
+ margin: 0 auto;
155
+ .data-nav-card-back {
156
+ width: 100%;
157
+ height: 265px;
158
+ }
159
+ .data-nav-card {
160
+ z-index: 999;
161
+ position: fixed;
162
+ width: 100%;
163
+ top: 0;
164
+ background: #fff;
165
+ .search-title-card {
166
+ height: 65px;
167
+ width: 75%;
168
+ margin: 0 auto;
169
+ .search-title-logo {
170
+ width: 60px;
171
+ margin-right: 8px;
172
+ }
173
+ .search-title-text {
174
+ font-size: 20px;
175
+ font-weight: bold;
176
+ }
177
+ }
178
+ .search-card {
179
+ width: 100%;
180
+ height: 200px;
181
+ background-image: url('/public/img/dynamicStatistics/dynamicStatisticsBack.jpg');
182
+ background-size: cover;
183
+ position: relative;
184
+ }
185
+ }
186
+ .data-main-card {
187
+ width: 75%;
188
+ padding: 20px;
189
+ margin: 0 auto;
190
+ background-color: #f5f7fb;
191
+ }
192
+ .blue-overlay {
193
+ position: absolute;
194
+ top: 0;
195
+ left: 0;
196
+ width: 100%;
197
+ height: 100%;
198
+ background-color: rgba(#4F93FE, 0.8) // 这里设置蓝色蒙版的颜色和透明度
199
+ }
200
+ }
201
+ </style>