From 001f445bce48e0dfbce5204eab1712e9780cd0e5 Mon Sep 17 00:00:00 2001 From: jacky Date: Sat, 20 Apr 2024 11:35:28 +0800 Subject: [PATCH] =?UTF-8?q?=E4=BF=AE=E6=94=B9=E5=B9=BF=E5=91=8A=E7=AE=A1?= =?UTF-8?q?=E7=90=86=E4=B8=AD=E7=9A=84=E6=95=B0=E6=8D=AE=E6=A0=A1=E9=AA=8C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .eslintrc.js | 2 +- src/utils/image.js | 21 ++++++++-- src/utils/validator.js | 19 +++++++++ src/view/ad/content.vue | 43 ++++++++++++--------- src/view/ad/position.vue | 12 ++---- src/view/content/components/articleEdit.vue | 6 ++- 6 files changed, 69 insertions(+), 34 deletions(-) create mode 100644 src/utils/validator.js diff --git a/.eslintrc.js b/.eslintrc.js index 19abca3..b58b80f 100644 --- a/.eslintrc.js +++ b/.eslintrc.js @@ -222,7 +222,7 @@ module.exports = { } ], 'space-before-blocks': [2, 'always'], - 'space-before-function-paren': [2, 'always'], + 'space-before-function-paren': { anonymous: 'always', named: 'never', asyncArrow: 'always' }, 'space-in-parens': [2, 'never'], 'space-infix-ops': 2, 'space-unary-ops': [ diff --git a/src/utils/image.js b/src/utils/image.js index ccc70db..66c4679 100644 --- a/src/utils/image.js +++ b/src/utils/image.js @@ -94,10 +94,23 @@ export default class ImageCompress { const path = import.meta.env.VITE_FILE_API + '/' export const getUrl = (url) => url && url.slice(0, 4) !== 'http' ? path + url : url -export const isVideoExt = (url) => url.endsWith('.mp4') || url.endsWith('.mov') || url.endsWith('.webm') || url.endsWith('.ogg'); +export const isVideoExt = (url) => url.endsWith('.mp4') || url.endsWith('.mov') || url.endsWith('.webm') || url.endsWith('.ogg') -export const isVideoMime = (type) => type === 'video/mp4' || type === 'video/webm' || type === 'video/ogg'; +export const isVideoMime = (type) => type === 'video/mp4' || type === 'video/webm' || type === 'video/ogg' -export const isImageMime = (type) => type === 'image/jpeg' || type === 'image/png' || type === 'image/webp' || type === 'image/svg+xml'; +export const isImageMime = (type) => type === 'image/jpeg' || type === 'image/png' || type === 'image/webp' || type === 'image/svg+xml' -export const isGifMime = (type) => type === 'image/gif'; +export const isGifMime = (type) => type === 'image/gif' + +// 判断上传图片的宽高是否等于给定的宽高 +export const checkImageWHEqual = (file, width, height) => { + return new Promise(function (resolve, reject) { + const _URL = window.URL || window.webkitURL + const img = new Image() + img.onload = function () { + const valid = img.width === width && img.height === height + valid ? resolve() : reject() + } + img.src = _URL.createObjectURL(file) + }) +} diff --git a/src/utils/validator.js b/src/utils/validator.js new file mode 100644 index 0000000..20f2f48 --- /dev/null +++ b/src/utils/validator.js @@ -0,0 +1,19 @@ +export const isUrl = (rule, value, callback) => { + if (value === '') { + callback() + return + } + const pattern = /^(https?:\/\/)?((([a-z\d]([a-z\d-]*[a-z\d])*)\.)+[a-z]{2,}|((\d{1,3}\.){3}\d{1,3}))(\:\d+)?(\/[-a-z\d%_.~+]*)*(\?[;&a-z\d%_.~+=-]*)?(\#[-a-z\d_]*)?$/i + if (!pattern.test(value)) { + callback(new Error(rule.message)) + } + callback() +} + +export const isNumber = (rule, value, callback) => { + if (value <= 0) { + callback(new Error(rule.message)) + } else { + callback() + } +} diff --git a/src/view/ad/content.vue b/src/view/ad/content.vue index eb4a3e7..cb40e86 100644 --- a/src/view/ad/content.vue +++ b/src/view/ad/content.vue @@ -122,7 +122,7 @@ import { reactive, ref } from 'vue' import { ElMessage, ElMessageBox } from 'element-plus' import { formatOnlyDate } from '@/utils/format' import WarningBar from '@/components/warningBar/warningBar.vue' -import { isImageMime, isVideoMime, isGifMime } from '@/utils/image' +import { isImageMime, isVideoMime, isGifMime, checkImageWHEqual } from '@/utils/image' import { getAdContentList, addAdContent, @@ -132,10 +132,19 @@ import { getAdContentById } from '@/api/adContent' import { getAdPositionList } from '@/api/adPosition' +import { isUrl } from '@/utils/validator' const page = ref(1) const total = ref(0) const pageSize = ref(10) +const isDateEndGtStart = (rule, value, callback) => { + console.log('isDateEndGtStart', editForm.value.validStart, value) + if (value < editForm.value.validStart) { + callback(new Error(rule.message)) + } else { + callback() + } +} const rules = reactive({ adType: [ { required: true, message: '请选择广告类型', trigger: 'blur' } @@ -144,13 +153,15 @@ const rules = reactive({ { required: true, message: '请选择广告位', trigger: 'blur' } ], url: [ - { required: true, message: '请输入跳转地址', trigger: 'blur' } + { required: true, message: '请输入跳转地址', trigger: 'blur' }, + { validator: isUrl, message: '请输入正确的跳转地址', trigger: 'blur' } ], validStart: [ { required: true, message: '请选择有效起始日期', trigger: 'blur' } ], validEnd: [ - { required: true, message: '请选择有效截止日期', trigger: 'blur' } + { required: true, message: '请选择有效截止日期', trigger: 'blur' }, + { validator: isDateEndGtStart, message: '有效截止日期必须大于起始日期', trigger: 'blur' }, ], mediaUrl: [ { required: true, message: '请上传媒体信息', trigger: 'blur' } @@ -399,22 +410,16 @@ const beforeUpload = (file) => { } if (uploadInfo.value.mediaType === 'pic') { - const isSize = new Promise(function (resolve, reject) { - const width = uploadInfo.value.mediaWidth - const height = uploadInfo.value.mediaHeight - const _URL = window.URL || window.webkitURL - const img = new Image() - img.onload = function () { - const valid = img.width === width && img.height === height - valid ? resolve() : reject() - } - img.src = _URL.createObjectURL(file) - }).then(() => { - return file - }, () => { - ElMessage.error('上传文件宽X高必须为: ' + uploadInfo.value.mediaWidth + 'px X ' + uploadInfo.value.mediaHeight + 'px') - return Promise.reject() - }) + const isSize = checkImageWHEqual( + file, uploadInfo.value.mediaWidth, uploadInfo.value.mediaHeight + ).then( + () => { + return file + }, + () => { + ElMessage.error('上传文件宽*高必须为: ' + uploadInfo.value.mediaWidth + 'px*' + uploadInfo.value.mediaHeight + 'px') + return Promise.reject() + }) return isSize } diff --git a/src/view/ad/position.vue b/src/view/ad/position.vue index 6bdff98..bb5d5c2 100644 --- a/src/view/ad/position.vue +++ b/src/view/ad/position.vue @@ -81,17 +81,11 @@ import { getAdPositionById } from '@/api/adPosition' import { isImageMime } from '@/utils/image' +import { isNumber } from '@/utils/validator' const page = ref(1) const total = ref(0) const pageSize = ref(10) -const checkNumber = (rule, value, callback) => { - if (value <= 0) { - callback(new Error(rule.message)) - } else { - callback() - } -} const rules = reactive({ position: [ { required: true, message: '请输入广告位名称', trigger: 'blur' } @@ -100,10 +94,10 @@ const rules = reactive({ { required: true, message: '请输入广告位标题', trigger: 'blur' } ], mediaWidth: [ - { required: true, validator: checkNumber, message: '请输入 > 0 的整数', trigger: 'blur' } + { required: true, validator: isNumber, message: '请输入 > 0 的整数', trigger: 'blur' } ], mediaHeight: [ - { required: true, validator: checkNumber, message: '请输入 > 0 的整数', trigger: 'blur' } + { required: true, validator: isNumber, message: '请输入 > 0 的整数', trigger: 'blur' } ], }) diff --git a/src/view/content/components/articleEdit.vue b/src/view/content/components/articleEdit.vue index a08b89f..4979444 100644 --- a/src/view/content/components/articleEdit.vue +++ b/src/view/content/components/articleEdit.vue @@ -76,7 +76,7 @@ - + @@ -154,6 +154,7 @@ import { getArticleById, } from '@/api/article' import { importFetcherArticleById } from '@/api/fetcher' +import { isUrl } from '@/utils/validator' // 组件定义 defineOptions({ @@ -203,6 +204,9 @@ const formRules = reactive({ content: [ { required: true, message: '请输入文章内容', trigger: 'blur' } ], + url: [ + { validator: isUrl, message: '请输入正确的跳转地址', trigger: 'blur' } + ] }) const articleTypeOptions = ref([ { key: 1, label: '图文' },