From 03878eec5a861f21ba247f1c81d1e8238c26ca65 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?=E6=9D=8E=E5=BC=BA?= <1206709430@qq.com>
Date: Sun, 18 Jun 2023 10:02:38 +0800
Subject: [PATCH] =?UTF-8?q?=E5=8A=9F=E8=83=BD=E5=8F=98=E5=8C=96:=20?=
=?UTF-8?q?=E6=9B=B4=E6=96=B0=E7=BB=84=E4=BB=B6?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
docker_env/web/Dockerfile | 2 +-
web/src/components/file-uploader/index.js | 32 +
.../file-uploader/lib/cropper-uploader.vue | 377 ++++++++++
.../file-uploader/lib/cropper/index.vue | 420 +++++++++++
.../file-uploader/lib/cropper/vue-cropper.js | 367 ++++++++++
.../file-uploader/lib/file-uploader.vue | 666 ++++++++++++++++++
.../file-uploader/lib/files-format.vue | 96 +++
.../file-uploader/lib/images-format.vue | 133 ++++
.../file-uploader/lib/loading-spin.svg | 6 +
.../selector-table/selector-table.vue | 22 +-
10 files changed, 2114 insertions(+), 7 deletions(-)
create mode 100644 web/src/components/file-uploader/index.js
create mode 100644 web/src/components/file-uploader/lib/cropper-uploader.vue
create mode 100644 web/src/components/file-uploader/lib/cropper/index.vue
create mode 100644 web/src/components/file-uploader/lib/cropper/vue-cropper.js
create mode 100644 web/src/components/file-uploader/lib/file-uploader.vue
create mode 100644 web/src/components/file-uploader/lib/files-format.vue
create mode 100644 web/src/components/file-uploader/lib/images-format.vue
create mode 100644 web/src/components/file-uploader/lib/loading-spin.svg
diff --git a/docker_env/web/Dockerfile b/docker_env/web/Dockerfile
index dfa928a..74b0e8b 100644
--- a/docker_env/web/Dockerfile
+++ b/docker_env/web/Dockerfile
@@ -4,6 +4,6 @@ COPY web/. .
RUN npm install --registry=https://registry.npm.taobao.org
RUN npm run build
-FROM nginx:alpine
+FROM registry.cn-zhangjiakou.aliyuncs.com/dvadmin-pro/nginx:alpine
COPY ./docker_env/nginx/my.conf /etc/nginx/conf.d/my.conf
COPY --from=0 /web/dist /usr/share/nginx/html
diff --git a/web/src/components/file-uploader/index.js b/web/src/components/file-uploader/index.js
new file mode 100644
index 0000000..f0de3e6
--- /dev/null
+++ b/web/src/components/file-uploader/index.js
@@ -0,0 +1,32 @@
+import D2pImagesFormat from './lib/images-format'
+import D2pFilesFormat from './lib/files-format'
+import 'cropperjs/dist/cropper.css'
+import D2pUploader from 'd2p-extends/src/uploader'
+
+function install (Vue, options) {
+ Vue.component('d2p-file-uploader', () => import('./lib/file-uploader'))
+ Vue.component('d2p-images-format', D2pImagesFormat)
+ Vue.component('d2p-cropper-uploader', () => import('./lib/cropper-uploader'))
+ Vue.component('d2p-cropper', () => import('./lib/cropper'))
+ Vue.component('d2p-files-format', D2pFilesFormat)
+
+ if (options != null) {
+ Vue.use(D2pUploader, options)
+ }
+}
+
+const createAllUploadedValidator = (getFormComponentRef) => {
+ return (rule, value, callback) => {
+ const ref = getFormComponentRef(rule.fullField)
+ if (ref && ref.isHasUploadingItem()) {
+ callback(new Error('还有未上传完成的文件'))
+ return
+ }
+ callback()
+ }
+}
+
+export default {
+ install,
+ createAllUploadedValidator
+}
diff --git a/web/src/components/file-uploader/lib/cropper-uploader.vue b/web/src/components/file-uploader/lib/cropper-uploader.vue
new file mode 100644
index 0000000..43320dd
--- /dev/null
+++ b/web/src/components/file-uploader/lib/cropper-uploader.vue
@@ -0,0 +1,377 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/web/src/components/file-uploader/lib/cropper/index.vue b/web/src/components/file-uploader/lib/cropper/index.vue
new file mode 100644
index 0000000..58adcdc
--- /dev/null
+++ b/web/src/components/file-uploader/lib/cropper/index.vue
@@ -0,0 +1,420 @@
+
+
+
+
+
+
+
+选择图片
+
{{_uploadTip}}
+
+
+
+
+
+
+
+
+ 重新选择
+ 左右翻转
+ 上下翻转
+
+
+ 旋转
+ 重置
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/web/src/components/file-uploader/lib/cropper/vue-cropper.js b/web/src/components/file-uploader/lib/cropper/vue-cropper.js
new file mode 100644
index 0000000..e57a3c8
--- /dev/null
+++ b/web/src/components/file-uploader/lib/cropper/vue-cropper.js
@@ -0,0 +1,367 @@
+import Cropper from 'cropperjs'
+
+const previewPropType = typeof window === 'undefined'
+ ? [String, Array]
+ : [String, Array, Element, NodeList]
+
+export default {
+ render (h) {
+ return h('div', { style: this.containerStyle }, [
+ h('img', {
+ ref: 'img',
+ attrs: {
+ src: this.src,
+ alt: this.alt || 'image',
+ style: 'max-width: 100%'
+ },
+ style: this.imgStyle
+ })
+ ])
+ },
+ props: {
+ // Library props
+ containerStyle: Object,
+ src: {
+ type: String,
+ default: ''
+ },
+ alt: String,
+ imgStyle: Object,
+
+ // CropperJS props
+ viewMode: Number,
+ dragMode: String,
+ initialAspectRatio: Number,
+ aspectRatio: Number,
+ data: Object,
+ preview: previewPropType,
+ responsive: {
+ type: Boolean,
+ default: true
+ },
+ restore: {
+ type: Boolean,
+ default: true
+ },
+ checkCrossOrigin: {
+ type: Boolean,
+ default: true
+ },
+ checkOrientation: {
+ type: Boolean,
+ default: true
+ },
+ modal: {
+ type: Boolean,
+ default: true
+ },
+ guides: {
+ type: Boolean,
+ default: true
+ },
+ center: {
+ type: Boolean,
+ default: true
+ },
+ highlight: {
+ type: Boolean,
+ default: true
+ },
+ background: {
+ type: Boolean,
+ default: true
+ },
+ autoCrop: {
+ type: Boolean,
+ default: true
+ },
+ autoCropArea: Number,
+ movable: {
+ type: Boolean,
+ default: true
+ },
+ rotatable: {
+ type: Boolean,
+ default: true
+ },
+ scalable: {
+ type: Boolean,
+ default: true
+ },
+ zoomable: {
+ type: Boolean,
+ default: true
+ },
+ zoomOnTouch: {
+ type: Boolean,
+ default: true
+ },
+ zoomOnWheel: {
+ type: Boolean,
+ default: true
+ },
+ wheelZoomRatio: Number,
+ cropBoxMovable: {
+ type: Boolean,
+ default: true
+ },
+ cropBoxResizable: {
+ type: Boolean,
+ default: true
+ },
+ toggleDragModeOnDblclick: {
+ type: Boolean,
+ default: true
+ },
+
+ // Size limitation
+ minCanvasWidth: Number,
+ minCanvasHeight: Number,
+ minCropBoxWidth: Number,
+ minCropBoxHeight: Number,
+ minContainerWidth: Number,
+ minContainerHeight: Number,
+
+ // callbacks
+ ready: Function,
+ cropstart: Function,
+ cropmove: Function,
+ cropend: Function,
+ crop: Function,
+ zoom: Function
+ },
+ mounted () {
+ const { containerStyle, src, alt, imgStyle, ...data } = this.$options.props
+ const props = {}
+
+ for (const key in data) {
+ if (this[key] !== undefined) {
+ props[key] = this[key]
+ }
+ }
+
+ this.cropper = new Cropper(this.$refs.img, props)
+ },
+ methods: {
+ // Reset the image and crop box to their initial states
+ reset () {
+ return this.cropper.reset()
+ },
+
+ // Clear the crop box
+ clear () {
+ return this.cropper.clear()
+ },
+
+ // Init crop box manually
+ initCrop () {
+ return this.cropper.crop()
+ },
+
+ /**
+ * Replace the image's src and rebuild the cropper
+ * @param {string} url - The new URL.
+ * @param {boolean} [onlyColorChanged] - Indicate if the new image only changed color.
+ * @returns {Object} this
+ */
+ replace (url, onlyColorChanged = false) {
+ return this.cropper.replace(url, onlyColorChanged)
+ },
+
+ // Enable (unfreeze) the cropper
+ enable () {
+ return this.cropper.enable()
+ },
+
+ // Disable (freeze) the cropper
+ disable () {
+ return this.cropper.disable()
+ },
+
+ // Destroy the cropper and remove the instance from the image
+ destroy () {
+ return this.cropper.destroy()
+ },
+
+ /**
+ * Move the canvas with relative offsets
+ * @param {number} offsetX - The relative offset distance on the x-axis.
+ * @param {number} offsetY - The relative offset distance on the y-axis.
+ * @returns {Object} this
+ */
+ move (offsetX, offsetY) {
+ return this.cropper.move(offsetX, offsetY)
+ },
+
+ /**
+ * Move the canvas to an absolute point
+ * @param {number} x - The x-axis coordinate.
+ * @param {number} [y=x] - The y-axis coordinate.
+ * @returns {Object} this
+ */
+ moveTo (x, y = x) {
+ return this.cropper.moveTo(x, y)
+ },
+
+ /**
+ * Zoom the canvas with a relative ratio
+ * @param {number} ratio - The target ratio.
+ * @param {Event} _originalEvent - The original event if any.
+ * @returns {Object} this
+ */
+ relativeZoom (ratio, _originalEvent) {
+ return this.cropper.zoom(ratio, _originalEvent)
+ },
+
+ /**
+ * Zoom the canvas to an absolute ratio
+ * @param {number} ratio - The target ratio.
+ * @param {Event} _originalEvent - The original event if any.
+ * @returns {Object} this
+ */
+ zoomTo (ratio, _originalEvent) {
+ return this.cropper.zoomTo(ratio, _originalEvent)
+ },
+
+ /**
+ * Rotate the canvas with a relative degree
+ * @param {number} degree - The rotate degree.
+ * @returns {Object} this
+ */
+ rotate (degree) {
+ return this.cropper.rotate(degree)
+ },
+
+ /**
+ * Rotate the canvas to an absolute degree
+ * @param {number} degree - The rotate degree.
+ * @returns {Object} this
+ */
+ rotateTo (degree) {
+ return this.cropper.rotateTo(degree)
+ },
+
+ /**
+ * Scale the image on the x-axis.
+ * @param {number} scaleX - The scale ratio on the x-axis.
+ * @returns {Object} this
+ */
+ scaleX (scaleX) {
+ return this.cropper.scaleX(scaleX)
+ },
+
+ /**
+ * Scale the image on the y-axis.
+ * @param {number} scaleY - The scale ratio on the y-axis.
+ * @returns {Object} this
+ */
+ scaleY (scaleY) {
+ return this.cropper.scaleY(scaleY)
+ },
+
+ /**
+ * Scale the image
+ * @param {number} scaleX - The scale ratio on the x-axis.
+ * @param {number} [scaleY=scaleX] - The scale ratio on the y-axis.
+ * @returns {Object} this
+ */
+ scale (scaleX, scaleY = scaleX) {
+ return this.cropper.scale(scaleX, scaleY)
+ },
+
+ /**
+ * Get the cropped area position and size data (base on the original image)
+ * @param {boolean} [rounded=false] - Indicate if round the data values or not.
+ * @returns {Object} The result cropped data.
+ */
+ getData (rounded = false) {
+ return this.cropper.getData(rounded)
+ },
+
+ /**
+ * Set the cropped area position and size with new data
+ * @param {Object} data - The new data.
+ * @returns {Object} this
+ */
+ setData (data) {
+ return this.cropper.setData(data)
+ },
+
+ /**
+ * Get the container size data.
+ * @returns {Object} The result container data.
+ */
+ getContainerData () {
+ return this.cropper.getContainerData()
+ },
+
+ /**
+ * Get the image position and size data.
+ * @returns {Object} The result image data.
+ */
+ getImageData () {
+ return this.cropper.getImageData()
+ },
+
+ /**
+ * Get the canvas position and size data.
+ * @returns {Object} The result canvas data.
+ */
+ getCanvasData () {
+ return this.cropper.getCanvasData()
+ },
+
+ /**
+ * Set the canvas position and size with new data.
+ * @param {Object} data - The new canvas data.
+ * @returns {Object} this
+ */
+ setCanvasData (data) {
+ return this.cropper.setCanvasData(data)
+ },
+
+ /**
+ * Get the crop box position and size data.
+ * @returns {Object} The result crop box data.
+ */
+ getCropBoxData () {
+ return this.cropper.getCropBoxData()
+ },
+
+ /**
+ * Set the crop box position and size with new data.
+ * @param {Object} data - The new crop box data.
+ * @returns {Object} this
+ */
+ setCropBoxData (data) {
+ return this.cropper.setCropBoxData(data)
+ },
+
+ /**
+ * Get a canvas drawn the cropped image.
+ * @param {Object} [options={}] - The config options.
+ * @returns {HTMLCanvasElement} - The result canvas.
+ */
+ getCroppedCanvas (options = {}) {
+ return this.cropper.getCroppedCanvas(options)
+ },
+
+ /**
+ * Change the aspect ratio of the crop box.
+ * @param {number} aspectRatio - The new aspect ratio.
+ * @returns {Object} this
+ */
+ setAspectRatio (aspectRatio) {
+ return this.cropper.setAspectRatio(aspectRatio)
+ },
+
+ /**
+ * Change the drag mode.
+ * @param {string} mode - The new drag mode.
+ * @returns {Object} this
+ */
+ setDragMode (mode) {
+ return this.cropper.setDragMode(mode)
+ }
+ }
+}
diff --git a/web/src/components/file-uploader/lib/file-uploader.vue b/web/src/components/file-uploader/lib/file-uploader.vue
new file mode 100644
index 0000000..7a0c5ca
--- /dev/null
+++ b/web/src/components/file-uploader/lib/file-uploader.vue
@@ -0,0 +1,666 @@
+
+
+
+ {{btnName}}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/web/src/components/file-uploader/lib/files-format.vue b/web/src/components/file-uploader/lib/files-format.vue
new file mode 100644
index 0000000..7fc52c6
--- /dev/null
+++ b/web/src/components/file-uploader/lib/files-format.vue
@@ -0,0 +1,96 @@
+
+
+
+
+ {{item.name}}
+
+
+
+
+ {{item.name}}
+
+
+
+
+
+
+
diff --git a/web/src/components/file-uploader/lib/images-format.vue b/web/src/components/file-uploader/lib/images-format.vue
new file mode 100644
index 0000000..8e4b4d2
--- /dev/null
+++ b/web/src/components/file-uploader/lib/images-format.vue
@@ -0,0 +1,133 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/web/src/components/file-uploader/lib/loading-spin.svg b/web/src/components/file-uploader/lib/loading-spin.svg
new file mode 100644
index 0000000..4dbb3ac
--- /dev/null
+++ b/web/src/components/file-uploader/lib/loading-spin.svg
@@ -0,0 +1,6 @@
+
diff --git a/web/src/components/selector-table/selector-table.vue b/web/src/components/selector-table/selector-table.vue
index d76c824..e213b59 100644
--- a/web/src/components/selector-table/selector-table.vue
+++ b/web/src/components/selector-table/selector-table.vue
@@ -2,7 +2,7 @@
@@ -16,7 +16,7 @@
size="mini"
border
:row-key="dict.value"
- style="width: 400px"
+ style="width: 600px"
max-height="200"
height="200"
:highlight-current-row="!_elProps.tableConfig.multiple"
@@ -25,8 +25,10 @@
>
-
+
+
+
{
+ queryList.push(res.prop)
+ })
+ params.query = `{${Array.from(new Set(queryList)).join(',')}}`
return request({
url: url,
params: params,
@@ -241,10 +247,14 @@ export default {
if (that.dict.params) {
dictParams = { ...that.dict.params }
}
+ const queryList = ['id', label, value]
+ this._elProps.tableConfig.columns.map(res => {
+ queryList.push(res.prop)
+ })
const params = {
page: that.pageConfig.page,
limit: that.pageConfig.limit,
- query: `{${label},${value}}`
+ query: `{${Array.from(new Set(queryList)).join(',')}}`
}
if (that.search) {
params.search = that.search