af-mobile-client-vue3 1.3.23 → 1.3.25
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 +1 -1
- package/src/components/data/XCellList/index.vue +322 -8
- package/src/components/data/XForm/index.vue +1 -1
- package/src/components/data/XFormGroup/doc/DeviceForm.vue +1 -1
- package/src/components/data/XFormGroup/doc/UserForm.vue +1 -1
- package/src/components/data/XReportGrid/XReportDemo.vue +33 -33
- package/src/components/data/XReportGrid/print.js +184 -184
- package/src/stores/modules/homeApp.ts +7 -6
- package/src/utils/queryFormDefaultRangePicker.ts +57 -57
- package/src/views/component/XCellListView/index.vue +113 -131
- package/src/views/component/XFormGroupView/index.vue +16 -26
- package/src/stores/modules/homeApp/README.md +0 -124
|
@@ -1,147 +1,129 @@
|
|
|
1
1
|
<script setup lang="ts">
|
|
2
2
|
import XCellList from '@af-mobile-client-vue3/components/data/XCellList/index.vue'
|
|
3
|
-
import
|
|
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'
|
|
4
6
|
import { useRouter } from 'vue-router'
|
|
5
7
|
|
|
6
|
-
|
|
7
|
-
const
|
|
8
|
-
|
|
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
|
+
// 访问路由
|
|
9
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: 'XFormGroupView',
|
|
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
|
+
|
|
10
94
|
// 删除功能
|
|
11
|
-
function
|
|
12
|
-
|
|
95
|
+
function deleteRow(result) {
|
|
96
|
+
emit('deleteRow', result.o_id)
|
|
13
97
|
}
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
98
|
+
|
|
99
|
+
// 多选操作处理
|
|
100
|
+
function handleMultiSelectAction(action: string, selectedItems: any[], selectedItemsArray: any[]) {
|
|
101
|
+
console.log('多选操作:', action, selectedItems, selectedItemsArray)
|
|
17
102
|
}
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
103
|
+
|
|
104
|
+
// 选择变化处理
|
|
105
|
+
function handleSelectionChange(selectedItems: any[]) {
|
|
106
|
+
console.log('选择变化,当前选中:', selectedItems.length, '个项目')
|
|
107
|
+
// 可以在这里更新UI状态,比如显示选中数量等
|
|
21
108
|
}
|
|
22
|
-
onMounted(() => {
|
|
23
|
-
console.log('初始化页面===')
|
|
24
|
-
})
|
|
25
|
-
onActivated(() => {
|
|
26
|
-
// 每次回到页面都会触发
|
|
27
|
-
console.log('activated: 每次回到页面都会触发')
|
|
28
|
-
})
|
|
29
109
|
</script>
|
|
30
110
|
|
|
31
111
|
<template>
|
|
32
|
-
<
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
112
|
+
<NormalDataLayout id="XCellListView" title="工作计划">
|
|
113
|
+
<template #layout_content>
|
|
114
|
+
<XCellList
|
|
115
|
+
config-name="lngChargeAuditMobileCRUD"
|
|
116
|
+
service-name="af-gaslink"
|
|
117
|
+
:enable-multi-select="true"
|
|
118
|
+
id-key="rr_id"
|
|
119
|
+
:multi-select-actions="multiSelectActions"
|
|
120
|
+
@to-detail="toDetail"
|
|
121
|
+
@multi-select-action="handleMultiSelectAction"
|
|
122
|
+
@selection-change="handleSelectionChange"
|
|
123
|
+
/>
|
|
124
|
+
</template>
|
|
125
|
+
</NormalDataLayout>
|
|
39
126
|
</template>
|
|
40
127
|
|
|
41
128
|
<style scoped lang="less">
|
|
42
|
-
.cell-search-after {
|
|
43
|
-
padding: 0 12px 12px 12px;
|
|
44
|
-
background-color: #fff;
|
|
45
|
-
.van-row:first-child {
|
|
46
|
-
align-items: center;
|
|
47
|
-
margin-bottom: 8px;
|
|
48
|
-
padding: 0 2px;
|
|
49
|
-
h4 {
|
|
50
|
-
font-size: 1.08rem;
|
|
51
|
-
font-weight: 600;
|
|
52
|
-
margin: 0;
|
|
53
|
-
color: #222;
|
|
54
|
-
letter-spacing: 1px;
|
|
55
|
-
}
|
|
56
|
-
.stat-date-range {
|
|
57
|
-
display: flex;
|
|
58
|
-
align-items: center;
|
|
59
|
-
justify-content: flex-end;
|
|
60
|
-
font-size: 0.92rem;
|
|
61
|
-
color: #b0b3b8;
|
|
62
|
-
font-weight: 400;
|
|
63
|
-
span {
|
|
64
|
-
margin-left: 4px;
|
|
65
|
-
font-size: 0.92rem;
|
|
66
|
-
color: #b0b3b8;
|
|
67
|
-
}
|
|
68
|
-
.van-icon {
|
|
69
|
-
font-size: 1rem;
|
|
70
|
-
color: #b0b3b8;
|
|
71
|
-
margin-right: 2px;
|
|
72
|
-
}
|
|
73
|
-
}
|
|
74
|
-
}
|
|
75
|
-
.van-row:nth-child(2) {
|
|
76
|
-
margin-top: 8px;
|
|
77
|
-
// 统计卡片间距由gutter控制
|
|
78
|
-
.van-col {
|
|
79
|
-
// 让卡片宽度自适应
|
|
80
|
-
.stat-card {
|
|
81
|
-
width: 100%;
|
|
82
|
-
}
|
|
83
|
-
}
|
|
84
|
-
}
|
|
85
|
-
.stat-card {
|
|
86
|
-
display: flex;
|
|
87
|
-
flex-direction: column;
|
|
88
|
-
align-items: center;
|
|
89
|
-
justify-content: center;
|
|
90
|
-
border-radius: 12px;
|
|
91
|
-
padding: 6px 0 4px 0; // 压缩高度
|
|
92
|
-
min-height: 44px; // 压缩高度
|
|
93
|
-
position: relative;
|
|
94
|
-
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.03);
|
|
95
|
-
background: #f7f8fa;
|
|
96
|
-
.stat-num {
|
|
97
|
-
font-size: 1.08rem; // 缩小字体
|
|
98
|
-
font-weight: 600;
|
|
99
|
-
margin-bottom: 2px;
|
|
100
|
-
}
|
|
101
|
-
.stat-label {
|
|
102
|
-
font-size: 0.82rem; // 缩小字体
|
|
103
|
-
margin-bottom: 2px;
|
|
104
|
-
}
|
|
105
|
-
.stat-icon {
|
|
106
|
-
position: absolute;
|
|
107
|
-
top: 6px;
|
|
108
|
-
right: 8px;
|
|
109
|
-
font-size: 1rem;
|
|
110
|
-
opacity: 0.4;
|
|
111
|
-
}
|
|
112
|
-
}
|
|
113
|
-
.stat-total {
|
|
114
|
-
background: #f0f5ff;
|
|
115
|
-
color: #2f54eb;
|
|
116
|
-
.stat-num,
|
|
117
|
-
.stat-label {
|
|
118
|
-
color: #2f54eb;
|
|
119
|
-
}
|
|
120
|
-
.stat-icon {
|
|
121
|
-
color: #2f54eb;
|
|
122
|
-
}
|
|
123
|
-
}
|
|
124
|
-
.stat-done {
|
|
125
|
-
background: #e6fffb;
|
|
126
|
-
color: #13c2c2;
|
|
127
|
-
.stat-num,
|
|
128
|
-
.stat-label {
|
|
129
|
-
color: #13c2c2;
|
|
130
|
-
}
|
|
131
|
-
.stat-icon {
|
|
132
|
-
color: #13c2c2;
|
|
133
|
-
}
|
|
134
|
-
}
|
|
135
|
-
.stat-processing {
|
|
136
|
-
background: #f9f0ff;
|
|
137
|
-
color: #b37feb;
|
|
138
|
-
.stat-num,
|
|
139
|
-
.stat-label {
|
|
140
|
-
color: #b37feb;
|
|
141
|
-
}
|
|
142
|
-
.stat-icon {
|
|
143
|
-
color: #b37feb;
|
|
144
|
-
}
|
|
145
|
-
}
|
|
146
|
-
}
|
|
147
129
|
</style>
|
|
@@ -5,31 +5,31 @@ import { showDialog } from 'vant'
|
|
|
5
5
|
import { ref } from 'vue'
|
|
6
6
|
import { useRoute } from 'vue-router'
|
|
7
7
|
|
|
8
|
+
// const configName = ref('reviewFormGroup')
|
|
9
|
+
// const serviceName = ref('af-revenue')
|
|
10
|
+
|
|
8
11
|
// 纯表单
|
|
9
|
-
const configName = ref('
|
|
10
|
-
const serviceName = ref('af-
|
|
12
|
+
// const configName = ref('form_check_test')
|
|
13
|
+
// const serviceName = ref('af-system')
|
|
11
14
|
|
|
12
15
|
// const configName = ref("计划下发Form")
|
|
13
16
|
// const serviceName = ref("af-linepatrol")
|
|
14
17
|
|
|
15
18
|
// 表单组
|
|
16
|
-
|
|
17
|
-
|
|
19
|
+
const configName = ref('lngChargeAuditMobileFormGroup')
|
|
20
|
+
const serviceName = ref('af-gaslink')
|
|
18
21
|
|
|
19
|
-
const formData = ref({
|
|
22
|
+
const formData = ref({})
|
|
20
23
|
const formGroup = ref(null)
|
|
21
24
|
const route = useRoute()
|
|
22
25
|
const isInit = ref(false)
|
|
23
26
|
function submit(_result) {
|
|
24
|
-
showDialog({ message: '提交成功' })
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
function setRef(value: any) {
|
|
29
|
-
console.log('myXForm', myXForm)
|
|
30
|
-
formGroup.value.setRef(myXForm.value)
|
|
31
|
-
console.log(formGroup)
|
|
27
|
+
showDialog({ message: '提交成功' }).then(() => {
|
|
28
|
+
console.log('12121')
|
|
29
|
+
// history.back()
|
|
30
|
+
})
|
|
32
31
|
}
|
|
32
|
+
|
|
33
33
|
// 表单组——数据
|
|
34
34
|
// function initComponents () {
|
|
35
35
|
// runLogic('getlngChargeAuditMobileFormGroupData', {id: 29}, 'af-gaslink').then((res) => {
|
|
@@ -59,30 +59,20 @@ function setRef(value: any) {
|
|
|
59
59
|
// onBeforeMount(() => {
|
|
60
60
|
// initComponents()
|
|
61
61
|
// })
|
|
62
|
-
function a() {
|
|
63
|
-
formData.value.t_userinfo.f_user_name = '453333333'
|
|
64
|
-
}
|
|
65
62
|
</script>
|
|
66
63
|
|
|
67
64
|
<template>
|
|
68
65
|
<NormalDataLayout id="XFormGroupView" title="纯表单">
|
|
69
66
|
<template #layout_content>
|
|
70
|
-
<button @click="a">
|
|
71
|
-
修改
|
|
72
|
-
</button>
|
|
73
67
|
<!-- v-if="isInit" -->
|
|
74
68
|
<XFormGroup
|
|
75
69
|
ref="formGroup"
|
|
76
|
-
|
|
77
|
-
|
|
70
|
+
config-name="ApplyAddContractFormGroup"
|
|
71
|
+
service-name="af-apply"
|
|
78
72
|
:group-form-data="formData"
|
|
79
73
|
mode="新增"
|
|
80
74
|
@submit="submit"
|
|
81
|
-
|
|
82
|
-
<!-- <template #device="{ setRef, removeRef, item, formData }">
|
|
83
|
-
<XFormView :setRef="setRef" :formGroupName="'myXForm'"/>
|
|
84
|
-
</template> -->
|
|
85
|
-
</XFormGroup>
|
|
75
|
+
/>
|
|
86
76
|
</template>
|
|
87
77
|
</NormalDataLayout>
|
|
88
78
|
</template>
|
|
@@ -1,124 +0,0 @@
|
|
|
1
|
-
# HomeApp Store 使用说明
|
|
2
|
-
|
|
3
|
-
## 概述
|
|
4
|
-
`useHomeAppStore` 是一个专门用于管理首页应用列表的 Pinia store,与 `useSettingStore` 配合使用。
|
|
5
|
-
|
|
6
|
-
## 特性
|
|
7
|
-
- 独立管理 `homeAppList` 数据
|
|
8
|
-
- 提供完整的 CRUD 操作
|
|
9
|
-
- 与 setting store 自动同步数据
|
|
10
|
-
- 支持类型安全的 TypeScript 接口
|
|
11
|
-
|
|
12
|
-
## 基本使用
|
|
13
|
-
|
|
14
|
-
### 1. 导入和使用
|
|
15
|
-
```typescript
|
|
16
|
-
import { useHomeAppStore } from '@/stores'
|
|
17
|
-
|
|
18
|
-
const homeAppStore = useHomeAppStore()
|
|
19
|
-
```
|
|
20
|
-
|
|
21
|
-
### 2. 获取应用列表
|
|
22
|
-
```typescript
|
|
23
|
-
// 获取所有应用
|
|
24
|
-
const apps = homeAppStore.getHomeAppList()
|
|
25
|
-
|
|
26
|
-
// 直接访问响应式数据
|
|
27
|
-
const apps = homeAppStore.homeAppList
|
|
28
|
-
```
|
|
29
|
-
|
|
30
|
-
### 3. 添加应用
|
|
31
|
-
```typescript
|
|
32
|
-
homeAppStore.addHomeApp({
|
|
33
|
-
id: 'new-app',
|
|
34
|
-
name: '新应用',
|
|
35
|
-
icon: '/icon.png',
|
|
36
|
-
url: 'https://example.com',
|
|
37
|
-
description: '应用描述'
|
|
38
|
-
})
|
|
39
|
-
```
|
|
40
|
-
|
|
41
|
-
### 4. 更新应用
|
|
42
|
-
```typescript
|
|
43
|
-
homeAppStore.updateHomeApp('app-id', {
|
|
44
|
-
name: '更新后的名称',
|
|
45
|
-
description: '新的描述'
|
|
46
|
-
})
|
|
47
|
-
```
|
|
48
|
-
|
|
49
|
-
### 5. 删除应用
|
|
50
|
-
```typescript
|
|
51
|
-
homeAppStore.removeHomeApp('app-id')
|
|
52
|
-
```
|
|
53
|
-
|
|
54
|
-
### 6. 清空列表
|
|
55
|
-
```typescript
|
|
56
|
-
homeAppStore.clearHomeAppList()
|
|
57
|
-
```
|
|
58
|
-
|
|
59
|
-
## 数据同步
|
|
60
|
-
|
|
61
|
-
### 自动同步
|
|
62
|
-
- 当 `useSettingStore.init()` 被调用时,`homeAppList` 会自动同步到 `useHomeAppStore`
|
|
63
|
-
- 无需手动同步,数据会自动保持一致
|
|
64
|
-
|
|
65
|
-
### 手动同步
|
|
66
|
-
```typescript
|
|
67
|
-
import { useSettingStore, useHomeAppStore } from '@/stores'
|
|
68
|
-
|
|
69
|
-
const settingStore = useSettingStore()
|
|
70
|
-
const homeAppStore = useHomeAppStore()
|
|
71
|
-
|
|
72
|
-
// 手动同步数据
|
|
73
|
-
homeAppStore.setHomeAppList(settingStore.getSetting()?.homeAppList || [])
|
|
74
|
-
```
|
|
75
|
-
|
|
76
|
-
## 在组件中使用
|
|
77
|
-
|
|
78
|
-
### Vue 组件示例
|
|
79
|
-
```vue
|
|
80
|
-
<template>
|
|
81
|
-
<div class="home-apps">
|
|
82
|
-
<div
|
|
83
|
-
v-for="app in homeAppStore.homeAppList"
|
|
84
|
-
:key="app.id"
|
|
85
|
-
class="app-item"
|
|
86
|
-
@click="openApp(app)"
|
|
87
|
-
>
|
|
88
|
-
<img :src="app.icon" :alt="app.name" />
|
|
89
|
-
<span>{{ app.name }}</span>
|
|
90
|
-
</div>
|
|
91
|
-
</div>
|
|
92
|
-
</template>
|
|
93
|
-
|
|
94
|
-
<script setup lang="ts">
|
|
95
|
-
import { useHomeAppStore } from '@/stores'
|
|
96
|
-
|
|
97
|
-
const homeAppStore = useHomeAppStore()
|
|
98
|
-
|
|
99
|
-
function openApp(app) {
|
|
100
|
-
// 处理应用点击
|
|
101
|
-
window.open(app.url, '_blank')
|
|
102
|
-
}
|
|
103
|
-
</script>
|
|
104
|
-
```
|
|
105
|
-
|
|
106
|
-
## 注意事项
|
|
107
|
-
|
|
108
|
-
1. **初始化顺序**:确保先调用 `useSettingStore.init()`,再使用 `useHomeAppStore`
|
|
109
|
-
2. **数据一致性**:两个 store 中的数据会自动保持同步
|
|
110
|
-
3. **类型安全**:使用 TypeScript 接口确保类型安全
|
|
111
|
-
4. **响应式**:所有数据都是响应式的,可以直接在模板中使用
|
|
112
|
-
|
|
113
|
-
## 接口定义
|
|
114
|
-
|
|
115
|
-
```typescript
|
|
116
|
-
export interface HomeApp {
|
|
117
|
-
id: string // 应用唯一标识
|
|
118
|
-
name: string // 应用名称
|
|
119
|
-
icon: string // 应用图标
|
|
120
|
-
url: string // 应用链接
|
|
121
|
-
description?: string // 应用描述(可选)
|
|
122
|
-
[key: string]: any // 其他属性
|
|
123
|
-
}
|
|
124
|
-
```
|