af-mobile-client-vue3 1.6.4 → 1.6.6
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/__dummy__ +9 -9
- package/build/vite/optimize.ts +36 -36
- package/package.json +1 -1
- package/public/favicon.svg +4 -4
- package/scripts/verifyCommit.js +19 -19
- package/src/components/common/MateChat/composables/useMateChat.ts +66 -4
- package/src/components/common/otherCharge/ChargePrintSelectorAndRemarks.vue +137 -137
- package/src/components/common/otherCharge/CodePayment.vue +357 -357
- package/src/components/common/otherCharge/FileUploader.vue +602 -602
- package/src/components/common/otherCharge/GridFileUploader.vue +846 -846
- package/src/components/common/otherCharge/PaymentMethodSelector.vue +202 -202
- package/src/components/common/otherCharge/PaymentMethodSelectorCard.vue +45 -45
- package/src/components/common/otherCharge/ReceiptModal.vue +273 -273
- package/src/components/common/otherCharge/index.ts +43 -43
- package/src/components/data/OtherCharge/OtherChargeItemModal.vue +547 -547
- package/src/components/data/UserDetail/recordEntries.ts +178 -178
- package/src/components/data/UserDetail/types.ts +1 -1
- package/src/components/data/XReportGrid/XAddReport/index.js +3 -3
- package/src/components/data/XReportGrid/XAddReport/index.ts +1 -1
- package/src/components/data/XReportGrid/XReportDrawer/index.js +3 -3
- package/src/components/data/XReportGrid/XReportDrawer/index.ts +1 -1
- package/src/components/data/XTag/index.vue +10 -10
- package/src/hooks/useCommon.ts +9 -9
- package/src/plugins/AppData.ts +38 -38
- package/src/services/api/common.ts +109 -109
- package/src/services/api/manage.ts +8 -8
- package/src/services/api/search.ts +16 -16
- package/src/services/restTools.ts +56 -56
- package/src/utils/authority-utils.ts +84 -84
- package/src/utils/crypto.ts +39 -39
- package/src/utils/queryFormDefaultRangePicker.ts +57 -57
- package/src/utils/runEvalFunction.ts +13 -13
- package/src/views/component/EvaluateRecordView/index.vue +40 -40
- package/src/views/component/MateChat/MateChatView.vue +10 -10
- package/src/views/component/XCellListView/index.vue +101 -117
- package/src/views/component/XFormGroupView/index.vue +10 -47
- package/src/views/component/XFormView/index.vue +30 -20
- package/src/views/component/XReportFormIframeView/index.vue +47 -47
- package/src/views/component/XReportFormView/index.vue +13 -13
- package/src/views/component/XSignatureView/index.vue +50 -50
- package/src/views/component/notice.vue +46 -46
- package/src/views/component/topNav.vue +36 -36
- package/src/views/invoiceShow/index.vue +61 -61
- package/src/views/user/login/index.vue +22 -22
package/__dummy__
CHANGED
|
@@ -1,10 +1,10 @@
|
|
|
1
|
-
{
|
|
2
|
-
"cells": [],
|
|
3
|
-
"metadata": {
|
|
4
|
-
"language_info": {
|
|
5
|
-
"name": "python"
|
|
6
|
-
}
|
|
7
|
-
},
|
|
8
|
-
"nbformat": 4,
|
|
9
|
-
"nbformat_minor": 2
|
|
1
|
+
{
|
|
2
|
+
"cells": [],
|
|
3
|
+
"metadata": {
|
|
4
|
+
"language_info": {
|
|
5
|
+
"name": "python"
|
|
6
|
+
}
|
|
7
|
+
},
|
|
8
|
+
"nbformat": 4,
|
|
9
|
+
"nbformat_minor": 2
|
|
10
10
|
}
|
package/build/vite/optimize.ts
CHANGED
|
@@ -1,36 +1,36 @@
|
|
|
1
|
-
const include = [
|
|
2
|
-
'axios',
|
|
3
|
-
'echarts',
|
|
4
|
-
'lodash-es',
|
|
5
|
-
'resize-detector',
|
|
6
|
-
'vant/es',
|
|
7
|
-
'vant/es/cell-group/style/index',
|
|
8
|
-
'vant/es/popup/style/index',
|
|
9
|
-
'vant/es/picker/style/index',
|
|
10
|
-
'vant/es/cell/style/index',
|
|
11
|
-
'vant/es/switch/style/index',
|
|
12
|
-
'vant/es/space/style/index',
|
|
13
|
-
'vant/es/button/style/index',
|
|
14
|
-
'vant/es/empty/style/index',
|
|
15
|
-
'vant/es/icon/style/index',
|
|
16
|
-
'vant/es/stepper/style/index',
|
|
17
|
-
'vant/es/image/style/index',
|
|
18
|
-
'vant/es/form/style/index',
|
|
19
|
-
'vant/es/field/style/index',
|
|
20
|
-
'vant/es/notify/style/index',
|
|
21
|
-
'vant/es/config-provider/style/index',
|
|
22
|
-
'vant/es/nav-bar/style/index',
|
|
23
|
-
'vant/es/tabbar/style/index',
|
|
24
|
-
'vant/es/tabbar-item/style/index',
|
|
25
|
-
'vant/es/list/style/index',
|
|
26
|
-
'vant/es/text-ellipsis/style/index',
|
|
27
|
-
// 确保 @matechat/core 及其依赖 xss 被正确预构建
|
|
28
|
-
'@matechat/core',
|
|
29
|
-
]
|
|
30
|
-
|
|
31
|
-
const exclude = [
|
|
32
|
-
'@iconify/json',
|
|
33
|
-
'@iconify/vue',
|
|
34
|
-
]
|
|
35
|
-
|
|
36
|
-
export { exclude, include }
|
|
1
|
+
const include = [
|
|
2
|
+
'axios',
|
|
3
|
+
'echarts',
|
|
4
|
+
'lodash-es',
|
|
5
|
+
'resize-detector',
|
|
6
|
+
'vant/es',
|
|
7
|
+
'vant/es/cell-group/style/index',
|
|
8
|
+
'vant/es/popup/style/index',
|
|
9
|
+
'vant/es/picker/style/index',
|
|
10
|
+
'vant/es/cell/style/index',
|
|
11
|
+
'vant/es/switch/style/index',
|
|
12
|
+
'vant/es/space/style/index',
|
|
13
|
+
'vant/es/button/style/index',
|
|
14
|
+
'vant/es/empty/style/index',
|
|
15
|
+
'vant/es/icon/style/index',
|
|
16
|
+
'vant/es/stepper/style/index',
|
|
17
|
+
'vant/es/image/style/index',
|
|
18
|
+
'vant/es/form/style/index',
|
|
19
|
+
'vant/es/field/style/index',
|
|
20
|
+
'vant/es/notify/style/index',
|
|
21
|
+
'vant/es/config-provider/style/index',
|
|
22
|
+
'vant/es/nav-bar/style/index',
|
|
23
|
+
'vant/es/tabbar/style/index',
|
|
24
|
+
'vant/es/tabbar-item/style/index',
|
|
25
|
+
'vant/es/list/style/index',
|
|
26
|
+
'vant/es/text-ellipsis/style/index',
|
|
27
|
+
// 确保 @matechat/core 及其依赖 xss 被正确预构建
|
|
28
|
+
'@matechat/core',
|
|
29
|
+
]
|
|
30
|
+
|
|
31
|
+
const exclude = [
|
|
32
|
+
'@iconify/json',
|
|
33
|
+
'@iconify/vue',
|
|
34
|
+
]
|
|
35
|
+
|
|
36
|
+
export { exclude, include }
|
package/package.json
CHANGED
package/public/favicon.svg
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
<svg t="1709866807903" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="4913" width="32" height="32">
|
|
2
|
-
<path d="M512 598.528a111.232 111.232 0 0 0-111.232 111.2064V870.4h222.464v-160.6656c0-61.44-49.792-111.232-111.232-111.232z m0 58.0608c-30.72 0-55.6032 24.9088-55.6032 55.6288v105.0368h111.2064v-105.0368c0-30.72-24.8832-55.6288-55.6032-55.6288z" fill="#FB4D31" p-id="4914"></path>
|
|
3
|
-
<path d="M542.08 270.208l45.2608-78.5408a24.5248 24.5248 0 0 0 0-25.6A26.4448 26.4448 0 0 0 564.1472 153.6a26.3424 26.3424 0 0 0-22.5792 13.44L512 217.6256l-29.5424-50.5344c-4.5824-8.192-13.184-13.312-22.5536-13.4912a26.4448 26.4448 0 0 0-23.2448 12.4928 24.5248 24.5248 0 0 0 0 25.6l45.2352 78.5152L156.928 832.768a24.4736 24.4736 0 0 0 0.3328 25.088c4.8384 7.8336 13.3888 12.544 22.5792 12.5184h664.3456c9.3184 0 17.92-4.7616 22.6304-12.4672a24.4736 24.4736 0 0 0 0.3072-25.088l-325.0176-562.688v0.0512zM619.52 816.64h-33.3568c-12.3648 0-9.6768 0.1024-65.0496 0H512c-55.3728 0.1024-24.704 0-61.7984 0H225.28L512 322.1248 798.72 816.64h-179.2z" fill="#000000" p-id="4915"></path>
|
|
4
|
-
</svg>
|
|
1
|
+
<svg t="1709866807903" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="4913" width="32" height="32">
|
|
2
|
+
<path d="M512 598.528a111.232 111.232 0 0 0-111.232 111.2064V870.4h222.464v-160.6656c0-61.44-49.792-111.232-111.232-111.232z m0 58.0608c-30.72 0-55.6032 24.9088-55.6032 55.6288v105.0368h111.2064v-105.0368c0-30.72-24.8832-55.6288-55.6032-55.6288z" fill="#FB4D31" p-id="4914"></path>
|
|
3
|
+
<path d="M542.08 270.208l45.2608-78.5408a24.5248 24.5248 0 0 0 0-25.6A26.4448 26.4448 0 0 0 564.1472 153.6a26.3424 26.3424 0 0 0-22.5792 13.44L512 217.6256l-29.5424-50.5344c-4.5824-8.192-13.184-13.312-22.5536-13.4912a26.4448 26.4448 0 0 0-23.2448 12.4928 24.5248 24.5248 0 0 0 0 25.6l45.2352 78.5152L156.928 832.768a24.4736 24.4736 0 0 0 0.3328 25.088c4.8384 7.8336 13.3888 12.544 22.5792 12.5184h664.3456c9.3184 0 17.92-4.7616 22.6304-12.4672a24.4736 24.4736 0 0 0 0.3072-25.088l-325.0176-562.688v0.0512zM619.52 816.64h-33.3568c-12.3648 0-9.6768 0.1024-65.0496 0H512c-55.3728 0.1024-24.704 0-61.7984 0H225.28L512 322.1248 798.72 816.64h-179.2z" fill="#000000" p-id="4915"></path>
|
|
4
|
+
</svg>
|
package/scripts/verifyCommit.js
CHANGED
|
@@ -1,19 +1,19 @@
|
|
|
1
|
-
import fs from 'node:fs'
|
|
2
|
-
|
|
3
|
-
// import process from 'node:process'
|
|
4
|
-
|
|
5
|
-
const msg = fs.readFileSync('.git/COMMIT_EDITMSG', 'utf-8').trim()
|
|
6
|
-
|
|
7
|
-
const commitRE = /^(?:revert: )?(?:feat|fix|docs|dx|style|refactor|perf|test|workflow|build|ci|chore|types|wip|release)(?:\(.+\))?: .{1,50}/
|
|
8
|
-
// const mergeRe = /^(Merge pull request|Merge branch)/
|
|
9
|
-
|
|
10
|
-
if (!commitRE.test(msg)) {
|
|
11
|
-
// if (!mergeRe.test(msg)) {
|
|
12
|
-
// console.log('git commit unpass')
|
|
13
|
-
// console.error('git commit error, needs title(scope): desc')
|
|
14
|
-
// process.exit(1)
|
|
15
|
-
// }
|
|
16
|
-
}
|
|
17
|
-
else {
|
|
18
|
-
console.log('git commit pass')
|
|
19
|
-
}
|
|
1
|
+
import fs from 'node:fs'
|
|
2
|
+
|
|
3
|
+
// import process from 'node:process'
|
|
4
|
+
|
|
5
|
+
const msg = fs.readFileSync('.git/COMMIT_EDITMSG', 'utf-8').trim()
|
|
6
|
+
|
|
7
|
+
const commitRE = /^(?:revert: )?(?:feat|fix|docs|dx|style|refactor|perf|test|workflow|build|ci|chore|types|wip|release)(?:\(.+\))?: .{1,50}/
|
|
8
|
+
// const mergeRe = /^(Merge pull request|Merge branch)/
|
|
9
|
+
|
|
10
|
+
if (!commitRE.test(msg)) {
|
|
11
|
+
// if (!mergeRe.test(msg)) {
|
|
12
|
+
// console.log('git commit unpass')
|
|
13
|
+
// console.error('git commit error, needs title(scope): desc')
|
|
14
|
+
// process.exit(1)
|
|
15
|
+
// }
|
|
16
|
+
}
|
|
17
|
+
else {
|
|
18
|
+
console.log('git commit pass')
|
|
19
|
+
}
|
|
@@ -10,6 +10,42 @@ import { showToast } from 'vant'
|
|
|
10
10
|
import { ref } from 'vue'
|
|
11
11
|
import { chatBiz, chatCompletionsStream, getPaginationRecords } from '../apiService'
|
|
12
12
|
|
|
13
|
+
/** 空回复兜底文案:归因服务端繁忙 */
|
|
14
|
+
const EMPTY_RESPONSE_MESSAGE = '服务器繁忙,请稍后再试。'
|
|
15
|
+
|
|
16
|
+
/** 网络/请求异常兜底文案 */
|
|
17
|
+
const CHAT_ERROR_MESSAGE = '抱歉,服务暂时不可用,请稍后再试。'
|
|
18
|
+
|
|
19
|
+
/**
|
|
20
|
+
* 判定模型返回内容是否「有效为空」
|
|
21
|
+
*/
|
|
22
|
+
function isEmptyModelResponse(content: string | null | undefined): boolean {
|
|
23
|
+
const text = (content ?? '').trim()
|
|
24
|
+
if (!text) {
|
|
25
|
+
return true
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
try {
|
|
29
|
+
const parsed = JSON.parse(text) as Record<string, unknown>
|
|
30
|
+
if (!parsed || typeof parsed !== 'object') {
|
|
31
|
+
return false
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
const msgType = parsed.msgType
|
|
35
|
+
if (msgType === 'card' || msgType === 'transfer') {
|
|
36
|
+
return false
|
|
37
|
+
}
|
|
38
|
+
if (msgType === 'options' && Array.isArray(parsed.options) && parsed.options.length > 0) {
|
|
39
|
+
return false
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
catch {
|
|
43
|
+
// 非 JSON 普通文本,trim 已判定非空
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
return false
|
|
47
|
+
}
|
|
48
|
+
|
|
13
49
|
/**
|
|
14
50
|
* 生成随机 chatId
|
|
15
51
|
*/
|
|
@@ -35,6 +71,24 @@ export function useMateChat(config: MateChatConfig) {
|
|
|
35
71
|
// 使用会话消息缓存
|
|
36
72
|
const { getCachedMessages, setCachedMessages, appendMessages } = useChatMessagesCache()
|
|
37
73
|
|
|
74
|
+
/** 请求成功但 content 为空时,统一替换为服务端繁忙提示 */
|
|
75
|
+
function applyEmptyResponseFallback(
|
|
76
|
+
loadingIndex: number,
|
|
77
|
+
userText: string,
|
|
78
|
+
currentChatId: string,
|
|
79
|
+
) {
|
|
80
|
+
messages.value[loadingIndex] = {
|
|
81
|
+
from: 'model',
|
|
82
|
+
content: EMPTY_RESPONSE_MESSAGE,
|
|
83
|
+
loading: false,
|
|
84
|
+
typing: false,
|
|
85
|
+
}
|
|
86
|
+
appendMessages(currentChatId, [
|
|
87
|
+
{ from: 'user', content: userText },
|
|
88
|
+
{ from: 'model', content: EMPTY_RESPONSE_MESSAGE, loading: false, typing: false },
|
|
89
|
+
])
|
|
90
|
+
}
|
|
91
|
+
|
|
38
92
|
/**
|
|
39
93
|
* 新建会话:回到起始页并清空历史消息,生成新的 chatId
|
|
40
94
|
* 同时清除历史会话列表缓存,以便下次打开时重新获取
|
|
@@ -105,6 +159,9 @@ export function useMateChat(config: MateChatConfig) {
|
|
|
105
159
|
{ from: 'service', content: '您好,客服xxx工号xxx为你服务。功能开发中,敬请期待。' },
|
|
106
160
|
])
|
|
107
161
|
}
|
|
162
|
+
else if (isEmptyModelResponse(result.content)) {
|
|
163
|
+
applyEmptyResponseFallback(loadingMessageIndex, evt, chatId.value)
|
|
164
|
+
}
|
|
108
165
|
else {
|
|
109
166
|
let typing = true
|
|
110
167
|
try {
|
|
@@ -135,13 +192,13 @@ export function useMateChat(config: MateChatConfig) {
|
|
|
135
192
|
console.error('聊天请求失败:', error)
|
|
136
193
|
messages.value[loadingMessageIndex] = {
|
|
137
194
|
from: 'model',
|
|
138
|
-
content:
|
|
195
|
+
content: CHAT_ERROR_MESSAGE,
|
|
139
196
|
loading: false,
|
|
140
197
|
}
|
|
141
198
|
// 更新缓存:追加用户消息和错误消息
|
|
142
199
|
appendMessages(chatId.value, [
|
|
143
200
|
{ from: 'user', content: evt },
|
|
144
|
-
{ from: 'model', content:
|
|
201
|
+
{ from: 'model', content: CHAT_ERROR_MESSAGE, loading: false },
|
|
145
202
|
])
|
|
146
203
|
showToast(error?.message || '请求失败,请稍后再试')
|
|
147
204
|
}
|
|
@@ -229,6 +286,11 @@ export function useMateChat(config: MateChatConfig) {
|
|
|
229
286
|
msg.typing = true
|
|
230
287
|
}
|
|
231
288
|
|
|
289
|
+
if (isEmptyModelResponse(msg.content)) {
|
|
290
|
+
applyEmptyResponseFallback(loadingMessageIndex, evt, chatId.value)
|
|
291
|
+
return
|
|
292
|
+
}
|
|
293
|
+
|
|
232
294
|
// 统一更新缓存
|
|
233
295
|
appendMessages(chatId.value, [
|
|
234
296
|
{ from: 'user', content: evt },
|
|
@@ -241,12 +303,12 @@ export function useMateChat(config: MateChatConfig) {
|
|
|
241
303
|
if (!msg) {
|
|
242
304
|
return
|
|
243
305
|
}
|
|
244
|
-
msg.content =
|
|
306
|
+
msg.content = CHAT_ERROR_MESSAGE
|
|
245
307
|
msg.loading = false
|
|
246
308
|
// 更新缓存:追加用户消息和错误消息
|
|
247
309
|
appendMessages(chatId.value, [
|
|
248
310
|
{ from: 'user', content: evt },
|
|
249
|
-
{ from: 'model', content:
|
|
311
|
+
{ from: 'model', content: CHAT_ERROR_MESSAGE, loading: false },
|
|
250
312
|
])
|
|
251
313
|
showToast((error as any)?.message || '请求失败,请稍后再试')
|
|
252
314
|
},
|
|
@@ -1,137 +1,137 @@
|
|
|
1
|
-
<script setup lang="ts">
|
|
2
|
-
import CardContainer from '@af-mobile-client-vue3/components/data/CardContainer/CardContainer.vue'
|
|
3
|
-
import CardHeader from '@af-mobile-client-vue3/components/data/CardContainer/CardHeader.vue'
|
|
4
|
-
import {
|
|
5
|
-
Field as VanField,
|
|
6
|
-
Picker as VanPicker,
|
|
7
|
-
Popup as VanPopup,
|
|
8
|
-
} from 'vant'
|
|
9
|
-
import { ref, watch } from 'vue'
|
|
10
|
-
|
|
11
|
-
const props = defineProps<{
|
|
12
|
-
modelValue: string
|
|
13
|
-
remarks: string
|
|
14
|
-
}>()
|
|
15
|
-
|
|
16
|
-
const emit = defineEmits<{
|
|
17
|
-
(e: 'update:modelValue', value: string): void
|
|
18
|
-
(e: 'update:remarks', value: string): void
|
|
19
|
-
}>()
|
|
20
|
-
|
|
21
|
-
const printOptions = [
|
|
22
|
-
{ text: '电子发票', value: '电子发票' },
|
|
23
|
-
{ text: '普通收据', value: '普通收据' },
|
|
24
|
-
{ text: '两者都需要', value: 'both' },
|
|
25
|
-
]
|
|
26
|
-
|
|
27
|
-
const selectedOption = ref(getOptionText(props.modelValue))
|
|
28
|
-
const remarks = ref(props.remarks)
|
|
29
|
-
const showPicker = ref(false)
|
|
30
|
-
|
|
31
|
-
function getOptionText(value: string): string {
|
|
32
|
-
const option = printOptions.find(opt => opt.value === value)
|
|
33
|
-
return option ? option.text : ''
|
|
34
|
-
}
|
|
35
|
-
|
|
36
|
-
function onConfirm({ selectedValues }: { selectedValues: string[] }) {
|
|
37
|
-
selectedOption.value = selectedValues[0]
|
|
38
|
-
emit('update:modelValue', selectedValues[0])
|
|
39
|
-
showPicker.value = false
|
|
40
|
-
}
|
|
41
|
-
|
|
42
|
-
watch(() => remarks.value, (newValue) => {
|
|
43
|
-
emit('update:remarks', newValue)
|
|
44
|
-
})
|
|
45
|
-
|
|
46
|
-
// 当从外部更新值时更新内部状态
|
|
47
|
-
watch(() => props.modelValue, (newValue) => {
|
|
48
|
-
selectedOption.value = getOptionText(newValue)
|
|
49
|
-
})
|
|
50
|
-
|
|
51
|
-
watch(() => props.remarks, (newValue) => {
|
|
52
|
-
remarks.value = newValue
|
|
53
|
-
})
|
|
54
|
-
</script>
|
|
55
|
-
|
|
56
|
-
<template>
|
|
57
|
-
<CardContainer class="charge-print-and-remarks">
|
|
58
|
-
<CardHeader title="打印及备注" />
|
|
59
|
-
<div class="charge-print-options">
|
|
60
|
-
<div class="charge-print-options__section">
|
|
61
|
-
<label class="charge-print-options__label">收据打印选项</label>
|
|
62
|
-
<div class="charge-print-options__selector">
|
|
63
|
-
<VanField
|
|
64
|
-
v-model="selectedOption"
|
|
65
|
-
is-link
|
|
66
|
-
readonly
|
|
67
|
-
placeholder="请选择打印方式"
|
|
68
|
-
@click="showPicker = true"
|
|
69
|
-
/>
|
|
70
|
-
</div>
|
|
71
|
-
</div>
|
|
72
|
-
|
|
73
|
-
<div class="charge-print-options__section">
|
|
74
|
-
<label class="charge-print-options__label">备注</label>
|
|
75
|
-
<div class="charge-print-options__selector">
|
|
76
|
-
<VanField
|
|
77
|
-
v-model="remarks"
|
|
78
|
-
type="textarea"
|
|
79
|
-
placeholder="可选填写备注信息"
|
|
80
|
-
rows="2"
|
|
81
|
-
autosize
|
|
82
|
-
maxlength="200"
|
|
83
|
-
show-word-limit
|
|
84
|
-
/>
|
|
85
|
-
</div>
|
|
86
|
-
</div>
|
|
87
|
-
|
|
88
|
-
<VanPopup v-model:show="showPicker" position="bottom" round teleport="body">
|
|
89
|
-
<VanPicker
|
|
90
|
-
:columns="printOptions"
|
|
91
|
-
show-toolbar
|
|
92
|
-
title="选择打印方式"
|
|
93
|
-
@confirm="onConfirm"
|
|
94
|
-
@cancel="showPicker = false"
|
|
95
|
-
/>
|
|
96
|
-
</VanPopup>
|
|
97
|
-
</div>
|
|
98
|
-
</CardContainer>
|
|
99
|
-
</template>
|
|
100
|
-
|
|
101
|
-
<style scoped lang="less">
|
|
102
|
-
.charge-print-and-remarks {
|
|
103
|
-
margin-bottom: 16px;
|
|
104
|
-
}
|
|
105
|
-
|
|
106
|
-
.charge-print-options {
|
|
107
|
-
&__section {
|
|
108
|
-
margin-bottom: 16px;
|
|
109
|
-
|
|
110
|
-
&:last-child {
|
|
111
|
-
margin-bottom: 0;
|
|
112
|
-
}
|
|
113
|
-
}
|
|
114
|
-
|
|
115
|
-
&__label {
|
|
116
|
-
display: block;
|
|
117
|
-
font-size: 12px;
|
|
118
|
-
font-weight: 500;
|
|
119
|
-
color: #6b7280;
|
|
120
|
-
margin-bottom: 4px;
|
|
121
|
-
}
|
|
122
|
-
|
|
123
|
-
&__selector {
|
|
124
|
-
position: relative;
|
|
125
|
-
|
|
126
|
-
:deep(.van-field) {
|
|
127
|
-
background-color: #f9fafb;
|
|
128
|
-
border-radius: 6px;
|
|
129
|
-
}
|
|
130
|
-
}
|
|
131
|
-
|
|
132
|
-
:deep(.van-field__control) {
|
|
133
|
-
background-color: #f9fafb;
|
|
134
|
-
border-radius: 6px;
|
|
135
|
-
}
|
|
136
|
-
}
|
|
137
|
-
</style>
|
|
1
|
+
<script setup lang="ts">
|
|
2
|
+
import CardContainer from '@af-mobile-client-vue3/components/data/CardContainer/CardContainer.vue'
|
|
3
|
+
import CardHeader from '@af-mobile-client-vue3/components/data/CardContainer/CardHeader.vue'
|
|
4
|
+
import {
|
|
5
|
+
Field as VanField,
|
|
6
|
+
Picker as VanPicker,
|
|
7
|
+
Popup as VanPopup,
|
|
8
|
+
} from 'vant'
|
|
9
|
+
import { ref, watch } from 'vue'
|
|
10
|
+
|
|
11
|
+
const props = defineProps<{
|
|
12
|
+
modelValue: string
|
|
13
|
+
remarks: string
|
|
14
|
+
}>()
|
|
15
|
+
|
|
16
|
+
const emit = defineEmits<{
|
|
17
|
+
(e: 'update:modelValue', value: string): void
|
|
18
|
+
(e: 'update:remarks', value: string): void
|
|
19
|
+
}>()
|
|
20
|
+
|
|
21
|
+
const printOptions = [
|
|
22
|
+
{ text: '电子发票', value: '电子发票' },
|
|
23
|
+
{ text: '普通收据', value: '普通收据' },
|
|
24
|
+
{ text: '两者都需要', value: 'both' },
|
|
25
|
+
]
|
|
26
|
+
|
|
27
|
+
const selectedOption = ref(getOptionText(props.modelValue))
|
|
28
|
+
const remarks = ref(props.remarks)
|
|
29
|
+
const showPicker = ref(false)
|
|
30
|
+
|
|
31
|
+
function getOptionText(value: string): string {
|
|
32
|
+
const option = printOptions.find(opt => opt.value === value)
|
|
33
|
+
return option ? option.text : ''
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
function onConfirm({ selectedValues }: { selectedValues: string[] }) {
|
|
37
|
+
selectedOption.value = selectedValues[0]
|
|
38
|
+
emit('update:modelValue', selectedValues[0])
|
|
39
|
+
showPicker.value = false
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
watch(() => remarks.value, (newValue) => {
|
|
43
|
+
emit('update:remarks', newValue)
|
|
44
|
+
})
|
|
45
|
+
|
|
46
|
+
// 当从外部更新值时更新内部状态
|
|
47
|
+
watch(() => props.modelValue, (newValue) => {
|
|
48
|
+
selectedOption.value = getOptionText(newValue)
|
|
49
|
+
})
|
|
50
|
+
|
|
51
|
+
watch(() => props.remarks, (newValue) => {
|
|
52
|
+
remarks.value = newValue
|
|
53
|
+
})
|
|
54
|
+
</script>
|
|
55
|
+
|
|
56
|
+
<template>
|
|
57
|
+
<CardContainer class="charge-print-and-remarks">
|
|
58
|
+
<CardHeader title="打印及备注" />
|
|
59
|
+
<div class="charge-print-options">
|
|
60
|
+
<div class="charge-print-options__section">
|
|
61
|
+
<label class="charge-print-options__label">收据打印选项</label>
|
|
62
|
+
<div class="charge-print-options__selector">
|
|
63
|
+
<VanField
|
|
64
|
+
v-model="selectedOption"
|
|
65
|
+
is-link
|
|
66
|
+
readonly
|
|
67
|
+
placeholder="请选择打印方式"
|
|
68
|
+
@click="showPicker = true"
|
|
69
|
+
/>
|
|
70
|
+
</div>
|
|
71
|
+
</div>
|
|
72
|
+
|
|
73
|
+
<div class="charge-print-options__section">
|
|
74
|
+
<label class="charge-print-options__label">备注</label>
|
|
75
|
+
<div class="charge-print-options__selector">
|
|
76
|
+
<VanField
|
|
77
|
+
v-model="remarks"
|
|
78
|
+
type="textarea"
|
|
79
|
+
placeholder="可选填写备注信息"
|
|
80
|
+
rows="2"
|
|
81
|
+
autosize
|
|
82
|
+
maxlength="200"
|
|
83
|
+
show-word-limit
|
|
84
|
+
/>
|
|
85
|
+
</div>
|
|
86
|
+
</div>
|
|
87
|
+
|
|
88
|
+
<VanPopup v-model:show="showPicker" position="bottom" round teleport="body">
|
|
89
|
+
<VanPicker
|
|
90
|
+
:columns="printOptions"
|
|
91
|
+
show-toolbar
|
|
92
|
+
title="选择打印方式"
|
|
93
|
+
@confirm="onConfirm"
|
|
94
|
+
@cancel="showPicker = false"
|
|
95
|
+
/>
|
|
96
|
+
</VanPopup>
|
|
97
|
+
</div>
|
|
98
|
+
</CardContainer>
|
|
99
|
+
</template>
|
|
100
|
+
|
|
101
|
+
<style scoped lang="less">
|
|
102
|
+
.charge-print-and-remarks {
|
|
103
|
+
margin-bottom: 16px;
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
.charge-print-options {
|
|
107
|
+
&__section {
|
|
108
|
+
margin-bottom: 16px;
|
|
109
|
+
|
|
110
|
+
&:last-child {
|
|
111
|
+
margin-bottom: 0;
|
|
112
|
+
}
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
&__label {
|
|
116
|
+
display: block;
|
|
117
|
+
font-size: 12px;
|
|
118
|
+
font-weight: 500;
|
|
119
|
+
color: #6b7280;
|
|
120
|
+
margin-bottom: 4px;
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
&__selector {
|
|
124
|
+
position: relative;
|
|
125
|
+
|
|
126
|
+
:deep(.van-field) {
|
|
127
|
+
background-color: #f9fafb;
|
|
128
|
+
border-radius: 6px;
|
|
129
|
+
}
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
:deep(.van-field__control) {
|
|
133
|
+
background-color: #f9fafb;
|
|
134
|
+
border-radius: 6px;
|
|
135
|
+
}
|
|
136
|
+
}
|
|
137
|
+
</style>
|