mgacn-commonsdk 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +128 -0
- package/dist/mgacn-commonsdk.js +688 -0
- package/dist/mgacn-commonsdk.umd.cjs +1 -0
- package/dist/style.css +9 -0
- package/package.json +58 -0
package/README.md
ADDED
|
@@ -0,0 +1,128 @@
|
|
|
1
|
+
# mgacn-commonsdk
|
|
2
|
+
|
|
3
|
+
芒果 ACN 公共组件库:公共组件、工具方法与网络请求封装。
|
|
4
|
+
|
|
5
|
+
## 环境
|
|
6
|
+
|
|
7
|
+
- Node.js `24.19.0`
|
|
8
|
+
|
|
9
|
+
```bash
|
|
10
|
+
nvm use
|
|
11
|
+
npm install
|
|
12
|
+
```
|
|
13
|
+
|
|
14
|
+
## 安装(接入系统)
|
|
15
|
+
|
|
16
|
+
```bash
|
|
17
|
+
npm install mgacn-commonsdk
|
|
18
|
+
```
|
|
19
|
+
|
|
20
|
+
`axios`、`ali-oss`、`cropperjs` 已作为组件库自带依赖,**宿主无需单独安装**。
|
|
21
|
+
|
|
22
|
+
以下一般由宿主项目已有(与 SDK 共用):
|
|
23
|
+
|
|
24
|
+
- `vue`
|
|
25
|
+
- `element-plus`
|
|
26
|
+
- `@element-plus/icons-vue`
|
|
27
|
+
|
|
28
|
+
## 使用
|
|
29
|
+
|
|
30
|
+
```js
|
|
31
|
+
import MgacnCommonSdk from 'mgacn-commonsdk'
|
|
32
|
+
import 'mgacn-commonsdk/style.css'
|
|
33
|
+
|
|
34
|
+
app.use(MgacnCommonSdk, {
|
|
35
|
+
tokenKey: 'your_token_key',
|
|
36
|
+
baseURL: import.meta.env.VITE_API_BASE_URL,
|
|
37
|
+
systemIdKey: 'mgacn_systemid', // 可选,有的系统需要
|
|
38
|
+
})
|
|
39
|
+
```
|
|
40
|
+
|
|
41
|
+
### 网络请求(宿主使用 .GET / .POST)
|
|
42
|
+
|
|
43
|
+
先 `app.use` 后,页面里这样调:
|
|
44
|
+
|
|
45
|
+
```js
|
|
46
|
+
// Options API
|
|
47
|
+
this.$request.GET('/yhAdmin/user/queryUserById', { params: { id: 1 } })
|
|
48
|
+
this.$request.POST('/yhAdmin/user/edit', { name: '张三' })
|
|
49
|
+
this.$request.DELETE(`/yhAdmin/portal/deleteManager/${userId}`)
|
|
50
|
+
|
|
51
|
+
// Composition API / <script setup>
|
|
52
|
+
import { getRequest } from 'mgacn-commonsdk'
|
|
53
|
+
|
|
54
|
+
const request = getRequest()
|
|
55
|
+
await request.GET('/path', { params: { page: 1 } })
|
|
56
|
+
await request.POST('/path', { foo: 1 })
|
|
57
|
+
```
|
|
58
|
+
|
|
59
|
+
也可继续用封装好的 api:
|
|
60
|
+
|
|
61
|
+
```js
|
|
62
|
+
import { getApi } from 'mgacn-commonsdk'
|
|
63
|
+
await getApi().getUserInfo(userId)
|
|
64
|
+
```
|
|
65
|
+
|
|
66
|
+
### 手动创建
|
|
67
|
+
|
|
68
|
+
```js
|
|
69
|
+
import { createRequest, createApi } from 'mgacn-commonsdk'
|
|
70
|
+
|
|
71
|
+
const request = createRequest({
|
|
72
|
+
tokenKey: 'your_token_key',
|
|
73
|
+
baseURL: '/api',
|
|
74
|
+
systemIdKey: 'mgacn_systemid', // 可选
|
|
75
|
+
})
|
|
76
|
+
const api = createApi(request)
|
|
77
|
+
```
|
|
78
|
+
|
|
79
|
+
### 图片上传
|
|
80
|
+
|
|
81
|
+
```vue
|
|
82
|
+
<template>
|
|
83
|
+
<MgImageUpload
|
|
84
|
+
v-model="urls"
|
|
85
|
+
v-model:uploading="uploading"
|
|
86
|
+
fold-name="portal_cms"
|
|
87
|
+
:file-num="3"
|
|
88
|
+
:max-file-size="5"
|
|
89
|
+
/>
|
|
90
|
+
<el-button :disabled="uploading" @click="submit">提交</el-button>
|
|
91
|
+
</template>
|
|
92
|
+
|
|
93
|
+
<script>
|
|
94
|
+
export default {
|
|
95
|
+
data() {
|
|
96
|
+
return {
|
|
97
|
+
urls: [], // 统一为 string[],无图时为 []
|
|
98
|
+
uploading: false,
|
|
99
|
+
}
|
|
100
|
+
},
|
|
101
|
+
methods: {
|
|
102
|
+
submit() {
|
|
103
|
+
if (this.uploading) {
|
|
104
|
+
this.$message.warning('图片上传中,请稍候')
|
|
105
|
+
return
|
|
106
|
+
}
|
|
107
|
+
// this.urls => ['https://...', 'https://...']
|
|
108
|
+
},
|
|
109
|
+
},
|
|
110
|
+
}
|
|
111
|
+
</script>
|
|
112
|
+
```
|
|
113
|
+
|
|
114
|
+
也可通过 ref 判断:
|
|
115
|
+
|
|
116
|
+
```js
|
|
117
|
+
if (this.$refs.upload.isUploading()) return
|
|
118
|
+
```
|
|
119
|
+
|
|
120
|
+
先 `app.use(MgacnCommonSdk, { tokenKey, baseURL })` 后,组件内部通过项目 `api.getOssSts` 获取凭证。
|
|
121
|
+
|
|
122
|
+
## 本地开发 / 发布
|
|
123
|
+
|
|
124
|
+
```bash
|
|
125
|
+
npm run dev
|
|
126
|
+
npm run build
|
|
127
|
+
npm publish
|
|
128
|
+
```
|
|
@@ -0,0 +1,688 @@
|
|
|
1
|
+
import { Plus as V, Delete as z, CircleCloseFilled as Y } from "@element-plus/icons-vue";
|
|
2
|
+
import { ElMessage as U, ElMessageBox as q } from "element-plus";
|
|
3
|
+
import K from "cropperjs";
|
|
4
|
+
import H from "ali-oss";
|
|
5
|
+
import { resolveComponent as y, openBlock as g, createElementBlock as h, createElementVNode as d, toDisplayString as S, createCommentVNode as v, createTextVNode as b, Fragment as P, renderList as G, normalizeStyle as T, normalizeClass as W, createVNode as p, withCtx as f, withModifiers as J, withDirectives as I, vShow as O } from "vue";
|
|
6
|
+
import Q from "axios";
|
|
7
|
+
function X(e) {
|
|
8
|
+
if (!e)
|
|
9
|
+
throw new Error("[mgacn-commonsdk] createApi 需要传入 request 实例");
|
|
10
|
+
return {
|
|
11
|
+
getUserInfo(t) {
|
|
12
|
+
return e.GET("/yhAdmin/user/queryUserById", { params: { id: t } });
|
|
13
|
+
},
|
|
14
|
+
getOssSts(t) {
|
|
15
|
+
return e.GET("/yhAdmin/oss/fileUploadSts", { params: { dir: t } });
|
|
16
|
+
}
|
|
17
|
+
};
|
|
18
|
+
}
|
|
19
|
+
let x = null;
|
|
20
|
+
function Z(e) {
|
|
21
|
+
x = e;
|
|
22
|
+
}
|
|
23
|
+
function ee() {
|
|
24
|
+
if (!x)
|
|
25
|
+
throw new Error("[mgacn-commonsdk] 请先 app.use(MgacnCommonSdk, { tokenKey, baseURL })");
|
|
26
|
+
return x;
|
|
27
|
+
}
|
|
28
|
+
function N(e) {
|
|
29
|
+
return String(e).padStart(2, "0");
|
|
30
|
+
}
|
|
31
|
+
function te() {
|
|
32
|
+
const e = /* @__PURE__ */ new Date();
|
|
33
|
+
return `${e.getFullYear()}${N(e.getMonth() + 1)}${N(e.getDate())}`;
|
|
34
|
+
}
|
|
35
|
+
function B(e = 10) {
|
|
36
|
+
const t = "0123456789abcdefghijklmnopqrstuvwxyz";
|
|
37
|
+
let r = "";
|
|
38
|
+
for (let s = 0; s < e; s++)
|
|
39
|
+
r += t[Math.floor(Math.random() * t.length)];
|
|
40
|
+
return r;
|
|
41
|
+
}
|
|
42
|
+
function F(e = "portal_cms") {
|
|
43
|
+
return `${e}/${te()}/`;
|
|
44
|
+
}
|
|
45
|
+
function j(e) {
|
|
46
|
+
return ee().getOssSts(e);
|
|
47
|
+
}
|
|
48
|
+
async function M(e = {}) {
|
|
49
|
+
const { dir: t, foldName: r, getOss: s, ossinfo: o } = e, i = t || F(r || "portal_cms"), n = o || (typeof s == "function" ? await s(i) : await j(i));
|
|
50
|
+
if (!n)
|
|
51
|
+
throw new Error("[mgacn-commonsdk] 获取 OSS STS 失败");
|
|
52
|
+
const c = new H({
|
|
53
|
+
bucket: n.bucketName,
|
|
54
|
+
accessKeyId: n.accessKeyId,
|
|
55
|
+
accessKeySecret: n.accessKeySecret,
|
|
56
|
+
success_action_status: "200",
|
|
57
|
+
stsToken: n.securityToken,
|
|
58
|
+
endpoint: n.endPoint
|
|
59
|
+
});
|
|
60
|
+
return c.options.ossUrl = n.ossUrl || n.domain || (n.bucketName && n.endPoint ? `https://${n.bucketName}.${n.endPoint}` : ""), c.options.uploadDir = i, c;
|
|
61
|
+
}
|
|
62
|
+
async function re(e = {}) {
|
|
63
|
+
const { client: t, file: r, dir: s, foldName: o, fileName: i, onProgress: n } = e;
|
|
64
|
+
if (!r)
|
|
65
|
+
throw new Error("[mgacn-commonsdk] uploadToOss 缺少 file");
|
|
66
|
+
const c = t || await M({ dir: s, foldName: o }), C = s || c.options.uploadDir || F(o);
|
|
67
|
+
let l = i;
|
|
68
|
+
if (!l) {
|
|
69
|
+
const k = r.name || "file", u = k.indexOf("."), _ = u > -1 ? k.slice(u) : "";
|
|
70
|
+
l = `${C}${B(10)}${_}`;
|
|
71
|
+
}
|
|
72
|
+
const a = await c.multipartUpload(l, r, {
|
|
73
|
+
progress: (k) => {
|
|
74
|
+
typeof n == "function" && n(Math.floor(k * 100));
|
|
75
|
+
}
|
|
76
|
+
});
|
|
77
|
+
if (a.res && a.res.statusCode !== 200)
|
|
78
|
+
throw new Error("[mgacn-commonsdk] 上传失败");
|
|
79
|
+
const w = (c.options.ossUrl || "").replace(/\/$/, ""), m = w ? `${w}/${l}` : l;
|
|
80
|
+
return { name: l, url: m, raw: a, client: c };
|
|
81
|
+
}
|
|
82
|
+
const se = {
|
|
83
|
+
methods: {
|
|
84
|
+
getDir() {
|
|
85
|
+
return F(this.foldName || "portal_cms");
|
|
86
|
+
},
|
|
87
|
+
randomString: B,
|
|
88
|
+
getOss() {
|
|
89
|
+
return j(this.getDir());
|
|
90
|
+
},
|
|
91
|
+
async createOssClient() {
|
|
92
|
+
return M({
|
|
93
|
+
dir: this.getDir(),
|
|
94
|
+
getOss: () => this.getOss()
|
|
95
|
+
});
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
}, ie = (e, t) => {
|
|
99
|
+
const r = e.__vccOpts || e;
|
|
100
|
+
for (const [s, o] of t)
|
|
101
|
+
r[s] = o;
|
|
102
|
+
return r;
|
|
103
|
+
};
|
|
104
|
+
let E = 0;
|
|
105
|
+
function $() {
|
|
106
|
+
return E += 1, `mg-img-${Date.now()}-${E}`;
|
|
107
|
+
}
|
|
108
|
+
function oe(e) {
|
|
109
|
+
return Array.isArray(e) ? e.filter(Boolean) : e ? [e] : [];
|
|
110
|
+
}
|
|
111
|
+
function A(e) {
|
|
112
|
+
return e.map((t) => ({
|
|
113
|
+
uid: $(),
|
|
114
|
+
url: t,
|
|
115
|
+
status: "success",
|
|
116
|
+
percent: 100,
|
|
117
|
+
previewUrl: ""
|
|
118
|
+
}));
|
|
119
|
+
}
|
|
120
|
+
function ne(e = "") {
|
|
121
|
+
const t = e.lastIndexOf(".");
|
|
122
|
+
return t > -1 ? e.slice(t + 1).toLowerCase() : "";
|
|
123
|
+
}
|
|
124
|
+
const le = {
|
|
125
|
+
name: "MgImageUpload",
|
|
126
|
+
mixins: [se],
|
|
127
|
+
components: { CircleCloseFilled: Y, Delete: z, Plus: V },
|
|
128
|
+
props: {
|
|
129
|
+
/** v-model 统一为 string[];入参兼容 string / string[] */
|
|
130
|
+
modelValue: { type: [Array, String], default: () => [] },
|
|
131
|
+
greyTips: String,
|
|
132
|
+
otherTips: String,
|
|
133
|
+
maxFileSize: { type: Number, default: 100 },
|
|
134
|
+
fileNum: { type: Number, default: 1 },
|
|
135
|
+
initFileList: { type: Array, default: () => [] },
|
|
136
|
+
isCropper: Boolean,
|
|
137
|
+
isDegree: Boolean,
|
|
138
|
+
degree: { type: Number, default: 3 },
|
|
139
|
+
aspectRatio: { type: Number, default: 1 },
|
|
140
|
+
imageStyle: Object,
|
|
141
|
+
resetFilelist: Boolean,
|
|
142
|
+
accept: { type: String, default: ".jpg,.jpeg,.png,.gif,.svg" },
|
|
143
|
+
foldName: { type: String, default: "portal_cms" },
|
|
144
|
+
disabled: Boolean,
|
|
145
|
+
/** 是否有未完成上传(支持 v-model:uploading) */
|
|
146
|
+
uploading: { type: Boolean, default: !1 }
|
|
147
|
+
},
|
|
148
|
+
emits: [
|
|
149
|
+
"update:modelValue",
|
|
150
|
+
"update:uploading",
|
|
151
|
+
"sendFile",
|
|
152
|
+
"success",
|
|
153
|
+
"error",
|
|
154
|
+
"progress"
|
|
155
|
+
],
|
|
156
|
+
expose: ["hasPendingUpload", "isUploading"],
|
|
157
|
+
data() {
|
|
158
|
+
return {
|
|
159
|
+
fileList: [],
|
|
160
|
+
cropImageUrl: "",
|
|
161
|
+
dialogVisible: !1,
|
|
162
|
+
cropper: null
|
|
163
|
+
};
|
|
164
|
+
},
|
|
165
|
+
computed: {
|
|
166
|
+
multiple() {
|
|
167
|
+
return this.fileNum > 1 && !this.isCropper;
|
|
168
|
+
},
|
|
169
|
+
/** 是否存在未上传完的任务 */
|
|
170
|
+
hasPendingUpload() {
|
|
171
|
+
return this.fileList.some((e) => e.status === "uploading");
|
|
172
|
+
},
|
|
173
|
+
uploadingCount() {
|
|
174
|
+
return this.fileList.filter((e) => e.status === "uploading").length;
|
|
175
|
+
},
|
|
176
|
+
showUploadBtn() {
|
|
177
|
+
return !this.disabled && this.fileList.length < this.fileNum;
|
|
178
|
+
},
|
|
179
|
+
acceptList() {
|
|
180
|
+
return this.accept.split(",").map((e) => e.replace(".", "").trim().toLowerCase()).filter(Boolean);
|
|
181
|
+
},
|
|
182
|
+
successUrls() {
|
|
183
|
+
return this.fileList.filter((e) => e.status === "success").map((e) => e.url);
|
|
184
|
+
}
|
|
185
|
+
},
|
|
186
|
+
watch: {
|
|
187
|
+
hasPendingUpload: {
|
|
188
|
+
immediate: !0,
|
|
189
|
+
handler(e) {
|
|
190
|
+
e !== this.uploading && this.$emit("update:uploading", e);
|
|
191
|
+
}
|
|
192
|
+
},
|
|
193
|
+
initFileList: {
|
|
194
|
+
deep: !0,
|
|
195
|
+
immediate: !0,
|
|
196
|
+
handler(e) {
|
|
197
|
+
e != null && e.length && this.replaceList(A(e));
|
|
198
|
+
}
|
|
199
|
+
},
|
|
200
|
+
modelValue: {
|
|
201
|
+
immediate: !0,
|
|
202
|
+
handler(e) {
|
|
203
|
+
var s;
|
|
204
|
+
if ((s = this.initFileList) != null && s.length) return;
|
|
205
|
+
const t = oe(e), r = this.successUrls;
|
|
206
|
+
t.length === r.length && t.every((o, i) => o === r[i]) || this.replaceList(A(t));
|
|
207
|
+
}
|
|
208
|
+
},
|
|
209
|
+
cropImageUrl(e) {
|
|
210
|
+
this.cropper && (e ? this.cropper.replace(e) : this.destroyCropper());
|
|
211
|
+
}
|
|
212
|
+
},
|
|
213
|
+
beforeUnmount() {
|
|
214
|
+
this.destroyCropper(), this.revokeAllPreviews();
|
|
215
|
+
},
|
|
216
|
+
methods: {
|
|
217
|
+
/** 供父组件通过 ref 调用:是否有未完成上传 */
|
|
218
|
+
isUploading() {
|
|
219
|
+
return this.hasPendingUpload;
|
|
220
|
+
},
|
|
221
|
+
replaceList(e) {
|
|
222
|
+
this.revokeAllPreviews(), this.fileList = e;
|
|
223
|
+
},
|
|
224
|
+
revokePreview(e) {
|
|
225
|
+
e != null && e.previewUrl && (URL.revokeObjectURL(e.previewUrl), e.previewUrl = "");
|
|
226
|
+
},
|
|
227
|
+
revokeAllPreviews() {
|
|
228
|
+
this.fileList.forEach((e) => this.revokePreview(e));
|
|
229
|
+
},
|
|
230
|
+
emitFile() {
|
|
231
|
+
const e = [...this.successUrls];
|
|
232
|
+
this.$emit("update:modelValue", e), this.$emit("sendFile", e);
|
|
233
|
+
},
|
|
234
|
+
openFilePicker() {
|
|
235
|
+
const e = this.$refs.fileInput;
|
|
236
|
+
e && (e.value = "", e.click());
|
|
237
|
+
},
|
|
238
|
+
handleUpload() {
|
|
239
|
+
if (!this.disabled) {
|
|
240
|
+
if (this.fileList.length >= this.fileNum) {
|
|
241
|
+
U.error(`文件数量不超过${this.fileNum}`);
|
|
242
|
+
return;
|
|
243
|
+
}
|
|
244
|
+
this.openFilePicker();
|
|
245
|
+
}
|
|
246
|
+
},
|
|
247
|
+
onFileChange(e) {
|
|
248
|
+
const t = [...e.target.files || []];
|
|
249
|
+
if (!t.length) return;
|
|
250
|
+
const r = this.fileNum - this.fileList.length;
|
|
251
|
+
if (t.length > r) {
|
|
252
|
+
U.error(`文件数量不超过${this.fileNum}个`);
|
|
253
|
+
return;
|
|
254
|
+
}
|
|
255
|
+
const s = [], o = [];
|
|
256
|
+
if (t.forEach((i) => {
|
|
257
|
+
this.acceptList.includes(ne(i.name)) ? s.push(i) : o.push(i);
|
|
258
|
+
}), o.length) {
|
|
259
|
+
const i = o.map((n) => n.name).join(",");
|
|
260
|
+
q.confirm(
|
|
261
|
+
`已过滤以下 ${o.length} 个不符合要求的文件:<br/><p style="color:#f56c6c;font-size:12px;">${i}</p><br/>只接受:${this.acceptList.join("/")}`,
|
|
262
|
+
"提示",
|
|
263
|
+
{
|
|
264
|
+
confirmButtonText: "确认",
|
|
265
|
+
showCancelButton: !1,
|
|
266
|
+
dangerouslyUseHTMLString: !0,
|
|
267
|
+
type: "warning"
|
|
268
|
+
}
|
|
269
|
+
).catch(() => {
|
|
270
|
+
});
|
|
271
|
+
}
|
|
272
|
+
if (s.length) {
|
|
273
|
+
if (this.isCropper) {
|
|
274
|
+
this.openCropper(s[0]);
|
|
275
|
+
return;
|
|
276
|
+
}
|
|
277
|
+
this.startUpload(s);
|
|
278
|
+
}
|
|
279
|
+
},
|
|
280
|
+
openCropper(e) {
|
|
281
|
+
const t = new FileReader();
|
|
282
|
+
t.onloadend = (r) => {
|
|
283
|
+
this.cropImageUrl = r.target.result, this.dialogVisible = !0, this.cropper || this.$nextTick(() => this.initCropper());
|
|
284
|
+
}, t.readAsDataURL(e);
|
|
285
|
+
},
|
|
286
|
+
/** 先预览,再逐张上传;每张图独立进度蒙层 */
|
|
287
|
+
startUpload(e) {
|
|
288
|
+
this.resetFilelist && this.replaceList([]);
|
|
289
|
+
const t = this.maxFileSize * 1024 * 1024, r = [];
|
|
290
|
+
return e.forEach((s) => {
|
|
291
|
+
if (s.size > t) {
|
|
292
|
+
U.error(`「${s.name}」超出 ${this.maxFileSize}MB 限制`);
|
|
293
|
+
return;
|
|
294
|
+
}
|
|
295
|
+
const o = URL.createObjectURL(s), i = {
|
|
296
|
+
uid: $(),
|
|
297
|
+
url: o,
|
|
298
|
+
previewUrl: o,
|
|
299
|
+
status: "uploading",
|
|
300
|
+
percent: 0,
|
|
301
|
+
raw: s
|
|
302
|
+
};
|
|
303
|
+
this.fileList.push(i), r.push(this.uploadOne(i));
|
|
304
|
+
}), Promise.all(r);
|
|
305
|
+
},
|
|
306
|
+
async uploadOne(e) {
|
|
307
|
+
try {
|
|
308
|
+
const t = await re({
|
|
309
|
+
file: e.raw,
|
|
310
|
+
dir: this.getDir(),
|
|
311
|
+
onProgress: (r) => {
|
|
312
|
+
e.percent = r, this.$emit("progress", r, e.raw);
|
|
313
|
+
}
|
|
314
|
+
});
|
|
315
|
+
this.revokePreview(e), e.url = t.url, e.status = "success", e.percent = 100, e.raw = null, this.emitFile(), this.$emit("success", t, e);
|
|
316
|
+
} catch (t) {
|
|
317
|
+
e.status = "fail", e.percent = 0, this.$emit("error", t, e);
|
|
318
|
+
} finally {
|
|
319
|
+
this.dialogVisible && this.handleBack();
|
|
320
|
+
}
|
|
321
|
+
},
|
|
322
|
+
initCropper() {
|
|
323
|
+
const e = this.$refs.cropImage;
|
|
324
|
+
e && (this.cropper = new K(e, {
|
|
325
|
+
aspectRatio: this.aspectRatio,
|
|
326
|
+
autoCropArea: 0.8,
|
|
327
|
+
viewMode: 1,
|
|
328
|
+
movable: !0,
|
|
329
|
+
zoomable: !0,
|
|
330
|
+
rotatable: !0,
|
|
331
|
+
guides: !0,
|
|
332
|
+
background: !0,
|
|
333
|
+
cropBoxMovable: !0,
|
|
334
|
+
cropBoxResizable: !0,
|
|
335
|
+
minCropBoxWidth: 100,
|
|
336
|
+
minCropBoxHeight: 100
|
|
337
|
+
}));
|
|
338
|
+
},
|
|
339
|
+
destroyCropper() {
|
|
340
|
+
this.cropper && (this.cropper.destroy(), this.cropper = null);
|
|
341
|
+
},
|
|
342
|
+
rotate(e) {
|
|
343
|
+
var t;
|
|
344
|
+
(t = this.cropper) == null || t.rotate(e);
|
|
345
|
+
},
|
|
346
|
+
confirmCrop() {
|
|
347
|
+
if (this.uploadingCount) {
|
|
348
|
+
U.error("上传中,请稍后!");
|
|
349
|
+
return;
|
|
350
|
+
}
|
|
351
|
+
if (!this.cropper) return;
|
|
352
|
+
const e = this.cropper.getCroppedCanvas().toDataURL("image/jpeg");
|
|
353
|
+
this.startUpload([this.base64ToFile(e)]);
|
|
354
|
+
},
|
|
355
|
+
base64ToFile(e) {
|
|
356
|
+
const [t, r] = e.split(","), s = t.match(/:(.*?);/)[1], o = s.split("/")[1], i = atob(r), n = new Uint8Array(i.length);
|
|
357
|
+
for (let c = 0; c < i.length; c++) n[c] = i.charCodeAt(c);
|
|
358
|
+
return new File([n], `${Date.now()}.${o}`, { type: s });
|
|
359
|
+
},
|
|
360
|
+
handleBack() {
|
|
361
|
+
this.cropImageUrl = "", this.dialogVisible = !1;
|
|
362
|
+
},
|
|
363
|
+
removeImg(e) {
|
|
364
|
+
const t = this.fileList[e];
|
|
365
|
+
!t || t.status === "uploading" || (this.revokePreview(t), this.fileList.splice(e, 1), this.emitFile());
|
|
366
|
+
}
|
|
367
|
+
}
|
|
368
|
+
}, ae = { class: "upload-image-cropper" }, ce = ["multiple", "accept"], ue = {
|
|
369
|
+
key: 0,
|
|
370
|
+
class: "grey-tips"
|
|
371
|
+
}, pe = { key: 0 }, de = { class: "list-box" }, fe = {
|
|
372
|
+
key: 0,
|
|
373
|
+
class: "status-mask is-uploading"
|
|
374
|
+
}, me = { class: "progress-wrap" }, ge = { class: "percent-text" }, he = {
|
|
375
|
+
key: 1,
|
|
376
|
+
class: "status-mask is-fail"
|
|
377
|
+
}, ye = ["onClick"], we = { class: "cropper-box" }, ke = ["src"], be = { class: "btn-box" }, Ce = { class: "btn-box" };
|
|
378
|
+
function _e(e, t, r, s, o, i) {
|
|
379
|
+
const n = y("el-image"), c = y("el-progress"), C = y("CircleCloseFilled"), l = y("el-icon"), a = y("Delete"), w = y("Plus"), m = y("el-button"), k = y("el-dialog");
|
|
380
|
+
return g(), h("div", ae, [
|
|
381
|
+
d("input", {
|
|
382
|
+
ref: "fileInput",
|
|
383
|
+
type: "file",
|
|
384
|
+
class: "file-input",
|
|
385
|
+
multiple: i.multiple,
|
|
386
|
+
accept: r.accept,
|
|
387
|
+
onChange: t[0] || (t[0] = (...u) => i.onFileChange && i.onFileChange(...u))
|
|
388
|
+
}, null, 40, ce),
|
|
389
|
+
r.greyTips ? (g(), h("div", ue, [
|
|
390
|
+
r.otherTips ? (g(), h("div", pe, S(r.otherTips), 1)) : v("", !0),
|
|
391
|
+
b(" " + S(r.greyTips), 1)
|
|
392
|
+
])) : v("", !0),
|
|
393
|
+
d("div", de, [
|
|
394
|
+
(g(!0), h(P, null, G(o.fileList, (u, _) => (g(), h("div", {
|
|
395
|
+
key: u.uid,
|
|
396
|
+
class: W(["image-box", [`is-${u.status}`]]),
|
|
397
|
+
style: T(r.imageStyle)
|
|
398
|
+
}, [
|
|
399
|
+
p(n, {
|
|
400
|
+
src: u.url,
|
|
401
|
+
fit: "cover",
|
|
402
|
+
class: "img"
|
|
403
|
+
}, null, 8, ["src"]),
|
|
404
|
+
u.status === "uploading" ? (g(), h("div", fe, [
|
|
405
|
+
d("div", me, [
|
|
406
|
+
p(c, {
|
|
407
|
+
type: "circle",
|
|
408
|
+
percentage: u.percent,
|
|
409
|
+
width: 30,
|
|
410
|
+
"stroke-width": 3,
|
|
411
|
+
"show-text": !1,
|
|
412
|
+
color: "var(--mg-primary, #ff5722)"
|
|
413
|
+
}, null, 8, ["percentage"]),
|
|
414
|
+
d("span", ge, S(u.percent) + "%", 1)
|
|
415
|
+
])
|
|
416
|
+
])) : u.status === "fail" ? (g(), h("div", he, [
|
|
417
|
+
p(l, {
|
|
418
|
+
class: "fail-icon",
|
|
419
|
+
size: 16
|
|
420
|
+
}, {
|
|
421
|
+
default: f(() => [
|
|
422
|
+
p(C)
|
|
423
|
+
]),
|
|
424
|
+
_: 1
|
|
425
|
+
}),
|
|
426
|
+
t[5] || (t[5] = d("span", { class: "fail-text" }, "失败", -1)),
|
|
427
|
+
p(l, {
|
|
428
|
+
class: "remove-icon",
|
|
429
|
+
size: 14,
|
|
430
|
+
title: "删除",
|
|
431
|
+
onClick: J((R) => i.removeImg(_), ["stop"])
|
|
432
|
+
}, {
|
|
433
|
+
default: f(() => [
|
|
434
|
+
p(a)
|
|
435
|
+
]),
|
|
436
|
+
_: 1
|
|
437
|
+
}, 8, ["onClick"])
|
|
438
|
+
])) : (g(), h("div", {
|
|
439
|
+
key: 2,
|
|
440
|
+
class: "status-mask is-success",
|
|
441
|
+
onClick: (R) => i.removeImg(_)
|
|
442
|
+
}, [
|
|
443
|
+
p(l, {
|
|
444
|
+
class: "remove-icon",
|
|
445
|
+
size: 16
|
|
446
|
+
}, {
|
|
447
|
+
default: f(() => [
|
|
448
|
+
p(a)
|
|
449
|
+
]),
|
|
450
|
+
_: 1
|
|
451
|
+
})
|
|
452
|
+
], 8, ye))
|
|
453
|
+
], 6))), 128)),
|
|
454
|
+
I(d("div", {
|
|
455
|
+
class: "image-box upload-btn",
|
|
456
|
+
style: T(r.imageStyle),
|
|
457
|
+
onClick: t[1] || (t[1] = (...u) => i.handleUpload && i.handleUpload(...u))
|
|
458
|
+
}, [
|
|
459
|
+
p(l, {
|
|
460
|
+
class: "icon",
|
|
461
|
+
size: 14
|
|
462
|
+
}, {
|
|
463
|
+
default: f(() => [
|
|
464
|
+
p(w)
|
|
465
|
+
]),
|
|
466
|
+
_: 1
|
|
467
|
+
}),
|
|
468
|
+
t[6] || (t[6] = d("div", null, "上传图片", -1))
|
|
469
|
+
], 4), [
|
|
470
|
+
[O, i.showUploadBtn]
|
|
471
|
+
])
|
|
472
|
+
]),
|
|
473
|
+
p(k, {
|
|
474
|
+
modelValue: o.dialogVisible,
|
|
475
|
+
"onUpdate:modelValue": t[4] || (t[4] = (u) => o.dialogVisible = u),
|
|
476
|
+
title: "裁剪图片",
|
|
477
|
+
width: "600px",
|
|
478
|
+
top: "5vh",
|
|
479
|
+
"append-to-body": "",
|
|
480
|
+
"close-on-click-modal": !1,
|
|
481
|
+
onClose: i.handleBack
|
|
482
|
+
}, {
|
|
483
|
+
default: f(() => [
|
|
484
|
+
d("div", we, [
|
|
485
|
+
I(d("img", {
|
|
486
|
+
ref: "cropImage",
|
|
487
|
+
src: o.cropImageUrl,
|
|
488
|
+
class: "cropper-img"
|
|
489
|
+
}, null, 8, ke), [
|
|
490
|
+
[O, o.cropImageUrl]
|
|
491
|
+
])
|
|
492
|
+
]),
|
|
493
|
+
d("div", be, [
|
|
494
|
+
r.isDegree ? (g(), h(P, { key: 0 }, [
|
|
495
|
+
p(m, {
|
|
496
|
+
onClick: t[2] || (t[2] = (u) => i.rotate(-r.degree))
|
|
497
|
+
}, {
|
|
498
|
+
default: f(() => [...t[7] || (t[7] = [
|
|
499
|
+
b("向左旋转", -1)
|
|
500
|
+
])]),
|
|
501
|
+
_: 1
|
|
502
|
+
}),
|
|
503
|
+
p(m, {
|
|
504
|
+
onClick: t[3] || (t[3] = (u) => i.rotate(r.degree))
|
|
505
|
+
}, {
|
|
506
|
+
default: f(() => [...t[8] || (t[8] = [
|
|
507
|
+
b("向右旋转", -1)
|
|
508
|
+
])]),
|
|
509
|
+
_: 1
|
|
510
|
+
})
|
|
511
|
+
], 64)) : v("", !0),
|
|
512
|
+
p(m, {
|
|
513
|
+
type: "primary",
|
|
514
|
+
onClick: i.openFilePicker
|
|
515
|
+
}, {
|
|
516
|
+
default: f(() => [
|
|
517
|
+
b(S(o.cropImageUrl ? "重新上传" : "点击上传"), 1)
|
|
518
|
+
]),
|
|
519
|
+
_: 1
|
|
520
|
+
}, 8, ["onClick"])
|
|
521
|
+
]),
|
|
522
|
+
d("div", Ce, [
|
|
523
|
+
p(m, { onClick: i.handleBack }, {
|
|
524
|
+
default: f(() => [...t[9] || (t[9] = [
|
|
525
|
+
b("取 消", -1)
|
|
526
|
+
])]),
|
|
527
|
+
_: 1
|
|
528
|
+
}, 8, ["onClick"]),
|
|
529
|
+
p(m, {
|
|
530
|
+
type: "primary",
|
|
531
|
+
onClick: i.confirmCrop
|
|
532
|
+
}, {
|
|
533
|
+
default: f(() => [...t[10] || (t[10] = [
|
|
534
|
+
b("确定", -1)
|
|
535
|
+
])]),
|
|
536
|
+
_: 1
|
|
537
|
+
}, 8, ["onClick"])
|
|
538
|
+
])
|
|
539
|
+
]),
|
|
540
|
+
_: 1
|
|
541
|
+
}, 8, ["modelValue", "onClose"])
|
|
542
|
+
]);
|
|
543
|
+
}
|
|
544
|
+
const Ue = /* @__PURE__ */ ie(le, [["render", _e], ["__scopeId", "data-v-07c103ef"]]);
|
|
545
|
+
function Se(e) {
|
|
546
|
+
return !!(e == null || typeof e == "string" && e.trim() === "" || Array.isArray(e) && e.length === 0 || typeof e == "object" && !Array.isArray(e) && Object.keys(e).length === 0);
|
|
547
|
+
}
|
|
548
|
+
function L(e) {
|
|
549
|
+
if (e === null || typeof e != "object") return e;
|
|
550
|
+
if (e instanceof Date) return new Date(e.getTime());
|
|
551
|
+
if (Array.isArray(e)) return e.map((r) => L(r));
|
|
552
|
+
const t = {};
|
|
553
|
+
return Object.keys(e).forEach((r) => {
|
|
554
|
+
t[r] = L(e[r]);
|
|
555
|
+
}), t;
|
|
556
|
+
}
|
|
557
|
+
function ve(e, t = 300) {
|
|
558
|
+
let r = null;
|
|
559
|
+
return function(...o) {
|
|
560
|
+
r && clearTimeout(r), r = setTimeout(() => {
|
|
561
|
+
e.apply(this, o);
|
|
562
|
+
}, t);
|
|
563
|
+
};
|
|
564
|
+
}
|
|
565
|
+
function xe(e, t = 300) {
|
|
566
|
+
let r = 0;
|
|
567
|
+
return function(...o) {
|
|
568
|
+
const i = Date.now();
|
|
569
|
+
i - r >= t && (r = i, e.apply(this, o));
|
|
570
|
+
};
|
|
571
|
+
}
|
|
572
|
+
function Le(e, t = "YYYY-MM-DD HH:mm:ss") {
|
|
573
|
+
const r = e instanceof Date ? e : new Date(e);
|
|
574
|
+
if (Number.isNaN(r.getTime())) return "";
|
|
575
|
+
const s = {
|
|
576
|
+
YYYY: String(r.getFullYear()),
|
|
577
|
+
MM: String(r.getMonth() + 1).padStart(2, "0"),
|
|
578
|
+
DD: String(r.getDate()).padStart(2, "0"),
|
|
579
|
+
HH: String(r.getHours()).padStart(2, "0"),
|
|
580
|
+
mm: String(r.getMinutes()).padStart(2, "0"),
|
|
581
|
+
ss: String(r.getSeconds()).padStart(2, "0")
|
|
582
|
+
};
|
|
583
|
+
return Object.keys(s).reduce((o, i) => o.replace(i, s[i]), t);
|
|
584
|
+
}
|
|
585
|
+
function De(e = "id") {
|
|
586
|
+
return `${e}_${Date.now()}_${Math.random().toString(36).slice(2, 9)}`;
|
|
587
|
+
}
|
|
588
|
+
const $e = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({
|
|
589
|
+
__proto__: null,
|
|
590
|
+
debounce: ve,
|
|
591
|
+
deepClone: L,
|
|
592
|
+
formatDate: Le,
|
|
593
|
+
isEmpty: Se,
|
|
594
|
+
throttle: xe,
|
|
595
|
+
uniqueId: De
|
|
596
|
+
}, Symbol.toStringTag, { value: "Module" }));
|
|
597
|
+
function Fe(e = {}) {
|
|
598
|
+
const {
|
|
599
|
+
baseURL: t = "",
|
|
600
|
+
timeout: r = 6e4,
|
|
601
|
+
tokenKey: s,
|
|
602
|
+
systemIdKey: o,
|
|
603
|
+
loginUrl: i = "/login"
|
|
604
|
+
} = e, n = Q.create({ baseURL: t, timeout: r });
|
|
605
|
+
let c = !1;
|
|
606
|
+
function C() {
|
|
607
|
+
typeof localStorage < "u" && localStorage.clear(), !c && (c = !0, setTimeout(() => {
|
|
608
|
+
typeof window < "u" && window.location.replace(i);
|
|
609
|
+
}, 1500));
|
|
610
|
+
}
|
|
611
|
+
return n.interceptors.request.use(
|
|
612
|
+
(l) => {
|
|
613
|
+
if (l.headers["Content-Type"] = "application/json;charset=UTF-8", typeof localStorage < "u") {
|
|
614
|
+
if (s) {
|
|
615
|
+
const a = localStorage.getItem(s);
|
|
616
|
+
a && (l.headers.Authorization = a);
|
|
617
|
+
}
|
|
618
|
+
if (o) {
|
|
619
|
+
const a = localStorage.getItem(o);
|
|
620
|
+
a && (l.headers.systemId = a);
|
|
621
|
+
}
|
|
622
|
+
}
|
|
623
|
+
return l;
|
|
624
|
+
},
|
|
625
|
+
(l) => Promise.reject(l)
|
|
626
|
+
), n.interceptors.response.use(
|
|
627
|
+
(l) => {
|
|
628
|
+
if (l.status !== 200)
|
|
629
|
+
return Promise.reject(new Error(`请求发生错误,状态码 ${l.status}`));
|
|
630
|
+
const { data: a, config: w } = l;
|
|
631
|
+
if (w.responseType === "arraybuffer") return a;
|
|
632
|
+
if (a && a.code === 0) return a.data;
|
|
633
|
+
if (a && (a.code === 401 || a.code === 403))
|
|
634
|
+
return C(), Promise.reject(new Error("登录失效,请重新登录"));
|
|
635
|
+
const m = a && (a.data || a.message || a.msg) || "请求失败";
|
|
636
|
+
return Promise.reject(new Error(String(m)));
|
|
637
|
+
},
|
|
638
|
+
(l) => Promise.reject(l)
|
|
639
|
+
), n;
|
|
640
|
+
}
|
|
641
|
+
function Pe(e = {}) {
|
|
642
|
+
const t = Fe(e);
|
|
643
|
+
return {
|
|
644
|
+
GET(r, s = {}) {
|
|
645
|
+
return t({ method: "get", url: r, ...s });
|
|
646
|
+
},
|
|
647
|
+
POST(r, s, o = {}) {
|
|
648
|
+
return t({ method: "post", url: r, data: s, ...o });
|
|
649
|
+
},
|
|
650
|
+
DELETE(r, s = {}) {
|
|
651
|
+
return t({ method: "delete", url: r, ...s });
|
|
652
|
+
}
|
|
653
|
+
};
|
|
654
|
+
}
|
|
655
|
+
let D = null;
|
|
656
|
+
function Te(e) {
|
|
657
|
+
D = e;
|
|
658
|
+
}
|
|
659
|
+
function Re() {
|
|
660
|
+
if (!D)
|
|
661
|
+
throw new Error("[mgacn-commonsdk] 请先 app.use(MgacnCommonSdk, { tokenKey, baseURL })");
|
|
662
|
+
return D;
|
|
663
|
+
}
|
|
664
|
+
const Ie = [Ue], Oe = (e, t = {}) => {
|
|
665
|
+
Ie.forEach((o) => {
|
|
666
|
+
o.name && e.component(o.name, o);
|
|
667
|
+
});
|
|
668
|
+
const r = Pe(t), s = X(r);
|
|
669
|
+
Te(r), Z(s), e.config.globalProperties.$request = r, e.config.globalProperties.$api = s;
|
|
670
|
+
}, Ve = {
|
|
671
|
+
install: Oe,
|
|
672
|
+
version: "1.0.0"
|
|
673
|
+
};
|
|
674
|
+
export {
|
|
675
|
+
Ue as ImageUpload,
|
|
676
|
+
se as aliOssMixin,
|
|
677
|
+
X as createApi,
|
|
678
|
+
M as createOssClient,
|
|
679
|
+
Pe as createRequest,
|
|
680
|
+
Fe as createService,
|
|
681
|
+
Ve as default,
|
|
682
|
+
ee as getApi,
|
|
683
|
+
j as getOssSts,
|
|
684
|
+
Re as getRequest,
|
|
685
|
+
Oe as install,
|
|
686
|
+
re as uploadToOss,
|
|
687
|
+
$e as utils
|
|
688
|
+
};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
(function(a,f){typeof exports=="object"&&typeof module<"u"?f(exports,require("@element-plus/icons-vue"),require("element-plus"),require("cropperjs"),require("ali-oss"),require("vue"),require("axios")):typeof define=="function"&&define.amd?define(["exports","@element-plus/icons-vue","element-plus","cropperjs","ali-oss","vue","axios"],f):(a=typeof globalThis<"u"?globalThis:a||self,f(a.MgacnCommonSdk={},a.ElementPlusIconsVue,a.ElementPlus,a.Cropper,a.OSS,a.Vue,a.axios))})(this,(function(a,f,y,A,R,t,$){"use strict";function E(e){if(!e)throw new Error("[mgacn-commonsdk] createApi 需要传入 request 实例");return{getUserInfo(r){return e.GET("/yhAdmin/user/queryUserById",{params:{id:r}})},getOssSts(r){return e.GET("/yhAdmin/oss/fileUploadSts",{params:{dir:r}})}}}let C=null;function q(e){C=e}function V(){if(!C)throw new Error("[mgacn-commonsdk] 请先 app.use(MgacnCommonSdk, { tokenKey, baseURL })");return C}function x(e){return String(e).padStart(2,"0")}function z(){const e=new Date;return`${e.getFullYear()}${x(e.getMonth()+1)}${x(e.getDate())}`}function D(e=10){const r="0123456789abcdefghijklmnopqrstuvwxyz";let s="";for(let i=0;i<e;i++)s+=r[Math.floor(Math.random()*r.length)];return s}function S(e="portal_cms"){return`${e}/${z()}/`}function _(e){return V().getOssSts(e)}async function b(e={}){const{dir:r,foldName:s,getOss:i,ossinfo:n}=e,o=r||S(s||"portal_cms"),l=n||(typeof i=="function"?await i(o):await _(o));if(!l)throw new Error("[mgacn-commonsdk] 获取 OSS STS 失败");const p=new R({bucket:l.bucketName,accessKeyId:l.accessKeyId,accessKeySecret:l.accessKeySecret,success_action_status:"200",stsToken:l.securityToken,endpoint:l.endPoint});return p.options.ossUrl=l.ossUrl||l.domain||(l.bucketName&&l.endPoint?`https://${l.bucketName}.${l.endPoint}`:""),p.options.uploadDir=o,p}async function B(e={}){const{client:r,file:s,dir:i,foldName:n,fileName:o,onProgress:l}=e;if(!s)throw new Error("[mgacn-commonsdk] uploadToOss 缺少 file");const p=r||await b({dir:i,foldName:n}),k=i||p.options.uploadDir||S(n);let c=o;if(!c){const h=s.name||"file",u=h.indexOf("."),w=u>-1?h.slice(u):"";c=`${k}${D(10)}${w}`}const d=await p.multipartUpload(c,s,{progress:h=>{typeof l=="function"&&l(Math.floor(h*100))}});if(d.res&&d.res.statusCode!==200)throw new Error("[mgacn-commonsdk] 上传失败");const g=(p.options.ossUrl||"").replace(/\/$/,""),m=g?`${g}/${c}`:c;return{name:c,url:m,raw:d,client:p}}const T={methods:{getDir(){return S(this.foldName||"portal_cms")},randomString:D,getOss(){return _(this.getDir())},async createOssClient(){return b({dir:this.getDir(),getOss:()=>this.getOss()})}}},Y=(e,r)=>{const s=e.__vccOpts||e;for(const[i,n]of r)s[i]=n;return s};let L=0;function O(){return L+=1,`mg-img-${Date.now()}-${L}`}function K(e){return Array.isArray(e)?e.filter(Boolean):e?[e]:[]}function F(e){return e.map(r=>({uid:O(),url:r,status:"success",percent:100,previewUrl:""}))}function H(e=""){const r=e.lastIndexOf(".");return r>-1?e.slice(r+1).toLowerCase():""}const G={name:"MgImageUpload",mixins:[T],components:{CircleCloseFilled:f.CircleCloseFilled,Delete:f.Delete,Plus:f.Plus},props:{modelValue:{type:[Array,String],default:()=>[]},greyTips:String,otherTips:String,maxFileSize:{type:Number,default:100},fileNum:{type:Number,default:1},initFileList:{type:Array,default:()=>[]},isCropper:Boolean,isDegree:Boolean,degree:{type:Number,default:3},aspectRatio:{type:Number,default:1},imageStyle:Object,resetFilelist:Boolean,accept:{type:String,default:".jpg,.jpeg,.png,.gif,.svg"},foldName:{type:String,default:"portal_cms"},disabled:Boolean,uploading:{type:Boolean,default:!1}},emits:["update:modelValue","update:uploading","sendFile","success","error","progress"],expose:["hasPendingUpload","isUploading"],data(){return{fileList:[],cropImageUrl:"",dialogVisible:!1,cropper:null}},computed:{multiple(){return this.fileNum>1&&!this.isCropper},hasPendingUpload(){return this.fileList.some(e=>e.status==="uploading")},uploadingCount(){return this.fileList.filter(e=>e.status==="uploading").length},showUploadBtn(){return!this.disabled&&this.fileList.length<this.fileNum},acceptList(){return this.accept.split(",").map(e=>e.replace(".","").trim().toLowerCase()).filter(Boolean)},successUrls(){return this.fileList.filter(e=>e.status==="success").map(e=>e.url)}},watch:{hasPendingUpload:{immediate:!0,handler(e){e!==this.uploading&&this.$emit("update:uploading",e)}},initFileList:{deep:!0,immediate:!0,handler(e){e!=null&&e.length&&this.replaceList(F(e))}},modelValue:{immediate:!0,handler(e){var i;if((i=this.initFileList)!=null&&i.length)return;const r=K(e),s=this.successUrls;r.length===s.length&&r.every((n,o)=>n===s[o])||this.replaceList(F(r))}},cropImageUrl(e){this.cropper&&(e?this.cropper.replace(e):this.destroyCropper())}},beforeUnmount(){this.destroyCropper(),this.revokeAllPreviews()},methods:{isUploading(){return this.hasPendingUpload},replaceList(e){this.revokeAllPreviews(),this.fileList=e},revokePreview(e){e!=null&&e.previewUrl&&(URL.revokeObjectURL(e.previewUrl),e.previewUrl="")},revokeAllPreviews(){this.fileList.forEach(e=>this.revokePreview(e))},emitFile(){const e=[...this.successUrls];this.$emit("update:modelValue",e),this.$emit("sendFile",e)},openFilePicker(){const e=this.$refs.fileInput;e&&(e.value="",e.click())},handleUpload(){if(!this.disabled){if(this.fileList.length>=this.fileNum){y.ElMessage.error(`文件数量不超过${this.fileNum}`);return}this.openFilePicker()}},onFileChange(e){const r=[...e.target.files||[]];if(!r.length)return;const s=this.fileNum-this.fileList.length;if(r.length>s){y.ElMessage.error(`文件数量不超过${this.fileNum}个`);return}const i=[],n=[];if(r.forEach(o=>{this.acceptList.includes(H(o.name))?i.push(o):n.push(o)}),n.length){const o=n.map(l=>l.name).join(",");y.ElMessageBox.confirm(`已过滤以下 ${n.length} 个不符合要求的文件:<br/><p style="color:#f56c6c;font-size:12px;">${o}</p><br/>只接受:${this.acceptList.join("/")}`,"提示",{confirmButtonText:"确认",showCancelButton:!1,dangerouslyUseHTMLString:!0,type:"warning"}).catch(()=>{})}if(i.length){if(this.isCropper){this.openCropper(i[0]);return}this.startUpload(i)}},openCropper(e){const r=new FileReader;r.onloadend=s=>{this.cropImageUrl=s.target.result,this.dialogVisible=!0,this.cropper||this.$nextTick(()=>this.initCropper())},r.readAsDataURL(e)},startUpload(e){this.resetFilelist&&this.replaceList([]);const r=this.maxFileSize*1024*1024,s=[];return e.forEach(i=>{if(i.size>r){y.ElMessage.error(`「${i.name}」超出 ${this.maxFileSize}MB 限制`);return}const n=URL.createObjectURL(i),o={uid:O(),url:n,previewUrl:n,status:"uploading",percent:0,raw:i};this.fileList.push(o),s.push(this.uploadOne(o))}),Promise.all(s)},async uploadOne(e){try{const r=await B({file:e.raw,dir:this.getDir(),onProgress:s=>{e.percent=s,this.$emit("progress",s,e.raw)}});this.revokePreview(e),e.url=r.url,e.status="success",e.percent=100,e.raw=null,this.emitFile(),this.$emit("success",r,e)}catch(r){e.status="fail",e.percent=0,this.$emit("error",r,e)}finally{this.dialogVisible&&this.handleBack()}},initCropper(){const e=this.$refs.cropImage;e&&(this.cropper=new A(e,{aspectRatio:this.aspectRatio,autoCropArea:.8,viewMode:1,movable:!0,zoomable:!0,rotatable:!0,guides:!0,background:!0,cropBoxMovable:!0,cropBoxResizable:!0,minCropBoxWidth:100,minCropBoxHeight:100}))},destroyCropper(){this.cropper&&(this.cropper.destroy(),this.cropper=null)},rotate(e){var r;(r=this.cropper)==null||r.rotate(e)},confirmCrop(){if(this.uploadingCount){y.ElMessage.error("上传中,请稍后!");return}if(!this.cropper)return;const e=this.cropper.getCroppedCanvas().toDataURL("image/jpeg");this.startUpload([this.base64ToFile(e)])},base64ToFile(e){const[r,s]=e.split(","),i=r.match(/:(.*?);/)[1],n=i.split("/")[1],o=atob(s),l=new Uint8Array(o.length);for(let p=0;p<o.length;p++)l[p]=o.charCodeAt(p);return new File([l],`${Date.now()}.${n}`,{type:i})},handleBack(){this.cropImageUrl="",this.dialogVisible=!1},removeImg(e){const r=this.fileList[e];!r||r.status==="uploading"||(this.revokePreview(r),this.fileList.splice(e,1),this.emitFile())}}},W={class:"upload-image-cropper"},J=["multiple","accept"],Q={key:0,class:"grey-tips"},X={key:0},Z={class:"list-box"},v={key:0,class:"status-mask is-uploading"},ee={class:"progress-wrap"},te={class:"percent-text"},re={key:1,class:"status-mask is-fail"},se=["onClick"],ie={class:"cropper-box"},oe=["src"],ne={class:"btn-box"},le={class:"btn-box"};function ae(e,r,s,i,n,o){const l=t.resolveComponent("el-image"),p=t.resolveComponent("el-progress"),k=t.resolveComponent("CircleCloseFilled"),c=t.resolveComponent("el-icon"),d=t.resolveComponent("Delete"),g=t.resolveComponent("Plus"),m=t.resolveComponent("el-button"),h=t.resolveComponent("el-dialog");return t.openBlock(),t.createElementBlock("div",W,[t.createElementVNode("input",{ref:"fileInput",type:"file",class:"file-input",multiple:o.multiple,accept:s.accept,onChange:r[0]||(r[0]=(...u)=>o.onFileChange&&o.onFileChange(...u))},null,40,J),s.greyTips?(t.openBlock(),t.createElementBlock("div",Q,[s.otherTips?(t.openBlock(),t.createElementBlock("div",X,t.toDisplayString(s.otherTips),1)):t.createCommentVNode("",!0),t.createTextVNode(" "+t.toDisplayString(s.greyTips),1)])):t.createCommentVNode("",!0),t.createElementVNode("div",Z,[(t.openBlock(!0),t.createElementBlock(t.Fragment,null,t.renderList(n.fileList,(u,w)=>(t.openBlock(),t.createElementBlock("div",{key:u.uid,class:t.normalizeClass(["image-box",[`is-${u.status}`]]),style:t.normalizeStyle(s.imageStyle)},[t.createVNode(l,{src:u.url,fit:"cover",class:"img"},null,8,["src"]),u.status==="uploading"?(t.openBlock(),t.createElementBlock("div",v,[t.createElementVNode("div",ee,[t.createVNode(p,{type:"circle",percentage:u.percent,width:30,"stroke-width":3,"show-text":!1,color:"var(--mg-primary, #ff5722)"},null,8,["percentage"]),t.createElementVNode("span",te,t.toDisplayString(u.percent)+"%",1)])])):u.status==="fail"?(t.openBlock(),t.createElementBlock("div",re,[t.createVNode(c,{class:"fail-icon",size:16},{default:t.withCtx(()=>[t.createVNode(k)]),_:1}),r[5]||(r[5]=t.createElementVNode("span",{class:"fail-text"},"失败",-1)),t.createVNode(c,{class:"remove-icon",size:14,title:"删除",onClick:t.withModifiers(we=>o.removeImg(w),["stop"])},{default:t.withCtx(()=>[t.createVNode(d)]),_:1},8,["onClick"])])):(t.openBlock(),t.createElementBlock("div",{key:2,class:"status-mask is-success",onClick:we=>o.removeImg(w)},[t.createVNode(c,{class:"remove-icon",size:16},{default:t.withCtx(()=>[t.createVNode(d)]),_:1})],8,se))],6))),128)),t.withDirectives(t.createElementVNode("div",{class:"image-box upload-btn",style:t.normalizeStyle(s.imageStyle),onClick:r[1]||(r[1]=(...u)=>o.handleUpload&&o.handleUpload(...u))},[t.createVNode(c,{class:"icon",size:14},{default:t.withCtx(()=>[t.createVNode(g)]),_:1}),r[6]||(r[6]=t.createElementVNode("div",null,"上传图片",-1))],4),[[t.vShow,o.showUploadBtn]])]),t.createVNode(h,{modelValue:n.dialogVisible,"onUpdate:modelValue":r[4]||(r[4]=u=>n.dialogVisible=u),title:"裁剪图片",width:"600px",top:"5vh","append-to-body":"","close-on-click-modal":!1,onClose:o.handleBack},{default:t.withCtx(()=>[t.createElementVNode("div",ie,[t.withDirectives(t.createElementVNode("img",{ref:"cropImage",src:n.cropImageUrl,class:"cropper-img"},null,8,oe),[[t.vShow,n.cropImageUrl]])]),t.createElementVNode("div",ne,[s.isDegree?(t.openBlock(),t.createElementBlock(t.Fragment,{key:0},[t.createVNode(m,{onClick:r[2]||(r[2]=u=>o.rotate(-s.degree))},{default:t.withCtx(()=>[...r[7]||(r[7]=[t.createTextVNode("向左旋转",-1)])]),_:1}),t.createVNode(m,{onClick:r[3]||(r[3]=u=>o.rotate(s.degree))},{default:t.withCtx(()=>[...r[8]||(r[8]=[t.createTextVNode("向右旋转",-1)])]),_:1})],64)):t.createCommentVNode("",!0),t.createVNode(m,{type:"primary",onClick:o.openFilePicker},{default:t.withCtx(()=>[t.createTextVNode(t.toDisplayString(n.cropImageUrl?"重新上传":"点击上传"),1)]),_:1},8,["onClick"])]),t.createElementVNode("div",le,[t.createVNode(m,{onClick:o.handleBack},{default:t.withCtx(()=>[...r[9]||(r[9]=[t.createTextVNode("取 消",-1)])]),_:1},8,["onClick"]),t.createVNode(m,{type:"primary",onClick:o.confirmCrop},{default:t.withCtx(()=>[...r[10]||(r[10]=[t.createTextVNode("确定",-1)])]),_:1},8,["onClick"])])]),_:1},8,["modelValue","onClose"])])}const I=Y(G,[["render",ae],["__scopeId","data-v-07c103ef"]]);function ce(e){return!!(e==null||typeof e=="string"&&e.trim()===""||Array.isArray(e)&&e.length===0||typeof e=="object"&&!Array.isArray(e)&&Object.keys(e).length===0)}function N(e){if(e===null||typeof e!="object")return e;if(e instanceof Date)return new Date(e.getTime());if(Array.isArray(e))return e.map(s=>N(s));const r={};return Object.keys(e).forEach(s=>{r[s]=N(e[s])}),r}function de(e,r=300){let s=null;return function(...n){s&&clearTimeout(s),s=setTimeout(()=>{e.apply(this,n)},r)}}function pe(e,r=300){let s=0;return function(...n){const o=Date.now();o-s>=r&&(s=o,e.apply(this,n))}}function ue(e,r="YYYY-MM-DD HH:mm:ss"){const s=e instanceof Date?e:new Date(e);if(Number.isNaN(s.getTime()))return"";const i={YYYY:String(s.getFullYear()),MM:String(s.getMonth()+1).padStart(2,"0"),DD:String(s.getDate()).padStart(2,"0"),HH:String(s.getHours()).padStart(2,"0"),mm:String(s.getMinutes()).padStart(2,"0"),ss:String(s.getSeconds()).padStart(2,"0")};return Object.keys(i).reduce((n,o)=>n.replace(o,i[o]),r)}function me(e="id"){return`${e}_${Date.now()}_${Math.random().toString(36).slice(2,9)}`}const fe=Object.freeze(Object.defineProperty({__proto__:null,debounce:de,deepClone:N,formatDate:ue,isEmpty:ce,throttle:pe,uniqueId:me},Symbol.toStringTag,{value:"Module"}));function P(e={}){const{baseURL:r="",timeout:s=6e4,tokenKey:i,systemIdKey:n,loginUrl:o="/login"}=e,l=$.create({baseURL:r,timeout:s});let p=!1;function k(){typeof localStorage<"u"&&localStorage.clear(),!p&&(p=!0,setTimeout(()=>{typeof window<"u"&&window.location.replace(o)},1500))}return l.interceptors.request.use(c=>{if(c.headers["Content-Type"]="application/json;charset=UTF-8",typeof localStorage<"u"){if(i){const d=localStorage.getItem(i);d&&(c.headers.Authorization=d)}if(n){const d=localStorage.getItem(n);d&&(c.headers.systemId=d)}}return c},c=>Promise.reject(c)),l.interceptors.response.use(c=>{if(c.status!==200)return Promise.reject(new Error(`请求发生错误,状态码 ${c.status}`));const{data:d,config:g}=c;if(g.responseType==="arraybuffer")return d;if(d&&d.code===0)return d.data;if(d&&(d.code===401||d.code===403))return k(),Promise.reject(new Error("登录失效,请重新登录"));const m=d&&(d.data||d.message||d.msg)||"请求失败";return Promise.reject(new Error(String(m)))},c=>Promise.reject(c)),l}function M(e={}){const r=P(e);return{GET(s,i={}){return r({method:"get",url:s,...i})},POST(s,i,n={}){return r({method:"post",url:s,data:i,...n})},DELETE(s,i={}){return r({method:"delete",url:s,...i})}}}let U=null;function ge(e){U=e}function he(){if(!U)throw new Error("[mgacn-commonsdk] 请先 app.use(MgacnCommonSdk, { tokenKey, baseURL })");return U}const ye=[I],j=(e,r={})=>{ye.forEach(n=>{n.name&&e.component(n.name,n)});const s=M(r),i=E(s);ge(s),q(i),e.config.globalProperties.$request=s,e.config.globalProperties.$api=i},ke={install:j,version:"1.0.0"};a.ImageUpload=I,a.aliOssMixin=T,a.createApi=E,a.createOssClient=b,a.createRequest=M,a.createService=P,a.default=ke,a.getApi=V,a.getOssSts=_,a.getRequest=he,a.install=j,a.uploadToOss=B,a.utils=fe,Object.defineProperties(a,{__esModule:{value:!0},[Symbol.toStringTag]:{value:"Module"}})}));
|
package/dist/style.css
ADDED
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
/*!
|
|
2
|
+
* Cropper.js v1.6.2
|
|
3
|
+
* https://fengyuanchen.github.io/cropperjs
|
|
4
|
+
*
|
|
5
|
+
* Copyright 2015-present Chen Fengyuan
|
|
6
|
+
* Released under the MIT license
|
|
7
|
+
*
|
|
8
|
+
* Date: 2024-04-21T07:43:02.731Z
|
|
9
|
+
*/.cropper-container{direction:ltr;font-size:0;line-height:0;position:relative;-ms-touch-action:none;touch-action:none;-webkit-touch-callout:none;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none}.cropper-container img{backface-visibility:hidden;display:block;height:100%;image-orientation:0deg;max-height:none!important;max-width:none!important;min-height:0!important;min-width:0!important;width:100%}.cropper-wrap-box,.cropper-canvas,.cropper-drag-box,.cropper-crop-box,.cropper-modal{bottom:0;left:0;position:absolute;right:0;top:0}.cropper-wrap-box,.cropper-canvas{overflow:hidden}.cropper-drag-box{background-color:#fff;opacity:0}.cropper-modal{background-color:#000;opacity:.5}.cropper-view-box{display:block;height:100%;outline:1px solid #39f;outline-color:#3399ffbf;overflow:hidden;width:100%}.cropper-dashed{border:0 dashed #eee;display:block;opacity:.5;position:absolute}.cropper-dashed.dashed-h{border-bottom-width:1px;border-top-width:1px;height:calc(100% / 3);left:0;top:calc(100% / 3);width:100%}.cropper-dashed.dashed-v{border-left-width:1px;border-right-width:1px;height:100%;left:calc(100% / 3);top:0;width:calc(100% / 3)}.cropper-center{display:block;height:0;left:50%;opacity:.75;position:absolute;top:50%;width:0}.cropper-center:before,.cropper-center:after{background-color:#eee;content:" ";display:block;position:absolute}.cropper-center:before{height:1px;left:-3px;top:0;width:7px}.cropper-center:after{height:7px;left:0;top:-3px;width:1px}.cropper-face,.cropper-line,.cropper-point{display:block;height:100%;opacity:.1;position:absolute;width:100%}.cropper-face{background-color:#fff;left:0;top:0}.cropper-line{background-color:#39f}.cropper-line.line-e{cursor:ew-resize;right:-3px;top:0;width:5px}.cropper-line.line-n{cursor:ns-resize;height:5px;left:0;top:-3px}.cropper-line.line-w{cursor:ew-resize;left:-3px;top:0;width:5px}.cropper-line.line-s{bottom:-3px;cursor:ns-resize;height:5px;left:0}.cropper-point{background-color:#39f;height:5px;opacity:.75;width:5px}.cropper-point.point-e{cursor:ew-resize;margin-top:-3px;right:-3px;top:50%}.cropper-point.point-n{cursor:ns-resize;left:50%;margin-left:-3px;top:-3px}.cropper-point.point-w{cursor:ew-resize;left:-3px;margin-top:-3px;top:50%}.cropper-point.point-s{bottom:-3px;cursor:s-resize;left:50%;margin-left:-3px}.cropper-point.point-ne{cursor:nesw-resize;right:-3px;top:-3px}.cropper-point.point-nw{cursor:nwse-resize;left:-3px;top:-3px}.cropper-point.point-sw{bottom:-3px;cursor:nesw-resize;left:-3px}.cropper-point.point-se{bottom:-3px;cursor:nwse-resize;height:20px;opacity:1;right:-3px;width:20px}@media(min-width:768px){.cropper-point.point-se{height:15px;width:15px}}@media(min-width:992px){.cropper-point.point-se{height:10px;width:10px}}@media(min-width:1200px){.cropper-point.point-se{height:5px;opacity:.75;width:5px}}.cropper-point.point-se:before{background-color:#39f;bottom:-50%;content:" ";display:block;height:200%;opacity:0;position:absolute;right:-50%;width:200%}.cropper-invisible{opacity:0}.cropper-bg{background-image:url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQAQMAAAAlPW0iAAAAA3NCSVQICAjb4U/gAAAABlBMVEXMzMz////TjRV2AAAACXBIWXMAAArrAAAK6wGCiw1aAAAAHHRFWHRTb2Z0d2FyZQBBZG9iZSBGaXJld29ya3MgQ1M26LyyjAAAABFJREFUCJlj+M/AgBVhF/0PAH6/D/HkDxOGAAAAAElFTkSuQmCC)}.cropper-hide{display:block;height:0;position:absolute;width:0}.cropper-hidden{display:none!important}.cropper-move{cursor:move}.cropper-crop{cursor:crosshair}.cropper-disabled .cropper-drag-box,.cropper-disabled .cropper-face,.cropper-disabled .cropper-line,.cropper-disabled .cropper-point{cursor:not-allowed}.file-input[data-v-07c103ef]{display:none}.upload-image-cropper[data-v-07c103ef]{--mg-primary: var(--el-color-primary, var(--brand-primary, #ff5722));--mg-primary-soft: var(--el-color-primary-light-9, #fff7ec);--mg-primary-mid: var(--el-color-primary-light-5, #ffc570);--mg-border: var(--brand-border, var(--el-border-color, #e0e8e0));--mg-text: var(--brand-text-secondary, #8a9a8a);--mg-danger: var(--el-color-danger, #f56c6c);--mg-radius: 10px}.upload-image-cropper .grey-tips[data-v-07c103ef]{margin:0 0 10px;color:var(--mg-text);font-size:12px;line-height:18px}.upload-image-cropper .list-box[data-v-07c103ef]{display:flex;flex-wrap:wrap;gap:10px}.upload-image-cropper .image-box[data-v-07c103ef]{position:relative;box-sizing:border-box;width:59px;height:59px;overflow:hidden;border-radius:var(--mg-radius);background:#fff}.upload-image-cropper .image-box .img[data-v-07c103ef]{width:100%;height:100%;display:block;border:1px solid var(--mg-border);border-radius:var(--mg-radius)}.upload-image-cropper .image-box.is-fail .img[data-v-07c103ef]{border-color:var(--mg-danger)}.upload-image-cropper .upload-btn[data-v-07c103ef]{display:flex;flex-direction:column;align-items:center;justify-content:center;gap:2px;color:var(--mg-text);font-size:11px;line-height:1.2;border:1px dashed var(--mg-border);border-radius:var(--mg-radius);background:linear-gradient(180deg,#fff,#fafbf8);cursor:pointer;transition:color .2s ease,border-color .2s ease,background .2s ease,box-shadow .2s ease}.upload-image-cropper .upload-btn .icon[data-v-07c103ef]{color:var(--mg-text);transition:color .2s ease,transform .2s ease}.upload-image-cropper .upload-btn[data-v-07c103ef]:hover{color:var(--mg-primary);border-color:var(--mg-primary-mid);background:var(--mg-primary-soft);box-shadow:0 0 0 3px color-mix(in srgb,var(--mg-primary-mid) 28%,transparent)}.upload-image-cropper .upload-btn:hover .icon[data-v-07c103ef]{color:var(--mg-primary);transform:scale(1.06)}.upload-image-cropper .status-mask[data-v-07c103ef]{position:absolute;top:0;right:0;bottom:0;left:0;display:flex;flex-direction:column;align-items:center;justify-content:center;gap:4px;border-radius:var(--mg-radius)}.upload-image-cropper .status-mask.is-uploading[data-v-07c103ef]{background:#1b1f1b73}.upload-image-cropper .progress-wrap[data-v-07c103ef]{position:relative;width:30px;height:30px}.upload-image-cropper .percent-text[data-v-07c103ef]{position:absolute;top:0;right:0;bottom:0;left:0;display:flex;align-items:center;justify-content:center;color:#fff;font-size:10px;line-height:1;pointer-events:none}.upload-image-cropper .status-mask.is-fail[data-v-07c103ef]{background:#f56c6cb8;color:#fff}.upload-image-cropper .status-mask.is-fail .fail-icon[data-v-07c103ef]{color:#fff}.upload-image-cropper .status-mask.is-fail .fail-text[data-v-07c103ef]{font-size:11px;line-height:1}.upload-image-cropper .status-mask.is-fail .remove-icon[data-v-07c103ef]{position:absolute;top:4px;right:4px;cursor:pointer}.upload-image-cropper .status-mask.is-success[data-v-07c103ef]{background:#1b1f1b7a;opacity:0;cursor:pointer;transition:opacity .2s ease}.upload-image-cropper .image-box:hover .status-mask.is-success[data-v-07c103ef]{opacity:1}.upload-image-cropper .status-mask.is-success .remove-icon[data-v-07c103ef]{color:#fff}.upload-image-cropper .btn-box[data-v-07c103ef]{display:flex;justify-content:flex-end;flex-wrap:wrap;gap:8px;margin-top:16px}.upload-image-cropper .cropper-box[data-v-07c103ef]{display:flex;justify-content:center;padding:8px 0;background:var(--brand-bg-page, #f2f7f2);border-radius:var(--mg-radius)}.upload-image-cropper .cropper-img[data-v-07c103ef]{width:350px;height:350px;object-fit:contain}
|
package/package.json
ADDED
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "mgacn-commonsdk",
|
|
3
|
+
"version": "1.0.0",
|
|
4
|
+
"description": "芒果ACN公共组件库:公共组件、工具方法与网络请求封装",
|
|
5
|
+
"type": "module",
|
|
6
|
+
"main": "./dist/mgacn-commonsdk.umd.cjs",
|
|
7
|
+
"module": "./dist/mgacn-commonsdk.js",
|
|
8
|
+
"exports": {
|
|
9
|
+
".": {
|
|
10
|
+
"import": "./dist/mgacn-commonsdk.js",
|
|
11
|
+
"require": "./dist/mgacn-commonsdk.umd.cjs"
|
|
12
|
+
},
|
|
13
|
+
"./style.css": "./dist/style.css"
|
|
14
|
+
},
|
|
15
|
+
"files": [
|
|
16
|
+
"dist"
|
|
17
|
+
],
|
|
18
|
+
"sideEffects": [
|
|
19
|
+
"**/*.css",
|
|
20
|
+
"**/*.vue"
|
|
21
|
+
],
|
|
22
|
+
"scripts": {
|
|
23
|
+
"dev": "vite",
|
|
24
|
+
"build": "vite build",
|
|
25
|
+
"preview": "vite preview",
|
|
26
|
+
"prepublishOnly": "npm run build"
|
|
27
|
+
},
|
|
28
|
+
"engines": {
|
|
29
|
+
"node": ">=24.19.0"
|
|
30
|
+
},
|
|
31
|
+
"keywords": [
|
|
32
|
+
"vue3",
|
|
33
|
+
"element-plus",
|
|
34
|
+
"component-library",
|
|
35
|
+
"mgacn",
|
|
36
|
+
"sdk"
|
|
37
|
+
],
|
|
38
|
+
"author": "",
|
|
39
|
+
"license": "MIT",
|
|
40
|
+
"peerDependencies": {
|
|
41
|
+
"@element-plus/icons-vue": "^2.0.0",
|
|
42
|
+
"element-plus": "^2.0.0",
|
|
43
|
+
"vue": "^3.2.0"
|
|
44
|
+
},
|
|
45
|
+
"dependencies": {
|
|
46
|
+
"ali-oss": "^6.23.0",
|
|
47
|
+
"axios": "^1.19.0",
|
|
48
|
+
"cropperjs": "^1.6.2"
|
|
49
|
+
},
|
|
50
|
+
"devDependencies": {
|
|
51
|
+
"@element-plus/icons-vue": "^2.3.2",
|
|
52
|
+
"@vitejs/plugin-vue": "^5.2.3",
|
|
53
|
+
"element-plus": "^2.14.3",
|
|
54
|
+
"sass": "^1.62.1",
|
|
55
|
+
"vite": "^6.2.4",
|
|
56
|
+
"vue": "^3.5.13"
|
|
57
|
+
}
|
|
58
|
+
}
|