diff --git a/.env.development b/.env.development index d6204c2..4fad5c2 100644 --- a/.env.development +++ b/.env.development @@ -1,6 +1,6 @@ # just a flag -ENV = 'development' +ENV='development' # base api -VUE_APP_BASE_API = http://starter.ali251.langye.net -VUE_APP_UPLOAD_API =http://starter.ali251.langye.net/api/admin/upload-file +VUE_APP_BASE_API=http://starter.ali251.langye.net +VUE_APP_UPLOAD_API=http://starter.ali251.langye.net/api/admin/upload-file diff --git a/package.json b/package.json index 974be87..87db874 100644 --- a/package.json +++ b/package.json @@ -20,7 +20,7 @@ "axios": "0.18.1", "core-js": "3.6.5", "echarts": "^4.2.1", - "element-ui": "2.13.2", + "element-ui": "2.15.13", "js-cookie": "2.2.0", "less-loader": "^5.0.0", "moment": "^2.29.2", @@ -32,6 +32,7 @@ "vue": "2.6.10", "vue-count-to": "^1.0.13", "vue-router": "3.0.6", + "vuedraggable": "^2.24.3", "vuex": "3.1.0" }, "devDependencies": { diff --git a/src/api/system/baseForm.js b/src/api/system/baseForm.js index 15b3aad..d2443c8 100644 --- a/src/api/system/baseForm.js +++ b/src/api/system/baseForm.js @@ -24,11 +24,12 @@ export function index(params,isLoading = false) { }) } -export function show(params) { +export function show(params, isLoading = true) { return request({ method: "get", url: "/api/admin/base-form/show", - params + params, + isLoading }) } diff --git a/src/api/system/customForm.js b/src/api/system/customForm.js index 5e96e5b..6b19be6 100644 --- a/src/api/system/customForm.js +++ b/src/api/system/customForm.js @@ -33,14 +33,6 @@ export function destroy(params) { }) } -export function config(params) { - return request({ - method: "get", - url: "/api/admin/custom-form/config", - params - }) -} - export function update(params) { return request({ method: "get", diff --git a/src/api/system/customFormField.js b/src/api/system/customFormField.js index fc20320..f3e9d51 100644 --- a/src/api/system/customFormField.js +++ b/src/api/system/customFormField.js @@ -33,3 +33,20 @@ export function destroy(params) { }) } +export function config(params,isLoading = false) { + return request({ + method: "get", + url: "/api/admin/custom-form-field/config", + params, + isLoading + }) +} + +export function translate(params) { + return request({ + method: "get", + url: "/api/admin/custom-form-field/pinyin", + params, + isLoading: false + }) +} diff --git a/src/components/XyTable/index.vue b/src/components/XyTable/index.vue index 63ac781..aa0ecac 100644 --- a/src/components/XyTable/index.vue +++ b/src/components/XyTable/index.vue @@ -562,6 +562,20 @@ export default { let _this = this; if (_this.auths?.length > 0) { let btns = new Map(); + btns.set( + "detail", + _this.$emit('detail', scope.row, scope)} + > + 查看 + + ) btns.set( "edit", { for(let i in target){ diff --git a/src/store/index.js b/src/store/index.js index 6ae5dad..461e409 100644 --- a/src/store/index.js +++ b/src/store/index.js @@ -5,6 +5,7 @@ import app from './modules/app' import permission from './modules/permission' import settings from './modules/settings' import user from './modules/user' +import form from './modules/form' Vue.use(Vuex) @@ -13,7 +14,8 @@ const store = new Vuex.Store({ app, permission, settings, - user + user, + form }, getters }) diff --git a/src/store/modules/form.js b/src/store/modules/form.js new file mode 100644 index 0000000..4ffde47 --- /dev/null +++ b/src/store/modules/form.js @@ -0,0 +1,102 @@ +import { save, index, destroy } from "@/api/system/customFormField"; +import { Message } from "element-ui"; +const state = { + formList: [], //更个表单配置信息 + copyFormListId: [], //备份原始的字段id数组,以做删除 + selectedForm: null, //当前编辑的表单字段配置 + selectedIndex: null, +}; + +const mutations = { + SET_COPY_FORM_LIST_ID: (state, arr) => { + state.copyFormListId = arr; + }, + SET_SELECTED_INDEX: (state, index) => { + state.selectedIndex = index; + }, + CLEAR_SELECTED_INDEX: (state) => { + state.selectedIndex = null; + }, + SET_SELECTED: (state, value) => { + state.selectedForm = value; + }, + CLEAR_SELECTED: (state, value) => { + state.selectedForm = null; + }, + SET_FORM_LIST: (state, list) => { + state.formList = list; + }, + SPLICE_FORM_LIST: (state, info) => { + const { index, length, config } = info; + if (config) { + state.formList.splice(index, length || 0, config || state.selectedForm); + } else { + state.formList.splice(index, length || 0); + } + }, +}; + +const actions = { + submit: ({ state, commit }) => { + return new Promise((resolve, reject) => { + state.formList.forEach((item,index) => { + item.sort = index + 1 + }) + let formListId = state.formList.filter((i) => !!i.id).map((i) => i.id); + let deleteIds = state.copyFormListId.filter( + (i) => !formListId.includes(i) + ); + let promiseAll = [ + ...state.formList.map((i) => save(i)), + ...deleteIds.map((i) => destroy({ id: i })), + ]; + Promise.all(promiseAll) + .then((res) => { + Message({ + type: "success", + message: "保存成功", + }); + resolve(res); + }) + .catch((err) => { + reject(err); + }); + }); + }, + getFormList: ({ state, commit }, custom_form_id) => { + return new Promise((resolve, reject) => { + index( + { + page: 1, + page_size: 999, + sort_name: "sort", + sort_type: "asc", + custom_form_id, + }, + true + ) + .then((res) => { + resolve(res); + if (res?.data instanceof Array) { + commit("SET_FORM_LIST", res.data); + commit( + "SET_COPY_FORM_LIST_ID", + res.data.map((i) => i.id) + ); + } else { + console.warn("res.data not Array"); + } + }) + .catch((err) => { + reject(err); + }); + }); + }, +}; + +export default { + namespaced: true, + state, + mutations, + actions, +}; diff --git a/src/utils/auth.js b/src/utils/auth.js index 74ba1ab..d1a9d7c 100644 --- a/src/utils/auth.js +++ b/src/utils/auth.js @@ -1,6 +1,6 @@ import Cookies from 'js-cookie' -const TokenKey = 'sishitongtang_token' +const TokenKey = 'starter_token' export function getToken() { return Cookies.get(TokenKey) diff --git a/src/utils/downloadRequest.js b/src/utils/downloadRequest.js new file mode 100644 index 0000000..5489be5 --- /dev/null +++ b/src/utils/downloadRequest.js @@ -0,0 +1,92 @@ +import axios from "axios"; +import { getToken } from "@/utils/auth"; +import { Loading, Message } from "element-ui"; + +/* + * @params {string} url 请求拼接地址 + * @params {object} info 请求参数params或data + */ + +let loading; +export async function download(url, method = "get", info, filename) { + loading = Loading.service({ + lock: true, + background: "rgba(0,0,0,0.4)", + text: "文件正在生成中...", + }); + + let options = { + baseURL: process.env.VUE_APP_BASE_API, + url, + method, + responseType: "blob", + timeout: 10000, + headers: { + Accept: "application/json", + "Content-Type": "application/json; charset=utf-8", + withCredentials: true, + Authorization: "Bearer " + getToken(), + }, + }; + if (method === "get") { + Object.defineProperty(options, "params", { + value: info, + enumerable: true, + writable: false, + }); + } + if (method === "post") { + Object.defineProperty(options, "data", { + value: info, + enumerable: true, + writable: false, + }); + } + + try { + const response = await axios.request(options); + + loading.close(); + + // 提取文件名 + if (!filename) { + filename = + response.headers["content-disposition"]?.match(/filename=(.*)/)[1] || + ""; + } + + // 将二进制流转为blob + const blob = new Blob([response.data], { + type: "application/octet-stream", + }); + if (typeof window.navigator.msSaveBlob !== "undefined") { + // 兼容IE,window.navigator.msSaveBlob:以本地方式保存文件 + window.navigator.msSaveBlob(blob, decodeURI(filename)); + } else { + // 创建新的URL并指向File对象或者Blob对象的地址 + const blobURL = window.URL.createObjectURL(blob); + // 创建a标签,用于跳转至下载链接 + const tempLink = document.createElement("a"); + tempLink.style.display = "none"; + tempLink.href = blobURL; + tempLink.setAttribute("download", decodeURI(filename)); + // 兼容:某些浏览器不支持HTML5的download属性 + if (typeof tempLink.download === "undefined") { + tempLink.setAttribute("target", "_blank"); + } + // 挂载a标签 + document.body.appendChild(tempLink); + tempLink.click(); + document.body.removeChild(tempLink); + // 释放blob URL地址 + window.URL.revokeObjectURL(blobURL); + } + } catch (err) { + console.error(err); + loading.close(); + Message({ + type: "error", + message: err, + }); + } +} diff --git a/src/utils/index.js b/src/utils/index.js index cf4c5e1..32825fb 100644 --- a/src/utils/index.js +++ b/src/utils/index.js @@ -158,3 +158,16 @@ export function deepCopy(data) { return data; } } + +export function debounce(func, delay) { + let timer = null; + return function() { + const context = this; + const args = arguments; + clearTimeout(timer); + timer = setTimeout(function() { + func.apply(context, args); + }, delay); + } +} + diff --git a/src/views/component/dialog.vue b/src/views/component/dialog.vue index c046d93..8c7ac58 100644 --- a/src/views/component/dialog.vue +++ b/src/views/component/dialog.vue @@ -1,36 +1,24 @@ diff --git a/src/views/component/drawer.vue b/src/views/component/drawer.vue new file mode 100644 index 0000000..439da55 --- /dev/null +++ b/src/views/component/drawer.vue @@ -0,0 +1,116 @@ + + + + + diff --git a/src/views/component/form.vue b/src/views/component/form.vue deleted file mode 100644 index 2358601..0000000 --- a/src/views/component/form.vue +++ /dev/null @@ -1,248 +0,0 @@ - - - - - diff --git a/src/views/component/table.vue b/src/views/component/table.vue index 1a7ebb6..d870f0e 100644 --- a/src/views/component/table.vue +++ b/src/views/component/table.vue @@ -1,119 +1,328 @@ diff --git a/src/views/system/components/addField.vue b/src/views/system/components/addField.vue deleted file mode 100644 index da29b90..0000000 --- a/src/views/system/components/addField.vue +++ /dev/null @@ -1,305 +0,0 @@ - - - - - diff --git a/src/views/system/components/editPane.vue b/src/views/system/components/editPane.vue new file mode 100644 index 0000000..58dff3a --- /dev/null +++ b/src/views/system/components/editPane.vue @@ -0,0 +1,285 @@ + + + + + diff --git a/src/views/system/components/formEditor.vue b/src/views/system/components/formEditor.vue new file mode 100644 index 0000000..3cd5ffc --- /dev/null +++ b/src/views/system/components/formEditor.vue @@ -0,0 +1,350 @@ + + + + + diff --git a/src/views/system/components/formFields.vue b/src/views/system/components/formFields.vue deleted file mode 100644 index 306b047..0000000 --- a/src/views/system/components/formFields.vue +++ /dev/null @@ -1,159 +0,0 @@ - - - - - diff --git a/src/views/system/components/formSlotRender.vue b/src/views/system/components/formSlotRender.vue new file mode 100644 index 0000000..9e678a3 --- /dev/null +++ b/src/views/system/components/formSlotRender.vue @@ -0,0 +1,87 @@ + + + diff --git a/src/views/system/form.vue b/src/views/system/form.vue index dffe69f..f5ad469 100644 --- a/src/views/system/form.vue +++ b/src/views/system/form.vue @@ -30,13 +30,13 @@ - + @@ -46,10 +46,10 @@ import { authMixin } from "@/mixin/authMixin"; import LxHeader from "@/components/LxHeader/index.vue"; import addForm from "./components/addForm.vue"; -import formFields from "./components/formFields.vue"; +import formEditor from "@/views/system/components/formEditor.vue"; export default { components:{ - LxHeader,addForm,formFields + LxHeader,addForm,formEditor }, mixins: [authMixin], diff --git a/src/views/system/menu.vue b/src/views/system/menu.vue index a3e5340..221b580 100644 --- a/src/views/system/menu.vue +++ b/src/views/system/menu.vue @@ -124,7 +124,7 @@ - +