first commit
@@ -0,0 +1,6 @@
|
|||||||
|
# 开发环境配置
|
||||||
|
VUE_APP__ENV = 'development'
|
||||||
|
|
||||||
|
VUE_APP_OSS_ACCESS_KEY_ID = "LTAI5tE7wuNkeT9jZ42bQnyr"
|
||||||
|
|
||||||
|
VUE_APP_OSS_ACCESS_KEY_SECRET = "NnutvWhKl4HbQFSad3HosYbCkEkbjN"
|
||||||
@@ -0,0 +1,6 @@
|
|||||||
|
# 开发环境配置
|
||||||
|
VUE_APP__ENV = 'development'
|
||||||
|
|
||||||
|
VUE_APP_OSS_ACCESS_KEY_ID = "LTAI5tE7wuNkeT9jZ42bQnyr"
|
||||||
|
|
||||||
|
VUE_APP_OSS_ACCESS_KEY_SECRET = "NnutvWhKl4HbQFSad3HosYbCkEkbjN"
|
||||||
@@ -0,0 +1,6 @@
|
|||||||
|
# 生产环境配置
|
||||||
|
VUE_APP__ENV = 'production'
|
||||||
|
|
||||||
|
VUE_APP_OSS_ACCESS_KEY_ID = "LTAI5tE7wuNkeT9jZ42bQnyr"
|
||||||
|
|
||||||
|
VUE_APP_OSS_ACCESS_KEY_SECRET = "NnutvWhKl4HbQFSad3HosYbCkEkbjN"
|
||||||
@@ -0,0 +1,6 @@
|
|||||||
|
# 生产环境配置
|
||||||
|
VITE_APP_ENV = 'staging'
|
||||||
|
|
||||||
|
OSS_ACCESS_KEY_ID = "LTAI5tE7wuNkeT9jZ42bQnyr"
|
||||||
|
|
||||||
|
OSS_ACCESS_KEY_SECRET = "NnutvWhKl4HbQFSad3HosYbCkEkbjN"
|
||||||
@@ -0,0 +1,13 @@
|
|||||||
|
module.exports = {
|
||||||
|
env: {
|
||||||
|
browser: true,
|
||||||
|
es2021: true,
|
||||||
|
},
|
||||||
|
extends: ["eslint:recommended", "plugin:vue/essential"],
|
||||||
|
parserOptions: {
|
||||||
|
ecmaVersion: 12,
|
||||||
|
sourceType: "module",
|
||||||
|
},
|
||||||
|
plugins: ["vue"],
|
||||||
|
rules: {},
|
||||||
|
};
|
||||||
@@ -0,0 +1,23 @@
|
|||||||
|
.DS_Store
|
||||||
|
node_modules
|
||||||
|
/dist
|
||||||
|
# local env files
|
||||||
|
.env.local
|
||||||
|
.env.*.local
|
||||||
|
|
||||||
|
# Log files
|
||||||
|
npm-debug.log*
|
||||||
|
yarn-debug.log*
|
||||||
|
yarn-error.log*
|
||||||
|
pnpm-debug.log*
|
||||||
|
|
||||||
|
# Editor directories and files
|
||||||
|
.idea
|
||||||
|
.vscode
|
||||||
|
*.suo
|
||||||
|
*.ntvs*
|
||||||
|
*.njsproj
|
||||||
|
*.sln
|
||||||
|
*.sw?
|
||||||
|
yarn.lock
|
||||||
|
package-lock.json
|
||||||
@@ -0,0 +1,24 @@
|
|||||||
|
# info-form
|
||||||
|
|
||||||
|
## Project setup
|
||||||
|
```
|
||||||
|
yarn install
|
||||||
|
```
|
||||||
|
|
||||||
|
### Compiles and hot-reloads for development
|
||||||
|
```
|
||||||
|
yarn serve
|
||||||
|
```
|
||||||
|
|
||||||
|
### Compiles and minifies for production
|
||||||
|
```
|
||||||
|
yarn build
|
||||||
|
```
|
||||||
|
|
||||||
|
### Lints and fixes files
|
||||||
|
```
|
||||||
|
yarn lint
|
||||||
|
```
|
||||||
|
|
||||||
|
### Customize configuration
|
||||||
|
See [Configuration Reference](https://cli.vuejs.org/config/).
|
||||||
@@ -0,0 +1,5 @@
|
|||||||
|
module.exports = {
|
||||||
|
presets: [
|
||||||
|
'@vue/cli-plugin-babel/preset'
|
||||||
|
]
|
||||||
|
}
|
||||||
@@ -0,0 +1,19 @@
|
|||||||
|
{
|
||||||
|
"compilerOptions": {
|
||||||
|
"target": "es6",
|
||||||
|
"module": "esnext",
|
||||||
|
"baseUrl": "./",
|
||||||
|
"moduleResolution": "node",
|
||||||
|
"paths": {
|
||||||
|
"@/*": [
|
||||||
|
"src/*"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"lib": [
|
||||||
|
"esnext",
|
||||||
|
"dom",
|
||||||
|
"dom.iterable",
|
||||||
|
"scripthost"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,55 @@
|
|||||||
|
{
|
||||||
|
"name": "info-form",
|
||||||
|
"version": "0.1.0",
|
||||||
|
"private": true,
|
||||||
|
"scripts": {
|
||||||
|
"serve": "vue-cli-service serve --mode development",
|
||||||
|
"dev": "vue-cli-service serve --mode development",
|
||||||
|
"build": "vue-cli-service build --mode production",
|
||||||
|
"lint": "vue-cli-service lint"
|
||||||
|
},
|
||||||
|
"dependencies": {
|
||||||
|
"ali-oss": "^6.18.1",
|
||||||
|
"axios": "^1.6.2",
|
||||||
|
"core-js": "^3.8.3",
|
||||||
|
"dayjs": "^1.11.10",
|
||||||
|
"element-plus": "^2.4.2",
|
||||||
|
"file-saver": "^2.0.5",
|
||||||
|
"jszip": "^3.10.1",
|
||||||
|
"path": "^0.12.7",
|
||||||
|
"sass": "^1.69.5",
|
||||||
|
"sass-loader": "^13.3.2",
|
||||||
|
"scss": "^0.2.4",
|
||||||
|
"vue": "^3.2.13",
|
||||||
|
"vue-router": "4"
|
||||||
|
},
|
||||||
|
"devDependencies": {
|
||||||
|
"@babel/core": "^7.12.16",
|
||||||
|
"@babel/eslint-parser": "^7.12.16",
|
||||||
|
"@vue/cli-plugin-babel": "~5.0.0",
|
||||||
|
"@vue/cli-plugin-eslint": "~5.0.0",
|
||||||
|
"@vue/cli-service": "~5.0.0",
|
||||||
|
"eslint": "^7.32.0",
|
||||||
|
"eslint-plugin-vue": "^9.18.1"
|
||||||
|
},
|
||||||
|
"eslintConfig": {
|
||||||
|
"root": true,
|
||||||
|
"env": {
|
||||||
|
"node": true
|
||||||
|
},
|
||||||
|
"extends": [
|
||||||
|
"plugin:vue/vue3-essential",
|
||||||
|
"eslint:recommended"
|
||||||
|
],
|
||||||
|
"parserOptions": {
|
||||||
|
"parser": "@babel/eslint-parser"
|
||||||
|
},
|
||||||
|
"rules": {}
|
||||||
|
},
|
||||||
|
"browserslist": [
|
||||||
|
"> 1%",
|
||||||
|
"last 2 versions",
|
||||||
|
"not dead",
|
||||||
|
"not ie 11"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
Після Ширина: | Висота: | Розмір: 4.2 KiB |
@@ -0,0 +1,17 @@
|
|||||||
|
<!DOCTYPE html>
|
||||||
|
<html lang="">
|
||||||
|
<head>
|
||||||
|
<meta charset="utf-8">
|
||||||
|
<meta http-equiv="X-UA-Compatible" content="IE=edge">
|
||||||
|
<meta name="viewport" content="width=device-width,initial-scale=1.0">
|
||||||
|
<link rel="icon" href="<%= BASE_URL %>favicon.ico">
|
||||||
|
<title><%= htmlWebpackPlugin.options.title %></title>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<noscript>
|
||||||
|
<strong>We're sorry but <%= htmlWebpackPlugin.options.title %> doesn't work properly without JavaScript enabled. Please enable it to continue.</strong>
|
||||||
|
</noscript>
|
||||||
|
<div id="app"></div>
|
||||||
|
<!-- built files will be auto injected -->
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
@@ -0,0 +1,7 @@
|
|||||||
|
<template>
|
||||||
|
<router-view></router-view>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script></script>
|
||||||
|
|
||||||
|
<style></style>
|
||||||
@@ -0,0 +1,17 @@
|
|||||||
|
import request from "../utils/requests";
|
||||||
|
|
||||||
|
// 获取
|
||||||
|
export const getFormData = (data) => {
|
||||||
|
return request({
|
||||||
|
url: "get_product_form_data",
|
||||||
|
method: "post",
|
||||||
|
data,
|
||||||
|
});
|
||||||
|
};
|
||||||
|
export const saveFormData = (data) => {
|
||||||
|
return request({
|
||||||
|
url: "save_product_form_data",
|
||||||
|
method: "post",
|
||||||
|
data,
|
||||||
|
});
|
||||||
|
};
|
||||||
|
Після Ширина: | Висота: | Розмір: 1.7 KiB |
|
Після Ширина: | Висота: | Розмір: 1.1 KiB |
|
Після Ширина: | Висота: | Розмір: 1.5 KiB |
|
Після Ширина: | Висота: | Розмір: 1.5 KiB |
|
Після Ширина: | Висота: | Розмір: 1.1 KiB |
|
Після Ширина: | Висота: | Розмір: 1.5 KiB |
|
Після Ширина: | Висота: | Розмір: 1.1 KiB |
|
Після Ширина: | Висота: | Розмір: 1.0 KiB |
|
Після Ширина: | Висота: | Розмір: 1.1 KiB |
|
Після Ширина: | Висота: | Розмір: 1.2 KiB |
|
Після Ширина: | Висота: | Розмір: 1.1 KiB |
|
Після Ширина: | Висота: | Розмір: 1.1 KiB |
|
Після Ширина: | Висота: | Розмір: 1007 B |
|
Після Ширина: | Висота: | Розмір: 943 B |
|
Після Ширина: | Висота: | Розмір: 1.3 KiB |
|
Після Ширина: | Висота: | Розмір: 1.1 KiB |
@@ -0,0 +1,286 @@
|
|||||||
|
<template>
|
||||||
|
<div class="component-upload-image">
|
||||||
|
<el-upload
|
||||||
|
action="#"
|
||||||
|
list-type="picture-card"
|
||||||
|
drag
|
||||||
|
:on-success="handleSuccess"
|
||||||
|
:on-change="handleChange"
|
||||||
|
ref="uploadInner"
|
||||||
|
:auto-upload="false"
|
||||||
|
:file-list="fileList"
|
||||||
|
>
|
||||||
|
<el-icon><Plus /></el-icon>
|
||||||
|
<template #file="{ file }">
|
||||||
|
<div style="display: flex; flex-direction: column; position: relative">
|
||||||
|
<div style="width: 146px; height: 146px">
|
||||||
|
<img
|
||||||
|
class="el-upload-list__item-thumbnail"
|
||||||
|
:src="getImageUrl(file)"
|
||||||
|
alt=""
|
||||||
|
/>
|
||||||
|
<span class="el-upload-list__item-actions">
|
||||||
|
<span
|
||||||
|
class="el-upload-list__item-preview"
|
||||||
|
@click="handlePictureCardPreview(file)"
|
||||||
|
>
|
||||||
|
<el-icon><zoom-in /></el-icon>
|
||||||
|
</span>
|
||||||
|
<span
|
||||||
|
class="el-upload-list__item-delete"
|
||||||
|
@click="handleDownload(file)"
|
||||||
|
>
|
||||||
|
<el-icon><Download /></el-icon>
|
||||||
|
</span>
|
||||||
|
<span
|
||||||
|
class="el-upload-list__item-delete"
|
||||||
|
@click="handleRemove(file)"
|
||||||
|
>
|
||||||
|
<el-icon><Delete /></el-icon>
|
||||||
|
</span>
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
<span
|
||||||
|
style="
|
||||||
|
position: absolute;
|
||||||
|
bottom: 0;
|
||||||
|
width: 146px;
|
||||||
|
font-size: 11px;
|
||||||
|
line-height: 14px;
|
||||||
|
"
|
||||||
|
>{{ file.name }}</span
|
||||||
|
>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
</el-upload>
|
||||||
|
<el-dialog v-model="dialogVisible">
|
||||||
|
<img :src="dialogImageUrl" alt="Preview Image" style="width: 100%;"/>
|
||||||
|
</el-dialog>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script setup>
|
||||||
|
import { Delete, Download, Plus, ZoomIn } from "@element-plus/icons-vue";
|
||||||
|
import dayjs from "dayjs";
|
||||||
|
import OSS from "ali-oss";
|
||||||
|
import { ElLoading } from "element-plus";
|
||||||
|
import { ref, watch } from "vue";
|
||||||
|
import { handleBatchDownload } from "../../utils/downFile";
|
||||||
|
const props = defineProps({
|
||||||
|
modelValue: [String, Object, Array],
|
||||||
|
// 图片数量限制
|
||||||
|
limit: {
|
||||||
|
type: Number,
|
||||||
|
default: 5,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
const emit = defineEmits();
|
||||||
|
const uploadList = ref([]);
|
||||||
|
const baseUrl = "https://dfdiyfile.oss-cn-fuzhou.aliyuncs.com/";
|
||||||
|
const fileList = ref([]);
|
||||||
|
const dialogImageUrl = ref("");
|
||||||
|
const dialogVisible = ref(false);
|
||||||
|
const disabled = ref(false);
|
||||||
|
|
||||||
|
watch(
|
||||||
|
() => props.modelValue,
|
||||||
|
(val) => {
|
||||||
|
if (val) {
|
||||||
|
// 首先将值转为数组
|
||||||
|
const list = Array.isArray(val) ? val : props.modelValue.split(",");
|
||||||
|
// 然后将数组转为对象数组
|
||||||
|
fileList.value = list.map((item) => {
|
||||||
|
if (typeof item === "string") {
|
||||||
|
if (item.indexOf(baseUrl) === -1 && !item.startsWith("http")) {
|
||||||
|
item = { name: item, url: baseUrl + item };
|
||||||
|
} else {
|
||||||
|
item = { name: item, url: item };
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return item;
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
fileList.value = [];
|
||||||
|
return [];
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{ deep: true, immediate: true }
|
||||||
|
);
|
||||||
|
|
||||||
|
let fileTypes = [
|
||||||
|
{
|
||||||
|
logo: require("../../assets/iso.png"),
|
||||||
|
types: "iso,gho",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
logo: require("../../assets/mv.png"),
|
||||||
|
types: "rm,wav,mpg,rmvb,mov,mp4",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
logo: require("../../assets/txt.png"),
|
||||||
|
types: "txt,conf",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
logo: require("../../assets/excel.png"),
|
||||||
|
types: "xls,xlsx",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
logo: require("../../assets/exe.png"),
|
||||||
|
types: "exe,sh",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
logo: require("../../assets/html.png"),
|
||||||
|
types: "html,htm",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
logo: require("../../assets/image.png"),
|
||||||
|
types: "png,jpg,jpeg,bpm",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
logo: require("../../assets/music.png"),
|
||||||
|
types: "mp3,m4a",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
logo: require("../../assets/pdf.png"),
|
||||||
|
types: "pdf",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
logo: require("../../assets/psd.png"),
|
||||||
|
types: "psd",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
logo: require("../../assets/sql.png"),
|
||||||
|
types: "sql",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
logo: require("../../assets/word.png"),
|
||||||
|
types: "doc,docx",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
logo: require("../../assets/ppt.png"),
|
||||||
|
types: "ppt,pptx",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
logo: require("../../assets/zip.png"),
|
||||||
|
types: "zip,7z,gz",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
logo: require("../../assets/apk.png"),
|
||||||
|
types: "apk",
|
||||||
|
},
|
||||||
|
];
|
||||||
|
|
||||||
|
function getImageUrl(file) {
|
||||||
|
let suffix = file.name.split(".").pop();
|
||||||
|
if ("png,jpg,jpeg".indexOf(suffix) != -1) {
|
||||||
|
return file.url;
|
||||||
|
}
|
||||||
|
for (let ft of fileTypes) {
|
||||||
|
if (ft.types.indexOf(suffix) != -1) {
|
||||||
|
return ft.logo;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return "../../assets/other.png";
|
||||||
|
}
|
||||||
|
let loading = null;
|
||||||
|
const handlePictureCardPreview = (file) => {
|
||||||
|
dialogImageUrl.value = file.url;
|
||||||
|
dialogVisible.value = true;
|
||||||
|
};
|
||||||
|
function handleRemove(file) {
|
||||||
|
const findex = fileList.value.map((f) => f.name).indexOf(file.name);
|
||||||
|
fileList.value.splice(findex, 1);
|
||||||
|
emit("update:modelValue", listToString(fileList.value));
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
function handleDownload(file) {
|
||||||
|
handleBatchDownload([file.url]);
|
||||||
|
}
|
||||||
|
|
||||||
|
function handleSuccess(res, file) {
|
||||||
|
uploadList.value.push({ name: res.name, url: res.url });
|
||||||
|
uploadedSuccessfully();
|
||||||
|
}
|
||||||
|
|
||||||
|
// 上传结束处理
|
||||||
|
function uploadedSuccessfully() {
|
||||||
|
fileList.value = fileList.value
|
||||||
|
.filter((f) => f.url !== undefined)
|
||||||
|
.concat(uploadList.value);
|
||||||
|
|
||||||
|
uploadList.value = [];
|
||||||
|
emit("update:modelValue", listToString(fileList.value));
|
||||||
|
loading && loading.close();
|
||||||
|
}
|
||||||
|
|
||||||
|
function guid() {
|
||||||
|
return "xxxxxxxx-xxxx-4xxx-yxxx".replace(/[xy]/g, function (c) {
|
||||||
|
var r = (Math.random() * 16) | 0,
|
||||||
|
v = c == "x" ? r : (r & 0x3) | 0x8;
|
||||||
|
return v.toString(16);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
const progress = (p, _checkpoint) => {
|
||||||
|
// Object的上传进度。
|
||||||
|
console.log(p);
|
||||||
|
// 分片上传的断点信息。
|
||||||
|
console.log(_checkpoint);
|
||||||
|
};
|
||||||
|
|
||||||
|
function getSuff(name) {
|
||||||
|
return name.substring(name.lastIndexOf("."));
|
||||||
|
}
|
||||||
|
function handleChange(file, fileList) {
|
||||||
|
loading = ElLoading.service({
|
||||||
|
lock: true,
|
||||||
|
text: "Loading",
|
||||||
|
background: "rgba(0, 0, 0, 0.7)",
|
||||||
|
});
|
||||||
|
let fileDir = dayjs().format("YYYYMMDD");
|
||||||
|
const client = new OSS({
|
||||||
|
// yourregion填写Bucket所在地域。以华东1(杭州)为例,Region填写为oss-cn-hangzhou。
|
||||||
|
region: "oss-cn-fuzhou",
|
||||||
|
// 从环境变量中获取访问凭证。运行本代码示例之前,请确保已设置环境变量OSS_ACCESS_KEY_ID和OSS_ACCESS_KEY_SECRET。
|
||||||
|
accessKeyId: process.env.VUE_APP_OSS_ACCESS_KEY_ID,
|
||||||
|
accessKeySecret: process.env.VUE_APP_OSS_ACCESS_KEY_SECRET,
|
||||||
|
// 填写存储空间名称。
|
||||||
|
bucket: "dfdiyfile",
|
||||||
|
endpoint: "https://oss-cn-fuzhou.aliyuncs.com",
|
||||||
|
});
|
||||||
|
let name = "desgn/" + fileDir + "/" + guid() + getSuff(file.name);
|
||||||
|
// storeAs表示上传的object name , file表示上传的文件
|
||||||
|
client
|
||||||
|
.multipartUpload(name, file.raw, {
|
||||||
|
progress,
|
||||||
|
})
|
||||||
|
.then((result) => {
|
||||||
|
console.log(result);
|
||||||
|
let url = `https://dfdiyfile.oss-cn-fuzhou.aliyuncs.com/${result.name}`;
|
||||||
|
/**
|
||||||
|
* 设置本地上传成功的回调
|
||||||
|
*/
|
||||||
|
// this.imageUrl = result.res.requestUrl;
|
||||||
|
handleSuccess({ url, name: result.name }, file);
|
||||||
|
})
|
||||||
|
.catch(function (err) {
|
||||||
|
console.log(err);
|
||||||
|
/**
|
||||||
|
* 设置本地上传失败的回调
|
||||||
|
*/
|
||||||
|
});
|
||||||
|
}
|
||||||
|
// 对象转成指定字符串分隔
|
||||||
|
function listToString(list, separator) {
|
||||||
|
let strs = "";
|
||||||
|
separator = separator || ",";
|
||||||
|
for (let i in list) {
|
||||||
|
if (undefined !== list[i].url && list[i].url.indexOf("blob:") !== 0) {
|
||||||
|
strs += list[i].url.replace(baseUrl, "") + separator;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return strs != "" ? strs.substr(0, strs.length - 1) : "";
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style scoped lang="scss"></style>
|
||||||
@@ -0,0 +1,16 @@
|
|||||||
|
import { createApp } from "vue";
|
||||||
|
import App from "./App.vue";
|
||||||
|
import ElementPlus from "element-plus";
|
||||||
|
import "element-plus/dist/index.css";
|
||||||
|
import zhCn from "element-plus/dist/locale/zh-cn.mjs";
|
||||||
|
import router from "./router";
|
||||||
|
const app = createApp(App);
|
||||||
|
|
||||||
|
app.use(router);
|
||||||
|
app.use(ElementPlus);
|
||||||
|
app.use(ElementPlus, {
|
||||||
|
locale: zhCn,
|
||||||
|
// 支持 large、default、small
|
||||||
|
size: "default",
|
||||||
|
});
|
||||||
|
app.mount("#app");
|
||||||
@@ -0,0 +1,22 @@
|
|||||||
|
import { createWebHistory, createRouter } from "vue-router";
|
||||||
|
const routes = [
|
||||||
|
{
|
||||||
|
path: "/",
|
||||||
|
component: () => import("@/views/info"),
|
||||||
|
},
|
||||||
|
];
|
||||||
|
|
||||||
|
const router = createRouter({
|
||||||
|
// 4. 内部提供了 history 模式的实现。为了简单起见,我们在这里使用 hash 模式。
|
||||||
|
history: createWebHistory(),
|
||||||
|
routes, // `routes: routes` 的缩写
|
||||||
|
scrollBehavior(to, from, savedPosition) {
|
||||||
|
if (savedPosition) {
|
||||||
|
return savedPosition;
|
||||||
|
} else {
|
||||||
|
return { top: 0 };
|
||||||
|
}
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
export default router;
|
||||||
@@ -0,0 +1,46 @@
|
|||||||
|
import axios from "axios";
|
||||||
|
import JSZip from "jszip";
|
||||||
|
import FileSaver from "file-saver";
|
||||||
|
const getFile = (url) => {
|
||||||
|
return new Promise((resolve, reject) => {
|
||||||
|
axios({
|
||||||
|
method: "get",
|
||||||
|
url,
|
||||||
|
responseType: "arraybuffer",
|
||||||
|
headers: {
|
||||||
|
"Access-Control-Allow-Origin": "*",
|
||||||
|
Accept:
|
||||||
|
"image/avif,image/webp,image/apng,image/svg+xml,image/*,*/*;q=0.8",
|
||||||
|
},
|
||||||
|
})
|
||||||
|
.then((data) => {
|
||||||
|
resolve(data.data);
|
||||||
|
})
|
||||||
|
.catch((error) => {
|
||||||
|
reject(error.toString());
|
||||||
|
});
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
export function handleBatchDownload(data) {
|
||||||
|
const zip = new JSZip();
|
||||||
|
const cache = {};
|
||||||
|
const promises = [];
|
||||||
|
data.forEach((item) => {
|
||||||
|
const promise = getFile(item).then((data) => {
|
||||||
|
// 下载文件, 并存成ArrayBuffer对象
|
||||||
|
const arr_name = item.split("/");
|
||||||
|
const file_name = arr_name[arr_name.length - 1]; // 获取文件名
|
||||||
|
zip.file(file_name, data, { binary: true }); // 逐个添加文件
|
||||||
|
cache[file_name] = data;
|
||||||
|
});
|
||||||
|
promises.push(promise);
|
||||||
|
});
|
||||||
|
|
||||||
|
Promise.all(promises).then(() => {
|
||||||
|
zip.generateAsync({ type: "blob" }).then((content) => {
|
||||||
|
// 生成二进制流
|
||||||
|
FileSaver.saveAs(content, new Date().valueOf() + ".zip"); // 利用file-saver保存文件
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
@@ -0,0 +1,113 @@
|
|||||||
|
import axios from "axios";
|
||||||
|
import {
|
||||||
|
ElNotification,
|
||||||
|
ElMessageBox,
|
||||||
|
ElMessage,
|
||||||
|
ElLoading,
|
||||||
|
} from "element-plus";
|
||||||
|
axios.defaults.baseURL = "/api/Handler";
|
||||||
|
axios.defaults.headers["Content-Type"] =
|
||||||
|
"application/x-www-form-urlencoded; charset=UTF-8";
|
||||||
|
axios.defaults.headers["Accept"] = "*/*";
|
||||||
|
axios.defaults.headers["X-Requested-With"] = "XMLHttpRequest";
|
||||||
|
|
||||||
|
const request = axios.create({
|
||||||
|
timeout: 50000,
|
||||||
|
});
|
||||||
|
// 进行request请求拦截处理
|
||||||
|
request.interceptors.request.use(
|
||||||
|
(config) => {
|
||||||
|
// 是否需要防止数据重复提交
|
||||||
|
const isRepeatSubmit = (config.headers || {}).repeatSubmit === false;
|
||||||
|
config.url = "/noti.ashx?t=" + config.url;
|
||||||
|
// get请求映射params参数
|
||||||
|
if (config.method === "get" && config.params) {
|
||||||
|
let url = config.url + "&" + tansParams(config.params);
|
||||||
|
url = url.slice(0, -1);
|
||||||
|
config.params = {};
|
||||||
|
config.url = url;
|
||||||
|
}
|
||||||
|
if (
|
||||||
|
!isRepeatSubmit &&
|
||||||
|
(config.method === "post" || config.method === "put")
|
||||||
|
) {
|
||||||
|
const requestObj = {
|
||||||
|
url: config.url,
|
||||||
|
data:
|
||||||
|
typeof config.data === "object"
|
||||||
|
? JSON.stringify(config.data)
|
||||||
|
: config.data,
|
||||||
|
time: new Date().getTime(),
|
||||||
|
};
|
||||||
|
}
|
||||||
|
return config;
|
||||||
|
},
|
||||||
|
(error) => {
|
||||||
|
console.log(error);
|
||||||
|
Promise.reject(error);
|
||||||
|
}
|
||||||
|
);
|
||||||
|
// 进行response后端数据返回拦截
|
||||||
|
request.interceptors.response.use(
|
||||||
|
(response) => {
|
||||||
|
// 缩短一点
|
||||||
|
let res = response.data;
|
||||||
|
// 判断后端请求响应是否正确
|
||||||
|
if (res.success) {
|
||||||
|
return response.data;
|
||||||
|
} else if (res instanceof ArrayBuffer) {
|
||||||
|
return response;
|
||||||
|
} else if (res.type === "success") {
|
||||||
|
return response.data;
|
||||||
|
} else {
|
||||||
|
return Promise.reject(response.data.message);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
// 异常情况判断
|
||||||
|
(error) => {
|
||||||
|
console.log("请求异常了嗷~~", error);
|
||||||
|
if (error.response.data) {
|
||||||
|
error.massage = error.response.data.message;
|
||||||
|
}
|
||||||
|
// 无权限
|
||||||
|
else if (error.response.status === 401) {
|
||||||
|
}
|
||||||
|
// 404notfound
|
||||||
|
else if (error.response.status === 404) {
|
||||||
|
}
|
||||||
|
ElMessage({ message: error.massage, type: "error" });
|
||||||
|
return Promise.reject(error);
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 参数处理
|
||||||
|
* @param {*} params 参数
|
||||||
|
*/
|
||||||
|
function tansParams(params) {
|
||||||
|
let result = "";
|
||||||
|
for (const propName of Object.keys(params)) {
|
||||||
|
const value = params[propName];
|
||||||
|
var part = encodeURIComponent(propName) + "=";
|
||||||
|
if (value !== null && value !== "" && typeof value !== "undefined") {
|
||||||
|
if (typeof value === "object") {
|
||||||
|
for (const key of Object.keys(value)) {
|
||||||
|
if (
|
||||||
|
value[key] !== null &&
|
||||||
|
value[key] !== "" &&
|
||||||
|
typeof value[key] !== "undefined"
|
||||||
|
) {
|
||||||
|
let params = propName + "[" + key + "]";
|
||||||
|
var subPart = encodeURIComponent(params) + "=";
|
||||||
|
result += subPart + encodeURIComponent(value[key]) + "&";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
result += part + encodeURIComponent(value) + "&";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
export default request;
|
||||||
@@ -0,0 +1,201 @@
|
|||||||
|
<template>
|
||||||
|
<div class="container">
|
||||||
|
<el-form label-position="left">
|
||||||
|
<template v-for="(item, index) in fromData">
|
||||||
|
<template v-if="item.type === 'upload'">
|
||||||
|
<el-form-item :label="item.title" label-width="200px">
|
||||||
|
<FileUpload
|
||||||
|
v-model:modelValue="item.content"
|
||||||
|
v-model:loaderData="loaderData"
|
||||||
|
/>
|
||||||
|
</el-form-item>
|
||||||
|
</template>
|
||||||
|
<template v-if="item.type === 'input'">
|
||||||
|
<el-form-item
|
||||||
|
:label="item.title"
|
||||||
|
label-width="200px"
|
||||||
|
:required="
|
||||||
|
item.title == '手机号' ||
|
||||||
|
item.title == '微信号' ||
|
||||||
|
item.title == '需要设计的内容'
|
||||||
|
"
|
||||||
|
>
|
||||||
|
<el-input
|
||||||
|
v-model="item.content"
|
||||||
|
:placeholder="'请输入' + item.title"
|
||||||
|
/>
|
||||||
|
</el-form-item>
|
||||||
|
</template>
|
||||||
|
</template>
|
||||||
|
<el-button type="primary" @click="saveData">确认</el-button>
|
||||||
|
<el-button type="primary" @click="handleDownload(loaderData)"
|
||||||
|
>下载全部文件</el-button
|
||||||
|
>
|
||||||
|
</el-form>
|
||||||
|
<div style="text-align: center; margin-top: 50px">
|
||||||
|
闽ICP备2023014112号-1
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script setup>
|
||||||
|
import { getFormData, saveFormData } from "../api/index";
|
||||||
|
import { useRouter } from "vue-router";
|
||||||
|
import { ElMessage } from "element-plus";
|
||||||
|
import { handleBatchDownload } from "../utils/downFile";
|
||||||
|
const baseUrl = "https://dfdiyfile.oss-cn-fuzhou.aliyuncs.com/";
|
||||||
|
import { ref } from "vue";
|
||||||
|
import FileUpload from "../components/FileUpload/index";
|
||||||
|
const { currentRoute } = useRouter();
|
||||||
|
const tid = currentRoute.value.query.tid;
|
||||||
|
const userId = currentRoute.value.query.userId;
|
||||||
|
|
||||||
|
const fromData = ref([]);
|
||||||
|
const uploadList = ref([]);
|
||||||
|
const CeErpOrderFormData = ref({});
|
||||||
|
const loaderData = ref([]);
|
||||||
|
async function saveData() {
|
||||||
|
let mobile = false;
|
||||||
|
let wx = false;
|
||||||
|
let need_content = false;
|
||||||
|
let mobile_number = "123";
|
||||||
|
fromData.value?.map((item) => {
|
||||||
|
if (item.title == "手机号" && !item?.content) {
|
||||||
|
mobile = true;
|
||||||
|
}
|
||||||
|
if (item.title == "手机号" && item?.content) {
|
||||||
|
mobile_number = item?.content;
|
||||||
|
}
|
||||||
|
if (item.title == "微信号" && !item?.content) {
|
||||||
|
wx = true;
|
||||||
|
}
|
||||||
|
if (item.title == "需要设计的内容" && !item?.content) {
|
||||||
|
need_content = true;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
if (need_content) {
|
||||||
|
return ElMessage({
|
||||||
|
message: "需要设计的内容不能为空",
|
||||||
|
type: "error",
|
||||||
|
});
|
||||||
|
}
|
||||||
|
if (mobile && wx) {
|
||||||
|
return ElMessage({
|
||||||
|
message: "手机号或者微信号不能都为空",
|
||||||
|
type: "error",
|
||||||
|
});
|
||||||
|
}
|
||||||
|
let regex =
|
||||||
|
/^(13[0-9]|14[01456879]|15[0-35-9]|16[2567]|17[0-8]|18[0-9]|19[0-35-9])\d{8}$/;
|
||||||
|
// if (mobile_number != "123" && !regex.test(mobile_number)) {
|
||||||
|
// return ElMessage({
|
||||||
|
// message: "请输入正确手机号",
|
||||||
|
// type: "error",
|
||||||
|
// });
|
||||||
|
// }
|
||||||
|
let data = await saveFormData({
|
||||||
|
id: CeErpOrderFormData.value ? CeErpOrderFormData.value.id : 0,
|
||||||
|
tid,
|
||||||
|
userId,
|
||||||
|
content: JSON.stringify(fromData.value),
|
||||||
|
});
|
||||||
|
if (data.type === "success") {
|
||||||
|
ElMessage({
|
||||||
|
message: "保存成功",
|
||||||
|
type: "success",
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
async function getData() {
|
||||||
|
if (!tid) {
|
||||||
|
return ElMessage({
|
||||||
|
message: "获取不到参数",
|
||||||
|
type: "error",
|
||||||
|
});
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
let data = await getFormData({ tid });
|
||||||
|
if (data.code === 200) {
|
||||||
|
let product = data.product;
|
||||||
|
CeErpOrderFormData.value = data.CeErpOrderFormData;
|
||||||
|
let info = {};
|
||||||
|
let json_info = `[{"title":"logo文件上传/模板截图/设计素材上传等等~","type":"upload"},
|
||||||
|
{"title":"需要设计的内容","type":"input"},
|
||||||
|
{"title":"手机号","type":"input"},
|
||||||
|
{"title":"微信号","type":"input"},
|
||||||
|
{"title":"请上传微信二维码","type":"upload"}]`;
|
||||||
|
if (!product) {
|
||||||
|
product = {
|
||||||
|
FormJson: json_info,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
if (CeErpOrderFormData.value && CeErpOrderFormData.value.content) {
|
||||||
|
CeErpOrderFormData.value = {
|
||||||
|
content: JSON.parse(CeErpOrderFormData.value.content),
|
||||||
|
id: CeErpOrderFormData.value.ID,
|
||||||
|
tid: CeErpOrderFormData.value.tid,
|
||||||
|
};
|
||||||
|
CeErpOrderFormData.value?.content.map((item) => {
|
||||||
|
if (
|
||||||
|
item.type == "upload" &&
|
||||||
|
item.content &&
|
||||||
|
typeof item.content == "string"
|
||||||
|
) {
|
||||||
|
item.content?.split(",")?.map((e) => {
|
||||||
|
loaderData.value.push(baseUrl + e);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
product.FormJson = json_info;
|
||||||
|
if (product && product.FormJson != "") {
|
||||||
|
let formJson = JSON.parse(product.FormJson);
|
||||||
|
let need = true;
|
||||||
|
formJson.map((item) => {
|
||||||
|
if (item.type === "upload") {
|
||||||
|
item.content = [];
|
||||||
|
} else {
|
||||||
|
item.content = "";
|
||||||
|
}
|
||||||
|
if (CeErpOrderFormData.value && CeErpOrderFormData.value.content) {
|
||||||
|
CeErpOrderFormData.value.content.map((e) => {
|
||||||
|
if (e.title === item.title && e.type === item.type) {
|
||||||
|
item.content = e.content;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
if (item.title == "手机号") {
|
||||||
|
need = false;
|
||||||
|
}
|
||||||
|
if (item.title == "微信号") {
|
||||||
|
need = false;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
if (need) {
|
||||||
|
formJson.push(
|
||||||
|
...[
|
||||||
|
{ title: "手机号", type: "input" },
|
||||||
|
{ title: "微信号", type: "input" },
|
||||||
|
]
|
||||||
|
);
|
||||||
|
}
|
||||||
|
fromData.value = formJson;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} catch (error) {
|
||||||
|
console.log("🚀 ~ file: info.vue:15 ~ getData ~ error:", error);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
function handleDownload(data) {
|
||||||
|
handleBatchDownload(data);
|
||||||
|
}
|
||||||
|
getData();
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style scoped lang="scss">
|
||||||
|
.container {
|
||||||
|
max-width: 1400px;
|
||||||
|
margin: 0 auto;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
@@ -0,0 +1,20 @@
|
|||||||
|
const { defineConfig } = require("@vue/cli-service");
|
||||||
|
module.exports = defineConfig({
|
||||||
|
transpileDependencies: true,
|
||||||
|
lintOnSave: false,
|
||||||
|
devServer: {
|
||||||
|
port: 9955,
|
||||||
|
open: true,
|
||||||
|
proxy: {
|
||||||
|
"/api": {
|
||||||
|
// target: "http://localhost:911",
|
||||||
|
target: "http://47.114.150.226:88",
|
||||||
|
changeOrigin: true,
|
||||||
|
pathRewrite: {
|
||||||
|
"^/api": "",
|
||||||
|
},
|
||||||
|
ws: false,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
});
|
||||||