af-mobile-client-vue3 1.3.67 → 1.3.68

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,7 +1,7 @@
1
1
  {
2
2
  "name": "af-mobile-client-vue3",
3
3
  "type": "module",
4
- "version": "1.3.67",
4
+ "version": "1.3.68",
5
5
  "packageManager": "pnpm@10.13.1",
6
6
  "description": "Vue + Vite component lib",
7
7
  "engines": {
@@ -1,11 +1,14 @@
1
1
  <script setup lang="ts">
2
2
  import { getDictItemByValue } from '@af-mobile-client-vue3/utils/dictUtil'
3
+ import dayjs from 'dayjs/esm/index'
3
4
  import { ref } from 'vue'
4
5
 
5
- const { serviceName, dictName, dictValue } = defineProps<{
6
+ const { serviceName, dictName, dictValue, dictType } = defineProps<{
6
7
  serviceName: string
7
8
  dictName: string | null | undefined
8
- dictValue: string | null | undefined
9
+ dictValue: string | number | null | undefined
10
+ // 用于非字典型的格式化展示:如日期/小数/整数等
11
+ dictType?: 'date' | 'dateTime' | 'towDecimal' | 'fourDecimal' | 'int' | string
9
12
  }>()
10
13
 
11
14
  // 字面值
@@ -18,23 +21,86 @@ initComponent()
18
21
 
19
22
  // 组件初始化
20
23
  function initComponent() {
21
- if (dictValue === null || dictValue === undefined) {
24
+ if (dictValue === null || dictValue === undefined || dictValue === '') {
22
25
  label.value = '--'
26
+ className.value = ''
23
27
  return
24
28
  }
25
- if (!dictName || dictName === '') {
26
- label.value = dictValue.toString()
29
+
30
+ // 1) 优先使用字典映射
31
+ if (dictName && dictName !== '') {
32
+ getDictItemByValue(dictName, serviceName, String(dictValue), (result) => {
33
+ if (result == null) {
34
+ // 字典未命中,退回到格式化/原值
35
+ applyFormatFallback()
36
+ }
37
+ else {
38
+ label.value = result.label
39
+ className.value = `badge-${result.status}`
40
+ }
41
+ })
27
42
  return
28
43
  }
29
- getDictItemByValue(dictName, serviceName, dictValue, (result) => {
30
- if (result == null) {
31
- label.value = dictValue.toString()
32
- }
33
- else {
34
- label.value = result.label
35
- className.value = `badge-${result.status}`
36
- }
37
- })
44
+
45
+ // 2) 无字典名时,按 dictType 做格式化
46
+ applyFormatFallback()
47
+ }
48
+
49
+ function applyFormatFallback() {
50
+ className.value = ''
51
+ if (!dictType || dictType === '') {
52
+ label.value = String(dictValue)
53
+ return
54
+ }
55
+ switch (dictType) {
56
+ case 'date':
57
+ label.value = formatDateLike(dictValue, 'YYYY-MM-DD')
58
+ break
59
+ case 'dateTime':
60
+ label.value = formatDateLike(dictValue, 'YYYY-MM-DD HH:mm:ss')
61
+ break
62
+ case 'towDecimal':
63
+ label.value = formatNumberLike(dictValue, 2)
64
+ break
65
+ case 'fourDecimal':
66
+ label.value = formatNumberLike(dictValue, 4)
67
+ break
68
+ case 'int':
69
+ label.value = formatNumberLike(dictValue, 0)
70
+ break
71
+ default:
72
+ label.value = String(dictValue)
73
+ break
74
+ }
75
+ }
76
+
77
+ function pad2(num: number): string {
78
+ return String(num).padStart(2, '0')
79
+ }
80
+
81
+ function formatDateLike(val: string | number, pattern: string): string {
82
+ // 1️⃣ 先判断时间是否合法
83
+ const date = dayjs(val)
84
+ if (!date.isValid()) {
85
+ console.warn('时间字符串不合法:', val)
86
+ return val as string
87
+ }
88
+
89
+ // 2️⃣ 判断格式字符串是否有效(简单校验,格式字符串非空)
90
+ if (!pattern || typeof pattern !== 'string') {
91
+ console.warn('格式字符串不合法:', pattern)
92
+ return val as string
93
+ }
94
+
95
+ // 3️⃣ 使用 dayjs 格式化
96
+ return date.format(pattern)
97
+ }
98
+
99
+ function formatNumberLike(val: string | number, digits: number): string {
100
+ const num = typeof val === 'number' ? val : Number(val)
101
+ if (Number.isNaN(num))
102
+ return String(val)
103
+ return num.toFixed(digits)
38
104
  }
39
105
  </script>
40
106
 
@@ -841,7 +841,13 @@ function handleCheckboxChange(item: any, checked: boolean) {
841
841
  :class="{ 'selectable-title': isMultiSelectMode }"
842
842
  @click="handleTitleClick(item, $event)"
843
843
  >
844
- {{ item[column.dataIndex] ?? '--' }}
844
+ <XBadge
845
+ :style="handleFunctionStyle(column.styleFunctionForValue, item)"
846
+ :dict-name="column.dictName"
847
+ :dict-value="item[column.dataIndex]"
848
+ :dict-type="column.slotType"
849
+ :service-name="serviceName"
850
+ />
845
851
  </p>
846
852
  </div>
847
853
  <div v-for="(column) in subTitleColumns" :key="`subtitle_${column.dataIndex}`" class="sub-title">
@@ -851,7 +857,9 @@ function handleCheckboxChange(item: any, checked: boolean) {
851
857
  >
852
858
  <XBadge
853
859
  :style="handleFunctionStyle(column.styleFunctionForValue, item)"
854
- :dict-name="column.dictName" :dict-value="item[column.dataIndex]"
860
+ :dict-name="column.dictName"
861
+ :dict-value="item[column.dataIndex]"
862
+ :dict-type="column.slotType"
855
863
  :service-name="serviceName"
856
864
  />
857
865
  </p>
@@ -876,7 +884,9 @@ function handleCheckboxChange(item: any, checked: boolean) {
876
884
  {{ (column.showLabel === undefined || column.showLabel) ? `${column.title}: ` : '' }}
877
885
  <XBadge
878
886
  :style="handleFunctionStyle(column.styleFunctionForValue, item)"
879
- :dict-name="column.dictName" :dict-value="item[column.dataIndex]"
887
+ :dict-name="column.dictName"
888
+ :dict-value="item[column.dataIndex]"
889
+ :dict-type="column.slotType"
880
890
  :service-name="serviceName"
881
891
  />
882
892
  </p>
@@ -924,7 +934,9 @@ function handleCheckboxChange(item: any, checked: boolean) {
924
934
  </span>
925
935
  <XBadge
926
936
  :style="handleFunctionStyle(column.styleFunctionForValue, item)"
927
- :dict-name="column.dictName" :dict-value="item[column.dataIndex]"
937
+ :dict-name="column.dictName"
938
+ :dict-value="item[column.dataIndex]"
939
+ :dict-type="column.slotType"
928
940
  :service-name="serviceName"
929
941
  />
930
942
  </p>
@@ -1,134 +1,134 @@
1
- <script setup lang="ts">
2
- import XCellList from '@af-mobile-client-vue3/components/data/XCellList/index.vue'
3
- import NormalDataLayout from '@af-mobile-client-vue3/components/layout/NormalDataLayout/index.vue'
4
- import { useUserStore } from '@af-mobile-client-vue3/stores/modules/user'
5
- import { defineEmits, ref } from 'vue'
6
- import { useRouter } from 'vue-router'
7
-
8
- // 定义事件
9
- const emit = defineEmits(['deleteRow'])
10
-
11
- // 多选操作配置
12
- const multiSelectActions = ref([
13
- { name: '批量审核', key: 'batchAudit', color: '#000000', icon: 'passed' },
14
- ])
15
-
16
- const userInfo = useUserStore().getUserInfo()
17
- // 访问路由
18
- const router = useRouter()
19
- // 获取默认值
20
- const idKey = ref('o_id')
21
-
22
- // 简易crud表单测试
23
- const configName = ref('lngChargeAuditMobileCRUD')
24
- const serviceName = ref('af-gaslink')
25
-
26
- // 资源权限测试
27
- // const configName = ref('crud_sources_test')
28
- // const serviceName = ref('af-system')
29
-
30
- // 实际业务测试
31
- // const configName = ref('lngChargeAuditMobileCRUD')
32
- // const serviceName = ref('af-gaslink')
33
-
34
- // 跳转到详情页面
35
- // function toDetail(item) {
36
- // router.push({
37
- // name: 'XCellDetailView',
38
- // params: { id: item[idKey.value] }, // 如果使用命名路由,推荐使用路由参数而不是直接构建 URL
39
- // query: {
40
- // operName: item[operNameKey.value],
41
- // method:item[methodKey.value],
42
- // requestMethod:item[requestMethodKey.value],
43
- // operatorType:item[operatorTypeKey.value],
44
- // operUrl:item[operUrlKey.value],
45
- // operIp:item[operIpKey.value],
46
- // costTime:item[costTimeKey.value],
47
- // operTime:item[operTimeKey.value],
48
- //
49
- // title: item[titleKey.value],
50
- // businessType: item[businessTypeKey.value],
51
- // status:item[statusKey.value]
52
- // }
53
- // })
54
- // }
55
-
56
- // 跳转到表单——以表单组来渲染纯表单
57
- function toDetail(item) {
58
- router.push({
59
- name: 'XFormView',
60
- query: {
61
- id: item[idKey.value],
62
- // id: item.rr_id,
63
- // o_id: item.o_id,
64
- },
65
- })
66
- }
67
-
68
- // 新增功能
69
- // function addOption(totalCount) {
70
- // router.push({
71
- // name: 'XFormView',
72
- // params: { id: totalCount, openid: totalCount },
73
- // query: {
74
- // configName: configName.value,
75
- // serviceName: serviceName.value,
76
- // mode: '新增',
77
- // },
78
- // })
79
- // }
80
-
81
- // 修改功能
82
- // function updateRow(result) {
83
- // router.push({
84
- // name: 'XFormView',
85
- // params: { id: result.o_id, openid: result.o_id },
86
- // query: {
87
- // configName: configName.value,
88
- // serviceName: serviceName.value,
89
- // mode: '修改',
90
- // },
91
- // })
92
- // }
93
-
94
- // 删除功能
95
- function deleteRow(result) {
96
- emit('deleteRow', result.o_id)
97
- }
98
-
99
- // 多选操作处理
100
- function handleMultiSelectAction(action: string, selectedItems: any[], selectedItemsArray: any[]) {
101
- console.log('多选操作:', action, selectedItems, selectedItemsArray)
102
- }
103
-
104
- // 选择变化处理
105
- function handleSelectionChange(selectedItems: any[]) {
106
- console.log('选择变化,当前选中:', selectedItems.length, '个项目')
107
- // 可以在这里更新UI状态,比如显示选中数量等
108
- }
109
-
110
- // 数据加载完成后处理 @after-load
111
- function afterLoad(result) {
112
- console.log('afterLoad:', result)
113
- }
114
- </script>
115
-
116
- <template>
117
- <NormalDataLayout id="XCellListView" title="工作计划">
118
- <template #layout_content>
119
- <XCellList
120
- config-name="saleOrderAuditMobileCRUD"
121
- service-name="af-gaslink"
122
- :enable-multi-select="true"
123
- id-key="rr_id"
124
- :multi-select-actions="multiSelectActions"
125
- @to-detail="toDetail"
126
- @multi-select-action="handleMultiSelectAction"
127
- @selection-change="handleSelectionChange"
128
- />
129
- </template>
130
- </NormalDataLayout>
131
- </template>
132
-
133
- <style scoped lang="less">
134
- </style>
1
+ <script setup lang="ts">
2
+ import XCellList from '@af-mobile-client-vue3/components/data/XCellList/index.vue'
3
+ import NormalDataLayout from '@af-mobile-client-vue3/components/layout/NormalDataLayout/index.vue'
4
+ import { useUserStore } from '@af-mobile-client-vue3/stores/modules/user'
5
+ import { defineEmits, ref } from 'vue'
6
+ import { useRouter } from 'vue-router'
7
+
8
+ // 定义事件
9
+ const emit = defineEmits(['deleteRow'])
10
+
11
+ // 多选操作配置
12
+ const multiSelectActions = ref([
13
+ { name: '批量审核', key: 'batchAudit', color: '#000000', icon: 'passed' },
14
+ ])
15
+
16
+ const userInfo = useUserStore().getUserInfo()
17
+ // 访问路由
18
+ const router = useRouter()
19
+ // 获取默认值
20
+ const idKey = ref('o_id')
21
+
22
+ // 简易crud表单测试
23
+ const configName = ref('lngChargeAuditMobileCRUD')
24
+ const serviceName = ref('af-gaslink')
25
+
26
+ // 资源权限测试
27
+ // const configName = ref('crud_sources_test')
28
+ // const serviceName = ref('af-system')
29
+
30
+ // 实际业务测试
31
+ // const configName = ref('lngChargeAuditMobileCRUD')
32
+ // const serviceName = ref('af-gaslink')
33
+
34
+ // 跳转到详情页面
35
+ // function toDetail(item) {
36
+ // router.push({
37
+ // name: 'XCellDetailView',
38
+ // params: { id: item[idKey.value] }, // 如果使用命名路由,推荐使用路由参数而不是直接构建 URL
39
+ // query: {
40
+ // operName: item[operNameKey.value],
41
+ // method:item[methodKey.value],
42
+ // requestMethod:item[requestMethodKey.value],
43
+ // operatorType:item[operatorTypeKey.value],
44
+ // operUrl:item[operUrlKey.value],
45
+ // operIp:item[operIpKey.value],
46
+ // costTime:item[costTimeKey.value],
47
+ // operTime:item[operTimeKey.value],
48
+ //
49
+ // title: item[titleKey.value],
50
+ // businessType: item[businessTypeKey.value],
51
+ // status:item[statusKey.value]
52
+ // }
53
+ // })
54
+ // }
55
+
56
+ // 跳转到表单——以表单组来渲染纯表单
57
+ function toDetail(item) {
58
+ router.push({
59
+ name: 'XFormView',
60
+ query: {
61
+ id: item[idKey.value],
62
+ // id: item.rr_id,
63
+ // o_id: item.o_id,
64
+ },
65
+ })
66
+ }
67
+
68
+ // 新增功能
69
+ // function addOption(totalCount) {
70
+ // router.push({
71
+ // name: 'XFormView',
72
+ // params: { id: totalCount, openid: totalCount },
73
+ // query: {
74
+ // configName: configName.value,
75
+ // serviceName: serviceName.value,
76
+ // mode: '新增',
77
+ // },
78
+ // })
79
+ // }
80
+
81
+ // 修改功能
82
+ // function updateRow(result) {
83
+ // router.push({
84
+ // name: 'XFormView',
85
+ // params: { id: result.o_id, openid: result.o_id },
86
+ // query: {
87
+ // configName: configName.value,
88
+ // serviceName: serviceName.value,
89
+ // mode: '修改',
90
+ // },
91
+ // })
92
+ // }
93
+
94
+ // 删除功能
95
+ function deleteRow(result) {
96
+ emit('deleteRow', result.o_id)
97
+ }
98
+
99
+ // 多选操作处理
100
+ function handleMultiSelectAction(action: string, selectedItems: any[], selectedItemsArray: any[]) {
101
+ console.log('多选操作:', action, selectedItems, selectedItemsArray)
102
+ }
103
+
104
+ // 选择变化处理
105
+ function handleSelectionChange(selectedItems: any[]) {
106
+ console.log('选择变化,当前选中:', selectedItems.length, '个项目')
107
+ // 可以在这里更新UI状态,比如显示选中数量等
108
+ }
109
+
110
+ // 数据加载完成后处理 @after-load
111
+ function afterLoad(result) {
112
+ console.log('afterLoad:', result)
113
+ }
114
+ </script>
115
+
116
+ <template>
117
+ <NormalDataLayout id="XCellListView" title="工作计划">
118
+ <template #layout_content>
119
+ <XCellList
120
+ config-name="saleOrderAuditMobileCRUD"
121
+ service-name="af-gaslink"
122
+ :enable-multi-select="true"
123
+ id-key="rr_id"
124
+ :multi-select-actions="multiSelectActions"
125
+ @to-detail="toDetail"
126
+ @multi-select-action="handleMultiSelectAction"
127
+ @selection-change="handleSelectionChange"
128
+ />
129
+ </template>
130
+ </NormalDataLayout>
131
+ </template>
132
+
133
+ <style scoped lang="less">
134
+ </style>
@@ -1,42 +1,42 @@
1
- <script setup lang="ts">
2
- import XForm from '@af-mobile-client-vue3/components/data/XForm/index.vue'
3
- import NormalDataLayout from '@af-mobile-client-vue3/components/layout/NormalDataLayout/index.vue'
4
- import { ref } from 'vue'
5
- import {
6
- Button as VanButton,
7
- } from 'vant'
8
-
9
- const configName = ref('测试Form')
10
- const serviceName = ref('af-safecheck')
11
- const formGroupAddConstruction = ref()
12
-
13
- // 提交测试
14
- function onSubmit(form) {
15
- console.log('事件触发提交表单----', form)
16
- }
17
- async function onAsyncSubmit() {
18
- const res = await formGroupAddConstruction.value.asyncSubmit()
19
- console.log('异步提交表单----', res)
20
- }
21
- </script>
22
-
23
- <template>
24
- <NormalDataLayout id="XFormGroupView" title="纯表单">
25
- <template #layout_content>
26
- <XForm
27
- ref="formGroupAddConstruction"
28
- mode="新增"
29
- :config-name="configName"
30
- :show-tab-header="false"
31
- service-name="af-safecheck"
32
- :is-group-form="true"
33
- @on-submit="onSubmit"
34
- />
35
- </template>
36
- </NormalDataLayout>
37
- <van-button type="primary" @click="onAsyncSubmit">提交</van-button>
38
- </template>
39
-
40
- <style scoped lang="less">
41
-
42
- </style>
1
+ <script setup lang="ts">
2
+ import XForm from '@af-mobile-client-vue3/components/data/XForm/index.vue'
3
+ import NormalDataLayout from '@af-mobile-client-vue3/components/layout/NormalDataLayout/index.vue'
4
+ import { ref } from 'vue'
5
+ import {
6
+ Button as VanButton,
7
+ } from 'vant'
8
+
9
+ const configName = ref('测试Form')
10
+ const serviceName = ref('af-safecheck')
11
+ const formGroupAddConstruction = ref()
12
+
13
+ // 提交测试
14
+ function onSubmit(form) {
15
+ console.log('事件触发提交表单----', form)
16
+ }
17
+ async function onAsyncSubmit() {
18
+ const res = await formGroupAddConstruction.value.asyncSubmit()
19
+ console.log('异步提交表单----', res)
20
+ }
21
+ </script>
22
+
23
+ <template>
24
+ <NormalDataLayout id="XFormGroupView" title="纯表单">
25
+ <template #layout_content>
26
+ <XForm
27
+ ref="formGroupAddConstruction"
28
+ mode="新增"
29
+ :config-name="configName"
30
+ :show-tab-header="false"
31
+ service-name="af-safecheck"
32
+ :is-group-form="true"
33
+ @on-submit="onSubmit"
34
+ />
35
+ </template>
36
+ </NormalDataLayout>
37
+ <van-button type="primary" @click="onAsyncSubmit">提交</van-button>
38
+ </template>
39
+
40
+ <style scoped lang="less">
41
+
42
+ </style>