diff --git a/src/components/upload/common.vue b/src/components/upload/common.vue index 84686d7..4f8d9a0 100644 --- a/src/components/upload/common.vue +++ b/src/components/upload/common.vue @@ -1,10 +1,8 @@ + + diff --git a/src/components/vueCropper/exif-js-min.js b/src/components/vueCropper/exif-js-min.js new file mode 100644 index 0000000..e16a6e3 --- /dev/null +++ b/src/components/vueCropper/exif-js-min.js @@ -0,0 +1,159 @@ +const Exif = {}; + +Exif.getData = (img) => new Promise((reslove, reject) => { + let obj = {}; + getImageData(img).then(data => { + obj.arrayBuffer = data; + obj.orientation = getOrientation(data); + reslove(obj) + }).catch(error => { + reject(error) + }) +}) + +// 这里的获取exif要将图片转ArrayBuffer对象,这里假设获取了图片的baes64 +// 步骤一 +// base64转ArrayBuffer对象 +function getImageData(img) { + let data = null; + return new Promise((reslove, reject) => { + if (img.src) { + if (/^data\:/i.test(img.src)) { // Data URI + data = base64ToArrayBuffer(img.src); + reslove(data) + } else if (/^blob\:/i.test(img.src)) { // Object URL + var fileReader = new FileReader(); + fileReader.onload = function (e) { + data = e.target.result; + reslove(data) + }; + objectURLToBlob(img.src, function (blob) { + fileReader.readAsArrayBuffer(blob); + }); + } else { + var http = new XMLHttpRequest(); + http.onload = function () { + if (this.status == 200 || this.status === 0) { + data = http.response + reslove(data) + } else { + throw "Could not load image"; + } + http = null; + }; + http.open("GET", img.src, true); + http.responseType = "arraybuffer"; + http.send(null); + } + } else { + reject('img error') + } + }) +} + +function objectURLToBlob(url, callback) { + var http = new XMLHttpRequest(); + http.open("GET", url, true); + http.responseType = "blob"; + http.onload = function () { + if (this.status == 200 || this.status === 0) { + callback(this.response); + } + }; + http.send(); +} + + + +function base64ToArrayBuffer(base64) { + base64 = base64.replace(/^data\:([^\;]+)\;base64,/gmi, ''); + var binary = atob(base64); + var len = binary.length; + var buffer = new ArrayBuffer(len); + var view = new Uint8Array(buffer); + for (var i = 0; i < len; i++) { + view[i] = binary.charCodeAt(i); + } + return buffer; +} +// 步骤二,Unicode码转字符串 +// ArrayBuffer对象 Unicode码转字符串 +function getStringFromCharCode(dataView, start, length) { + var str = ''; + var i; + for (i = start, length += start; i < length; i++) { + str += String.fromCharCode(dataView.getUint8(i)); + } + return str; +} + +// 步骤三,获取jpg图片的exif的角度(在ios体现最明显) +function getOrientation(arrayBuffer) { + var dataView = new DataView(arrayBuffer); + var length = dataView.byteLength; + var orientation; + var exifIDCode; + var tiffOffset; + var firstIFDOffset; + var littleEndian; + var endianness; + var app1Start; + var ifdStart; + var offset; + var i; + // Only handle JPEG image (start by 0xFFD8) + if (dataView.getUint8(0) === 0xFF && dataView.getUint8(1) === 0xD8) { + offset = 2; + while (offset < length) { + if (dataView.getUint8(offset) === 0xFF && dataView.getUint8(offset + 1) === 0xE1) { + app1Start = offset; + break; + } + offset++; + } + } + if (app1Start) { + exifIDCode = app1Start + 4; + tiffOffset = app1Start + 10; + if (getStringFromCharCode(dataView, exifIDCode, 4) === 'Exif') { + endianness = dataView.getUint16(tiffOffset); + littleEndian = endianness === 0x4949; + + if (littleEndian || endianness === 0x4D4D /* bigEndian */) { + if (dataView.getUint16(tiffOffset + 2, littleEndian) === 0x002A) { + firstIFDOffset = dataView.getUint32(tiffOffset + 4, littleEndian); + + if (firstIFDOffset >= 0x00000008) { + ifdStart = tiffOffset + firstIFDOffset; + } + } + } + } + } + if (ifdStart) { + length = dataView.getUint16(ifdStart, littleEndian); + + for (i = 0; i < length; i++) { + offset = ifdStart + i * 12 + 2; + if (dataView.getUint16(offset, littleEndian) === 0x0112 /* Orientation */) { + + // 8 is the offset of the current tag's value + offset += 8; + + // Get the original orientation value + orientation = dataView.getUint16(offset, littleEndian); + + // Override the orientation with its default value for Safari (#120) + // if (IS_SAFARI_OR_UIWEBVIEW) { + // dataView.setUint16(offset, 1, littleEndian); + // } + break; + } + } + } + return orientation; +} + + + +export default Exif \ No newline at end of file diff --git a/src/components/vueCropper/index.js b/src/components/vueCropper/index.js new file mode 100644 index 0000000..4c76e40 --- /dev/null +++ b/src/components/vueCropper/index.js @@ -0,0 +1,8 @@ +// 导入组件,组件必须声明 name +import VueCropper from './src/vue-cropper.vue' + +VueCropper.install = function (Vue) { + Vue.component(VueCropper.name, VueCropper) +} + +export default VueCropper \ No newline at end of file diff --git a/src/components/vueCropper/src/vue-cropper.vue b/src/components/vueCropper/src/vue-cropper.vue new file mode 100644 index 0000000..c3d6cd7 --- /dev/null +++ b/src/components/vueCropper/src/vue-cropper.vue @@ -0,0 +1,2020 @@ + + + + + diff --git a/src/style/main.scss b/src/style/main.scss index 06f4b63..ab6cf19 100644 --- a/src/style/main.scss +++ b/src/style/main.scss @@ -690,7 +690,6 @@ li { @apply mb-3 flex gap-2 items-center; } - #nprogress .bar { background: #29d !important; } @@ -753,7 +752,7 @@ li { .el-icon.avatar-uploader-icon { font-size: 28px; - color: #8c939d; + color: var(--el-text-color-secondary); width: 120px; height: 120px; text-align: center; diff --git a/src/view/content/components/academicianEdit.vue b/src/view/content/components/academicianEdit.vue index 177fe4c..fc3eef5 100644 --- a/src/view/content/components/academicianEdit.vue +++ b/src/view/content/components/academicianEdit.vue @@ -57,41 +57,55 @@ - - - - - - +
+ + 直接上传 + + +
+
+ +
- - 上传 - - +
+ + 上传 + +
+
+ +
- - - - - - +
+ + 直接上传 + + +
+
+ +
@@ -105,6 +119,7 @@ import { ref, reactive } from 'vue' import { ElMessage } from 'element-plus' import RichEdit from '@/components/richtext/rich-edit.vue' import { isImageMime, isVideoMime, isGifMime, checkImageWHEqual } from '@/utils/image' +import CropperImg from '@/components/upload/cropperImg.vue' import { addAcademician, updateAcademician, @@ -120,6 +135,7 @@ const props = defineProps({ title: { type: String, default: '' } }) +const cropperImgRef = ref(null) const showDrawer = ref(false) const showErrMessage = ref('') const fullscreenLoading = ref(true) @@ -232,6 +248,7 @@ const qrcodeInfo = { } const videoRef = ref(null) const imgUploadPath = import.meta.env.VITE_BASE_API + const beforeUpload = (file, info) => { const isLtSize = file.size / 1024 < info.fileSize const isVideo = isVideoMime(file.type) diff --git a/src/view/content/components/entrepreneurEdit.vue b/src/view/content/components/entrepreneurEdit.vue index 80feb37..9f47277 100644 --- a/src/view/content/components/entrepreneurEdit.vue +++ b/src/view/content/components/entrepreneurEdit.vue @@ -3,7 +3,7 @@ :close-on-press-escape="false">