widget.qw 1.0.6 → 1.0.8

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": "widget.qw",
3
3
  "private": false,
4
- "version": "1.0.6",
4
+ "version": "1.0.8",
5
5
  "description": "marqstree Vue3组件库",
6
6
  "main": "build/widget.qw.es.js",
7
7
  "keywords": [
package/src/api/index.js CHANGED
@@ -40,7 +40,7 @@ export const dictionary_dict = (data) => {
40
40
  // 获取产品列表
41
41
  export const project_list = (data) => {
42
42
  return request_json({
43
- url: vm.urlCallback() + "/qw-api/server-crm/project/list",
43
+ url: vm.urlCallback() + "/ac-api/project/list",
44
44
  method: "POST",
45
45
  data,
46
46
  });
@@ -3,10 +3,10 @@
3
3
  :placeholder="props.placeholder" :is-link="isReadonly ? false : true" @click="data.isShowPop = !isReadonly"
4
4
  label-class="label">
5
5
  <template #input v-if="modelValue">
6
- <van-tag class="selected-node" v-if="modelValue" :closeable="!isDisabled" color="#fff" text-color="#333" size="medium"
7
- @close.stop="onDelete">
8
- {{ data.selectedNode.formatLabel }}
9
- </van-tag>
6
+ <van-tag class="selected-node" v-if="modelValue" :closeable="!isDisabled" color="#fff" text-color="#333" size="medium"
7
+ @close.stop="onDelete">
8
+ {{ data.selectedNode.formatLabel }}
9
+ </van-tag>
10
10
  </template>
11
11
  </van-field>
12
12
 
@@ -78,6 +78,7 @@ onMounted(() => {
78
78
 
79
79
  const onSelect = (node) => {
80
80
  data.selectedNode = node
81
+ emit('select', data.selectedNode)
81
82
  }
82
83
 
83
84
  const onDelete=()=>{
@@ -84,8 +84,6 @@ const data = reactive({
84
84
  totalNodes: [],
85
85
  // 搜索关键字
86
86
  keyword: "",
87
- //关键字搜索到的节点列表
88
- searchNodes: [],
89
87
  //当前节点
90
88
  currentNode: null,
91
89
  //勾选的节点id
@@ -94,9 +92,7 @@ const data = reactive({
94
92
 
95
93
  // 待选节点列表
96
94
  const optionNodes = computed(() => {
97
- if (data.keyword)
98
- return data.searchNodes
99
- else if (data.currentNode)
95
+ if (data.currentNode)
100
96
  return data.currentNode?.children ? data.currentNode.children : []
101
97
  else
102
98
  return data.totalNodes ? data.totalNodes : []
@@ -123,7 +119,8 @@ const queryTotalNodes = async () => {
123
119
  // 关键字查询
124
120
  const onSearch = async () => {
125
121
  await props.queryNodes({keyword:data.keyword,parentId:''}, (nodes) => {
126
- data.searchNodes = nodes
122
+ data.totalNodes = nodes
123
+ data.currentNode = null
127
124
  })
128
125
  }
129
126
 
@@ -138,7 +135,6 @@ const onBack = () => {
138
135
 
139
136
  const onClear=()=>{
140
137
  data.keyword = ''
141
- data.searchNodes = []
142
138
  }
143
139
 
144
140
  // 清除掉选中节点
@@ -1,16 +1,16 @@
1
1
  <template>
2
2
  <div class="widget">
3
- <!-- 项目名称选择 -->
4
- <DataSelector v-model="modelValue" v-if="!isGone" :label="props.label" :required="isRequired" :rules="props.rules"
5
- :disabled="isDisabled" :readonly="isReadonly" mode="single" :options="data.options" class="selector-field"
6
- @select="onSelect" />
3
+ <van-field v-model="formatLabel" is-link :label="props.label" :placeholder="props.placeholder" readonly
4
+ :required="isRequired" :disabled="isDisabled" @click="data.isShow = true" />
5
+ <van-popup v-model:show="data.isShow" destroy-on-close round position="bottom">
6
+ <van-picker :columns="data.options" @cancel="onCancel" @confirm="onConfirm" />
7
+ </van-popup>
7
8
  </div>
8
9
  </template>
9
10
 
10
11
  <script setup>
11
- import { ref, onMounted, watch, reactive } from 'vue'
12
+ import { ref, onMounted, watch, reactive, computed } from 'vue'
12
13
  import util from '../util'
13
- import DataSelector from './data_selector.vue'
14
14
  import { useVModel } from '@vueuse/core'
15
15
 
16
16
  const props = defineProps({
@@ -18,63 +18,61 @@ const props = defineProps({
18
18
  type: String,
19
19
  default: null
20
20
  },
21
- required: {
22
- type: Boolean,
23
- default: true
24
- },
25
21
  label: {
26
22
  type: String,
27
- default: "",
23
+ default: ''
28
24
  },
29
25
  placeholder: {
30
26
  type: String,
31
- default: "请选择项目",
27
+ default: ''
32
28
  },
33
- readonly: {
29
+ required: {
34
30
  type: Boolean,
35
31
  default: false,
36
32
  },
37
- rules: {
38
- type: Array,
39
- default: () => []
33
+ readonly: {
34
+ type: Boolean,
35
+ default: true,
40
36
  },
41
37
  auth: {
42
38
  type: String,
43
39
  default: "",
44
40
  },
45
- maxStage: {
46
- type: String,
47
- default: ''
41
+ query: {
42
+ type: Function,
43
+ default: () => { }
48
44
  }
49
45
  })
50
46
 
51
47
  const emit = defineEmits(['update:modelValue', 'select'])
52
- const { isRequired, isReadonly, isGone, isDisabled } = util.props2auth(props)
48
+ const modelValue = useVModel(props, 'modelValue', emit)
49
+ const { isRequired, isReadonly, isGone, isDisabled } = util.props2auth(props);
53
50
  const data = reactive({
51
+ isShow: false,
54
52
  options: []
55
53
  })
56
- const modelValue = useVModel(props, 'modelValue', emit)
54
+ const formatLabel = computed(() => {
55
+ let one = data.options.find(item => item.value == modelValue.value)
56
+ return one ? one.text : ''
57
+ })
57
58
 
58
- const query = async () => {
59
- let params = { isBasic: true, limit: 99999, page: 1 }
60
- if (props.maxStage)
61
- params.maxStage = props.maxStage
59
+ onMounted(async () => {
60
+ props.query((options) => {
61
+ data.options = options
62
+ })
63
+ })
62
64
 
63
- const res = await util.project_list(params)
64
- data.options = res.data.list.map(item => ({
65
- text: `${item.projectCode}/${item.name}`,
66
- value: item.id
67
- }))
65
+ const onConfirm = ({ selectedOptions }) => {
66
+ console.log("selectedOptions: " + selectedOptions)
67
+ let selectOption = selectedOptions[selectedOptions.length - 1]
68
+ modelValue.value = selectOption.value
69
+ emit('select', selectOption)
70
+ data.isShow = false
68
71
  }
69
72
 
70
- const onSelect = (item) => {
71
- emit('select', item)
73
+ const onCancel = () => {
74
+ data.isShow = false
72
75
  }
73
-
74
- // 修改后的挂载逻辑
75
- onMounted(async () => {
76
- query()
77
- })
78
76
  </script>
79
77
 
80
78
  <style lang="scss" scoped>
@@ -8,7 +8,6 @@ import CheckGroup from "./CheckGroup.vue";
8
8
  import DatetimePicker from "./DatetimePicker/index.vue";
9
9
  import DataSelector from "./data_selector.vue";
10
10
  import MultListSelector from "./mult_list_selector.vue";
11
- import ProductSelector from "./product_selector.vue";
12
11
  import SubdepartmentSelector from "./subdepartment_selector.vue";
13
12
  import UserSelector from "./user_selector.vue";
14
13
  import ImagePicker from "./image_picker.vue";
@@ -18,17 +17,16 @@ import SingleUserSelector from "./SingleUserSelector.vue";
18
17
  import UsersPicker from "./UsersPicker.vue"
19
18
  import UserPicker from "./UserPicker.vue"
20
19
  import UserProfile from "./UserProfile.vue"
21
- import ProjectPicker from "./ProjectPicker.vue"
22
20
  import BillCard from './BillCard.vue'
23
21
  import YearDropdown from "./YearDropdown.vue";
24
22
  import MonthDropdown from "./MonthDropdown.vue";
25
23
  import DayDropdown from "./DayDropdown.vue";
26
- import ProjectDropdown from "./ProjectDropdown.vue";
27
24
  import Switch from './Switch.vue'
28
25
  import Sheet from './Sheet.vue'
29
26
  import TreePicker from './TreePicker.vue'
30
27
  import CascaderPop from './CascaderPop.vue'
31
28
  import CascaderPicker from './CascaderPicker.vue'
29
+ import SingleApiPicker from "./SingleApiPicker.vue";
32
30
 
33
31
  const components = [
34
32
  {
@@ -63,10 +61,6 @@ const components = [
63
61
  name: "WidgetQwMultListSelector",
64
62
  widget: MultListSelector,
65
63
  },
66
- {
67
- name: "WidgetQwProductSelector",
68
- widget: ProductSelector,
69
- },
70
64
  {
71
65
  name: "WidgetQwSubdepartmentSelector",
72
66
  widget: SubdepartmentSelector,
@@ -103,10 +97,6 @@ const components = [
103
97
  name: 'WidgetQwUserPicker',
104
98
  widget: UserPicker
105
99
  },
106
- {
107
- name: 'WidgetQwProjectPicker',
108
- widget: ProjectPicker
109
- },
110
100
  {
111
101
  name: 'WidgetQwUserProfile',
112
102
  widget: UserProfile
@@ -123,10 +113,6 @@ const components = [
123
113
  name: 'WidgetQwDayDropdown',
124
114
  widget: DayDropdown
125
115
  },
126
- {
127
- name: 'WidgetQwProjectDropdown',
128
- widget: ProjectDropdown
129
- },
130
116
  {
131
117
  name: 'WidgetQwSwitch',
132
118
  widget: Switch
@@ -146,7 +132,11 @@ const components = [
146
132
  {
147
133
  name: 'WidgetQwCascaderPicker',
148
134
  widget: CascaderPicker
149
- }
135
+ },
136
+ {
137
+ name: 'WidgetQwSingleApiPicker',
138
+ widget: SingleApiPicker
139
+ },
150
140
  ];
151
141
  // 导出组件
152
142
  export const WidgetQw = {
@@ -45,11 +45,6 @@ const routes: Array<RouteRecordRaw> = [
45
45
  name: "secretnotify",
46
46
  component: () => import("../views/secretnotify/index.vue"),
47
47
  },
48
- {
49
- path: "/productSelector",
50
- name: "productSelector",
51
- component: () => import("../views/productSelector/index.vue"),
52
- },
53
48
  {
54
49
  path: "/dataSelector",
55
50
  name: "dataSelector",
@@ -105,11 +100,6 @@ const routes: Array<RouteRecordRaw> = [
105
100
  name: "userpicker",
106
101
  component: () => import("../views/userpicker/index.vue"),
107
102
  },
108
- {
109
- path: "/projectpicker",
110
- name: "projectpicker",
111
- component: () => import("../views/projectpicker/index.vue"),
112
- },
113
103
  {
114
104
  path: "/userprofile",
115
105
  name: "userprofile",
@@ -130,11 +120,6 @@ const routes: Array<RouteRecordRaw> = [
130
120
  name: "daydropdown",
131
121
  component: () => import("../views/daydropdown/index.vue"),
132
122
  },
133
- {
134
- path: "/projectdropdown",
135
- name: "projectdropdown",
136
- component: () => import("../views/projectdropdown/index.vue"),
137
- },
138
123
  {
139
124
  path: "/switch",
140
125
  name: "switch",
@@ -159,16 +144,25 @@ const routes: Array<RouteRecordRaw> = [
159
144
  path: "/cascaderpicker",
160
145
  name: "cascaderpicker",
161
146
  component: () => import("../views/cascaderpicker/index.vue"),
147
+ },
148
+ {
149
+ path: "/singleapipicker",
150
+ name: "singleapipicker",
151
+ component: () => import("../views/singleapipicker/index.vue"),
162
152
  }
163
153
  ]
164
154
 
165
155
  const router = createRouter({
166
156
  history: createWebHashHistory(process.env.BASE_URL),
167
157
  routes,
158
+ scrollBehavior(to, from, savedPosition) {
159
+ return { top: 0 }; // 强制滚动到顶部
160
+ }
168
161
  });
169
162
 
170
163
  router.beforeEach((to, from, next) => {
171
164
  console.log("+++路由回调++++++++++++++++++++++");
165
+ const showTabBar = to.meta.showTabBar ?? true // 默认显示
172
166
  next();
173
167
  });
174
168
 
Binary file
@@ -1,62 +0,0 @@
1
- <template>
2
- <van-dropdown-item v-model="modelValue" :options="totalOptions" />
3
- </template>
4
- <script setup>
5
- import { reactive, onMounted, computed } from "vue";
6
- import util from "../util"
7
- import { useVModel } from '@vueuse/core'
8
-
9
- const props = defineProps({
10
- modelValue: {
11
- type: Number,
12
- default: 0,
13
- },
14
- label: {
15
- type: String,
16
- default: "选择项目",
17
- },
18
- placeholder: {
19
- type: String,
20
- default: "请选择项目",
21
- },
22
- maxStage: {
23
- type: String,
24
- default: ''
25
- }
26
- });
27
-
28
- // 弹出层
29
- const data = reactive({
30
- options: []
31
- })
32
-
33
- // 定义emit
34
- const emit = defineEmits(["update:modelValue"]);
35
- const modelValue = useVModel(props, 'modelValue', emit)
36
-
37
- const totalOptions = computed(() => {
38
- return [{
39
- text: '工程编号',
40
- value: ''
41
- }, ...data.options]
42
- })
43
-
44
- //首页加载
45
- onMounted(() => {
46
- query()
47
- })
48
-
49
- const query = async () => {
50
- let params = { isBasic: true, limit: 99999, page: 1 }
51
- if(props.maxStage)
52
- params.maxStage = props.maxStage
53
-
54
- const res = await util.project_list(params)
55
- data.options = res.data.list.map(item => ({
56
- text: `${item.projectCode}/${item.name}`,
57
- value: item.id
58
- }))
59
- }
60
- </script>
61
-
62
- <style scoped></style>
@@ -1,186 +0,0 @@
1
- <template>
2
- <div class="project-selector">
3
- <!-- 产品名称选择 -->
4
- <data-selector v-model="selectedProjectCode" label="产品名称" placeholder="请选择产品" mode="single"
5
- :options="productOptions" @update:modelValue="handleProjectChange" class="selector-field"
6
- :required="props.required" :rules="props.rules" :readonly="props.readonly" />
7
-
8
- <!-- 产品编号显示 -->
9
- <van-field v-model="projectCode" label="产品编号" placeholder="系统自动填入" readonly class="readonly-field"
10
- :required="props.required" />
11
- </div>
12
- </template>
13
-
14
- <script setup>
15
- import { ref, onMounted, watch, nextTick } from 'vue'
16
- import util from '../util'
17
- import dataSelector from './data_selector.vue'
18
-
19
- // 缓存定义在组件内部(模块作用域)
20
- const productListCache = {
21
- data: ref([]),
22
- loading: ref(false),
23
- error: ref(null)
24
- }
25
-
26
- const props = defineProps({
27
- modelValue: {
28
- type: Object,
29
- default: () => ({
30
- productName: '',
31
- productCode: ''
32
- })
33
- },
34
- required: {
35
- type: Boolean,
36
- default: true
37
- },
38
- readonly: {
39
- type: Boolean,
40
- default: false,
41
- },
42
- rules: {
43
- type: Array,
44
- default: () => []
45
- }
46
- })
47
-
48
- const emit = defineEmits(['update:modelValue'])
49
-
50
- // 响应式数据
51
- const productOptions = ref([])
52
- const selectedProjectCode = ref('')
53
- const projectCode = ref('')
54
-
55
- // 获取产品列表
56
- // const fetchProducts = async () => {
57
- // try {
58
- // const params = {
59
- // limit: 99999,
60
- // page: 0
61
- // }
62
- // const response = await ApiUtil.project_list(params)
63
-
64
- // console.log('获取产品列表成功:', response)
65
-
66
- // if (response.code === 200) {
67
- // productOptions.value = response.data.list.map(item => ({
68
- // text: item.name,
69
- // value: item.projectCode
70
- // }))
71
- // }
72
- // } catch (error) {
73
- // console.error('获取产品列表失败:', error)
74
- // }
75
- // }
76
-
77
- // 修改后的获取产品列表方法
78
- const fetchProducts = async () => {
79
- try {
80
- if (productListCache.data.value.length > 0) return
81
- if (productListCache.loading.value) return
82
-
83
- productListCache.loading.value = true
84
- const response = await util.project_list({ limit: 999, page: 0 })
85
-
86
- if (response.code === 200) {
87
- productListCache.data.value = response.data.list.map(item => ({
88
- text: item.name,
89
- value: item.projectCode
90
- }))
91
- }
92
- } catch (error) {
93
- productListCache.error.value = error
94
- console.error('获取产品列表失败:', error)
95
- } finally {
96
- productListCache.loading.value = false
97
- }
98
- }
99
-
100
-
101
- // 处理产品选择变化
102
- const handleProjectChange = (value) => {
103
- const selectedProduct = productOptions.value.find(item => item.value === value)
104
- if (selectedProduct) {
105
- emit('update:modelValue', {
106
- productName: selectedProduct.text,
107
- productCode: value
108
- })
109
- projectCode.value = value
110
- }
111
- }
112
-
113
- // 添加modelValue监听
114
- // 修改后的watch监听
115
- watch(() => props.modelValue, (newVal) => {
116
- // 当productOptions加载完成后再更新选中状态
117
- if (productOptions.value.length > 0 && newVal.productCode !== selectedProjectCode.value) {
118
- selectedProjectCode.value = newVal.productCode
119
- projectCode.value = newVal.productCode
120
- }
121
- }, { deep: true, immediate: true })
122
-
123
- // 新增对productOptions的监听
124
- watch(productOptions, (newOptions) => {
125
- // 当选项列表更新后检查外部传入的值是否有效
126
- if (props.modelValue.productCode && newOptions.length > 0) {
127
- const exists = newOptions.some(opt => opt.value === props.modelValue.productCode)
128
- if (exists) {
129
- selectedProjectCode.value = props.modelValue.productCode
130
- projectCode.value = props.modelValue.productCode
131
- }
132
- }
133
- })
134
-
135
- // 修改后的挂载逻辑
136
- onMounted(async () => {
137
- if (productListCache.data.value.length === 0) {
138
- await fetchProducts()
139
- // 确保赋值操作在数据加载后
140
- productOptions.value = [...productListCache.data.value]
141
- } else {
142
- productOptions.value = [...productListCache.data.value]
143
- }
144
-
145
- // 延迟执行确保选项已渲染
146
- nextTick(() => {
147
- if (props.modelValue.productCode) {
148
- selectedProjectCode.value = props.modelValue.productCode
149
- projectCode.value = props.modelValue.productCode
150
- }
151
- })
152
- })
153
- </script>
154
-
155
- <style scoped>
156
- .project-selector {
157
- :deep(.van-cell) {
158
- align-items: center;
159
- }
160
-
161
- :deep(.van-field__label) {
162
- width: 90px;
163
- flex: none;
164
- }
165
-
166
- .readonly-field {
167
- :deep(.van-field__control) {
168
- color: #323233;
169
- /* 修改文字颜色与普通字段一致 */
170
- padding-right: 16px;
171
- }
172
-
173
- /* 添加必填星号对齐 */
174
- &.van-field--required {
175
- :deep(.van-field__label::before) {
176
- margin-right: 4px;
177
- }
178
- }
179
- }
180
-
181
- /* 统一字段间距 */
182
- .readonly-field {
183
- margin: 4px 0;
184
- }
185
- }
186
- </style>