jufubao-third 1.0.19-beta1 → 1.0.19-beta2

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.
Files changed (27) hide show
  1. package/docs/modules/router-guide.md +288 -0
  2. package/docs/modules/template/selector/XdIconSelect.vue +331 -0
  3. package/docs/modules/template/selector/XdNameCheck.vue +282 -0
  4. package/docs/modules/template/selector/XdSelectTag.vue +247 -0
  5. package/docs/modules/template/selector/XdSiteSelectList.vue +243 -0
  6. package/docs/modules/template/selector/XdStyleImage.vue +647 -0
  7. package/docs/modules/template/style/XdBorder.vue +380 -0
  8. package/docs/modules/template/style/XdCusSwitch.vue +157 -0
  9. package/docs/modules/template/style/XdFont.vue +521 -0
  10. package/docs/modules/template/style/XdGradientColor.vue +233 -0
  11. package/docs/modules/template/style/XdShadow.vue +418 -0
  12. package/docs/modules/template/style/XdSlider.vue +269 -0
  13. package/docs/modules/template/style/XdTextAndBgc.vue +933 -0
  14. package/docs/modules/template/style/XdWidthAndHeight.vue +204 -0
  15. package/docs/modules/uni-attr.md +2456 -0
  16. package/docs/modules/uni-components.md +124 -0
  17. package/docs/modules/uni-mixins.md +435 -0
  18. package/docs/modules/uni-other-component.md +437 -0
  19. package/docs/modules/uni-template.md +1490 -0
  20. package/docs/modules/uni-utils.md +3760 -0
  21. package/docs/modules/vuex-guide.md +210 -0
  22. package/package.json +2 -2
  23. package/src/components/JfbThirdCopyUrl/Api.js +1 -52
  24. package/src/components/JfbThirdCopyUrl/Attr.js +6 -41
  25. package/src/components/JfbThirdCopyUrl/JfbThirdCopyUrl.vue +139 -36
  26. package/src/components/JfbThirdCopyUrl/Mock.js +1 -11
  27. package/src/components/JfbThirdCopyUrl/cusAttr/content.js +253 -0
@@ -0,0 +1,288 @@
1
+ # 路由配置规范
2
+
3
+ > 本文档定义项目路由配置规范,为智能体协同开发提供统一参考。
4
+
5
+ ---
6
+
7
+ ## 一、文件结构
8
+
9
+ ```
10
+ src/router/
11
+ ├── index.js # 主入口文件
12
+ ├── constantRoutes.js # 常量路由(无需权限)
13
+ └── modules/ # 权限路由模块
14
+ ├── user.js # 用户管理路由
15
+ ├── order.js # 订单管理路由
16
+ └── ... # 其他模块
17
+ ```
18
+
19
+ ---
20
+
21
+ ## 二、路由类型
22
+
23
+ ### 2.1 常量路由
24
+
25
+ **文件路径**:`/src/router/constantRoutes.js`
26
+
27
+ 无需权限验证的路由,如登录页、404页面等。
28
+
29
+ ```javascript
30
+ /**
31
+ * 常量路由 - 无需权限验证
32
+ */
33
+ export const constantRoutes = [
34
+ {
35
+ path: '/login',
36
+ name: 'Login',
37
+ component: () => import('@/views/login/index'),
38
+ hidden: true,
39
+ meta: { title: '登录' }
40
+ },
41
+ {
42
+ path: '/404',
43
+ name: '404',
44
+ component: () => import('@/views/404'),
45
+ hidden: true,
46
+ meta: { title: '404' }
47
+ }
48
+ ]
49
+ ```
50
+
51
+ ---
52
+
53
+ ### 2.2 权限路由
54
+
55
+ **文件路径**:`/src/router/modules/[模块名].js`
56
+
57
+ 需要权限验证的路由,存放在 modules 目录下自动加载。
58
+
59
+ ```javascript
60
+ /**
61
+ * [模块名称]路由配置
62
+ */
63
+
64
+ /** 路由路径前缀 */
65
+ const basePath = '/module'
66
+
67
+ /**
68
+ * [模块名称]路由
69
+ */
70
+ export default [
71
+ {
72
+ path: `${basePath}/list`,
73
+ name: 'ModuleList',
74
+ component: () => import('@/views/module/list'),
75
+ meta: {
76
+ title: '列表页',
77
+ icon: 'list'
78
+ }
79
+ },
80
+ {
81
+ path: `${basePath}/detail`,
82
+ name: 'ModuleDetail',
83
+ component: () => import('@/views/module/detail'),
84
+ meta: {
85
+ title: '详情页',
86
+ icon: 'detail'
87
+ },
88
+ hidden: true
89
+ }
90
+ ]
91
+ ```
92
+
93
+ ---
94
+
95
+ ## 三、路由配置说明
96
+
97
+ ### 3.1 配置字段
98
+
99
+ | 字段名 | 类型 | 必填 | 说明 |
100
+ |-------|------|------|------|
101
+ | path | String | 是 | 路由路径 |
102
+ | name | String | 是 | 路由名称(用于 keep-alive) |
103
+ | component | Function | 是 | 组件,使用动态导入 |
104
+ | redirect | String | 否 | 重定向路径 |
105
+ | meta | Object | 是 | 路由元信息 |
106
+ | hidden | Boolean | 否 | 是否隐藏菜单 |
107
+ | children | Array | 否 | 子路由 |
108
+
109
+ ---
110
+
111
+ ### 3.2 Meta 字段
112
+
113
+ | 字段名 | 类型 | 必填 | 说明 |
114
+ |-------|------|------|------|
115
+ | title | String | 是 | 页面标题(显示在侧边栏) |
116
+ | icon | String | 是 | 图标名称 |
117
+ | roles | Array | 否 | 权限角色 |
118
+ | noCache | Boolean | 否 | 是否禁用缓存 |
119
+ | breadcrumb | Boolean | 否 | 是否显示面包屑 |
120
+ | activeMenu | String | 否 | 高亮菜单路径 |
121
+
122
+ ---
123
+
124
+ ## 四、路由示例
125
+
126
+ ### 4.1 列表页路由
127
+
128
+ ```javascript
129
+ {
130
+ path: '/user/list',
131
+ name: 'UserList',
132
+ component: () => import('@/views/user/list'),
133
+ meta: {
134
+ title: '用户列表',
135
+ icon: 'user'
136
+ }
137
+ }
138
+ ```
139
+
140
+ ---
141
+
142
+ ### 4.2 详情页路由
143
+
144
+ ```javascript
145
+ {
146
+ path: '/user/detail/:id',
147
+ name: 'UserDetail',
148
+ component: () => import('@/views/user/detail'),
149
+ meta: {
150
+ title: '用户详情',
151
+ icon: 'user'
152
+ },
153
+ hidden: true
154
+ }
155
+ ```
156
+
157
+ ---
158
+
159
+ ### 4.3 嵌套路由
160
+
161
+ ```javascript
162
+ {
163
+ path: '/system',
164
+ name: 'System',
165
+ redirect: '/system/user',
166
+ meta: {
167
+ title: '系统管理',
168
+ icon: 'system'
169
+ },
170
+ children: [
171
+ {
172
+ path: 'user',
173
+ name: 'SystemUser',
174
+ component: () => import('@/views/system/user'),
175
+ meta: {
176
+ title: '用户管理',
177
+ icon: 'user'
178
+ }
179
+ },
180
+ {
181
+ path: 'role',
182
+ name: 'SystemRole',
183
+ component: () => import('@/views/system/role'),
184
+ meta: {
185
+ title: '角色管理',
186
+ icon: 'role'
187
+ }
188
+ }
189
+ ]
190
+ }
191
+ ```
192
+
193
+ ---
194
+
195
+ ## 五、路由跳转
196
+
197
+ ### 5.1 编程式导航
198
+
199
+ ```javascript
200
+ // 路径跳转
201
+ this.$router.push('/user/list')
202
+
203
+ // 命名路由跳转
204
+ this.$router.push({ name: 'UserList' })
205
+
206
+ // 带参数跳转
207
+ this.$router.push({
208
+ name: 'UserDetail',
209
+ params: { id: 1 }
210
+ })
211
+
212
+ // 带查询参数跳转
213
+ this.$router.push({
214
+ path: '/user/list',
215
+ query: { keyword: 'test' }
216
+ })
217
+ ```
218
+
219
+ ---
220
+
221
+ ### 5.2 路由返回
222
+
223
+ ```javascript
224
+ // 返回上一页
225
+ this.$router.go(-1)
226
+
227
+ // 返回指定页
228
+ this.$router.go(-2)
229
+
230
+ // 替换当前路由
231
+ this.$router.replace('/login')
232
+ ```
233
+
234
+ ---
235
+
236
+ ## 六、路由守卫
237
+
238
+ ### 6.1 全局前置守卫
239
+
240
+ **文件路径**:`/src/permission.js`
241
+
242
+ ```javascript
243
+ router.beforeEach(async(to, from, next) => {
244
+ // 获取 token
245
+ const hasToken = getToken()
246
+
247
+ if (hasToken) {
248
+ if (to.path === '/login') {
249
+ next({ path: '/' })
250
+ } else {
251
+ // 验证权限
252
+ const hasRoles = store.getters.roles && store.getters.roles.length > 0
253
+ if (hasRoles) {
254
+ next()
255
+ } else {
256
+ // 获取用户信息
257
+ const { roles } = await store.dispatch('user/getInfo')
258
+ // 生成可访问路由
259
+ const accessRoutes = await store.dispatch('permission/generateRoutes', roles)
260
+ // 动态添加路由
261
+ router.addRoutes(accessRoutes)
262
+ next({ ...to, replace: true })
263
+ }
264
+ }
265
+ } else {
266
+ // 无 token,跳转登录
267
+ if (whiteList.indexOf(to.path) !== -1) {
268
+ next()
269
+ } else {
270
+ next(`/login?redirect=${to.path}`)
271
+ }
272
+ }
273
+ })
274
+ ```
275
+
276
+ ---
277
+
278
+ ## 七、注意事项
279
+
280
+ 1. **路由 name 必须唯一**:用于 keep-alive 缓存
281
+ 2. **动态导入组件**:`() => import()` 实现懒加载
282
+ 3. **meta 必须包含 title 和 icon**:用于侧边栏显示
283
+ 4. **详情页设置 hidden: true**:不在菜单中显示
284
+ 5. **路由路径使用小写**:遵循 kebab-case 规范
285
+
286
+ ---
287
+
288
+ > **待完善**:需要根据实际项目补充具体路由配置
@@ -0,0 +1,331 @@
1
+ <template>
2
+ <div class="xd-icon-select">
3
+ <div class="cur_icon" @click="handleToChoseIcon">
4
+ <xd-font-icon v-if="curIcon" :icon="curIcon" :size="28"></xd-font-icon>
5
+ <span v-else style="font-size: 12px;color: #666;">选择图标</span>
6
+ </div>
7
+ <xd-dialog
8
+ title="选择图标"
9
+ width="850px"
10
+ :show.sync="iconShow"
11
+ v-if="iconShow"
12
+ @onClose="handleClear"
13
+ >
14
+ <div class="iconFont">
15
+ <div class="iconFont-search">
16
+ <el-input
17
+ placeholder="请输入内容"
18
+ v-model="searchVal"
19
+ @input="handleSearch"
20
+ @clear="handleClearSearch"
21
+ >
22
+ </el-input>
23
+ <el-button type="primary" icon="el-icon-search">搜索</el-button>
24
+ </div>
25
+ <div class="iconFont-item">
26
+ <table class="iconFont-table" style="border-collapse: collapse; width: 100%">
27
+ <tr v-for="(items,index) in tableList" :key="index">
28
+ <td
29
+ align="center"
30
+ :style="`background:${item.value === tempSelected ? 'rgba(255,0,0,.1)':''}; width:${100/items.length}%`"
31
+ v-for="item in items"
32
+ :key="item.value"
33
+ @click="handleTableItem(item)"
34
+ >
35
+ <div class="iconFont-item-icon"><i :style="`color:${item.value === tempSelected ? 'red':'#666'};`" :class='`iconfont ${item.value}`'></i></div>
36
+ <div class="iconFont-item-text" :style="`color:${item.value === tempSelected ? 'red':'#666'};`">{{item.label|nameFilter}}</div>
37
+ </td>
38
+ </tr>
39
+ </table>
40
+ </div>
41
+ </div>
42
+ <template slot="btn">
43
+ <el-button :size="size" @click="handleClear">取 消</el-button>
44
+ <el-button :size="size" type="primary" @click="handleConfirm">确 定</el-button>
45
+ </template>
46
+ </xd-dialog>
47
+ </div>
48
+ </template>
49
+
50
+ <script>
51
+ import emitter from 'element-ui/src/mixins/emitter';
52
+ import XdDialog from "@/components/XdDialog.vue";
53
+ import XdFontIcon from "@/components/XdFontIcon.vue";
54
+ export default {
55
+ name: "XdIconSelect",
56
+ mixins: [emitter],
57
+ components: {
58
+ XdDialog,
59
+ XdFontIcon
60
+ },
61
+ props:{
62
+ defaultValue: {
63
+ type: String,
64
+ default: '',
65
+ },
66
+
67
+ maps: {
68
+ type: Object | null,
69
+ default() {
70
+ return null
71
+ },
72
+ },
73
+
74
+ setting: {
75
+ type: Object,
76
+ default() {
77
+ return {
78
+ // fullUnit: '元',
79
+ // cutUnit: '元',
80
+ // fullName: '金额满',
81
+ // cutName: '运费减'
82
+ //todo 插件配置表(外面传入)
83
+ }
84
+ },
85
+ },
86
+
87
+ disabled: {
88
+ type: Boolean,
89
+ default: false,
90
+ },
91
+
92
+ size: {
93
+ type: String,
94
+ default: 'medium', //medium / small / mini
95
+ },
96
+
97
+ placeholder: {
98
+ type: Object,
99
+ default() {
100
+ return {
101
+ //todo
102
+ // fullPlaceholder: '请输入金额',
103
+ // cutPlaceholder: '请输入金额',
104
+ //todo 插件文本框所使用提示(外面传入)
105
+ }
106
+ },
107
+ },
108
+
109
+ required: {
110
+ type: Boolean,
111
+ default: false,
112
+ },
113
+
114
+ //是否启用自定义校验器
115
+ useCustomRules: {
116
+ type: Boolean,
117
+ default: false,
118
+ },
119
+
120
+ //数字字符串 转 数字
121
+ isNumber: {
122
+ type: Boolean,
123
+ default: true,
124
+ },
125
+ list: {
126
+ type: Array,
127
+ default() {
128
+ return []
129
+ },
130
+ },
131
+
132
+ //自定义方法
133
+ handleCustom: {
134
+ type: Function || null,
135
+ default: null
136
+ },
137
+
138
+ },
139
+ data(){
140
+ return {
141
+ //icon
142
+ searchVal:'',//搜索词
143
+ iconInput:true,
144
+ iconList:[], //原生数据
145
+ iconType:'icon', //icon image
146
+ iconShow: false,
147
+ tableList:[], //渲染数据
148
+ tempSelected:'',
149
+ curIcon: '',
150
+ actIcon:{
151
+ '--icon-act-setting-color': 'red',
152
+ '--icon-setting-color': '#333',
153
+ },
154
+ }
155
+ },
156
+ filters:{
157
+ nameFilter(str){
158
+ if(str.length > 5) return str.substring(0,10) + '...'
159
+ return str;
160
+ }
161
+ },
162
+ created(){
163
+ //设置默认值为空时候处理
164
+ if (this.defaultValue === null || this.defaultValue.length === 0) {
165
+ //todo 初始化插件所使用到绑定值
166
+ }
167
+ //非空处理
168
+ else {
169
+ this.handleMapToList();
170
+ }
171
+ if(this.list && this.list.length > 0) {
172
+ this.iconInput = false;
173
+ this.iconList = this.$xdHelper.cloneDeep(this.list);
174
+ this.initIcon();
175
+ }
176
+ //绑定数据
177
+ this.update();
178
+ },
179
+
180
+ methods: {
181
+ handleToChoseIcon(){
182
+ this.iconShow = true;
183
+ this.tempSelected = this.curIcon;
184
+ },
185
+ handleConfirm(){
186
+ console.log(this.tempSelected);
187
+ this.iconShow = false;
188
+ this.curIcon = this.tempSelected;
189
+ this.searchVal = '';
190
+ this.tempSelected = '';
191
+ this.update();
192
+ },
193
+ handleTableItem(item) {
194
+ this.tempSelected = item.value;
195
+ },
196
+ handleClearSearch(){
197
+ this.handleSearch();
198
+ },
199
+ handleClear(){
200
+ this.tempSelected = '';
201
+ this.iconShow = false;
202
+ },
203
+ handleSearch(){
204
+ this.initIcon();
205
+ },
206
+ initIcon(){
207
+ let cell = 6;
208
+ let tempArray = [];
209
+ let len = Math.ceil(this.iconList.length/cell);
210
+ let orgIcons = this.$xdHelper.cloneDeep(this.iconList);
211
+ if(this.searchVal) {
212
+ orgIcons = orgIcons.filter(item=>{
213
+ return item.label.indexOf(this.searchVal) !== -1 || item.value.indexOf(this.searchVal) !== -1
214
+ })
215
+ }
216
+ for(let i=0; i < len; i++) {
217
+ tempArray.push(orgIcons.splice(0,cell));
218
+ }
219
+ this.tableList = tempArray;
220
+ },
221
+ /**
222
+ * @description 返回映射关系对象数据(需要自己实现)
223
+ * 把内部数据转化为返回数据格式
224
+ */
225
+ handleListToMap() {
226
+ //todo 返回绑定值
227
+ return this.curIcon;
228
+ },
229
+
230
+ /**
231
+ * @description 初始化映射关系到数据列表(需要自己实现)
232
+ * 把默认数据转化为内部数据
233
+ */
234
+ handleMapToList() {
235
+ //todo 把传入中转化绑定值列表
236
+ this.tempSelected = this.defaultValue;
237
+ this.curIcon = this.defaultValue;
238
+ },
239
+
240
+ /**
241
+ * @description 需要校验检查参数是正确处理方法
242
+ */
243
+ checkParams(){
244
+ if (!this.required) return this.handleListToMap();
245
+ //校验成功
246
+ return this.handleListToMap();
247
+ },
248
+
249
+ /**
250
+ * @description 数据改变事件
251
+ */
252
+ change(){
253
+ this.$emit('onChange', this.checkParams())
254
+ },
255
+
256
+
257
+ /**
258
+ * @description 双向绑定数据处理
259
+ */
260
+ update(){
261
+ this.$emit('input', this.checkParams());
262
+ if (this.$parent.$options['componentName'] === 'ElFormItem') {
263
+ this.dispatch('ElFormItem', 'el.form.change', [this.checkParams()]);
264
+ this.dispatch('ElFormItem', 'el.form.blur', [this.checkParams()])
265
+ }
266
+ },
267
+ }
268
+ }
269
+ </script>
270
+
271
+ <style scoped lang="scss">
272
+ .xd-icon-select {
273
+ .cur_icon{
274
+ width: 60px;
275
+ height: 60px;
276
+ border: 1px solid #ddd;
277
+ display: flex;
278
+ align-items: center;
279
+ justify-content: center;
280
+ }
281
+
282
+ }
283
+ .iconFont {
284
+
285
+ &-search {
286
+ margin-bottom: 10px;
287
+ width: 50%;
288
+ display: flex;
289
+ justify-content: flex-start;
290
+ align-items: center;
291
+
292
+ & > *:first-child {
293
+ margin-right: 10px;
294
+ }
295
+ }
296
+
297
+ &-item {
298
+ height: 500px;
299
+ overflow-y: auto;
300
+ &-icon {
301
+ margin-top: 20px;
302
+ & i {
303
+ font-size:25px;
304
+ color: #666;
305
+ }
306
+
307
+ }
308
+ &-text {
309
+ color: #999;
310
+ font-size: 12px;
311
+ margin-top: 10px;
312
+ margin-bottom: 20px;
313
+ }
314
+ }
315
+
316
+ &-table{
317
+ table-layout: fixed;
318
+ border:1px solid #eee;
319
+
320
+ & td, & th {
321
+ cursor: pointer;
322
+ border: 1px solid #eee;
323
+ }
324
+ }
325
+ }
326
+
327
+ @media screen and (max-width: 768px) {
328
+ .xd-icon-select {
329
+ }
330
+ }
331
+ </style>