widget.qw 0.0.1 → 1.0.0
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/build/style.css +101 -0
- package/build/widget.qw.es.js +639 -236
- package/build/widget.qw.umd.js +639 -236
- package/package.json +1 -1
- package/src/api/index.js +16 -0
- package/src/components/CascaderPicker.vue +107 -0
- package/src/components/index.js +35 -30
- package/src/components/widget/CascaderPop.vue +313 -0
- package/src/main.js +2 -2
- package/src/router/index.ts +5 -0
- package/src/util/tree_util.js +34 -0
- package/src/views/auditbar/index.vue +1 -1
- package/src/views/billcard/index.vue +1 -1
- package/src/views/cascaderpicker/index.vue +86 -0
- package/src/views/checkgroup/index.vue +1 -1
- package/src/views/dataSelector/index.vue +2 -2
- package/src/views/datetimepicker/index.vue +1 -1
- package/src/views/daydropdown/index.vue +1 -1
- package/src/views/filepicker/index.vue +1 -1
- package/src/views/home/index.vue +1 -0
- package/src/views/imagepicker/index.vue +1 -1
- package/src/views/imagespicker/index.vue +1 -1
- package/src/views/input/index.vue +1 -1
- package/src/views/monthdropdown/index.vue +1 -1
- package/src/views/multListSelector/index.vue +1 -1
- package/src/views/multipicker/index.vue +1 -1
- package/src/views/productSelector/index.vue +1 -1
- package/src/views/projectdropdown/index.vue +1 -1
- package/src/views/projectpicker/index.vue +1 -1
- package/src/views/sheet/index.vue +4 -4
- package/src/views/singlepicker/index.vue +1 -1
- package/src/views/subdepartmentSelector/index.vue +1 -1
- package/src/views/switch/index.vue +1 -1
- package/src/views/treepicker/index.vue +1 -1
- package/src/views/userSelector/index.vue +3 -3
- package/src/views/userSelectorNew/index.vue +1 -1
- package/src/views/userpicker/index.vue +1 -1
- package/src/views/userprofile/index.vue +1 -1
- package/src/views/userspicker/index.vue +1 -1
- package/src/views/yeardropdown/index.vue +1 -1
- package/vite.config.ts +2 -2
package/package.json
CHANGED
package/src/api/index.js
CHANGED
|
@@ -123,4 +123,20 @@ export const auth_get_user_info = (data) => {
|
|
|
123
123
|
method: "POST",
|
|
124
124
|
data: data,
|
|
125
125
|
})
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
export const part_children = (data) => {
|
|
129
|
+
return request_json({
|
|
130
|
+
url: vm.urlCallback() + "/ac-api/part/children",
|
|
131
|
+
method: "POST",
|
|
132
|
+
data: data,
|
|
133
|
+
})
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
export const part_detail = (data) => {
|
|
137
|
+
return request_json({
|
|
138
|
+
url: vm.urlCallback() + "/ac-api/part/detail",
|
|
139
|
+
method: "POST",
|
|
140
|
+
data: data,
|
|
141
|
+
})
|
|
126
142
|
}
|
|
@@ -0,0 +1,107 @@
|
|
|
1
|
+
<template>
|
|
2
|
+
<van-field v-if="!isGone" :label="props.label" :required="isRequired" :rules="props.rules" :disabled="isDisabled"
|
|
3
|
+
:placeholder="props.placeholder" :is-link="isReadonly ? false : true" @click="data.isShowPop = !isReadonly"
|
|
4
|
+
label-class="label">
|
|
5
|
+
<template #input>
|
|
6
|
+
<van-tag class="selected-node" v-if="modelValue" :closeable="!isDisabled" type="primary" size="medium"
|
|
7
|
+
@close.stop="onDelete">
|
|
8
|
+
{{ data.selectedNode.formatLabel }}
|
|
9
|
+
</van-tag>
|
|
10
|
+
</template>
|
|
11
|
+
</van-field>
|
|
12
|
+
|
|
13
|
+
<CascaderPop v-model:show="data.isShowPop"
|
|
14
|
+
v-model="modelValue"
|
|
15
|
+
:placeholder="props.placeholder"
|
|
16
|
+
@select="onSelect" :queryNodes="props.queryNodes" :queryNode="props.queryNode" />
|
|
17
|
+
|
|
18
|
+
</template>
|
|
19
|
+
<script setup>
|
|
20
|
+
import { reactive, onMounted, watch } from "vue";
|
|
21
|
+
import util from "../util"
|
|
22
|
+
import { useVModel } from '@vueuse/core'
|
|
23
|
+
import CascaderPop from './widget/CascaderPop.vue'
|
|
24
|
+
|
|
25
|
+
const props = defineProps({
|
|
26
|
+
modelValue: {
|
|
27
|
+
type: String,
|
|
28
|
+
default: '',
|
|
29
|
+
},
|
|
30
|
+
label: {
|
|
31
|
+
type: String,
|
|
32
|
+
default: "",
|
|
33
|
+
},
|
|
34
|
+
placeholder: {
|
|
35
|
+
type: String,
|
|
36
|
+
default: "",
|
|
37
|
+
},
|
|
38
|
+
required: {
|
|
39
|
+
type: Boolean,
|
|
40
|
+
default: false,
|
|
41
|
+
},
|
|
42
|
+
readonly: {
|
|
43
|
+
type: Boolean,
|
|
44
|
+
default: false,
|
|
45
|
+
},
|
|
46
|
+
rules: {
|
|
47
|
+
type: Array,
|
|
48
|
+
default: [],
|
|
49
|
+
},
|
|
50
|
+
auth: {
|
|
51
|
+
type: String,
|
|
52
|
+
default: "",
|
|
53
|
+
},
|
|
54
|
+
queryNodes:{
|
|
55
|
+
type:Function,
|
|
56
|
+
default:()=>{}
|
|
57
|
+
},
|
|
58
|
+
queryNode:{
|
|
59
|
+
type:Function,
|
|
60
|
+
default:()=>{}
|
|
61
|
+
}
|
|
62
|
+
});
|
|
63
|
+
|
|
64
|
+
// 弹出层
|
|
65
|
+
const data = reactive({
|
|
66
|
+
isShowPop: false,
|
|
67
|
+
selectedNode: {}
|
|
68
|
+
})
|
|
69
|
+
|
|
70
|
+
// 定义emit
|
|
71
|
+
const emit = defineEmits(["update:modelValue", "select"]);
|
|
72
|
+
const modelValue = useVModel(props, 'modelValue', emit)
|
|
73
|
+
const { isRequired, isReadonly, isGone, isDisabled } = util.props2auth(props);
|
|
74
|
+
|
|
75
|
+
//首页加载
|
|
76
|
+
onMounted(() => {
|
|
77
|
+
})
|
|
78
|
+
|
|
79
|
+
const onSelect = (node) => {
|
|
80
|
+
data.selectedNode = node
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
const onDelete=()=>{
|
|
84
|
+
data.selectedNode={}
|
|
85
|
+
modelValue.value = null
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
watch(() => modelValue.value, async (n, o) => {
|
|
89
|
+
if (!n) {
|
|
90
|
+
data.selectedNode = {}
|
|
91
|
+
return
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
props.queryNode((node)=>{
|
|
95
|
+
data.selectedNode = node
|
|
96
|
+
emit('select', data.selectedNode)
|
|
97
|
+
})
|
|
98
|
+
}, {
|
|
99
|
+
immediate: true
|
|
100
|
+
})
|
|
101
|
+
</script>
|
|
102
|
+
|
|
103
|
+
<style scoped>
|
|
104
|
+
.user{
|
|
105
|
+
padding:4px 8px;
|
|
106
|
+
}
|
|
107
|
+
</style>
|
package/src/components/index.js
CHANGED
|
@@ -27,119 +27,124 @@ import ProjectDropdown from "./ProjectDropdown.vue";
|
|
|
27
27
|
import Switch from './Switch.vue'
|
|
28
28
|
import Sheet from './Sheet.vue'
|
|
29
29
|
import TreePicker from './TreePicker.vue'
|
|
30
|
+
import CascaderPicker from './CascaderPicker.vue'
|
|
30
31
|
|
|
31
32
|
const components = [
|
|
32
33
|
{
|
|
33
|
-
name: "
|
|
34
|
+
name: "WidgetQwAuditBar",
|
|
34
35
|
widget: AuditBar,
|
|
35
36
|
},
|
|
36
37
|
{
|
|
37
|
-
name: "
|
|
38
|
+
name: "WidgetQwInput",
|
|
38
39
|
widget: Input,
|
|
39
40
|
},
|
|
40
41
|
{
|
|
41
|
-
name: "
|
|
42
|
+
name: "WidgetQwSinglePicker",
|
|
42
43
|
widget: SinglePicker,
|
|
43
44
|
},
|
|
44
45
|
{
|
|
45
|
-
name: "
|
|
46
|
+
name: "WidgetQwMultiPicker",
|
|
46
47
|
widget: MultiPicker,
|
|
47
48
|
},
|
|
48
49
|
{
|
|
49
|
-
name: "
|
|
50
|
+
name: "WidgetQwCheckGroup",
|
|
50
51
|
widget: CheckGroup,
|
|
51
52
|
},
|
|
52
53
|
{
|
|
53
|
-
name: "
|
|
54
|
+
name: "WidgetQwDatetimePicker",
|
|
54
55
|
widget: DatetimePicker,
|
|
55
56
|
},
|
|
56
57
|
{
|
|
57
|
-
name: "
|
|
58
|
+
name: "WidgetQwDataSelector",
|
|
58
59
|
widget: DataSelector,
|
|
59
60
|
},
|
|
60
61
|
{
|
|
61
|
-
name: "
|
|
62
|
+
name: "WidgetQwMultListSelector",
|
|
62
63
|
widget: MultListSelector,
|
|
63
64
|
},
|
|
64
65
|
{
|
|
65
|
-
name: "
|
|
66
|
+
name: "WidgetQwProductSelector",
|
|
66
67
|
widget: ProductSelector,
|
|
67
68
|
},
|
|
68
69
|
{
|
|
69
|
-
name: "
|
|
70
|
+
name: "WidgetQwSubdepartmentSelector",
|
|
70
71
|
widget: SubdepartmentSelector,
|
|
71
72
|
},
|
|
72
73
|
{
|
|
73
|
-
name: "
|
|
74
|
+
name: "WidgetQwSingleUserSelector",
|
|
74
75
|
widget: SingleUserSelector,
|
|
75
76
|
},
|
|
76
77
|
{
|
|
77
|
-
name: "
|
|
78
|
+
name: "WidgetQwImagePicker",
|
|
78
79
|
widget: ImagePicker,
|
|
79
80
|
},
|
|
80
81
|
{
|
|
81
|
-
name: "
|
|
82
|
+
name: "WidgetQwImagesPicker",
|
|
82
83
|
widget: ImagesPicker,
|
|
83
84
|
},
|
|
84
85
|
{
|
|
85
|
-
name: "
|
|
86
|
+
name: "WidgetQwFilePicker",
|
|
86
87
|
widget: FilePicker,
|
|
87
88
|
},
|
|
88
89
|
{
|
|
89
|
-
name: '
|
|
90
|
+
name: 'WidgetQwBillCard',
|
|
90
91
|
widget: BillCard
|
|
91
92
|
},
|
|
92
93
|
{
|
|
93
|
-
name: '
|
|
94
|
+
name: 'WidgetQwUserSelector',
|
|
94
95
|
widget: UserSelector
|
|
95
96
|
},
|
|
96
97
|
{
|
|
97
|
-
name: '
|
|
98
|
+
name: 'WidgetQwUsersPicker',
|
|
98
99
|
widget: UsersPicker
|
|
99
100
|
},
|
|
100
101
|
{
|
|
101
|
-
name: '
|
|
102
|
+
name: 'WidgetQwUserPicker',
|
|
102
103
|
widget: UserPicker
|
|
103
104
|
},
|
|
104
105
|
{
|
|
105
|
-
name: '
|
|
106
|
+
name: 'WidgetQwProjectPicker',
|
|
106
107
|
widget: ProjectPicker
|
|
107
108
|
},
|
|
108
109
|
{
|
|
109
|
-
name: '
|
|
110
|
+
name: 'WidgetQwUserProfile',
|
|
110
111
|
widget: UserProfile
|
|
111
112
|
},
|
|
112
113
|
{
|
|
113
|
-
name: '
|
|
114
|
+
name: 'WidgetQwYearDropdown',
|
|
114
115
|
widget: YearDropdown
|
|
115
116
|
},
|
|
116
117
|
{
|
|
117
|
-
name: '
|
|
118
|
+
name: 'WidgetQwMonthDropdown',
|
|
118
119
|
widget: MonthDropdown
|
|
119
120
|
},
|
|
120
121
|
{
|
|
121
|
-
name: '
|
|
122
|
+
name: 'WidgetQwDayDropdown',
|
|
122
123
|
widget: DayDropdown
|
|
123
124
|
},
|
|
124
125
|
{
|
|
125
|
-
name: '
|
|
126
|
+
name: 'WidgetQwProjectDropdown',
|
|
126
127
|
widget: ProjectDropdown
|
|
127
128
|
},
|
|
128
129
|
{
|
|
129
|
-
name: '
|
|
130
|
+
name: 'WidgetQwSwitch',
|
|
130
131
|
widget: Switch
|
|
131
132
|
},
|
|
132
133
|
{
|
|
133
|
-
name: '
|
|
134
|
+
name: 'WidgetQwSheet',
|
|
134
135
|
widget: Sheet
|
|
135
136
|
},
|
|
136
137
|
{
|
|
137
|
-
name: '
|
|
138
|
+
name: 'WidgetQwTreePicker',
|
|
138
139
|
widget: TreePicker
|
|
140
|
+
},
|
|
141
|
+
{
|
|
142
|
+
name: 'WidgetQwCascaderPicker',
|
|
143
|
+
widget: CascaderPicker
|
|
139
144
|
}
|
|
140
145
|
];
|
|
141
146
|
// 导出组件
|
|
142
|
-
export const
|
|
147
|
+
export const WidgetQw = {
|
|
143
148
|
install(app) {
|
|
144
149
|
components.forEach((component) => {
|
|
145
150
|
app.component(component.name, component.widget);
|
|
@@ -150,8 +155,8 @@ export const UIQW = {
|
|
|
150
155
|
// 导出初始化方法
|
|
151
156
|
export function setup(params) {
|
|
152
157
|
vm.urlCallback = params.urlCallback;
|
|
153
|
-
|
|
154
|
-
|
|
158
|
+
vm.tokenCallback = params.tokenCallback;
|
|
159
|
+
vm.needLoginCallback = params.needLoginCallback;
|
|
155
160
|
}
|
|
156
161
|
|
|
157
162
|
export * from "./SecretNotify";
|
|
@@ -0,0 +1,313 @@
|
|
|
1
|
+
<template>
|
|
2
|
+
<van-popup v-model:show="show" round position="bottom" class="cascader-pop">
|
|
3
|
+
<div class="cascader-selector">
|
|
4
|
+
<div class="cascader-header">
|
|
5
|
+
<div class="header-left">
|
|
6
|
+
<van-button @click="onBack" icon="arrow-left" size="small" />
|
|
7
|
+
</div>
|
|
8
|
+
|
|
9
|
+
<!-- 移除header-center包装,直接使用current-path -->
|
|
10
|
+
<div class="current-path">{{ pathsLabel }}</div>
|
|
11
|
+
|
|
12
|
+
<div class="header-right">
|
|
13
|
+
<van-button size="small" @click="onCancel" class="cancel-btn">取消</van-button>
|
|
14
|
+
|
|
15
|
+
<van-button type="primary" size="small" @click="onSubmit" class="confirm-btn">确定</van-button>
|
|
16
|
+
</div>
|
|
17
|
+
</div>
|
|
18
|
+
|
|
19
|
+
<!-- 搜索框 -->
|
|
20
|
+
<van-search v-model="data.keyword" :placeholder="props.placeholder" @clear="onClear" @search="onSearch"
|
|
21
|
+
@cancel="onClear" show-action>
|
|
22
|
+
<template #action>
|
|
23
|
+
<div @click="onSearch">搜索</div>
|
|
24
|
+
</template>
|
|
25
|
+
</van-search>
|
|
26
|
+
|
|
27
|
+
<div class="scroll-container">
|
|
28
|
+
<!-- 遍历子节点列表 -->
|
|
29
|
+
<van-cell-group>
|
|
30
|
+
<van-cell v-for="(item, i) in optionNodes" :key="i" >
|
|
31
|
+
<template #title>
|
|
32
|
+
<div class="cell-content">
|
|
33
|
+
<div class="circle-selector" @click.stop="onToggle(item)">
|
|
34
|
+
<van-icon v-if="data.selectedNodeId === item.id" name="success" size="20" color="#409eff"/>
|
|
35
|
+
<van-icon v-if="data.selectedNodeId != item.id" name="circle" size="20" color="#e0e0e0"/>
|
|
36
|
+
</div>
|
|
37
|
+
<span class="name">{{ item.label }}</span>
|
|
38
|
+
</div>
|
|
39
|
+
</template>
|
|
40
|
+
<template #right-icon v-if="item.hasChildren" >
|
|
41
|
+
<van-icon name="arrow" @click.stop="onNextLevel(item)"/>
|
|
42
|
+
</template>
|
|
43
|
+
</van-cell>
|
|
44
|
+
</van-cell-group>
|
|
45
|
+
</div>
|
|
46
|
+
</div>
|
|
47
|
+
</van-popup>
|
|
48
|
+
</template>
|
|
49
|
+
|
|
50
|
+
<script setup>
|
|
51
|
+
import { ref, onMounted, watch, reactive, computed } from "vue";
|
|
52
|
+
import util from "../../util"
|
|
53
|
+
import { useVModel } from '@vueuse/core'
|
|
54
|
+
|
|
55
|
+
const props = defineProps({
|
|
56
|
+
modelValue: {
|
|
57
|
+
type: String,
|
|
58
|
+
default: ''
|
|
59
|
+
},
|
|
60
|
+
show: {
|
|
61
|
+
type: Boolean,
|
|
62
|
+
default: false,
|
|
63
|
+
},
|
|
64
|
+
placeholder: {
|
|
65
|
+
type: String,
|
|
66
|
+
default: ''
|
|
67
|
+
},
|
|
68
|
+
queryNodes: {
|
|
69
|
+
type: Function,
|
|
70
|
+
default: () => { }
|
|
71
|
+
},
|
|
72
|
+
queryNode: {
|
|
73
|
+
type: Function,
|
|
74
|
+
default: () => { }
|
|
75
|
+
}
|
|
76
|
+
});
|
|
77
|
+
// 定义emit
|
|
78
|
+
const emit = defineEmits(["update:show", "select"]);
|
|
79
|
+
// 弹出?
|
|
80
|
+
const show = useVModel(props, 'show', emit)
|
|
81
|
+
const modelValue = useVModel(props, 'modelValue', emit)
|
|
82
|
+
const data = reactive({
|
|
83
|
+
// 所有节点
|
|
84
|
+
totalNodes: [],
|
|
85
|
+
// 搜索关键字
|
|
86
|
+
keyword: "",
|
|
87
|
+
//关键字搜索到的节点列表
|
|
88
|
+
searchNodes: [],
|
|
89
|
+
//当前节点
|
|
90
|
+
currentNode: null,
|
|
91
|
+
//勾选的节点id
|
|
92
|
+
selectedNodeId: ''
|
|
93
|
+
})
|
|
94
|
+
|
|
95
|
+
// 待选节点列表
|
|
96
|
+
const optionNodes = computed(() => {
|
|
97
|
+
if (data.keyword)
|
|
98
|
+
return data.searchNodes
|
|
99
|
+
else if (data.currentNode)
|
|
100
|
+
return data.currentNode?.children ? data.currentNode.children : []
|
|
101
|
+
else
|
|
102
|
+
return data.totalNodes ? data.totalNodes : []
|
|
103
|
+
})
|
|
104
|
+
|
|
105
|
+
//选中节点的路径:父/子/孙
|
|
106
|
+
const pathsLabel = computed(() => {
|
|
107
|
+
if (!data.currentNode || !data.currentNode.id)
|
|
108
|
+
return ''
|
|
109
|
+
|
|
110
|
+
let paths = util.findPaths(data.currentNode.id, data.totalNodes)
|
|
111
|
+
console.log("paths", paths);
|
|
112
|
+
let res = paths.map(item => item.label).join('/')
|
|
113
|
+
return res
|
|
114
|
+
})
|
|
115
|
+
|
|
116
|
+
// 查询树状节点列表
|
|
117
|
+
const queryTotalNodes = async () => {
|
|
118
|
+
await props.queryNodes({keyword:data.keyword,parentId:''}, (nodes) => {
|
|
119
|
+
data.totalNodes = nodes
|
|
120
|
+
})
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
// 关键字查询
|
|
124
|
+
const onSearch = async () => {
|
|
125
|
+
await util.queryNodes({keyword:data.keyword,parentId:''}, (nodes) => {
|
|
126
|
+
data.searchNodes = nodes
|
|
127
|
+
})
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
// 返回上一级
|
|
131
|
+
const onBack = () => {
|
|
132
|
+
if (!data.currentNode || !data.currentNode.id)
|
|
133
|
+
return
|
|
134
|
+
|
|
135
|
+
data.keyword = ""
|
|
136
|
+
data.currentNode = util.findParent(data.currentNode.id, data.totalNodes)
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
const onClear=()=>{
|
|
140
|
+
data.keyword = ''
|
|
141
|
+
data.searchNodes = []
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
// 清除掉选中节点
|
|
145
|
+
const reset = () => {
|
|
146
|
+
// 当前节点
|
|
147
|
+
data.currentNode = null
|
|
148
|
+
// 搜索关键字
|
|
149
|
+
data.keyword = ""
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
// 确认按钮
|
|
153
|
+
const onSubmit = () => {
|
|
154
|
+
if (!data.selectedNodeId) {
|
|
155
|
+
util.warnToast("请选择")
|
|
156
|
+
return
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
let selectedNode = util.findNode(data.selectedNodeId, data.totalNodes)
|
|
160
|
+
modelValue.value = selectedNode.id
|
|
161
|
+
emit('select', selectedNode)
|
|
162
|
+
show.value = false
|
|
163
|
+
|
|
164
|
+
reset()
|
|
165
|
+
}
|
|
166
|
+
|
|
167
|
+
// 取消按钮
|
|
168
|
+
const onCancel = () => {
|
|
169
|
+
show.value = false
|
|
170
|
+
reset()
|
|
171
|
+
}
|
|
172
|
+
|
|
173
|
+
const onToggle = (node) => {
|
|
174
|
+
if(data.selectedNodeId == node.id)
|
|
175
|
+
data.selectedNodeId = ''
|
|
176
|
+
else
|
|
177
|
+
data.selectedNodeId = node.id
|
|
178
|
+
}
|
|
179
|
+
|
|
180
|
+
const onNextLevel = (node) => {
|
|
181
|
+
props.queryNodes({ keyword: data.keyword, parentId: node.id }, (nodes) => {
|
|
182
|
+
node.children = nodes
|
|
183
|
+
data.currentNode = node
|
|
184
|
+
})
|
|
185
|
+
}
|
|
186
|
+
|
|
187
|
+
//首页加载
|
|
188
|
+
onMounted(async () => {
|
|
189
|
+
await queryTotalNodes()
|
|
190
|
+
})
|
|
191
|
+
|
|
192
|
+
watch(() => props.modelValue, () => {
|
|
193
|
+
// 初始化当前节点
|
|
194
|
+
data.currentNode = util.findParent(props.modelValue, data.totalNodes)
|
|
195
|
+
}, { immediate: true })
|
|
196
|
+
</script>
|
|
197
|
+
|
|
198
|
+
<style scoped>
|
|
199
|
+
.cascader-pop {
|
|
200
|
+
width: 100%;
|
|
201
|
+
overflow: hidden;
|
|
202
|
+
}
|
|
203
|
+
|
|
204
|
+
.cascader-selector {
|
|
205
|
+
padding: 10px;
|
|
206
|
+
}
|
|
207
|
+
|
|
208
|
+
.search-buttons {
|
|
209
|
+
display: flex;
|
|
210
|
+
gap: 10px;
|
|
211
|
+
}
|
|
212
|
+
|
|
213
|
+
.clear-btn {
|
|
214
|
+
background-color: #f2f3f5;
|
|
215
|
+
border: none;
|
|
216
|
+
border-radius: 4px;
|
|
217
|
+
padding: 4px 8px;
|
|
218
|
+
font-size: 14px;
|
|
219
|
+
}
|
|
220
|
+
|
|
221
|
+
.confirm-btn {
|
|
222
|
+
background-color: #1989fa;
|
|
223
|
+
color: white;
|
|
224
|
+
border: none;
|
|
225
|
+
border-radius: 4px;
|
|
226
|
+
padding: 4px 8px;
|
|
227
|
+
font-size: 14px;
|
|
228
|
+
}
|
|
229
|
+
|
|
230
|
+
.no-results {
|
|
231
|
+
text-align: center;
|
|
232
|
+
padding: 20px;
|
|
233
|
+
color: #969799;
|
|
234
|
+
}
|
|
235
|
+
|
|
236
|
+
.cascader-header {
|
|
237
|
+
padding: 10px;
|
|
238
|
+
border-bottom: 1px solid #ebedf0;
|
|
239
|
+
display: flex;
|
|
240
|
+
justify-content: space-between;
|
|
241
|
+
align-items: center;
|
|
242
|
+
}
|
|
243
|
+
|
|
244
|
+
.current-path {
|
|
245
|
+
flex: 1;
|
|
246
|
+
font-size: 14px;
|
|
247
|
+
color: #323233;
|
|
248
|
+
white-space: nowrap;
|
|
249
|
+
overflow: hidden;
|
|
250
|
+
text-overflow: ellipsis;
|
|
251
|
+
}
|
|
252
|
+
|
|
253
|
+
.header-right {
|
|
254
|
+
display: flex;
|
|
255
|
+
gap: 8px;
|
|
256
|
+
margin-left: auto;
|
|
257
|
+
}
|
|
258
|
+
|
|
259
|
+
.cancel-btn {
|
|
260
|
+
color: #969799;
|
|
261
|
+
margin-right: 5px;
|
|
262
|
+
}
|
|
263
|
+
|
|
264
|
+
.scroll-container {
|
|
265
|
+
height: calc(80vh - 150px);
|
|
266
|
+
overflow-y: auto;
|
|
267
|
+
}
|
|
268
|
+
|
|
269
|
+
|
|
270
|
+
.cell-content {
|
|
271
|
+
display: flex;
|
|
272
|
+
align-items: center;
|
|
273
|
+
gap: 12px;
|
|
274
|
+
}
|
|
275
|
+
|
|
276
|
+
.circle-selector {
|
|
277
|
+
width: 20px;
|
|
278
|
+
height: 20px;
|
|
279
|
+
border-radius: 50%;
|
|
280
|
+
display: flex;
|
|
281
|
+
align-items: center;
|
|
282
|
+
justify-content: center;
|
|
283
|
+
transition: all 0.2s;
|
|
284
|
+
flex-shrink: 0;
|
|
285
|
+
}
|
|
286
|
+
|
|
287
|
+
.circle-selector.selected {
|
|
288
|
+
background-color: #1989fa;
|
|
289
|
+
border-color: #1989fa;
|
|
290
|
+
}
|
|
291
|
+
|
|
292
|
+
.circle-selector.selected .van-icon {
|
|
293
|
+
color: white;
|
|
294
|
+
font-size: 14px;
|
|
295
|
+
}
|
|
296
|
+
|
|
297
|
+
.van-cell__right-icon {
|
|
298
|
+
color: #969799;
|
|
299
|
+
font-size: 16px;
|
|
300
|
+
margin-left: 8px;
|
|
301
|
+
}
|
|
302
|
+
|
|
303
|
+
.name {
|
|
304
|
+
flex: 1;
|
|
305
|
+
overflow: hidden;
|
|
306
|
+
text-overflow: ellipsis;
|
|
307
|
+
white-space: nowrap;
|
|
308
|
+
}
|
|
309
|
+
|
|
310
|
+
.cancel-btn {
|
|
311
|
+
color: #969799;
|
|
312
|
+
}
|
|
313
|
+
</style>
|
package/src/main.js
CHANGED
|
@@ -49,7 +49,7 @@ import {
|
|
|
49
49
|
} from "vant";
|
|
50
50
|
import "vant/lib/index.css";
|
|
51
51
|
//本地测试 初始化组件
|
|
52
|
-
import {
|
|
52
|
+
import { WidgetQw, setup } from "@/components";
|
|
53
53
|
setup({
|
|
54
54
|
urlCallback: () => {
|
|
55
55
|
return process.env.VUE_APP_DOMAIN;
|
|
@@ -107,5 +107,5 @@ createApp(App)
|
|
|
107
107
|
.use(Tag)
|
|
108
108
|
.use(Switch)
|
|
109
109
|
.use(TreeSelect)
|
|
110
|
-
.use(
|
|
110
|
+
.use(WidgetQw)
|
|
111
111
|
.mount("#app");
|
package/src/router/index.ts
CHANGED
|
@@ -149,6 +149,11 @@ const routes: Array<RouteRecordRaw> = [
|
|
|
149
149
|
path: "/treepicker",
|
|
150
150
|
name: "treepicker",
|
|
151
151
|
component: () => import("../views/treepicker/index.vue"),
|
|
152
|
+
},
|
|
153
|
+
{
|
|
154
|
+
path: "/cascaderpicker",
|
|
155
|
+
name: "cascaderpicker",
|
|
156
|
+
component: () => import("../views/cascaderpicker/index.vue"),
|
|
152
157
|
}
|
|
153
158
|
];
|
|
154
159
|
|
package/src/util/tree_util.js
CHANGED
|
@@ -41,6 +41,40 @@ export const findNode = (id, nodes) => {
|
|
|
41
41
|
return res[res.length - 1]
|
|
42
42
|
}
|
|
43
43
|
|
|
44
|
+
// 查找节点路径列表
|
|
45
|
+
// 返回:[父,子,孙]
|
|
46
|
+
export const findPaths =(targetId, nodes, path = [])=> {
|
|
47
|
+
if (!nodes || nodes.length < 1 || !targetId)
|
|
48
|
+
return []
|
|
49
|
+
|
|
50
|
+
for (const node of nodes) {
|
|
51
|
+
if (node.id === targetId) {
|
|
52
|
+
return [...path, node];
|
|
53
|
+
}
|
|
54
|
+
if (node.children?.length) {
|
|
55
|
+
const founds = findPaths(targetId, node.children, [...path, node]);
|
|
56
|
+
if (founds && founds.length > 0) return founds;
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
return []
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
//查找父节点
|
|
64
|
+
export const findParent = (id, nodes) => {
|
|
65
|
+
if (!nodes || !id) {
|
|
66
|
+
return null
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
let paths = findPaths(id, nodes)
|
|
70
|
+
|
|
71
|
+
if (!paths || paths.length < 2) {
|
|
72
|
+
return null
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
return paths[paths.length-2]
|
|
76
|
+
}
|
|
77
|
+
|
|
44
78
|
// id列表转为节点对象列表
|
|
45
79
|
export const ids2nodes=(ids,totalNodes)=>{
|
|
46
80
|
if(!totalNodes || totalNodes.length<1 || !ids || ids.length<1)
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
<template>
|
|
2
2
|
<div class="page">
|
|
3
|
-
<
|
|
3
|
+
<widget-qw-audit-bar v-if="data.userId" :processId="data.processId" :mouldId="data.mouldId" :userId="data.userId" :form="data.form"
|
|
4
4
|
@apply="onApply" @pass="onPass" @refuse="onRefuse" @auth="onAuth" />
|
|
5
5
|
</div>
|
|
6
6
|
</template>
|