Commit 7a52d6a811ee17211130eb870d421cb90a4c76b0
1 parent
15ee21cf
1
Showing
13 changed files
with
2465 additions
and
324 deletions
components/uni-forms-item/uni-forms-item.vue
0 → 100644
| 1 | +<template> | |
| 2 | + <view class="uni-forms-item" :class="{'uni-forms-item--border':border,'is-first-border':border&&isFirstBorder,'uni-forms-item-error':msg}"> | |
| 3 | + <view class="uni-forms-item__inner" :class="['is-direction-'+labelPos,]"> | |
| 4 | + <view v-if="label" class="uni-forms-item__label" :style="{width:labelWid+'px',justifyContent: justifyContent}"> | |
| 5 | + <slot name="left"> | |
| 6 | + <uni-icons v-if="leftIcon" class="label-icon" size="16" :type="leftIcon" :color="iconColor" /> | |
| 7 | + <text>{{label}}</text> | |
| 8 | + <text v-if="required" class="is-required">*</text> | |
| 9 | + </slot> | |
| 10 | + </view> | |
| 11 | + <view class="uni-forms-item__content" :class="{'is-input-error-border': msg}"> | |
| 12 | + <slot></slot> | |
| 13 | + </view> | |
| 14 | + </view> | |
| 15 | + <view class="uni-error-message" :class="{'uni-error-msg--boeder':border}" :style="{ | |
| 16 | + paddingLeft: (labelPos === 'left'? Number(labelWid)+5:5) + 'px' | |
| 17 | + }">{{ showMsg === 'undertext' ? msg:'' }}</view> | |
| 18 | + </view> | |
| 19 | +</template> | |
| 20 | + | |
| 21 | +<script> | |
| 22 | + /** | |
| 23 | + * Field 输入框 | |
| 24 | + * @description 此组件可以实现表单的输入与校验,包括 "text" 和 "textarea" 类型。 | |
| 25 | + * @tutorial https://ext.dcloud.net.cn/plugin?id=21001 | |
| 26 | + * @property {Boolean} required 是否必填,左边显示红色"*"号(默认false) | |
| 27 | + * @property {String} validateTrigger = [bind|submit] 校验触发器方式 默认 submit 可选 | |
| 28 | + * @value bind 发生变化时触发 | |
| 29 | + * @value submit 提交时触发 | |
| 30 | + * @property {String } leftIcon label左边的图标,限 uni-ui 的图标名称 | |
| 31 | + * @property {String } iconColor 左边通过icon配置的图标的颜色(默认#606266) | |
| 32 | + * @property {String } label 输入框左边的文字提示 | |
| 33 | + * @property {Number } labelWidth label的宽度,单位px(默认65) | |
| 34 | + * @property {String } labelAlign = [left|center|right] label的文字对齐方式(默认left) | |
| 35 | + * @value left label 左侧显示 | |
| 36 | + * @value center label 居中 | |
| 37 | + * @value right label 右侧对齐 | |
| 38 | + * @property {String } labelPosition = [top|left] label的文字的位置(默认left) | |
| 39 | + * @value top 顶部显示 label | |
| 40 | + * @value left 左侧显示 label | |
| 41 | + * @property {String } errorMessage 显示的错误提示内容,如果为空字符串或者false,则不显示错误信息 | |
| 42 | + * @property {String } name 表单域的属性名,在使用校验规则时必填 | |
| 43 | + */ | |
| 44 | + | |
| 45 | + | |
| 46 | + | |
| 47 | + export default { | |
| 48 | + name: "uniFormsItem", | |
| 49 | + props: { | |
| 50 | + // 自定义内容 | |
| 51 | + custom: { | |
| 52 | + type: Boolean, | |
| 53 | + default: false | |
| 54 | + }, | |
| 55 | + // 是否显示报错信息 | |
| 56 | + showMessage: { | |
| 57 | + type: Boolean, | |
| 58 | + default: true | |
| 59 | + }, | |
| 60 | + name: String, | |
| 61 | + required: Boolean, | |
| 62 | + validateTrigger: { | |
| 63 | + type: String, | |
| 64 | + default: '' | |
| 65 | + }, | |
| 66 | + leftIcon: String, | |
| 67 | + iconColor: { | |
| 68 | + type: String, | |
| 69 | + default: '#606266' | |
| 70 | + }, | |
| 71 | + label: String, | |
| 72 | + // 左边标题的宽度单位px | |
| 73 | + labelWidth: { | |
| 74 | + type: [Number, String], | |
| 75 | + default: '' | |
| 76 | + }, | |
| 77 | + // 对齐方式,left|center|right | |
| 78 | + labelAlign: { | |
| 79 | + type: String, | |
| 80 | + default: '' | |
| 81 | + }, | |
| 82 | + // lable的位置,可选为 left-左边,top-上边 | |
| 83 | + labelPosition: { | |
| 84 | + type: String, | |
| 85 | + default: '' | |
| 86 | + }, | |
| 87 | + errorMessage: { | |
| 88 | + type: [String, Boolean], | |
| 89 | + default: '' | |
| 90 | + } | |
| 91 | + }, | |
| 92 | + data() { | |
| 93 | + return { | |
| 94 | + errorTop: false, | |
| 95 | + errorBottom: false, | |
| 96 | + labelMarginBottom: '', | |
| 97 | + errorWidth: '', | |
| 98 | + errMsg: '', | |
| 99 | + val: '', | |
| 100 | + labelPos: '', | |
| 101 | + labelWid: '', | |
| 102 | + labelAli: '', | |
| 103 | + showMsg: 'undertext', | |
| 104 | + border: false, | |
| 105 | + isFirstBorder: false | |
| 106 | + }; | |
| 107 | + }, | |
| 108 | + computed: { | |
| 109 | + msg() { | |
| 110 | + return this.errorMessage || this.errMsg; | |
| 111 | + }, | |
| 112 | + fieldStyle() { | |
| 113 | + let style = {} | |
| 114 | + if (this.labelPos == 'top') { | |
| 115 | + style.padding = '0 0' | |
| 116 | + this.labelMarginBottom = '6px' | |
| 117 | + } | |
| 118 | + if (this.labelPos == 'left' && this.msg !== false && this.msg != '') { | |
| 119 | + style.paddingBottom = '0px' | |
| 120 | + this.errorBottom = true | |
| 121 | + this.errorTop = false | |
| 122 | + } else if (this.labelPos == 'top' && this.msg !== false && this.msg != '') { | |
| 123 | + this.errorBottom = false | |
| 124 | + this.errorTop = true | |
| 125 | + } else { | |
| 126 | + // style.paddingBottom = '' | |
| 127 | + this.errorTop = false | |
| 128 | + this.errorBottom = false | |
| 129 | + } | |
| 130 | + return style | |
| 131 | + }, | |
| 132 | + | |
| 133 | + // uni不支持在computed中写style.justifyContent = 'center'的形式,故用此方法 | |
| 134 | + justifyContent() { | |
| 135 | + if (this.labelAli === 'left') return 'flex-start'; | |
| 136 | + if (this.labelAli === 'center') return 'center'; | |
| 137 | + if (this.labelAli === 'right') return 'flex-end'; | |
| 138 | + } | |
| 139 | + }, | |
| 140 | + watch: { | |
| 141 | + validateTrigger(trigger) { | |
| 142 | + this.formTrigger = trigger | |
| 143 | + } | |
| 144 | + }, | |
| 145 | + created() { | |
| 146 | + this.form = this.getForm() | |
| 147 | + this.group = this.getForm('uniGroup') | |
| 148 | + this.formRules = [] | |
| 149 | + this.formTrigger = this.validateTrigger | |
| 150 | + if (this.form) { | |
| 151 | + this.form.childrens.push(this) | |
| 152 | + } | |
| 153 | + this.init() | |
| 154 | + }, | |
| 155 | + destroyed() { | |
| 156 | + if (this.form) { | |
| 157 | + this.form.childrens.forEach((item, index) => { | |
| 158 | + if (item === this) { | |
| 159 | + this.form.childrens.splice(index, 1) | |
| 160 | + delete this.form.formData[item.name] | |
| 161 | + } | |
| 162 | + }) | |
| 163 | + } | |
| 164 | + }, | |
| 165 | + methods: { | |
| 166 | + init() { | |
| 167 | + if (this.form) { | |
| 168 | + let { | |
| 169 | + formRules, | |
| 170 | + validator, | |
| 171 | + formData, | |
| 172 | + value, | |
| 173 | + labelPosition, | |
| 174 | + labelWidth, | |
| 175 | + labelAlign, | |
| 176 | + errShowType | |
| 177 | + } = this.form | |
| 178 | + | |
| 179 | + this.labelPos = this.labelPosition ? this.labelPosition : labelPosition | |
| 180 | + this.labelWid = this.label ? (this.labelWidth ? this.labelWidth : labelWidth):0 | |
| 181 | + this.labelAli = this.labelAlign ? this.labelAlign : labelAlign | |
| 182 | + | |
| 183 | + // 判断第一个 item | |
| 184 | + if (!this.form.isFirstBorder) { | |
| 185 | + this.form.isFirstBorder = true | |
| 186 | + this.isFirstBorder = true | |
| 187 | + } | |
| 188 | + | |
| 189 | + // 判断 group 里的第一个 item | |
| 190 | + if (this.group) { | |
| 191 | + if (!this.group.isFirstBorder) { | |
| 192 | + this.group.isFirstBorder = true | |
| 193 | + this.isFirstBorder = true | |
| 194 | + } | |
| 195 | + } | |
| 196 | + | |
| 197 | + this.border = this.form.border | |
| 198 | + this.showMsg = errShowType | |
| 199 | + | |
| 200 | + if (formRules) { | |
| 201 | + this.formRules = formRules[this.name] || {} | |
| 202 | + } | |
| 203 | + | |
| 204 | + this.validator = validator | |
| 205 | + } else { | |
| 206 | + this.labelPos = this.labelPosition || 'left' | |
| 207 | + this.labelWid = this.labelWidth || 65 | |
| 208 | + this.labelAli = this.labelAlign || 'left' | |
| 209 | + } | |
| 210 | + }, | |
| 211 | + /** | |
| 212 | + * 获取父元素实例 | |
| 213 | + */ | |
| 214 | + getForm(name = 'uniForms') { | |
| 215 | + let parent = this.$parent; | |
| 216 | + let parentName = parent.$options.name; | |
| 217 | + while (parentName !== name) { | |
| 218 | + parent = parent.$parent; | |
| 219 | + if (!parent) return false | |
| 220 | + parentName = parent.$options.name; | |
| 221 | + } | |
| 222 | + return parent; | |
| 223 | + }, | |
| 224 | + | |
| 225 | + /** | |
| 226 | + * 移除该表单项的校验结果 | |
| 227 | + */ | |
| 228 | + clearValidate() { | |
| 229 | + this.errMsg = '' | |
| 230 | + }, | |
| 231 | + | |
| 232 | + setValue(value){ | |
| 233 | + if (this.name) { | |
| 234 | + if(this.errMsg) this.errMsg = '' | |
| 235 | + this.form.formData[this.name] = this.form._getValue(this.name, value) | |
| 236 | + if(!this.formRules || (typeof(this.formRules) && JSON.stringify(this.formRules) === '{}')) return | |
| 237 | + this.triggerCheck(this.form._getValue(this.name, value)) | |
| 238 | + } | |
| 239 | + }, | |
| 240 | + | |
| 241 | + /** | |
| 242 | + * 校验规则 | |
| 243 | + * @param {Object} value | |
| 244 | + */ | |
| 245 | + async triggerCheck(value, callback) { | |
| 246 | + let promise = null; | |
| 247 | + this.errMsg = '' | |
| 248 | + // if no callback, return promise | |
| 249 | + // if (callback && typeof callback !== 'function' && Promise) { | |
| 250 | + // promise = new Promise((resolve, reject) => { | |
| 251 | + // callback = function(valid) { | |
| 252 | + // !valid ? resolve(valid) : reject(valid) | |
| 253 | + // }; | |
| 254 | + // }); | |
| 255 | + // } | |
| 256 | + // if (!this.validator) { | |
| 257 | + // typeof callback === 'function' && callback(null); | |
| 258 | + // if (promise) return promise | |
| 259 | + // } | |
| 260 | + if (!this.validator) return | |
| 261 | + const isNoField = this.isRequired(this.formRules.rules || []) | |
| 262 | + let isTrigger = this.isTrigger(this.formRules.validateTrigger, this.validateTrigger, this.form.validateTrigger) | |
| 263 | + let result = null | |
| 264 | + if (!(!isTrigger)) { | |
| 265 | + result = await this.validator.validateUpdate({ | |
| 266 | + [this.name]: value | |
| 267 | + }, this.form.formData) | |
| 268 | + } | |
| 269 | + // 判断是否必填 | |
| 270 | + if (!isNoField && !value) { | |
| 271 | + result = null | |
| 272 | + } | |
| 273 | + if (isTrigger && result && result.errorMessage) { | |
| 274 | + const inputComp = this.form.inputChildrens.find(child => child.rename === this.name) | |
| 275 | + if (inputComp) { | |
| 276 | + inputComp.errMsg = result.errorMessage | |
| 277 | + } | |
| 278 | + if (this.form.errShowType === 'toast') { | |
| 279 | + uni.showToast({ | |
| 280 | + title: result.errorMessage || '校验错误', | |
| 281 | + icon: 'none' | |
| 282 | + }) | |
| 283 | + } | |
| 284 | + if (this.form.errShowType === 'modal') { | |
| 285 | + uni.showModal({ | |
| 286 | + title: '提示', | |
| 287 | + content: result.errorMessage || '校验错误' | |
| 288 | + }) | |
| 289 | + } | |
| 290 | + } | |
| 291 | + | |
| 292 | + this.errMsg = !result ? '' : result.errorMessage | |
| 293 | + // 触发validate事件 | |
| 294 | + this.form.validateCheck(result ? result : null) | |
| 295 | + // typeof callback === 'function' && callback(result ? result : null); | |
| 296 | + // if (promise) return promise | |
| 297 | + | |
| 298 | + }, | |
| 299 | + /** | |
| 300 | + * 触发时机 | |
| 301 | + * @param {Object} event | |
| 302 | + */ | |
| 303 | + isTrigger(rule, itemRlue, parentRule) { | |
| 304 | + let rl = true; | |
| 305 | + // bind submit | |
| 306 | + if (rule === 'submit' || !rule) { | |
| 307 | + if (rule === undefined) { | |
| 308 | + if (itemRlue !== 'bind') { | |
| 309 | + if (!itemRlue) { | |
| 310 | + return parentRule === 'bind' ? true : false | |
| 311 | + } | |
| 312 | + return false | |
| 313 | + } | |
| 314 | + return true | |
| 315 | + } | |
| 316 | + return false | |
| 317 | + } | |
| 318 | + return true; | |
| 319 | + }, | |
| 320 | + // 是否有必填字段 | |
| 321 | + isRequired(rules) { | |
| 322 | + let isNoField = false | |
| 323 | + for (let i = 0; i < rules.length; i++) { | |
| 324 | + const ruleData = rules[i] | |
| 325 | + if (ruleData.required) { | |
| 326 | + isNoField = true | |
| 327 | + break | |
| 328 | + } | |
| 329 | + } | |
| 330 | + return isNoField | |
| 331 | + } | |
| 332 | + } | |
| 333 | + }; | |
| 334 | +</script> | |
| 335 | + | |
| 336 | +<style lang="scss" scoped> | |
| 337 | + .uni-forms-item { | |
| 338 | + position: relative; | |
| 339 | + // padding: 16px 14px; | |
| 340 | + text-align: left; | |
| 341 | + color: #333; | |
| 342 | + font-size: 14px; | |
| 343 | + margin-bottom: 22px; | |
| 344 | + background-color: #fff; | |
| 345 | + } | |
| 346 | + | |
| 347 | + .uni-forms-item__inner { | |
| 348 | + /* #ifndef APP-NVUE */ | |
| 349 | + display: flex; | |
| 350 | + /* #endif */ | |
| 351 | + // flex-direction: row; | |
| 352 | + // align-items: center; | |
| 353 | + } | |
| 354 | + | |
| 355 | + .is-direction-left { | |
| 356 | + flex-direction: row; | |
| 357 | + } | |
| 358 | + | |
| 359 | + .is-direction-top { | |
| 360 | + flex-direction: column; | |
| 361 | + } | |
| 362 | + | |
| 363 | + .uni-forms-item__label { | |
| 364 | + /* #ifndef APP-NVUE */ | |
| 365 | + display: flex; | |
| 366 | + flex-shrink: 0; | |
| 367 | + /* #endif */ | |
| 368 | + flex-direction: row; | |
| 369 | + align-items: center; | |
| 370 | + font-size: 14px; | |
| 371 | + color: #333; | |
| 372 | + width: 65px; | |
| 373 | + // line-height: 2; | |
| 374 | + // margin-top: 3px; | |
| 375 | + padding: 5px 0; | |
| 376 | + box-sizing: border-box; | |
| 377 | + height: 36px; | |
| 378 | + margin-right: 5px; | |
| 379 | + } | |
| 380 | + | |
| 381 | + .uni-forms-item__content { | |
| 382 | + /* #ifndef APP-NVUE */ | |
| 383 | + width: 100%; | |
| 384 | + // display: flex; | |
| 385 | + /* #endif */ | |
| 386 | + // flex: 1; | |
| 387 | + // flex-direction: row; | |
| 388 | + // align-items: center; | |
| 389 | + box-sizing: border-box; | |
| 390 | + min-height: 36px; | |
| 391 | + } | |
| 392 | + | |
| 393 | + | |
| 394 | + .label-icon { | |
| 395 | + margin-right: 5px; | |
| 396 | + margin-top: -1px; | |
| 397 | + } | |
| 398 | + | |
| 399 | + // 必填 | |
| 400 | + .is-required { | |
| 401 | + color: $uni-color-error; | |
| 402 | + } | |
| 403 | + | |
| 404 | + .uni-error-message { | |
| 405 | + position: absolute; | |
| 406 | + bottom: -17px; | |
| 407 | + left: 0; | |
| 408 | + line-height: 12px; | |
| 409 | + color: $uni-color-error; | |
| 410 | + font-size: 12px; | |
| 411 | + text-align: left; | |
| 412 | + } | |
| 413 | + | |
| 414 | + .uni-error-msg--boeder { | |
| 415 | + position: relative; | |
| 416 | + bottom: 0; | |
| 417 | + line-height: 22px; | |
| 418 | + } | |
| 419 | + | |
| 420 | + .is-input-error-border { | |
| 421 | + border-color: $uni-color-error; | |
| 422 | + } | |
| 423 | + | |
| 424 | + .uni-forms-item--border { | |
| 425 | + margin-bottom: 0; | |
| 426 | + padding: 10px 15px; | |
| 427 | + // padding-bottom: 0; | |
| 428 | + border-top: 1px #eee solid; | |
| 429 | + } | |
| 430 | + | |
| 431 | + .uni-forms-item-error { | |
| 432 | + padding-bottom: 0; | |
| 433 | + } | |
| 434 | + | |
| 435 | + .is-first-border { | |
| 436 | + border: none; | |
| 437 | + } | |
| 438 | +</style> | ... | ... |
components/uni-forms/uni-forms.vue
0 → 100644
| 1 | +<template> | |
| 2 | + <!-- --> | |
| 3 | + <view class="uni-forms" :class="{'uni-forms--top':!border}"> | |
| 4 | + <form @submit.stop="submitForm" @reset="resetForm"> | |
| 5 | + <slot></slot> | |
| 6 | + </form> | |
| 7 | + </view> | |
| 8 | +</template> | |
| 9 | + | |
| 10 | +<script> | |
| 11 | + /** | |
| 12 | + * Forms 表单 | |
| 13 | + * @description 由输入框、选择器、单选框、多选框等控件组成,用以收集、校验、提交数据 | |
| 14 | + * @tutorial https://ext.dcloud.net.cn/plugin?id=2773 | |
| 15 | + * @property {Object} rules 表单校验规则 | |
| 16 | + * @property {String} validateTrigger = [bind|submit] 校验触发器方式 默认 submit 可选 | |
| 17 | + * @value bind 发生变化时触发 | |
| 18 | + * @value submit 提交时触发 | |
| 19 | + * @property {String} labelPosition = [top|left] label 位置 默认 left 可选 | |
| 20 | + * @value top 顶部显示 label | |
| 21 | + * @value left 左侧显示 label | |
| 22 | + * @property {String} labelWidth label 宽度,默认 65px | |
| 23 | + * @property {String} labelAlign = [left|center|right] label 居中方式 默认 left 可选 | |
| 24 | + * @value left label 左侧显示 | |
| 25 | + * @value center label 居中 | |
| 26 | + * @value right label 右侧对齐 | |
| 27 | + * @property {String} errShowType = [undertext|toast|modal] 校验错误信息提示方式 | |
| 28 | + * @value undertext 错误信息在底部显示 | |
| 29 | + * @value toast 错误信息toast显示 | |
| 30 | + * @value modal 错误信息modal显示 | |
| 31 | + * @event {Function} submit 提交时触发 | |
| 32 | + */ | |
| 33 | + import Vue from 'vue' | |
| 34 | + Vue.prototype.binddata = function(name, value, formName) { | |
| 35 | + if (formName) { | |
| 36 | + this.$refs[formName].setValue(name, value) | |
| 37 | + } else { | |
| 38 | + let formVm | |
| 39 | + for (let i in this.$refs) { | |
| 40 | + const vm = this.$refs[i] | |
| 41 | + if (vm && vm.$options && vm.$options.name === 'uniForms') { | |
| 42 | + formVm = vm | |
| 43 | + break | |
| 44 | + } | |
| 45 | + } | |
| 46 | + if (!formVm) return console.error('当前 uni-froms 组件缺少 ref 属性') | |
| 47 | + formVm.setValue(name, value) | |
| 48 | + } | |
| 49 | + } | |
| 50 | + | |
| 51 | + import Validator from './validate.js' | |
| 52 | + | |
| 53 | + export default { | |
| 54 | + name: 'uniForms', | |
| 55 | + props: { | |
| 56 | + value: { | |
| 57 | + type: Object, | |
| 58 | + default () { | |
| 59 | + return {} | |
| 60 | + } | |
| 61 | + }, | |
| 62 | + // 表单校验规则 | |
| 63 | + rules: { | |
| 64 | + type: Object, | |
| 65 | + default () { | |
| 66 | + return {} | |
| 67 | + } | |
| 68 | + }, | |
| 69 | + // 校验触发器方式,默认 关闭 | |
| 70 | + validateTrigger: { | |
| 71 | + type: String, | |
| 72 | + default: '' | |
| 73 | + }, | |
| 74 | + // label 位置,可选值 top/left | |
| 75 | + labelPosition: { | |
| 76 | + type: String, | |
| 77 | + default: 'left' | |
| 78 | + }, | |
| 79 | + // label 宽度,单位 px | |
| 80 | + labelWidth: { | |
| 81 | + type: [String, Number], | |
| 82 | + default: 65 | |
| 83 | + }, | |
| 84 | + // label 居中方式,可选值 left/center/right | |
| 85 | + labelAlign: { | |
| 86 | + type: String, | |
| 87 | + default: 'left' | |
| 88 | + }, | |
| 89 | + errShowType: { | |
| 90 | + type: String, | |
| 91 | + default: 'undertext' | |
| 92 | + }, | |
| 93 | + border: { | |
| 94 | + type: Boolean, | |
| 95 | + default: false | |
| 96 | + } | |
| 97 | + }, | |
| 98 | + data() { | |
| 99 | + return { | |
| 100 | + formData: {} | |
| 101 | + }; | |
| 102 | + }, | |
| 103 | + watch: { | |
| 104 | + rules(newVal) { | |
| 105 | + this.init(newVal) | |
| 106 | + }, | |
| 107 | + trigger(trigger) { | |
| 108 | + this.formTrigger = trigger | |
| 109 | + }, | |
| 110 | + }, | |
| 111 | + created() { | |
| 112 | + let _this = this | |
| 113 | + this.childrens = [] | |
| 114 | + this.inputChildrens = [] | |
| 115 | + this.checkboxChildrens = [] | |
| 116 | + this.formRules = [] | |
| 117 | + // this.init(this.rules) | |
| 118 | + }, | |
| 119 | + mounted() { | |
| 120 | + this.init(this.rules) | |
| 121 | + }, | |
| 122 | + methods: { | |
| 123 | + init(formRules) { | |
| 124 | + // 判断是否有规则 | |
| 125 | + if (Object.keys(formRules).length > 0) { | |
| 126 | + this.formTrigger = this.trigger | |
| 127 | + this.formRules = formRules | |
| 128 | + if (!this.validator) { | |
| 129 | + this.validator = new Validator(formRules) | |
| 130 | + } | |
| 131 | + } else { | |
| 132 | + return | |
| 133 | + } | |
| 134 | + // 判断表单存在那些实例 | |
| 135 | + for (let i in this.value) { | |
| 136 | + const itemData = this.childrens.find(v => v.name === i) | |
| 137 | + if (itemData) { | |
| 138 | + this.formData[i] = this.value[i] | |
| 139 | + itemData.init() | |
| 140 | + } | |
| 141 | + } | |
| 142 | + | |
| 143 | + // watch 每个属性 ,需要知道具体那个属性发变化 | |
| 144 | + Object.keys(this.value).forEach((key) => { | |
| 145 | + this.$watch('value.' + key, (newVal) => { | |
| 146 | + const itemData = this.childrens.find(v => v.name === key) | |
| 147 | + if (itemData) { | |
| 148 | + this.formData[key] = this._getValue(key, newVal) | |
| 149 | + itemData.init() | |
| 150 | + } else { | |
| 151 | + this.formData[key] = this.value[key] || null | |
| 152 | + } | |
| 153 | + }) | |
| 154 | + }) | |
| 155 | + }, | |
| 156 | + /** | |
| 157 | + * 设置校验规则 | |
| 158 | + * @param {Object} formRules | |
| 159 | + */ | |
| 160 | + setRules(formRules) { | |
| 161 | + this.init(formRules) | |
| 162 | + }, | |
| 163 | + /** | |
| 164 | + * 公开给用户使用 | |
| 165 | + * 设置自定义表单组件 value 值 | |
| 166 | + * @param {String} name 字段名称 | |
| 167 | + * @param {String} value 字段值 | |
| 168 | + */ | |
| 169 | + setValue(name, value, callback) { | |
| 170 | + let example = this.childrens.find(child => child.name === name) | |
| 171 | + if (!example) return null | |
| 172 | + value = this._getValue(example.name, value) | |
| 173 | + this.formData[name] = value | |
| 174 | + example.val = value | |
| 175 | + this.$emit('input', Object.assign({}, this.value, this.formData)) | |
| 176 | + return example.triggerCheck(value, callback) | |
| 177 | + }, | |
| 178 | + | |
| 179 | + /** | |
| 180 | + * TODO 表单提交, 小程序暂不支持这种用法 | |
| 181 | + * @param {Object} event | |
| 182 | + */ | |
| 183 | + submitForm(event) { | |
| 184 | + const value = event.detail.value | |
| 185 | + return this.validateAll(value || this.formData, 'submit') | |
| 186 | + }, | |
| 187 | + | |
| 188 | + /** | |
| 189 | + * 表单重置 | |
| 190 | + * @param {Object} event | |
| 191 | + */ | |
| 192 | + resetForm(event) { | |
| 193 | + this.childrens.forEach(item => { | |
| 194 | + item.errMsg = '' | |
| 195 | + const inputComp = this.inputChildrens.find(child => child.rename === item.name) | |
| 196 | + if (inputComp) { | |
| 197 | + inputComp.errMsg = '' | |
| 198 | + inputComp.$emit('input', inputComp.multiple ? [] : '') | |
| 199 | + } | |
| 200 | + }) | |
| 201 | + | |
| 202 | + this.childrens.forEach((item) => { | |
| 203 | + if (item.name) { | |
| 204 | + this.formData[item.name] = this._getValue(item.name, '') | |
| 205 | + } | |
| 206 | + }) | |
| 207 | + | |
| 208 | + this.$emit('input', this.formData) | |
| 209 | + this.$emit('reset', event) | |
| 210 | + }, | |
| 211 | + | |
| 212 | + /** | |
| 213 | + * 触发表单校验,通过 @validate 获取 | |
| 214 | + * @param {Object} validate | |
| 215 | + */ | |
| 216 | + validateCheck(validate) { | |
| 217 | + if (validate === null) validate = null | |
| 218 | + this.$emit('validate', validate) | |
| 219 | + }, | |
| 220 | + /** | |
| 221 | + * 校验所有或者部分表单 | |
| 222 | + */ | |
| 223 | + async validateAll(invalidFields, type, callback) { | |
| 224 | + this.childrens.forEach(item => { | |
| 225 | + item.errMsg = '' | |
| 226 | + }) | |
| 227 | + | |
| 228 | + let promise; | |
| 229 | + if (!callback && typeof callback !== 'function' && Promise) { | |
| 230 | + promise = new Promise((resolve, reject) => { | |
| 231 | + callback = function(valid, invalidFields) { | |
| 232 | + !valid ? resolve(invalidFields) : reject(valid); | |
| 233 | + }; | |
| 234 | + }); | |
| 235 | + } | |
| 236 | + | |
| 237 | + let fieldsValue = {} | |
| 238 | + let tempInvalidFields = Object.assign({}, invalidFields) | |
| 239 | + | |
| 240 | + Object.keys(this.formRules).forEach(item => { | |
| 241 | + const values = this.formRules[item] | |
| 242 | + const rules = (values && values.rules) || [] | |
| 243 | + let isNoField = false | |
| 244 | + for (let i = 0; i < rules.length; i++) { | |
| 245 | + const rule = rules[i] | |
| 246 | + if (rule.required) { | |
| 247 | + isNoField = true | |
| 248 | + break | |
| 249 | + } | |
| 250 | + } | |
| 251 | + // 如果存在 required 才会将内容插入校验对象 | |
| 252 | + if (!isNoField && (!tempInvalidFields[item] && tempInvalidFields[item] !== false)) { | |
| 253 | + delete tempInvalidFields[item] | |
| 254 | + } | |
| 255 | + }) | |
| 256 | + | |
| 257 | + // 循环字段是否存在于校验规则中 | |
| 258 | + for (let i in this.formRules) { | |
| 259 | + for (let j in tempInvalidFields) { | |
| 260 | + if (i === j) { | |
| 261 | + fieldsValue[i] = tempInvalidFields[i] | |
| 262 | + } | |
| 263 | + } | |
| 264 | + } | |
| 265 | + let result = [] | |
| 266 | + let example = null | |
| 267 | + | |
| 268 | + let newFormData = {} | |
| 269 | + this.childrens.forEach(v => { | |
| 270 | + newFormData[v.name] = this._getValue(v.name,invalidFields[v.name]) | |
| 271 | + }) | |
| 272 | + if (this.validator) { | |
| 273 | + for (let i in fieldsValue) { | |
| 274 | + // 循环校验,目的是异步校验 | |
| 275 | + const resultData = await this.validator.validateUpdate({ | |
| 276 | + [i]: fieldsValue[i] | |
| 277 | + }, this.formData) | |
| 278 | + | |
| 279 | + // 未通过 | |
| 280 | + if (resultData) { | |
| 281 | + // 获取当前未通过子组件实例 | |
| 282 | + example = this.childrens.find(child => child.name === resultData.key) | |
| 283 | + // 获取easyInput 组件实例 | |
| 284 | + const inputComp = this.inputChildrens.find(child => child.rename === (example && example.name)) | |
| 285 | + if (inputComp) { | |
| 286 | + inputComp.errMsg = resultData.errorMessage | |
| 287 | + } | |
| 288 | + result.push(resultData) | |
| 289 | + // 区分触发类型 | |
| 290 | + if (this.errShowType === 'undertext') { | |
| 291 | + if (example) example.errMsg = resultData.errorMessage | |
| 292 | + } else { | |
| 293 | + if (this.errShowType === 'toast') { | |
| 294 | + uni.showToast({ | |
| 295 | + title: resultData.errorMessage || '校验错误', | |
| 296 | + icon: 'none' | |
| 297 | + }) | |
| 298 | + break | |
| 299 | + } else if (this.errShowType === 'modal') { | |
| 300 | + uni.showModal({ | |
| 301 | + title: '提示', | |
| 302 | + content: resultData.errorMessage || '校验错误' | |
| 303 | + }) | |
| 304 | + break | |
| 305 | + } else { | |
| 306 | + if (example) example.errMsg = resultData.errorMessage | |
| 307 | + } | |
| 308 | + } | |
| 309 | + } | |
| 310 | + } | |
| 311 | + } | |
| 312 | + | |
| 313 | + if (Array.isArray(result)) { | |
| 314 | + if (result.length === 0) result = null | |
| 315 | + } | |
| 316 | + | |
| 317 | + if (type === 'submit') { | |
| 318 | + this.$emit('submit', { | |
| 319 | + detail: { | |
| 320 | + value: newFormData, | |
| 321 | + errors: result | |
| 322 | + } | |
| 323 | + }) | |
| 324 | + } else { | |
| 325 | + this.$emit('validate', result) | |
| 326 | + } | |
| 327 | + | |
| 328 | + callback && typeof callback === 'function' && callback(result, newFormData) | |
| 329 | + | |
| 330 | + if (promise && callback) { | |
| 331 | + return promise | |
| 332 | + } else { | |
| 333 | + return null | |
| 334 | + } | |
| 335 | + }, | |
| 336 | + | |
| 337 | + /** | |
| 338 | + * 外部调用方法 | |
| 339 | + * 手动提交校验表单 | |
| 340 | + * 对整个表单进行校验的方法,参数为一个回调函数。 | |
| 341 | + */ | |
| 342 | + submit(callback) { | |
| 343 | + // Object.assign(this.formData,formData) | |
| 344 | + return this.validateAll(this.formData, 'submit', callback) | |
| 345 | + }, | |
| 346 | + | |
| 347 | + /** | |
| 348 | + * 外部调用方法 | |
| 349 | + * 校验表单 | |
| 350 | + * 对整个表单进行校验的方法,参数为一个回调函数。 | |
| 351 | + */ | |
| 352 | + validate(callback) { | |
| 353 | + return this.validateAll(this.formData, '', callback) | |
| 354 | + }, | |
| 355 | + | |
| 356 | + /** | |
| 357 | + * 部分表单校验 | |
| 358 | + * @param {Object} props | |
| 359 | + * @param {Object} cb | |
| 360 | + */ | |
| 361 | + validateField(props, callback) { | |
| 362 | + props = [].concat(props); | |
| 363 | + let invalidFields = {} | |
| 364 | + this.childrens.forEach(item => { | |
| 365 | + if (props.indexOf(item.name) !== -1) { | |
| 366 | + invalidFields = Object.assign({}, invalidFields, { | |
| 367 | + [item.name]: this.formData[item.name] | |
| 368 | + }) | |
| 369 | + } | |
| 370 | + }) | |
| 371 | + return this.validateAll(invalidFields, '', callback) | |
| 372 | + }, | |
| 373 | + | |
| 374 | + /** | |
| 375 | + * 对整个表单进行重置,将所有字段值重置为初始值并移除校验结果 | |
| 376 | + */ | |
| 377 | + resetFields() { | |
| 378 | + this.resetForm() | |
| 379 | + }, | |
| 380 | + | |
| 381 | + /** | |
| 382 | + * 移除表单项的校验结果。传入待移除的表单项的 prop 属性或者 prop 组成的数组,如不传则移除整个表单的校验结果 | |
| 383 | + */ | |
| 384 | + clearValidate(props) { | |
| 385 | + props = [].concat(props); | |
| 386 | + this.childrens.forEach(item => { | |
| 387 | + const inputComp = this.inputChildrens.find(child => child.rename === item.name) | |
| 388 | + if (props.length === 0) { | |
| 389 | + item.errMsg = '' | |
| 390 | + if (inputComp) { | |
| 391 | + inputComp.errMsg = '' | |
| 392 | + } | |
| 393 | + } else { | |
| 394 | + if (props.indexOf(item.name) !== -1) { | |
| 395 | + item.errMsg = '' | |
| 396 | + if (inputComp) { | |
| 397 | + inputComp.errMsg = '' | |
| 398 | + } | |
| 399 | + } | |
| 400 | + } | |
| 401 | + }) | |
| 402 | + }, | |
| 403 | + /** | |
| 404 | + * 把 value 转换成指定的类型 | |
| 405 | + * @param {Object} key | |
| 406 | + * @param {Object} value | |
| 407 | + */ | |
| 408 | + _getValue(key, value) { | |
| 409 | + const rules = (this.formRules[key] && this.formRules[key].rules) || [] | |
| 410 | + const isRuleNum = rules.find(val => val.format && this.type_filter(val.format)) | |
| 411 | + const isRuleBool = rules.find(val => val.format && val.format === 'boolean' || val.format === 'bool') | |
| 412 | + // 输入值为 number | |
| 413 | + if (isRuleNum) { | |
| 414 | + value = isNaN(value) ? value : (value === '' || value === null ? null : Number(value)) | |
| 415 | + } | |
| 416 | + // 简单判断真假值 | |
| 417 | + if (isRuleBool) { | |
| 418 | + value = !value ? false : true | |
| 419 | + } | |
| 420 | + return value | |
| 421 | + }, | |
| 422 | + /** | |
| 423 | + * 过滤数字类型 | |
| 424 | + * @param {Object} format | |
| 425 | + */ | |
| 426 | + type_filter(format) { | |
| 427 | + return format === 'int' || format === 'double' || format === 'number' || format === 'timestamp' | |
| 428 | + } | |
| 429 | + } | |
| 430 | + } | |
| 431 | +</script> | |
| 432 | + | |
| 433 | +<style lang="scss" scoped> | |
| 434 | + .uni-forms { | |
| 435 | + // overflow: hidden; | |
| 436 | + // padding: 10px 15px; | |
| 437 | + // background-color: #fff; | |
| 438 | + } | |
| 439 | + | |
| 440 | + .uni-forms--top { | |
| 441 | + padding: 10px 15px; | |
| 442 | + // padding-top: 22px; | |
| 443 | + } | |
| 444 | +</style> | ... | ... |
components/uni-forms/validate.js
0 → 100644
| 1 | + | |
| 2 | +var pattern = { | |
| 3 | + email: /^\S+?@\S+?\.\S+?$/, | |
| 4 | + url: new RegExp("^(?!mailto:)(?:(?:http|https|ftp)://|//)(?:\\S+(?::\\S*)?@)?(?:(?:(?:[1-9]\\d?|1\\d\\d|2[01]\\d|22[0-3])(?:\\.(?:1?\\d{1,2}|2[0-4]\\d|25[0-5])){2}(?:\\.(?:[0-9]\\d?|1\\d\\d|2[0-4]\\d|25[0-4]))|(?:(?:[a-z\\u00a1-\\uffff0-9]+-*)*[a-z\\u00a1-\\uffff0-9]+)(?:\\.(?:[a-z\\u00a1-\\uffff0-9]+-*)*[a-z\\u00a1-\\uffff0-9]+)*(?:\\.(?:[a-z\\u00a1-\\uffff]{2,})))|localhost)(?::\\d{2,5})?(?:(/|\\?|#)[^\\s]*)?$", 'i') | |
| 5 | +}; | |
| 6 | + | |
| 7 | +const FORMAT_MAPPING = { | |
| 8 | + "int": 'number', | |
| 9 | + "bool": 'boolean', | |
| 10 | + "double": 'number', | |
| 11 | + "long": 'number', | |
| 12 | + "password": 'string' | |
| 13 | +} | |
| 14 | + | |
| 15 | +function formatMessage(args, resources) { | |
| 16 | + var defaultMessage = ['label'] | |
| 17 | + defaultMessage.forEach((item) => { | |
| 18 | + if (args[item] === undefined) { | |
| 19 | + args[item] = '' | |
| 20 | + } | |
| 21 | + }) | |
| 22 | + | |
| 23 | + let str = resources | |
| 24 | + for (let key in args) { | |
| 25 | + let reg = new RegExp('{' + key + '}') | |
| 26 | + str = str.replace(reg, args[key]) | |
| 27 | + } | |
| 28 | + return str | |
| 29 | +} | |
| 30 | + | |
| 31 | +function isEmptyValue(value, type) { | |
| 32 | + if (value === undefined || value === null) { | |
| 33 | + return true; | |
| 34 | + } | |
| 35 | + | |
| 36 | + if (typeof value === 'string' && !value) { | |
| 37 | + return true; | |
| 38 | + } | |
| 39 | + | |
| 40 | + if (Array.isArray(value) && !value.length) { | |
| 41 | + return true; | |
| 42 | + } | |
| 43 | + | |
| 44 | + if (type === 'object' && !Object.keys(value).length) { | |
| 45 | + return true; | |
| 46 | + } | |
| 47 | + | |
| 48 | + return false; | |
| 49 | +} | |
| 50 | + | |
| 51 | +const types = { | |
| 52 | + integer(value) { | |
| 53 | + return types.number(value) && parseInt(value, 10) === value; | |
| 54 | + }, | |
| 55 | + string(value) { | |
| 56 | + return typeof value === 'string'; | |
| 57 | + }, | |
| 58 | + number(value) { | |
| 59 | + if (isNaN(value)) { | |
| 60 | + return false; | |
| 61 | + } | |
| 62 | + return typeof value === 'number'; | |
| 63 | + }, | |
| 64 | + "boolean": function (value) { | |
| 65 | + return typeof value === 'boolean'; | |
| 66 | + }, | |
| 67 | + "float": function (value) { | |
| 68 | + return types.number(value) && !types.integer(value); | |
| 69 | + }, | |
| 70 | + array(value) { | |
| 71 | + return Array.isArray(value); | |
| 72 | + }, | |
| 73 | + object(value) { | |
| 74 | + return typeof value === 'object' && !types.array(value); | |
| 75 | + }, | |
| 76 | + date(value) { | |
| 77 | + var v | |
| 78 | + if (value instanceof Date) { | |
| 79 | + v = value; | |
| 80 | + } else { | |
| 81 | + v = new Date(value); | |
| 82 | + } | |
| 83 | + return typeof v.getTime === 'function' && typeof v.getMonth === 'function' && typeof v.getYear === 'function' && !isNaN(v.getTime()); | |
| 84 | + }, | |
| 85 | + timestamp(value) { | |
| 86 | + if (!this.integer(value) || Math.abs(value).toString().length > 16) { | |
| 87 | + return false | |
| 88 | + } | |
| 89 | + | |
| 90 | + return this.date(value); | |
| 91 | + }, | |
| 92 | + email(value) { | |
| 93 | + return typeof value === 'string' && !!value.match(pattern.email) && value.length < 255; | |
| 94 | + }, | |
| 95 | + url(value) { | |
| 96 | + return typeof value === 'string' && !!value.match(pattern.url); | |
| 97 | + }, | |
| 98 | + pattern(reg, value) { | |
| 99 | + try { | |
| 100 | + return new RegExp(reg).test(value); | |
| 101 | + } catch (e) { | |
| 102 | + return false; | |
| 103 | + } | |
| 104 | + }, | |
| 105 | + method(value) { | |
| 106 | + return typeof value === 'function'; | |
| 107 | + } | |
| 108 | +} | |
| 109 | + | |
| 110 | +class RuleValidator { | |
| 111 | + | |
| 112 | + constructor(message) { | |
| 113 | + this._message = message | |
| 114 | + } | |
| 115 | + | |
| 116 | + async validateRule(key, value, data, allData) { | |
| 117 | + var result = null | |
| 118 | + | |
| 119 | + let rules = key.rules | |
| 120 | + | |
| 121 | + let hasRequired = rules.findIndex((item) => { | |
| 122 | + return item.required | |
| 123 | + }) | |
| 124 | + if (hasRequired < 0) { | |
| 125 | + if (value === null || value === undefined) { | |
| 126 | + return result | |
| 127 | + } | |
| 128 | + if (typeof value === 'string' && !value.length) { | |
| 129 | + return result | |
| 130 | + } | |
| 131 | + } | |
| 132 | + | |
| 133 | + var message = this._message | |
| 134 | + | |
| 135 | + if (rules === undefined) { | |
| 136 | + return message['default'] | |
| 137 | + } | |
| 138 | + | |
| 139 | + for (var i = 0; i < rules.length; i++) { | |
| 140 | + let rule = rules[i] | |
| 141 | + let vt = this._getValidateType(rule) | |
| 142 | + | |
| 143 | + if (key.label !== undefined) { | |
| 144 | + Object.assign(rule, { | |
| 145 | + label: key.label | |
| 146 | + }) | |
| 147 | + } | |
| 148 | + | |
| 149 | + if (RuleValidatorHelper[vt]) { | |
| 150 | + result = RuleValidatorHelper[vt](rule, value, message) | |
| 151 | + if (result != null) { | |
| 152 | + break | |
| 153 | + } | |
| 154 | + } | |
| 155 | + | |
| 156 | + if (rule.validateExpr) { | |
| 157 | + let now = Date.now() | |
| 158 | + let resultExpr = rule.validateExpr(value, allData, now) | |
| 159 | + if (resultExpr === false) { | |
| 160 | + result = this._getMessage(rule, rule.errorMessage || this._message['default']) | |
| 161 | + break | |
| 162 | + } | |
| 163 | + } | |
| 164 | + | |
| 165 | + if (rule.validateFunction) { | |
| 166 | + result = await this.validateFunction(rule, value, data, allData, vt) | |
| 167 | + if (result !== null) { | |
| 168 | + break | |
| 169 | + } | |
| 170 | + } | |
| 171 | + } | |
| 172 | + | |
| 173 | + return result | |
| 174 | + } | |
| 175 | + | |
| 176 | + async validateFunction(rule, value, data, allData, vt) { | |
| 177 | + let result = null | |
| 178 | + try { | |
| 179 | + let callbackMessage = null | |
| 180 | + const res = await rule.validateFunction(rule, value, allData || data, (message) => { | |
| 181 | + callbackMessage = message | |
| 182 | + }) | |
| 183 | + if (callbackMessage || (typeof res === 'string' && res) || res === false) { | |
| 184 | + result = this._getMessage(rule, callbackMessage || res, vt) | |
| 185 | + } | |
| 186 | + } catch (e) { | |
| 187 | + result = this._getMessage(rule, e.message, vt) | |
| 188 | + } | |
| 189 | + return result | |
| 190 | + } | |
| 191 | + | |
| 192 | + _getMessage(rule, message, vt) { | |
| 193 | + return formatMessage(rule, message || rule.errorMessage || this._message[vt] || message['default']) | |
| 194 | + } | |
| 195 | + | |
| 196 | + _getValidateType(rule) { | |
| 197 | + // TODO | |
| 198 | + var result = '' | |
| 199 | + if (rule.required) { | |
| 200 | + result = 'required' | |
| 201 | + } else if (rule.format) { | |
| 202 | + result = 'format' | |
| 203 | + } else if (rule.range) { | |
| 204 | + result = 'range' | |
| 205 | + } else if (rule.maximum || rule.minimum) { | |
| 206 | + result = 'rangeNumber' | |
| 207 | + } else if (rule.maxLength || rule.minLength) { | |
| 208 | + result = 'rangeLength' | |
| 209 | + } else if (rule.pattern) { | |
| 210 | + result = 'pattern' | |
| 211 | + } | |
| 212 | + return result | |
| 213 | + } | |
| 214 | +} | |
| 215 | + | |
| 216 | +const RuleValidatorHelper = { | |
| 217 | + required(rule, value, message) { | |
| 218 | + if (rule.required && isEmptyValue(value, rule.format || typeof value)) { | |
| 219 | + return formatMessage(rule, rule.errorMessage || message.required); | |
| 220 | + } | |
| 221 | + | |
| 222 | + return null | |
| 223 | + }, | |
| 224 | + | |
| 225 | + range(rule, value, message) { | |
| 226 | + const { range, errorMessage } = rule; | |
| 227 | + | |
| 228 | + let list = new Array(range.length); | |
| 229 | + for (let i = 0; i < range.length; i++) { | |
| 230 | + const item = range[i]; | |
| 231 | + if (types.object(item) && item.value !== undefined) { | |
| 232 | + list[i] = item.value; | |
| 233 | + } else { | |
| 234 | + list[i] = item; | |
| 235 | + } | |
| 236 | + } | |
| 237 | + | |
| 238 | + let result = false | |
| 239 | + if (Array.isArray(value)) { | |
| 240 | + result = (new Set(value.concat(list)).size === list.length); | |
| 241 | + } else { | |
| 242 | + if (list.indexOf(value) > -1) { | |
| 243 | + result = true; | |
| 244 | + } | |
| 245 | + } | |
| 246 | + | |
| 247 | + if (!result) { | |
| 248 | + return formatMessage(rule, errorMessage || message['enum']); | |
| 249 | + } | |
| 250 | + | |
| 251 | + return null | |
| 252 | + }, | |
| 253 | + | |
| 254 | + rangeNumber(rule, value, message) { | |
| 255 | + if (!types.number(value)) { | |
| 256 | + return formatMessage(rule, rule.errorMessage || message.pattern.mismatch); | |
| 257 | + } | |
| 258 | + | |
| 259 | + let { minimum, maximum, exclusiveMinimum, exclusiveMaximum } = rule; | |
| 260 | + let min = exclusiveMinimum ? value <= minimum : value < minimum; | |
| 261 | + let max = exclusiveMaximum ? value >= maximum : value > maximum; | |
| 262 | + | |
| 263 | + if (minimum !== undefined && min) { | |
| 264 | + return formatMessage(rule, rule.errorMessage || message['number'].min) | |
| 265 | + } else if (maximum !== undefined && max) { | |
| 266 | + return formatMessage(rule, rule.errorMessage || message['number'].max) | |
| 267 | + } else if (minimum !== undefined && maximum !== undefined && (min || max)) { | |
| 268 | + return formatMessage(rule, rule.errorMessage || message['number'].range) | |
| 269 | + } | |
| 270 | + | |
| 271 | + return null | |
| 272 | + }, | |
| 273 | + | |
| 274 | + rangeLength(rule, value, message) { | |
| 275 | + if (!types.string(value) && !types.array(value)) { | |
| 276 | + return formatMessage(rule, rule.errorMessage || message.pattern.mismatch); | |
| 277 | + } | |
| 278 | + | |
| 279 | + let min = rule.minLength; | |
| 280 | + let max = rule.maxLength; | |
| 281 | + let val = value.length; | |
| 282 | + | |
| 283 | + if (min !== undefined && val < min) { | |
| 284 | + return formatMessage(rule, rule.errorMessage || message['length'].min) | |
| 285 | + } else if (max !== undefined && val > max) { | |
| 286 | + return formatMessage(rule, rule.errorMessage || message['length'].max) | |
| 287 | + } else if (min !== undefined && max !== undefined && (val < min || val > max)) { | |
| 288 | + return formatMessage(rule, rule.errorMessage || message['length'].range) | |
| 289 | + } | |
| 290 | + | |
| 291 | + return null | |
| 292 | + }, | |
| 293 | + | |
| 294 | + pattern(rule, value, message) { | |
| 295 | + if (!types['pattern'](rule.pattern, value)) { | |
| 296 | + return formatMessage(rule, rule.errorMessage || message.pattern.mismatch); | |
| 297 | + } | |
| 298 | + | |
| 299 | + return null | |
| 300 | + }, | |
| 301 | + | |
| 302 | + format(rule, value, message) { | |
| 303 | + var customTypes = Object.keys(types); | |
| 304 | + var format = FORMAT_MAPPING[rule.format] ? FORMAT_MAPPING[rule.format] : rule.format; | |
| 305 | + | |
| 306 | + if (customTypes.indexOf(format) > -1) { | |
| 307 | + if (!types[format](value)) { | |
| 308 | + return formatMessage(rule, rule.errorMessage || message.types[format]); | |
| 309 | + } | |
| 310 | + } | |
| 311 | + | |
| 312 | + return null | |
| 313 | + } | |
| 314 | +} | |
| 315 | + | |
| 316 | +class SchemaValidator extends RuleValidator { | |
| 317 | + | |
| 318 | + constructor(schema, options) { | |
| 319 | + super(SchemaValidator.message); | |
| 320 | + | |
| 321 | + this._schema = schema | |
| 322 | + this._options = options || null | |
| 323 | + } | |
| 324 | + | |
| 325 | + updateSchema(schema) { | |
| 326 | + this._schema = schema | |
| 327 | + } | |
| 328 | + | |
| 329 | + async validate(data, allData) { | |
| 330 | + let result = this._checkFieldInSchema(data) | |
| 331 | + if (!result) { | |
| 332 | + result = await this.invokeValidate(data, false, allData) | |
| 333 | + } | |
| 334 | + return result.length ? result[0] : null | |
| 335 | + } | |
| 336 | + | |
| 337 | + async validateAll(data, allData) { | |
| 338 | + let result = this._checkFieldInSchema(data) | |
| 339 | + if (!result) { | |
| 340 | + result = await this.invokeValidate(data, true, allData) | |
| 341 | + } | |
| 342 | + return result | |
| 343 | + } | |
| 344 | + | |
| 345 | + async validateUpdate(data, allData) { | |
| 346 | + let result = this._checkFieldInSchema(data) | |
| 347 | + if (!result) { | |
| 348 | + result = await this.invokeValidateUpdate(data, false, allData) | |
| 349 | + } | |
| 350 | + return result.length ? result[0] : null | |
| 351 | + } | |
| 352 | + | |
| 353 | + async invokeValidate(data, all, allData) { | |
| 354 | + let result = [] | |
| 355 | + let schema = this._schema | |
| 356 | + for (let key in schema) { | |
| 357 | + let value = schema[key] | |
| 358 | + let errorMessage = await this.validateRule(value, data[key], data, allData) | |
| 359 | + if (errorMessage != null) { | |
| 360 | + result.push({ | |
| 361 | + key, | |
| 362 | + errorMessage | |
| 363 | + }) | |
| 364 | + if (!all) break | |
| 365 | + } | |
| 366 | + } | |
| 367 | + return result | |
| 368 | + } | |
| 369 | + | |
| 370 | + async invokeValidateUpdate(data, all, allData) { | |
| 371 | + let result = [] | |
| 372 | + for (let key in data) { | |
| 373 | + let errorMessage = await this.validateRule(this._schema[key], data[key], data, allData) | |
| 374 | + if (errorMessage != null) { | |
| 375 | + result.push({ | |
| 376 | + key, | |
| 377 | + errorMessage | |
| 378 | + }) | |
| 379 | + if (!all) break | |
| 380 | + } | |
| 381 | + } | |
| 382 | + return result | |
| 383 | + } | |
| 384 | + | |
| 385 | + _checkFieldInSchema(data) { | |
| 386 | + var keys = Object.keys(data) | |
| 387 | + var keys2 = Object.keys(this._schema) | |
| 388 | + if (new Set(keys.concat(keys2)).size === keys2.length) { | |
| 389 | + return '' | |
| 390 | + } | |
| 391 | + return [{ | |
| 392 | + key: 'invalid', | |
| 393 | + errorMessage: SchemaValidator.message['defaultInvalid'] | |
| 394 | + }] | |
| 395 | + } | |
| 396 | +} | |
| 397 | + | |
| 398 | +function Message() { | |
| 399 | + return { | |
| 400 | + default: '验证错误', | |
| 401 | + defaultInvalid: '字段超出范围', | |
| 402 | + required: '{label}必填', | |
| 403 | + 'enum': '{label}超出范围', | |
| 404 | + whitespace: '{label}不能为空', | |
| 405 | + date: { | |
| 406 | + format: '{label}日期{value}格式无效', | |
| 407 | + parse: '{label}日期无法解析,{value}无效', | |
| 408 | + invalid: '{label}日期{value}无效' | |
| 409 | + }, | |
| 410 | + types: { | |
| 411 | + string: '{label}类型无效', | |
| 412 | + array: '{label}类型无效', | |
| 413 | + object: '{label}类型无效', | |
| 414 | + number: '{label}类型无效', | |
| 415 | + date: '{label}类型无效', | |
| 416 | + boolean: '{label}类型无效', | |
| 417 | + integer: '{label}类型无效', | |
| 418 | + float: '{label}类型无效', | |
| 419 | + regexp: '{label}无效', | |
| 420 | + email: '{label}类型无效', | |
| 421 | + url: '{label}类型无效' | |
| 422 | + }, | |
| 423 | + length: { | |
| 424 | + min: '{label}长度不能少于{minLength}', | |
| 425 | + max: '{label}长度不能超过{maxLength}', | |
| 426 | + range: '{label}必须介于{minLength}和{maxLength}之间' | |
| 427 | + }, | |
| 428 | + number: { | |
| 429 | + min: '{label}不能小于{minimum}', | |
| 430 | + max: '{label}不能大于{maximum}', | |
| 431 | + range: '{label}必须介于{minimum}and{maximum}之间' | |
| 432 | + }, | |
| 433 | + pattern: { | |
| 434 | + mismatch: '{label}格式不匹配' | |
| 435 | + } | |
| 436 | + }; | |
| 437 | +} | |
| 438 | + | |
| 439 | + | |
| 440 | +SchemaValidator.message = new Message(); | |
| 441 | + | |
| 442 | +export default SchemaValidator | ... | ... |
components/usp-tinymce/dynamicLoadScript.js
0 → 100644
| 1 | +let callbacks = [] | |
| 2 | + | |
| 3 | +function loadedTinymce() { | |
| 4 | + // to fixed https://github.com/PanJiaChen/vue-element-admin/issues/2144 | |
| 5 | + // check is successfully downloaded script | |
| 6 | + return window.tinymce | |
| 7 | +} | |
| 8 | + | |
| 9 | +const dynamicLoadScript = (src, callback) => { | |
| 10 | + const existingScript = document.getElementById(src) | |
| 11 | + const cb = callback || function() {} | |
| 12 | + | |
| 13 | + if (!existingScript) { | |
| 14 | + const script = document.createElement('script') | |
| 15 | + script.src = src // src url for the third-party library being loaded. | |
| 16 | + script.id = src | |
| 17 | + document.body.appendChild(script) | |
| 18 | + callbacks.push(cb) | |
| 19 | + const onEnd = 'onload' in script ? stdOnEnd : ieOnEnd | |
| 20 | + onEnd(script) | |
| 21 | + } | |
| 22 | + | |
| 23 | + if (existingScript && cb) { | |
| 24 | + if (loadedTinymce()) { | |
| 25 | + cb(null, existingScript) | |
| 26 | + } else { | |
| 27 | + callbacks.push(cb) | |
| 28 | + } | |
| 29 | + } | |
| 30 | + | |
| 31 | + function stdOnEnd(script) { | |
| 32 | + script.onload = function() { | |
| 33 | + // this.onload = null here is necessary | |
| 34 | + // because even IE9 works not like others | |
| 35 | + this.onerror = this.onload = null | |
| 36 | + for (const cb of callbacks) { | |
| 37 | + cb(null, script) | |
| 38 | + } | |
| 39 | + callbacks = null | |
| 40 | + } | |
| 41 | + script.onerror = function() { | |
| 42 | + this.onerror = this.onload = null | |
| 43 | + cb(new Error('Failed to load ' + src), script) | |
| 44 | + } | |
| 45 | + } | |
| 46 | + | |
| 47 | + function ieOnEnd(script) { | |
| 48 | + script.onreadystatechange = function() { | |
| 49 | + if (this.readyState !== 'complete' && this.readyState !== 'loaded') return | |
| 50 | + this.onreadystatechange = null | |
| 51 | + for (const cb of callbacks) { | |
| 52 | + cb(null, script) // there is no way to catch loading errors in IE8 | |
| 53 | + } | |
| 54 | + callbacks = null | |
| 55 | + } | |
| 56 | + } | |
| 57 | +} | |
| 58 | + | |
| 59 | +export default dynamicLoadScript | ... | ... |
components/usp-tinymce/plugins.js
0 → 100644
| 1 | +// Any plugins you want to use has to be imported | |
| 2 | +// Detail plugins list see https://www.tinymce.com/docs/plugins/ | |
| 3 | +// Custom builds see https://www.tinymce.com/download/custom-builds/ | |
| 4 | + | |
| 5 | +const plugins = [ | |
| 6 | + ` | |
| 7 | + advlist | |
| 8 | + autolink | |
| 9 | + autosave | |
| 10 | + code | |
| 11 | + codesample | |
| 12 | + colorpicker | |
| 13 | + colorpicker | |
| 14 | + contextmenu | |
| 15 | + directionality | |
| 16 | + emoticons | |
| 17 | + fullscreen | |
| 18 | + hr | |
| 19 | + image | |
| 20 | + imagetools | |
| 21 | + insertdatetime | |
| 22 | + lists | |
| 23 | + media | |
| 24 | + nonbreaking | |
| 25 | + noneditable | |
| 26 | + paste | |
| 27 | + preview | |
| 28 | ||
| 29 | + save | |
| 30 | + searchreplace | |
| 31 | + tabfocus | |
| 32 | + table | |
| 33 | + textcolor | |
| 34 | + textpattern | |
| 35 | + visualblocks | |
| 36 | + visualchars | |
| 37 | + wordcount | |
| 38 | + ` | |
| 39 | +] | |
| 40 | + | |
| 41 | +export default plugins | ... | ... |
components/usp-tinymce/toolbar.js
0 → 100644
| 1 | +// Here is a list of the toolbar | |
| 2 | +// Detail list see https://www.tinymce.com/docs/advanced/editor-control-identifiers/#toolbarcontrols | |
| 3 | + | |
| 4 | +const toolbar = [ | |
| 5 | + 'bold italic underline strikethrough alignleft aligncenter alignright outdent indent blockquote undo redo removeformat subscript superscript', | |
| 6 | + 'hr bullist numlist image table forecolor backcolor code preview fullscreen' | |
| 7 | +] | |
| 8 | + | |
| 9 | +export default toolbar | ... | ... |
components/usp-tinymce/usp-tinymce.vue
0 → 100644
| 1 | +<template> | |
| 2 | + <div :class="{fullscreen:fullscreen, loaded: loaded}" class="tinymce-container" :style="{width:containerWidth}"> | |
| 3 | + <textarea :id="tinymceId" class="tinymce-textarea" /> | |
| 4 | + </div> | |
| 5 | +</template> | |
| 6 | + | |
| 7 | +<script> | |
| 8 | +import plugins from './plugins' | |
| 9 | +import toolbar from './toolbar' | |
| 10 | +import load from './dynamicLoadScript' | |
| 11 | + | |
| 12 | +const tinymceCDN = 'https://cdn.jsdelivr.net/npm/tinymce-all-in-one@4.9.3/tinymce.min.js' | |
| 13 | + | |
| 14 | +export default { | |
| 15 | + name: 'uspTinymce', | |
| 16 | + props: { | |
| 17 | + id: { | |
| 18 | + type: String, | |
| 19 | + default() { | |
| 20 | + return 'vue-tinymce-' + +new Date() + ((Math.random() * 1000).toFixed(0) + '') | |
| 21 | + } | |
| 22 | + }, | |
| 23 | + value: { | |
| 24 | + type: String, | |
| 25 | + default: '' | |
| 26 | + }, | |
| 27 | + toolbar: { | |
| 28 | + type: Array, | |
| 29 | + required: false, | |
| 30 | + default() { | |
| 31 | + return [] | |
| 32 | + } | |
| 33 | + }, | |
| 34 | + menubar: { | |
| 35 | + type: String, | |
| 36 | + default: 'file edit insert view format table' | |
| 37 | + }, | |
| 38 | + height: { | |
| 39 | + type: [Number, String], | |
| 40 | + required: false, | |
| 41 | + default: 360 | |
| 42 | + }, | |
| 43 | + width: { | |
| 44 | + type: [Number, String], | |
| 45 | + required: false, | |
| 46 | + default: 'auto' | |
| 47 | + }, | |
| 48 | + isHtml:{ | |
| 49 | + type: Boolean, | |
| 50 | + default: true | |
| 51 | + } | |
| 52 | + }, | |
| 53 | + data() { | |
| 54 | + return { | |
| 55 | + loaded: false, | |
| 56 | + hasChange: false, | |
| 57 | + hasInit: false, | |
| 58 | + tinymceId: this.id, | |
| 59 | + fullscreen: false, | |
| 60 | + languageTypeList: { | |
| 61 | + 'en': 'en', | |
| 62 | + 'zh': 'zh_CN', | |
| 63 | + 'es': 'es_MX', | |
| 64 | + 'ja': 'ja' | |
| 65 | + } | |
| 66 | + } | |
| 67 | + }, | |
| 68 | + computed: { | |
| 69 | + containerWidth() { | |
| 70 | + const width = this.width | |
| 71 | + if (/^[\d]+(\.[\d]+)?$/.test(width)) { // matches `100`, `'100'` | |
| 72 | + return `${width}px` | |
| 73 | + } | |
| 74 | + return width | |
| 75 | + } | |
| 76 | + }, | |
| 77 | + watch: { | |
| 78 | + value(val) { | |
| 79 | + if (!this.hasChange && this.hasInit) { | |
| 80 | + this.$nextTick(() =>window.tinymce.get(this.tinymceId).setContent(val || '')) | |
| 81 | + } | |
| 82 | + } | |
| 83 | + }, | |
| 84 | + mounted() { | |
| 85 | + this.init() | |
| 86 | + }, | |
| 87 | + activated() { | |
| 88 | + if (window.tinymce) { | |
| 89 | + this.initTinymce() | |
| 90 | + } | |
| 91 | + }, | |
| 92 | + deactivated() { | |
| 93 | + this.destroyTinymce() | |
| 94 | + }, | |
| 95 | + destroyed() { | |
| 96 | + this.destroyTinymce() | |
| 97 | + }, | |
| 98 | + methods: { | |
| 99 | + init() { | |
| 100 | + // dynamic load tinymce from cdn | |
| 101 | + load(tinymceCDN, (err) => { | |
| 102 | + if (err) { | |
| 103 | + this.$message.error(err.message) | |
| 104 | + return | |
| 105 | + } | |
| 106 | + this.initTinymce() | |
| 107 | + }) | |
| 108 | + }, | |
| 109 | + initTinymce() { | |
| 110 | + const _this = this | |
| 111 | + window.tinymce.init({ | |
| 112 | + selector: `#${this.tinymceId}`, | |
| 113 | + images_upload_handler: async (blobInfo, succFun, failFun, progress)=> { | |
| 114 | + progress(0); | |
| 115 | + let fileName = + new Date() + ('000000' + Math.floor(Math.random() * 999999)).slice(-6); | |
| 116 | + fileName += blobInfo.blob().type === 'image/jpeg' ? '.jpg' : '.png'; | |
| 117 | + const result = await uniCloud.uploadFile({ | |
| 118 | + filePath: blobInfo.blobUri(), | |
| 119 | + cloudPath: fileName, | |
| 120 | + onUploadProgress: progressEvent=> { | |
| 121 | + progress(Math.round( | |
| 122 | + (progressEvent.loaded * 100) / progressEvent.total | |
| 123 | + )); | |
| 124 | + } | |
| 125 | + }); | |
| 126 | + | |
| 127 | + const tempFiles = await uniCloud.getTempFileURL({ | |
| 128 | + fileList: [result.fileID] | |
| 129 | + }) | |
| 130 | + const tempFile = tempFiles.fileList[0]; | |
| 131 | + if(tempFile.code === 'SUCCESS'){ | |
| 132 | + succFun(tempFile.download_url); | |
| 133 | + }else{ | |
| 134 | + failFun('上传失败'); | |
| 135 | + } | |
| 136 | + }, | |
| 137 | + language: this.languageTypeList['zh'], | |
| 138 | + height: this.height, | |
| 139 | + body_class: 'panel-body ', | |
| 140 | + object_resizing: false, | |
| 141 | + toolbar: this.toolbar.length > 0 ? this.toolbar : toolbar, | |
| 142 | + menubar: this.menubar, | |
| 143 | + plugins: plugins, | |
| 144 | + end_container_on_empty_block: true, | |
| 145 | + powerpaste_word_import: 'clean', | |
| 146 | + code_dialog_height: 450, | |
| 147 | + code_dialog_width: 1000, | |
| 148 | + advlist_bullet_styles: 'square', | |
| 149 | + advlist_number_styles: 'default', | |
| 150 | + imagetools_cors_hosts: ['www.tinymce.com', 'codepen.io'], | |
| 151 | + default_link_target: '_blank', | |
| 152 | + link_title: false, | |
| 153 | + nonbreaking_force_tab: true, // inserting nonbreaking space need Nonbreaking Space Plugin | |
| 154 | + init_instance_callback: editor => { | |
| 155 | + //if (_this.value) { | |
| 156 | + editor.setContent(_this.value || '') | |
| 157 | + setTimeout(()=>{ | |
| 158 | + this.loaded = true; | |
| 159 | + }, 100) | |
| 160 | + //} | |
| 161 | + _this.hasInit = true | |
| 162 | + editor.on('NodeChange Change KeyUp SetContent', () => { | |
| 163 | + this.hasChange = true | |
| 164 | + if(this.isHtml){ | |
| 165 | + this.$emit('input', editor.getContent()) | |
| 166 | + }else{ | |
| 167 | + this.$emit('input', editor.getContent({format: 'text'})) | |
| 168 | + } | |
| 169 | + }) | |
| 170 | + }, | |
| 171 | + setup(editor) { | |
| 172 | + editor.on('FullscreenStateChanged', (e) => { | |
| 173 | + _this.fullscreen = e.state | |
| 174 | + }) | |
| 175 | + } | |
| 176 | + }) | |
| 177 | + }, | |
| 178 | + destroyTinymce() { | |
| 179 | + const tinymce = window.tinymce.get(this.tinymceId) | |
| 180 | + if (this.fullscreen) { | |
| 181 | + tinymce.execCommand('mceFullScreen') | |
| 182 | + } | |
| 183 | + | |
| 184 | + if (tinymce) { | |
| 185 | + tinymce.destroy() | |
| 186 | + } | |
| 187 | + }, | |
| 188 | + setContent(value) { | |
| 189 | + window.tinymce.get(this.tinymceId).setContent(value) | |
| 190 | + }, | |
| 191 | + getContent() { | |
| 192 | + window.tinymce.get(this.tinymceId).getContent() | |
| 193 | + }, | |
| 194 | + imageSuccessCBK(arr) { | |
| 195 | + const _this = this | |
| 196 | + arr.forEach(v => { | |
| 197 | + window.tinymce.get(_this.tinymceId).insertContent(`<img class="wscnph" src="${v.url}" >`) | |
| 198 | + }) | |
| 199 | + } | |
| 200 | + } | |
| 201 | +} | |
| 202 | +</script> | |
| 203 | + | |
| 204 | +<style scoped lang="scss"> | |
| 205 | + /deep/ { | |
| 206 | + .tinymce-container { | |
| 207 | + position: relative; | |
| 208 | + line-height: normal; | |
| 209 | + } | |
| 210 | + .tinymce-container>>>.mce-fullscreen { | |
| 211 | + z-index: 10000; | |
| 212 | + } | |
| 213 | + .tinymce-textarea { | |
| 214 | + visibility: hidden; | |
| 215 | + z-index: -1; | |
| 216 | + } | |
| 217 | + .editor-custom-btn-container { | |
| 218 | + position: absolute; | |
| 219 | + right: 4px; | |
| 220 | + top: 4px; | |
| 221 | + /*z-index: 2005;*/ | |
| 222 | + } | |
| 223 | + .fullscreen .editor-custom-btn-container { | |
| 224 | + z-index: 10000; | |
| 225 | + position: fixed; | |
| 226 | + } | |
| 227 | + .editor-upload-btn { | |
| 228 | + display: inline-block; | |
| 229 | + } | |
| 230 | + .mce-tinymce{ | |
| 231 | + box-shadow: 0 1px 2px rgba(0, 0, 0, 0) !important; | |
| 232 | + border-color: #DCDFE6 !important; | |
| 233 | + } | |
| 234 | + .mce-top-part::before{ | |
| 235 | + box-shadow: 0 1px 2px rgba(0, 0, 0, 0) !important; | |
| 236 | + } | |
| 237 | + .mce-edit-area{ | |
| 238 | + border-color: #DCDFE6 !important; | |
| 239 | + | |
| 240 | + iframe{ | |
| 241 | + opacity: 0; | |
| 242 | + } | |
| 243 | + } | |
| 244 | + .mce-statusbar{ | |
| 245 | + border-color: #DCDFE6 !important; | |
| 246 | + } | |
| 247 | + #mceu_27{ | |
| 248 | + border-radius: 5px; | |
| 249 | + overflow: hidden; | |
| 250 | + } | |
| 251 | + /* 菜单图标字体颜色 */ | |
| 252 | + .mce-ico{ | |
| 253 | + color: #7e8086 !important; | |
| 254 | + } | |
| 255 | + /* 选中项图标为白色 */ | |
| 256 | + .mce-btn.mce-active i{ | |
| 257 | + color: #fff !important; | |
| 258 | + } | |
| 259 | + /* 背景颜色图标 */ | |
| 260 | + i.mce-i-backcolor{ | |
| 261 | + color: #fff !important; | |
| 262 | + background-color: #ff944c !important; | |
| 263 | + } | |
| 264 | + /* 字体颜色图标 */ | |
| 265 | + i.mce-i-forecolor{ | |
| 266 | + color: #ff944c !important; | |
| 267 | + transform: scale(1.1); | |
| 268 | + } | |
| 269 | + } | |
| 270 | + .loaded /deep/ iframe{ | |
| 271 | + opacity: 1; | |
| 272 | + } | |
| 273 | +</style> | |
| 0 | 274 | \ No newline at end of file | ... | ... |
pages.json
| 1 | -{ | |
| 2 | - "easycom": { | |
| 3 | - "^u-(.*)": "uview-ui/components/u-$1/u-$1.vue" | |
| 4 | - }, | |
| 5 | - "pages": [ //pages数组中第一项表示应用启动页,参考:https://uniapp.dcloud.io/collocation/pages | |
| 6 | - { | |
| 7 | - "path": "pages/home/home", | |
| 8 | - "style": { | |
| 9 | - "navigationStyle": "custom" | |
| 10 | - } | |
| 11 | - },{ | |
| 12 | - "path": "pages/login/login", | |
| 13 | - "style": { | |
| 14 | - "navigationStyle": "custom" | |
| 15 | - } | |
| 16 | - },{ | |
| 17 | - "path": "pages/workbench/workbench", | |
| 18 | - "style": { | |
| 19 | - "navigationStyle": "custom" | |
| 20 | - } | |
| 21 | - }, { | |
| 22 | - "path": "pages/my/my", | |
| 23 | - "style": { | |
| 24 | - "navigationStyle": "custom" | |
| 25 | - } | |
| 26 | - },{ | |
| 27 | - "path": "pages/apply/apply", | |
| 28 | - "style": { | |
| 29 | - "navigationBarTitleText": "申请记录", | |
| 30 | - "navigationBarBackgroundColor": "#FFFFFF" | |
| 31 | - } | |
| 32 | - },{ | |
| 33 | - "path": "pages/shops/shops", | |
| 34 | - "style": { | |
| 35 | - "navigationBarTitleText": "租商铺", | |
| 36 | - "navigationBarBackgroundColor": "#FFFFFF" | |
| 37 | - } | |
| 38 | - },{ | |
| 39 | - "path": "pages/applyDetail/applyDetail", | |
| 40 | - "style": { | |
| 41 | - "navigationBarTitleText": "详情", | |
| 42 | - "navigationBarBackgroundColor": "#FFFFFF" | |
| 43 | - } | |
| 44 | - },{ | |
| 45 | - "path": "pages/message/message", | |
| 46 | - "style": { | |
| 47 | - "navigationStyle": "custom" | |
| 48 | - } | |
| 49 | - },{ | |
| 50 | - "path": "pages/field/field", | |
| 51 | - "style": { | |
| 52 | - "navigationBarTitleText": "租场地", | |
| 53 | - "navigationBarBackgroundColor": "#FFFFFF" | |
| 54 | - } | |
| 55 | - },{ | |
| 56 | - "path": "pages/advertisementDetail/advertisementDetail", | |
| 57 | - "style": { | |
| 58 | - "navigationBarTitleText": "详情", | |
| 59 | - "navigationBarBackgroundColor": "#FFFFFF" | |
| 60 | - } | |
| 61 | - },{ | |
| 62 | - "path": "pages/advertisement/advertisement", | |
| 63 | - "style": { | |
| 64 | - "navigationBarTitleText": "租广告", | |
| 65 | - "navigationBarBackgroundColor": "#FFFFFF" | |
| 66 | - } | |
| 67 | - },{ | |
| 68 | - "path": "pages/details/details", | |
| 69 | - "style": { | |
| 70 | - "navigationBarTitleText": "详情", | |
| 71 | - "navigationBarBackgroundColor": "#FFFFFF" | |
| 72 | - } | |
| 73 | - },{ | |
| 74 | - "path": "pages/leaseAdd/leaseAdd", | |
| 75 | - "style": { | |
| 76 | - "navigationBarTitleText": "申请租赁", | |
| 77 | - "navigationBarBackgroundColor": "#FFFFFF" | |
| 78 | - } | |
| 79 | - }, | |
| 80 | - { | |
| 81 | - "path": "pages/intentionApply/intentionApply", | |
| 82 | - "style": { | |
| 83 | - "navigationBarTitleText": "意向申请", | |
| 84 | - "navigationBarBackgroundColor": "#FFFFFF" | |
| 85 | - } | |
| 86 | - }, | |
| 87 | - { | |
| 88 | - "path": "pages/recordService/recordService", | |
| 89 | - "style": { | |
| 90 | - "navigationBarTitleText": "服务记录", | |
| 91 | - "navigationBarBackgroundColor": "#FFFFFF" | |
| 92 | - } | |
| 93 | - },{ | |
| 94 | - "path": "pages/activityAdd/activityAdd", | |
| 95 | - "style": { | |
| 96 | - "navigationBarTitleText": "活动申请", | |
| 97 | - "navigationBarBackgroundColor": "#FFFFFF" | |
| 98 | - } | |
| 99 | - },{ | |
| 100 | - "path": "pages/complaint/complaint", | |
| 101 | - "style": { | |
| 102 | - "navigationBarTitleText": "投诉建议", | |
| 103 | - "navigationBarBackgroundColor": "#FFFFFF" | |
| 104 | - } | |
| 105 | - },{ | |
| 106 | - "path": "pages/repair/repair", | |
| 107 | - "style": { | |
| 108 | - "navigationBarTitleText": "故障报修", | |
| 109 | - "navigationBarBackgroundColor": "#FFFFFF" | |
| 110 | - } | |
| 111 | - },{ | |
| 112 | - "path": "pages/advertisementTime/advertisementTime", | |
| 113 | - "style": { | |
| 114 | - "navigationBarTitleText": "租赁时段选择", | |
| 115 | - "navigationBarBackgroundColor": "#FFFFFF" | |
| 116 | - } | |
| 117 | - },{ | |
| 118 | - "path": "pages/advertisementAdd/advertisementAdd", | |
| 119 | - "style": { | |
| 120 | - "navigationBarTitleText": "广告申请", | |
| 121 | - "navigationBarBackgroundColor": "#FFFFFF" | |
| 122 | - } | |
| 123 | - }, | |
| 124 | - { | |
| 125 | - "path": "pages/participation/participation", | |
| 126 | - "style": { | |
| 127 | - "navigationBarTitleText": "活动参与", | |
| 128 | - "navigationBarBackgroundColor": "#fff", | |
| 129 | - "enablePullDownRefresh": true | |
| 130 | - } | |
| 131 | - }, | |
| 132 | - { | |
| 133 | - "path": "pages/questionnaire/questionnaire", | |
| 134 | - "style": { | |
| 135 | - "navigationBarTitleText": "问卷调查", | |
| 136 | - "navigationBarBackgroundColor": "#FFFFFF" | |
| 137 | - } | |
| 138 | - }, | |
| 139 | - { | |
| 140 | - "path": "pages/createQuestionnaire/createQuestionnaire", | |
| 141 | - "style": { | |
| 142 | - "navigationBarTitleText": "创建问卷", | |
| 143 | - "navigationBarBackgroundColor": "#FFFFFF" | |
| 144 | - } | |
| 145 | - }, | |
| 146 | - { | |
| 147 | - "path": "pages/mycreated/mycreated", | |
| 148 | - "style": { | |
| 149 | - "navigationBarTitleText": "我的活动申请", | |
| 150 | - "navigationBarBackgroundColor": "#FFFFFF", | |
| 151 | - "enablePullDownRefresh": true | |
| 152 | - } | |
| 153 | - }, | |
| 154 | - { | |
| 155 | - "path": "pages/record/record", | |
| 156 | - "style": { | |
| 157 | - "navigationBarTitleText": "申请记录", | |
| 158 | - "navigationBarBackgroundColor": "#FFFFFF" | |
| 159 | - } | |
| 160 | - }, | |
| 161 | - { | |
| 162 | - "path": "pages/accepting/accepting", | |
| 163 | - "style": { | |
| 164 | - "navigationBarTitleText": "详情", | |
| 165 | - "navigationBarBackgroundColor": "#FFFFFF" | |
| 166 | - } | |
| 167 | - }, | |
| 168 | - { | |
| 169 | - "path": "pages/servicerecords/servicerecords", | |
| 170 | - "style": { | |
| 171 | - "navigationBarTitleText": "服务记录", | |
| 172 | - "navigationBarBackgroundColor": "#FFFFFF" | |
| 173 | - } | |
| 174 | - }, | |
| 175 | - { | |
| 176 | - "path": "pages/servicedetails/servicedetails", | |
| 177 | - "style": { | |
| 178 | - "navigationBarTitleText": "详情", | |
| 179 | - "navigationBarBackgroundColor": "#FFFFFF" | |
| 180 | - } | |
| 181 | - }, | |
| 182 | - { | |
| 183 | - "path": "pages/application/application", | |
| 184 | - "style": { | |
| 185 | - "navigationBarTitleText": "推广方案申请", | |
| 186 | - "navigationBarBackgroundColor": "#FFFFFF" | |
| 187 | - } | |
| 188 | - }, | |
| 189 | - { | |
| 190 | - "path": "pages/projectManagement/projectManagement", | |
| 191 | - "style": { | |
| 192 | - "navigationBarTitleText": "推广方案管理", | |
| 193 | - "navigationBarBackgroundColor": "#FFFFFF" | |
| 194 | - } | |
| 195 | - }, | |
| 196 | - { | |
| 197 | - "path": "pages/shopjcMsg/shopjcMsg", | |
| 198 | - "style": { | |
| 199 | - "navigationBarTitleText": "商家基本信息", | |
| 200 | - "navigationBarBackgroundColor": "#FFFFFF" | |
| 201 | - } | |
| 202 | - }, | |
| 203 | - { | |
| 204 | - "path": "pages/procedure/procedure", | |
| 205 | - "style": { | |
| 206 | - "navigationBarTitleText": "公告通知", | |
| 207 | - "navigationBarBackgroundColor": "#FFFFFF" | |
| 208 | - } | |
| 209 | - }, | |
| 210 | - { | |
| 211 | - "path": "pages/salesReporting/salesReporting", | |
| 212 | - "style": { | |
| 213 | - "navigationBarTitleText": "销售上报", | |
| 214 | - "navigationBarBackgroundColor": "#FFFFFF" | |
| 215 | - } | |
| 216 | - }, | |
| 217 | - { | |
| 218 | - "path": "pages/orderList/orderList", | |
| 219 | - "style": { | |
| 220 | - "navigationBarTitleText": "订单查询", | |
| 221 | - "navigationBarBackgroundColor": "#FFFFFF" | |
| 222 | - } | |
| 223 | - }, | |
| 224 | - { | |
| 225 | - "path": "pages/salesSta/salesSta", | |
| 226 | - "style": { | |
| 227 | - "navigationBarTitleText": "销售统计", | |
| 228 | - "navigationBarBackgroundColor": "#FFFFFF" | |
| 229 | - } | |
| 230 | - }, | |
| 231 | - { | |
| 232 | - "path": "pages/Iproposal/Iproposal", | |
| 233 | - "style": { | |
| 234 | - "navigationBarTitleText": "招商方案", | |
| 235 | - "navigationBarBackgroundColor": "#FFFFFF" | |
| 236 | - } | |
| 237 | - }, | |
| 238 | - // 营销推广活动 | |
| 239 | - { | |
| 240 | - "path": "pages/marketing/marketingList/marketingList", | |
| 241 | - "style": { | |
| 242 | - "navigationBarTitleText": "营销推广活动", | |
| 243 | - "navigationBarBackgroundColor": "#FFFFFF" | |
| 244 | - } | |
| 245 | - }, | |
| 246 | - { | |
| 247 | - "path": "pages/marketing/marketingDetail/marketingDetail", | |
| 248 | - "style": { | |
| 249 | - "navigationBarTitleText": "详情", | |
| 250 | - "navigationBarBackgroundColor": "#FFFFFF" | |
| 251 | - } | |
| 252 | - }, | |
| 253 | - // 商务合作 | |
| 254 | - { | |
| 255 | - "path": "pages/business/businessList/businessList", | |
| 256 | - "style": { | |
| 257 | - "navigationBarTitleText": "商务合作", | |
| 258 | - "navigationBarBackgroundColor": "#FFFFFF" | |
| 259 | - } | |
| 260 | - }, | |
| 261 | - { | |
| 262 | - "path": "pages/business/businessDetail/businessDetail", | |
| 263 | - "style": { | |
| 264 | - "navigationBarTitleText": "详情", | |
| 265 | - "navigationBarBackgroundColor": "#FFFFFF" | |
| 266 | - } | |
| 267 | - }, | |
| 268 | - // 物业缴费 | |
| 269 | - { | |
| 270 | - "path": "pages/propertyPay/propertyPayList/propertyPayList", | |
| 271 | - "style": { | |
| 272 | - "navigationBarTitleText": "物业缴费", | |
| 273 | - "navigationBarBackgroundColor": "#FFFFFF" | |
| 274 | - } | |
| 275 | - }, | |
| 276 | - { | |
| 277 | - "path": "pages/propertyPay/payRecord/payRecord", | |
| 278 | - "style": { | |
| 279 | - "navigationBarTitleText": "缴费记录", | |
| 280 | - "navigationBarBackgroundColor": "#FFFFFF" | |
| 281 | - } | |
| 282 | - }, | |
| 283 | - { | |
| 284 | - "path": "pages/propertyPay/payDetail/payDetail", | |
| 285 | - "style": { | |
| 286 | - "navigationBarTitleText": "缴费记录", | |
| 287 | - "navigationBarBackgroundColor": "#FFFFFF" | |
| 288 | - } | |
| 289 | - } | |
| 290 | - ], | |
| 291 | - "globalStyle": { | |
| 292 | - "navigationBarTextStyle": "black" | |
| 293 | - }, | |
| 294 | - "tabBar": { | |
| 295 | - "custom": true, | |
| 296 | - "selectedColor": "#F15A29", | |
| 297 | - "backgroundColor": "#fff", | |
| 298 | - "list": [{ | |
| 299 | - "iconPath": "/static/tabbar/tab_01.png", | |
| 300 | - "selectedIconPath": "/static/tabbar/tab_02.png", | |
| 301 | - "pagePath": "pages/home/home", | |
| 302 | - "text": "" | |
| 303 | - }, | |
| 304 | - { | |
| 305 | - "selectedIconPath": "/static/tabbar/tab_03.png", | |
| 306 | - "iconPath": "/static/tabbar/tab_04.png", | |
| 307 | - "pagePath": "pages/workbench/workbench", | |
| 308 | - "text": "" | |
| 309 | - }, | |
| 310 | - { | |
| 311 | - "iconPath": "/static/tabbar/tab_05.png", | |
| 312 | - "selectedIconPath": "/static/tabbar/tab_06.png", | |
| 313 | - "pagePath": "pages/message/message", | |
| 314 | - "text": "" | |
| 315 | - }, | |
| 316 | - { | |
| 317 | - "iconPath": "/static/tabbar/tab_07.png", | |
| 318 | - "selectedIconPath": "/static/tabbar/tab_08.png", | |
| 319 | - "pagePath": "pages/my/my", | |
| 320 | - "text": "" | |
| 321 | - } | |
| 322 | - ] | |
| 323 | - } | |
| 324 | -} | |
| 1 | +{ | |
| 2 | + "easycom": { | |
| 3 | + "^u-(.*)": "uview-ui/components/u-$1/u-$1.vue" | |
| 4 | + }, | |
| 5 | + "pages": [ | |
| 6 | + { | |
| 7 | + "path": "pages/home/home", | |
| 8 | + "style": { | |
| 9 | + "navigationStyle": "custom" | |
| 10 | + } | |
| 11 | + }, | |
| 12 | + { | |
| 13 | + "path": "pages/login/login", | |
| 14 | + "style": { | |
| 15 | + "navigationStyle": "custom" | |
| 16 | + } | |
| 17 | + }, | |
| 18 | + { | |
| 19 | + "path": "pages/workbench/workbench", | |
| 20 | + "style": { | |
| 21 | + "navigationStyle": "custom" | |
| 22 | + } | |
| 23 | + }, | |
| 24 | + { | |
| 25 | + "path": "pages/my/my", | |
| 26 | + "style": { | |
| 27 | + "navigationStyle": "custom" | |
| 28 | + } | |
| 29 | + }, | |
| 30 | + { | |
| 31 | + "path": "pages/apply/apply", | |
| 32 | + "style": { | |
| 33 | + "navigationBarTitleText": "申请记录", | |
| 34 | + "navigationBarBackgroundColor": "#FFFFFF" | |
| 35 | + } | |
| 36 | + }, | |
| 37 | + { | |
| 38 | + "path": "pages/shops/shops", | |
| 39 | + "style": { | |
| 40 | + "navigationBarTitleText": "租商铺", | |
| 41 | + "navigationBarBackgroundColor": "#FFFFFF" | |
| 42 | + } | |
| 43 | + }, | |
| 44 | + { | |
| 45 | + "path": "pages/applyDetail/applyDetail", | |
| 46 | + "style": { | |
| 47 | + "navigationBarTitleText": "详情", | |
| 48 | + "navigationBarBackgroundColor": "#FFFFFF" | |
| 49 | + } | |
| 50 | + }, | |
| 51 | + { | |
| 52 | + "path": "pages/message/message", | |
| 53 | + "style": { | |
| 54 | + "navigationStyle": "custom" | |
| 55 | + } | |
| 56 | + }, | |
| 57 | + { | |
| 58 | + "path": "pages/field/field", | |
| 59 | + "style": { | |
| 60 | + "navigationBarTitleText": "租场地", | |
| 61 | + "navigationBarBackgroundColor": "#FFFFFF" | |
| 62 | + } | |
| 63 | + }, | |
| 64 | + { | |
| 65 | + "path": "pages/advertisementDetail/advertisementDetail", | |
| 66 | + "style": { | |
| 67 | + "navigationBarTitleText": "详情", | |
| 68 | + "navigationBarBackgroundColor": "#FFFFFF" | |
| 69 | + } | |
| 70 | + }, | |
| 71 | + { | |
| 72 | + "path": "pages/advertisement/advertisement", | |
| 73 | + "style": { | |
| 74 | + "navigationBarTitleText": "租广告", | |
| 75 | + "navigationBarBackgroundColor": "#FFFFFF" | |
| 76 | + } | |
| 77 | + }, | |
| 78 | + { | |
| 79 | + "path": "pages/details/details", | |
| 80 | + "style": { | |
| 81 | + "navigationBarTitleText": "详情", | |
| 82 | + "navigationBarBackgroundColor": "#FFFFFF" | |
| 83 | + } | |
| 84 | + }, | |
| 85 | + { | |
| 86 | + "path": "pages/leaseAdd/leaseAdd", | |
| 87 | + "style": { | |
| 88 | + "navigationBarTitleText": "申请租赁", | |
| 89 | + "navigationBarBackgroundColor": "#FFFFFF" | |
| 90 | + } | |
| 91 | + }, | |
| 92 | + { | |
| 93 | + "path": "pages/intentionApply/intentionApply", | |
| 94 | + "style": { | |
| 95 | + "navigationBarTitleText": "意向申请", | |
| 96 | + "navigationBarBackgroundColor": "#FFFFFF" | |
| 97 | + } | |
| 98 | + }, | |
| 99 | + { | |
| 100 | + "path": "pages/recordService/recordService", | |
| 101 | + "style": { | |
| 102 | + "navigationBarTitleText": "服务记录", | |
| 103 | + "navigationBarBackgroundColor": "#FFFFFF" | |
| 104 | + } | |
| 105 | + }, | |
| 106 | + { | |
| 107 | + "path": "pages/activityAdd/activityAdd", | |
| 108 | + "style": { | |
| 109 | + "navigationBarTitleText": "活动申请", | |
| 110 | + "navigationBarBackgroundColor": "#FFFFFF" | |
| 111 | + } | |
| 112 | + }, | |
| 113 | + { | |
| 114 | + "path": "pages/complaint/complaint", | |
| 115 | + "style": { | |
| 116 | + "navigationBarTitleText": "投诉建议", | |
| 117 | + "navigationBarBackgroundColor": "#FFFFFF" | |
| 118 | + } | |
| 119 | + }, | |
| 120 | + { | |
| 121 | + "path": "pages/repair/repair", | |
| 122 | + "style": { | |
| 123 | + "navigationBarTitleText": "故障报修", | |
| 124 | + "navigationBarBackgroundColor": "#FFFFFF" | |
| 125 | + } | |
| 126 | + }, | |
| 127 | + { | |
| 128 | + "path": "pages/advertisementTime/advertisementTime", | |
| 129 | + "style": { | |
| 130 | + "enablePullDownRefresh": false, | |
| 131 | + "navigationBarTitleText": "投放时段", | |
| 132 | + "navigationBarBackgroundColor": "#FFFFFF" | |
| 133 | + } | |
| 134 | + }, | |
| 135 | + { | |
| 136 | + "path": "pages/advertisementAdd/advertisementAdd", | |
| 137 | + "style": { | |
| 138 | + "navigationBarTitleText": "广告申请", | |
| 139 | + "navigationBarBackgroundColor": "#FFFFFF" | |
| 140 | + } | |
| 141 | + }, | |
| 142 | + { | |
| 143 | + "path": "pages/participation/participation", | |
| 144 | + "style": { | |
| 145 | + "navigationBarTitleText": "活动参与", | |
| 146 | + "navigationBarBackgroundColor": "#fff", | |
| 147 | + "enablePullDownRefresh": true | |
| 148 | + } | |
| 149 | + }, | |
| 150 | + { | |
| 151 | + "path": "pages/questionnaire/questionnaire", | |
| 152 | + "style": { | |
| 153 | + "navigationBarTitleText": "问卷调查", | |
| 154 | + "navigationBarBackgroundColor": "#FFFFFF" | |
| 155 | + } | |
| 156 | + }, | |
| 157 | + { | |
| 158 | + "path": "pages/createQuestionnaire/createQuestionnaire", | |
| 159 | + "style": { | |
| 160 | + "navigationBarTitleText": "创建问卷", | |
| 161 | + "navigationBarBackgroundColor": "#FFFFFF" | |
| 162 | + } | |
| 163 | + }, | |
| 164 | + { | |
| 165 | + "path": "pages/mycreated/mycreated", | |
| 166 | + "style": { | |
| 167 | + "navigationBarTitleText": "我的活动申请", | |
| 168 | + "navigationBarBackgroundColor": "#FFFFFF", | |
| 169 | + "enablePullDownRefresh": true | |
| 170 | + } | |
| 171 | + }, | |
| 172 | + { | |
| 173 | + "path": "pages/record/record", | |
| 174 | + "style": { | |
| 175 | + "navigationBarTitleText": "申请记录", | |
| 176 | + "navigationBarBackgroundColor": "#FFFFFF" | |
| 177 | + } | |
| 178 | + }, | |
| 179 | + { | |
| 180 | + "path": "pages/accepting/accepting", | |
| 181 | + "style": { | |
| 182 | + "navigationBarTitleText": "详情", | |
| 183 | + "navigationBarBackgroundColor": "#FFFFFF" | |
| 184 | + } | |
| 185 | + }, | |
| 186 | + { | |
| 187 | + "path": "pages/servicerecords/servicerecords", | |
| 188 | + "style": { | |
| 189 | + "navigationBarTitleText": "服务记录", | |
| 190 | + "navigationBarBackgroundColor": "#FFFFFF" | |
| 191 | + } | |
| 192 | + }, | |
| 193 | + { | |
| 194 | + "path": "pages/servicedetails/servicedetails", | |
| 195 | + "style": { | |
| 196 | + "navigationBarTitleText": "详情", | |
| 197 | + "navigationBarBackgroundColor": "#FFFFFF" | |
| 198 | + } | |
| 199 | + }, | |
| 200 | + { | |
| 201 | + "path": "pages/application/application", | |
| 202 | + "style": { | |
| 203 | + "navigationBarTitleText": "推广方案申请", | |
| 204 | + "navigationBarBackgroundColor": "#FFFFFF" | |
| 205 | + } | |
| 206 | + }, | |
| 207 | + { | |
| 208 | + "path": "pages/projectManagement/projectManagement", | |
| 209 | + "style": { | |
| 210 | + "navigationBarTitleText": "推广方案管理", | |
| 211 | + "navigationBarBackgroundColor": "#FFFFFF" | |
| 212 | + } | |
| 213 | + }, | |
| 214 | + { | |
| 215 | + "path": "pages/shopjcMsg/shopjcMsg", | |
| 216 | + "style": { | |
| 217 | + "navigationBarTitleText": "商家基本信息", | |
| 218 | + "navigationBarBackgroundColor": "#FFFFFF" | |
| 219 | + } | |
| 220 | + }, | |
| 221 | + { | |
| 222 | + "path": "pages/procedure/procedure", | |
| 223 | + "style": { | |
| 224 | + "navigationBarTitleText": "公告通知", | |
| 225 | + "navigationBarBackgroundColor": "#FFFFFF" | |
| 226 | + } | |
| 227 | + }, | |
| 228 | + { | |
| 229 | + "path": "pages/salesReporting/salesReporting", | |
| 230 | + "style": { | |
| 231 | + "navigationBarTitleText": "销售上报", | |
| 232 | + "navigationBarBackgroundColor": "#FFFFFF" | |
| 233 | + } | |
| 234 | + }, | |
| 235 | + { | |
| 236 | + "path": "pages/orderList/orderList", | |
| 237 | + "style": { | |
| 238 | + "navigationBarTitleText": "订单查询", | |
| 239 | + "navigationBarBackgroundColor": "#FFFFFF" | |
| 240 | + } | |
| 241 | + }, | |
| 242 | + { | |
| 243 | + "path": "pages/salesSta/salesSta", | |
| 244 | + "style": { | |
| 245 | + "navigationBarTitleText": "销售统计", | |
| 246 | + "navigationBarBackgroundColor": "#FFFFFF" | |
| 247 | + } | |
| 248 | + }, | |
| 249 | + { | |
| 250 | + "path": "pages/Iproposal/Iproposal", | |
| 251 | + "style": { | |
| 252 | + "navigationBarTitleText": "招商方案", | |
| 253 | + "navigationBarBackgroundColor": "#FFFFFF" | |
| 254 | + } | |
| 255 | + }, | |
| 256 | + { | |
| 257 | + "path": "pages/marketing/marketingList/marketingList", | |
| 258 | + "style": { | |
| 259 | + "navigationBarTitleText": "营销推广活动", | |
| 260 | + "navigationBarBackgroundColor": "#FFFFFF" | |
| 261 | + } | |
| 262 | + }, | |
| 263 | + { | |
| 264 | + "path": "pages/marketing/marketingDetail/marketingDetail", | |
| 265 | + "style": { | |
| 266 | + "navigationBarTitleText": "详情", | |
| 267 | + "navigationBarBackgroundColor": "#FFFFFF" | |
| 268 | + } | |
| 269 | + }, | |
| 270 | + { | |
| 271 | + "path": "pages/business/businessList/businessList", | |
| 272 | + "style": { | |
| 273 | + "navigationBarTitleText": "商务合作", | |
| 274 | + "navigationBarBackgroundColor": "#FFFFFF" | |
| 275 | + } | |
| 276 | + }, | |
| 277 | + { | |
| 278 | + "path": "pages/business/businessDetail/businessDetail", | |
| 279 | + "style": { | |
| 280 | + "navigationBarTitleText": "详情", | |
| 281 | + "navigationBarBackgroundColor": "#FFFFFF" | |
| 282 | + } | |
| 283 | + }, | |
| 284 | + { | |
| 285 | + "path": "pages/propertyPay/propertyPayList/propertyPayList", | |
| 286 | + "style": { | |
| 287 | + "navigationBarTitleText": "物业缴费", | |
| 288 | + "navigationBarBackgroundColor": "#FFFFFF" | |
| 289 | + } | |
| 290 | + }, | |
| 291 | + { | |
| 292 | + "path": "pages/propertyPay/payRecord/payRecord", | |
| 293 | + "style": { | |
| 294 | + "navigationBarTitleText": "缴费记录", | |
| 295 | + "navigationBarBackgroundColor": "#FFFFFF" | |
| 296 | + } | |
| 297 | + }, | |
| 298 | + { | |
| 299 | + "path": "pages/propertyPay/payDetail/payDetail", | |
| 300 | + "style": { | |
| 301 | + "navigationBarTitleText": "缴费记录", | |
| 302 | + "navigationBarBackgroundColor": "#FFFFFF" | |
| 303 | + } | |
| 304 | + } | |
| 305 | + | |
| 306 | + ], | |
| 307 | + "globalStyle": { | |
| 308 | + "navigationBarTextStyle": "black" | |
| 309 | + }, | |
| 310 | + "tabBar": { | |
| 311 | + "custom": true, | |
| 312 | + "selectedColor": "#F15A29", | |
| 313 | + "backgroundColor": "#fff", | |
| 314 | + "list": [ | |
| 315 | + { | |
| 316 | + "iconPath": "/static/tabbar/tab_01.png", | |
| 317 | + "selectedIconPath": "/static/tabbar/tab_02.png", | |
| 318 | + "pagePath": "pages/home/home", | |
| 319 | + "text": "" | |
| 320 | + }, | |
| 321 | + { | |
| 322 | + "selectedIconPath": "/static/tabbar/tab_03.png", | |
| 323 | + "iconPath": "/static/tabbar/tab_04.png", | |
| 324 | + "pagePath": "pages/workbench/workbench", | |
| 325 | + "text": "" | |
| 326 | + }, | |
| 327 | + { | |
| 328 | + "iconPath": "/static/tabbar/tab_05.png", | |
| 329 | + "selectedIconPath": "/static/tabbar/tab_06.png", | |
| 330 | + "pagePath": "pages/message/message", | |
| 331 | + "text": "" | |
| 332 | + }, | |
| 333 | + { | |
| 334 | + "iconPath": "/static/tabbar/tab_07.png", | |
| 335 | + "selectedIconPath": "/static/tabbar/tab_08.png", | |
| 336 | + "pagePath": "pages/my/my", | |
| 337 | + "text": "" | |
| 338 | + } | |
| 339 | + ] | |
| 340 | + } | |
| 341 | +} | |
| 325 | 342 | \ No newline at end of file | ... | ... |
uniCloud-tcb/cloudfunctions/usp-test/index.js
0 → 100644
uniCloud-tcb/cloudfunctions/usp-test/package.json
0 → 100644
uni_modules/wn-calendar/components/wn-calendar/calendar.js
0 → 100644
| 1 | +/** | |
| 2 | + * | |
| 3 | + */ | |
| 4 | + | |
| 5 | +function getDays(year, month, data, isLess) { | |
| 6 | + if (!Array.isArray(data)) { | |
| 7 | + data = [] | |
| 8 | + } | |
| 9 | + | |
| 10 | + let today = new Date() | |
| 11 | + | |
| 12 | + let y, m | |
| 13 | + if (typeof(year) === 'number' && year > 2000 && typeof(month) === 'number') { | |
| 14 | + const d = new Date(year, month - 1) | |
| 15 | + y = d.getFullYear() | |
| 16 | + m = d.getMonth() | |
| 17 | + } else { | |
| 18 | + y = today.getFullYear() | |
| 19 | + m = today.getMonth() | |
| 20 | + } | |
| 21 | + | |
| 22 | + let st = new Date(y, m, 1).getDay(), | |
| 23 | + ed = new Date(y, m + 1, 0).getDay(), | |
| 24 | + len = new Date(y, m + 1, 0).getDate() | |
| 25 | + | |
| 26 | + let isfill = data.length > 0 | |
| 27 | + let days = Array.from(new Array(len), (x, i) => { | |
| 28 | + i = i + 1 | |
| 29 | + const date = `${y}/${m+1}/${i}` | |
| 30 | + x = null | |
| 31 | + if (isfill) { | |
| 32 | + x = data.find(item => item.date === date) | |
| 33 | + } | |
| 34 | + return { | |
| 35 | + show: true, | |
| 36 | + label: i, | |
| 37 | + date, | |
| 38 | + data: x | |
| 39 | + } | |
| 40 | + }) | |
| 41 | + | |
| 42 | + let prev = new Date(y, m - 1), | |
| 43 | + prevDate = `${prev.getFullYear()}/${prev.getMonth()+1}`, | |
| 44 | + prevLd = new Date(y, m, 0).getDate() | |
| 45 | + let prevDays = Array.from(new Array(st), (x, i) => { | |
| 46 | + i = prevLd - (st - 1 - i) | |
| 47 | + return { | |
| 48 | + show: false, | |
| 49 | + label: isLess ? '' : i, | |
| 50 | + date: `${prevDate}/${i}` | |
| 51 | + } | |
| 52 | + }) | |
| 53 | + days = prevDays.concat(days) | |
| 54 | + | |
| 55 | + let next = new Date(y, m + 1), | |
| 56 | + nextDate = `${next.getFullYear()}/${next.getMonth()+1}` | |
| 57 | + let lened = (days.length <= 35 ? 7 : 0) + (6 - ed) | |
| 58 | + if (isLess) { | |
| 59 | + lened = 6 - ed | |
| 60 | + } | |
| 61 | + let nextDays = Array.from(new Array(lened), (x, i) => { | |
| 62 | + i = i + 1 | |
| 63 | + return { | |
| 64 | + show: false, | |
| 65 | + label: isLess ? '' : i, | |
| 66 | + date: `${nextDate}/${i}` | |
| 67 | + } | |
| 68 | + }) | |
| 69 | + days = days.concat(nextDays) | |
| 70 | + | |
| 71 | + days = days.concat(Array.from(new Array(42 - days.length), (x, i) => { | |
| 72 | + return { | |
| 73 | + show: false, | |
| 74 | + label: '', | |
| 75 | + date: `*${i}` | |
| 76 | + } | |
| 77 | + })) | |
| 78 | + | |
| 79 | + return { | |
| 80 | + days, | |
| 81 | + year: y, | |
| 82 | + month: m | |
| 83 | + } | |
| 84 | +} | |
| 85 | + | |
| 86 | +function getEn (m) { | |
| 87 | + const en = [ | |
| 88 | + 'Jan', | |
| 89 | + 'Feb', | |
| 90 | + 'Mar', | |
| 91 | + 'Apr', | |
| 92 | + 'May', | |
| 93 | + 'Jun', | |
| 94 | + 'Jul', | |
| 95 | + 'Aug', | |
| 96 | + 'Sept', | |
| 97 | + 'Oct', | |
| 98 | + 'Nov', | |
| 99 | + 'Dec', | |
| 100 | + ] | |
| 101 | + return en[m - 1] | |
| 102 | +} | |
| 103 | + | |
| 104 | +const labels_en = [ | |
| 105 | + 'Sun', | |
| 106 | + 'Mon', | |
| 107 | + 'Tues', | |
| 108 | + 'Wed', | |
| 109 | + 'Thur', | |
| 110 | + 'Fri', | |
| 111 | + 'Sat', | |
| 112 | +] | |
| 113 | + | |
| 114 | +const labels_zh = [ | |
| 115 | + '日', | |
| 116 | + '一', | |
| 117 | + '二', | |
| 118 | + '三', | |
| 119 | + '四', | |
| 120 | + '五', | |
| 121 | + '六', | |
| 122 | +] | |
| 123 | + | |
| 124 | +export default { | |
| 125 | + getDays, | |
| 126 | + getEn, | |
| 127 | + labels_en, | |
| 128 | + labels_zh | |
| 129 | +} | |
| 0 | 130 | \ No newline at end of file | ... | ... |
uni_modules/wn-calendar/components/wn-calendar/wn-calendar.vue
0 → 100644
| 1 | +<template> | |
| 2 | + <view class="wn-calendar"> | |
| 3 | + | |
| 4 | + <view class="head"> | |
| 5 | + <image @click="onChange('prev')" | |
| 6 | + src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAADAAAAAwCAYAAABXAvmHAAAAAXNSR0IArs4c6QAAAY5JREFUaEPtmEtugzAQhsc3aW5SbhI2SSOVCJ+g6QmoQqWWbspRcpNyELArQojUVqmw52EswYaNH/PNP57xWEHkn4rcflgAQiu4KBC9AsXxYw2qa6CFRutdIw2ECqGirA4K4GkwWp1s26XSECiAl7KyPzxuobGdSSQhaAF6GmEIegBhCB6AS1xZMInOdifOg80KcBbDqlTvNzUXBDvAEFHwrLPtgQNCBIATQgxghIDW1JRpVhSAA0IcgLpqBwKgu3oEBKCp2mEBCKp2eICxardm5ZOdZgMwiOF+9ZgVQN9T5NkmcanY8wKw0OT77SpaAJ+L32wU8In/czVxkev32D8tpedivsaHB+jbT2VSTNMTTgEC4wMq4J4ub0VnAAXojA+gAK3xsgDK1vnjQ+qZqG5OEwmhqJt6TI6foharAtzGs54BCeN5AIgK1JTwwQMcqy9QcHfdTPhlGg/w+v4JVq3HpxLXZmSql/8bhzrE/cJF+Xbf/zEXMgwIGgCzOcXcBYDCi5g1FgUw3qOYG70C39PtD0Aq3TXKAAAAAElFTkSuQmCC" | |
| 7 | + class="arrow left" mode="aspectFit"></image> | |
| 8 | + <text class="t">{{headText}}</text> | |
| 9 | + <image @click="onChange('next')" | |
| 10 | + src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAADAAAAAwCAYAAABXAvmHAAAAAXNSR0IArs4c6QAAAY5JREFUaEPtmEtugzAQhsc3aW5SbhI2SSOVCJ+g6QmoQqWWbspRcpNyELArQojUVqmw52EswYaNH/PNP57xWEHkn4rcflgAQiu4KBC9AsXxYw2qa6CFRutdIw2ECqGirA4K4GkwWp1s26XSECiAl7KyPzxuobGdSSQhaAF6GmEIegBhCB6AS1xZMInOdifOg80KcBbDqlTvNzUXBDvAEFHwrLPtgQNCBIATQgxghIDW1JRpVhSAA0IcgLpqBwKgu3oEBKCp2mEBCKp2eICxardm5ZOdZgMwiOF+9ZgVQN9T5NkmcanY8wKw0OT77SpaAJ+L32wU8In/czVxkev32D8tpedivsaHB+jbT2VSTNMTTgEC4wMq4J4ub0VnAAXojA+gAK3xsgDK1vnjQ+qZqG5OEwmhqJt6TI6foharAtzGs54BCeN5AIgK1JTwwQMcqy9QcHfdTPhlGg/w+v4JVq3HpxLXZmSql/8bhzrE/cJF+Xbf/zEXMgwIGgCzOcXcBYDCi5g1FgUw3qOYG70C39PtD0Aq3TXKAAAAAElFTkSuQmCC" | |
| 11 | + class="arrow" mode="aspectFit"></image> | |
| 12 | + </view> | |
| 13 | + | |
| 14 | + <view class="labels"> | |
| 15 | + <view class="label-item" v-for="(label) in labels" :key="label"> | |
| 16 | + <text class="t">{{label}}</text> | |
| 17 | + </view> | |
| 18 | + </view> | |
| 19 | + | |
| 20 | + <view :class="['row', isBorder ? 'border' : '']" v-for="row in rows"> | |
| 21 | + <view @click="onChoose(item)" :class="[ | |
| 22 | + 'day-item', | |
| 23 | + item.show ? 'show' : '', | |
| 24 | + active === item.date ? 'active' : '' | |
| 25 | + ]" v-for="(item, ind) in days.slice(row*7, (row+1)*7)" :key="item.date"> | |
| 26 | + <text class="t">{{item.label}}</text> | |
| 27 | + <text v-if="item.data && item.data.text" class="data" | |
| 28 | + :style="`color: ${colors[item.data.type] || '#f3a73f'};`">{{item.data.text}}</text> | |
| 29 | + </view> | |
| 30 | + | |
| 31 | + </view> | |
| 32 | + </view> | |
| 33 | +</template> | |
| 34 | + | |
| 35 | +<script> | |
| 36 | + import calendar from './calendar' | |
| 37 | + export default { | |
| 38 | + name: "w-calendar", | |
| 39 | + emits: ['choose', 'change'], | |
| 40 | + props: { | |
| 41 | + data: { | |
| 42 | + type: Array, | |
| 43 | + default () { | |
| 44 | + return [] | |
| 45 | + } | |
| 46 | + }, | |
| 47 | + colors: { | |
| 48 | + type: Array, | |
| 49 | + default () { | |
| 50 | + return ['#2979ff', '#18bc37', '#f3a73f', '#e43d33', '#8f939c'] | |
| 51 | + } | |
| 52 | + }, | |
| 53 | + format: { | |
| 54 | + type: String, | |
| 55 | + default: '' | |
| 56 | + }, | |
| 57 | + isLess: { | |
| 58 | + type: Boolean, | |
| 59 | + default: false | |
| 60 | + }, | |
| 61 | + isBorder: { | |
| 62 | + type: Boolean, | |
| 63 | + default: true | |
| 64 | + }, | |
| 65 | + isEn: { | |
| 66 | + type: Boolean, | |
| 67 | + default: false | |
| 68 | + } | |
| 69 | + }, | |
| 70 | + computed: { | |
| 71 | + headText() { | |
| 72 | + if (this.format === '/') { | |
| 73 | + return `${this.year}/${this.month}` | |
| 74 | + } else { | |
| 75 | + if (this.isEn) { | |
| 76 | + return `${calendar.getEn(this.month)}, ${this.year}` | |
| 77 | + } else { | |
| 78 | + return `${this.year}年${this.month}月` | |
| 79 | + } | |
| 80 | + } | |
| 81 | + } | |
| 82 | + }, | |
| 83 | + data() { | |
| 84 | + return { | |
| 85 | + labels: this.isEn ? calendar.labels_en : calendar.labels_zh, | |
| 86 | + active: '', | |
| 87 | + rows: [0, 1, 2, 3, 4, 5, 6], | |
| 88 | + days: [], | |
| 89 | + year: '', | |
| 90 | + month: '', | |
| 91 | + | |
| 92 | + }; | |
| 93 | + }, | |
| 94 | + created() { | |
| 95 | + this.refresh() | |
| 96 | + }, | |
| 97 | + methods: { | |
| 98 | + refresh() { | |
| 99 | + this.$nextTick(() => { | |
| 100 | + const {days, year, month} = calendar.getDays(this.year, this.month, this.data, this.isLess) | |
| 101 | + this.days = days | |
| 102 | + this.year = year | |
| 103 | + this.month = month + 1 | |
| 104 | + }) | |
| 105 | + }, | |
| 106 | + onChange(type) { | |
| 107 | + this.month = type === 'prev' ? (this.month - 1) : (this.month + 1) | |
| 108 | + this.refresh() | |
| 109 | + this.$nextTick(() => { | |
| 110 | + this.$emit('change', { | |
| 111 | + year: this.year, | |
| 112 | + month: this.month | |
| 113 | + }) | |
| 114 | + }) | |
| 115 | + }, | |
| 116 | + onChoose(item) { | |
| 117 | + if (!item.show) return; | |
| 118 | + this.active = item.date | |
| 119 | + this.$nextTick(() => { | |
| 120 | + this.$emit('choose', { | |
| 121 | + date: item.date, | |
| 122 | + data: item.data | |
| 123 | + }) | |
| 124 | + }) | |
| 125 | + } | |
| 126 | + } | |
| 127 | + } | |
| 128 | +</script> | |
| 129 | + | |
| 130 | +<style scoped> | |
| 131 | + .arrow { | |
| 132 | + /* #ifndef APP-NVUE */ | |
| 133 | + box-sizing: border-box; | |
| 134 | + /* #endif */ | |
| 135 | + padding: 4px; | |
| 136 | + width: 22px; | |
| 137 | + height: 22px; | |
| 138 | + background: #f7f7f7; | |
| 139 | + border-radius: 22px; | |
| 140 | + } | |
| 141 | + | |
| 142 | + .arrow.left { | |
| 143 | + transform: rotate(180deg); | |
| 144 | + } | |
| 145 | + | |
| 146 | + .wn-calendar { | |
| 147 | + min-width: 294px; | |
| 148 | + background: white; | |
| 149 | + } | |
| 150 | + | |
| 151 | + .head { | |
| 152 | + /* #ifndef APP-NVUE */ | |
| 153 | + display: flex; | |
| 154 | + /* #endif */ | |
| 155 | + flex-direction: row; | |
| 156 | + justify-content: center; | |
| 157 | + align-items: center; | |
| 158 | + padding: 8px 0px; | |
| 159 | + } | |
| 160 | + | |
| 161 | + .head .t { | |
| 162 | + padding: 0 42px; | |
| 163 | + font-size: 16px; | |
| 164 | + line-height: 32px; | |
| 165 | + color: #3a3a3a; | |
| 166 | + } | |
| 167 | + | |
| 168 | + .labels { | |
| 169 | + /* #ifndef APP-NVUE */ | |
| 170 | + box-sizing: border-box; | |
| 171 | + display: flex; | |
| 172 | + /* #endif */ | |
| 173 | + flex-direction: row; | |
| 174 | + height: 36px; | |
| 175 | + align-items: center; | |
| 176 | + background: #f7f7f7; | |
| 177 | + border-top: 1px solid #f0f0f0; | |
| 178 | + border-bottom: 1px solid #f0f0f0; | |
| 179 | + } | |
| 180 | + | |
| 181 | + .label-item { | |
| 182 | + min-width: 42px; | |
| 183 | + flex: 1; | |
| 184 | + /* #ifndef APP-NVUE */ | |
| 185 | + display: flex; | |
| 186 | + align-items: center; | |
| 187 | + justify-content: center; | |
| 188 | + /* #endif */ | |
| 189 | + } | |
| 190 | + | |
| 191 | + .label-item .t { | |
| 192 | + font-size: 14px; | |
| 193 | + text-align: center; | |
| 194 | + line-height: 14px; | |
| 195 | + color: #3a3a3a; | |
| 196 | + } | |
| 197 | + | |
| 198 | + .row { | |
| 199 | + /* #ifndef APP-NVUE */ | |
| 200 | + box-sizing: border-box; | |
| 201 | + display: flex; | |
| 202 | + /* #endif */ | |
| 203 | + flex-direction: row; | |
| 204 | + border-bottom: 1px solid transparent; | |
| 205 | + } | |
| 206 | + | |
| 207 | + .row.border { | |
| 208 | + border-bottom: 1px solid #f0f0f0; | |
| 209 | + } | |
| 210 | + | |
| 211 | + .day-item { | |
| 212 | + /* #ifndef APP-NVUE */ | |
| 213 | + box-sizing: border-box; | |
| 214 | + display: flex; | |
| 215 | + flex-direction: column; | |
| 216 | + align-items: center; | |
| 217 | + /* #endif */ | |
| 218 | + flex: 1; | |
| 219 | + justify-content: center; | |
| 220 | + padding: 7px 0px; | |
| 221 | + border-radius: 4px; | |
| 222 | + height: 42px; | |
| 223 | + min-width: 42px; | |
| 224 | + } | |
| 225 | + | |
| 226 | + .day-item.show {} | |
| 227 | + | |
| 228 | + .day-item.active { | |
| 229 | + background: #ededed !important; | |
| 230 | + } | |
| 231 | + | |
| 232 | + .day-item.active .t { | |
| 233 | + font-weight: bold !important; | |
| 234 | + } | |
| 235 | + | |
| 236 | + .day-item .t { | |
| 237 | + font-size: 15px; | |
| 238 | + line-height: 15px; | |
| 239 | + text-align: center; | |
| 240 | + color: #909399; | |
| 241 | + } | |
| 242 | + | |
| 243 | + .day-item.show .t { | |
| 244 | + color: #3a3a3a; | |
| 245 | + } | |
| 246 | + | |
| 247 | + .day-item .data { | |
| 248 | + margin-top: 2px; | |
| 249 | + font-size: 11px; | |
| 250 | + line-height: 11px; | |
| 251 | + text-align: center; | |
| 252 | + /* #ifdef APP-NVUE */ | |
| 253 | + text-overflow: clip; | |
| 254 | + word-wrap: anywhere; | |
| 255 | + /* #endif */ | |
| 256 | + color: #3a3a3a; | |
| 257 | + } | |
| 258 | +</style> | |
| 0 | 259 | \ No newline at end of file | ... | ... |
uni_modules/wn-calendar/package.json
0 → 100644
| 1 | +{ | |
| 2 | + "id": "wn-calendar", | |
| 3 | + "name": "wn-calendar", | |
| 4 | + "displayName": "wn-calendar 展示打卡日历", | |
| 5 | + "version": "1.0.0", | |
| 6 | + "description": "展示打卡日历组件 | 主打轻巧易改、支持填充文本多色彩、选中日期返回、中英语言", | |
| 7 | + "keywords": [ | |
| 8 | + "日历", | |
| 9 | + "calendar", | |
| 10 | + "日期", | |
| 11 | + "打卡", | |
| 12 | + "打点" | |
| 13 | +], | |
| 14 | + "author": "Wenyp" | |
| 15 | +} | ... | ... |