Browse Source

first commit

zhuyiyi 9 months ago
commit
38fbfdaef6

+ 6 - 0
.env

@@ -0,0 +1,6 @@
+# 开发环境配置
+VUE_APP__ENV = 'development'
+
+VUE_APP_OSS_ACCESS_KEY_ID = "LTAI5tE7wuNkeT9jZ42bQnyr"
+
+VUE_APP_OSS_ACCESS_KEY_SECRET = "NnutvWhKl4HbQFSad3HosYbCkEkbjN"

+ 6 - 0
.env.development

@@ -0,0 +1,6 @@
+# 开发环境配置
+VUE_APP__ENV = 'development'
+
+VUE_APP_OSS_ACCESS_KEY_ID = "LTAI5tE7wuNkeT9jZ42bQnyr"
+
+VUE_APP_OSS_ACCESS_KEY_SECRET = "NnutvWhKl4HbQFSad3HosYbCkEkbjN"

+ 6 - 0
.env.production

@@ -0,0 +1,6 @@
+# 生产环境配置
+VUE_APP__ENV = 'production'
+
+VUE_APP_OSS_ACCESS_KEY_ID = "LTAI5tE7wuNkeT9jZ42bQnyr"
+
+VUE_APP_OSS_ACCESS_KEY_SECRET = "NnutvWhKl4HbQFSad3HosYbCkEkbjN"

+ 6 - 0
.env.staging

@@ -0,0 +1,6 @@
+# 生产环境配置
+VITE_APP_ENV = 'staging'
+
+OSS_ACCESS_KEY_ID = "LTAI5tE7wuNkeT9jZ42bQnyr"
+
+OSS_ACCESS_KEY_SECRET = "NnutvWhKl4HbQFSad3HosYbCkEkbjN"

+ 13 - 0
.eslintrc.js

@@ -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: {},
+};

+ 23 - 0
.gitignore

@@ -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

+ 24 - 0
README.md

@@ -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/).

+ 5 - 0
babel.config.js

@@ -0,0 +1,5 @@
+module.exports = {
+  presets: [
+    '@vue/cli-plugin-babel/preset'
+  ]
+}

+ 19 - 0
jsconfig.json

@@ -0,0 +1,19 @@
+{
+  "compilerOptions": {
+    "target": "es6",
+    "module": "esnext",
+    "baseUrl": "./",
+    "moduleResolution": "node",
+    "paths": {
+      "@/*": [
+        "src/*"
+      ]
+    },
+    "lib": [
+      "esnext",
+      "dom",
+      "dom.iterable",
+      "scripthost"
+    ]
+  }
+}

+ 55 - 0
package.json

@@ -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"
+  ]
+}

BIN
public/favicon.ico


+ 17 - 0
public/index.html

@@ -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>

+ 7 - 0
src/App.vue

@@ -0,0 +1,7 @@
+<template>
+  <router-view></router-view>
+</template>
+
+<script></script>
+
+<style></style>

+ 17 - 0
src/api/index.js

@@ -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,
+  });
+};

BIN
src/assets/apk.png


BIN
src/assets/excel.png


BIN
src/assets/exe.png


BIN
src/assets/html.png


BIN
src/assets/image.png


BIN
src/assets/iso.png


BIN
src/assets/music.png


BIN
src/assets/mv.png


BIN
src/assets/other.png


BIN
src/assets/pdf.png


BIN
src/assets/ppt.png


BIN
src/assets/psd.png


BIN
src/assets/sql.png


BIN
src/assets/txt.png


BIN
src/assets/word.png


BIN
src/assets/zip.png


+ 286 - 0
src/components/FileUpload/index.vue

@@ -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>

+ 16 - 0
src/main.js

@@ -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");

+ 22 - 0
src/router/index.js

@@ -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;

+ 46 - 0
src/utils/downFile.js

@@ -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保存文件
+    });
+  });
+}

+ 113 - 0
src/utils/requests.js

@@ -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;

+ 201 - 0
src/views/info.vue

@@ -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>

+ 20 - 0
vue.config.js

@@ -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,
+      },
+    },
+  },
+});