From db57d414affb72d7d6d0099686efd27b49036e39 Mon Sep 17 00:00:00 2001 From: xy <271556543@qq.com> Date: Tue, 9 Jul 2024 17:30:55 +0800 Subject: [PATCH] 2024-7-9 --- .env.development | 1 + .env.production | 3 +- .env.staging | 3 +- package.json | 1 + src/api/common.js | 40 +- src/api/user.js | 11 +- src/const/addProps.js | 2 +- src/const/validation.js | 10 + src/permission.js | 2 - src/settings.js | 2 +- src/store/modules/form.js | 125 +++++- src/styles/element-ui.scss | 19 + src/styles/sidebar.scss | 2 +- src/utils/auth.js | 9 +- src/utils/table.js | 242 +++++++++++ src/views/component/detail.vue | 20 +- src/views/component/dialog.vue | 465 +++++++++++---------- src/views/component/linkPickModal.vue | 41 +- src/views/component/table.vue | 251 +++-------- src/views/system/components/editPane.vue | 14 +- src/views/system/components/formEditor.vue | 33 +- src/views/system/components/linkWith.vue | 41 +- src/views/system/permission.vue | 80 +++- vue.config.js | 4 +- 24 files changed, 913 insertions(+), 508 deletions(-) create mode 100644 src/const/validation.js create mode 100644 src/utils/table.js diff --git a/.env.development b/.env.development index 4fad5c2..eec3e74 100644 --- a/.env.development +++ b/.env.development @@ -4,3 +4,4 @@ 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_PREVIEW_API=http://view.ali251.langye.net:8012/onlinePreview diff --git a/.env.production b/.env.production index f837c50..aaeb0c2 100644 --- a/.env.production +++ b/.env.production @@ -3,4 +3,5 @@ ENV = 'production' # base api VUE_APP_BASE_API = http://starter.ali251.langye.net -VUE_APP_UPLOAD_API =http://starter.ali251.langye.net/api/admin/upload-file \ No newline at end of file +VUE_APP_UPLOAD_API =http://starter.ali251.langye.net/api/admin/upload-file +VUE_APP_PREVIEW_API=http://view.ali251.langye.net:8012/onlinePreview diff --git a/.env.staging b/.env.staging index a8793a0..abeafcc 100644 --- a/.env.staging +++ b/.env.staging @@ -4,5 +4,6 @@ NODE_ENV = production ENV = 'staging' # base api -VUE_APP_BASE_API = '/stage-api' +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 4dca0f6..c0c964d 100644 --- a/package.json +++ b/package.json @@ -36,6 +36,7 @@ "vue-router": "3.0.6", "vuedraggable": "^2.24.3", "vuex": "3.1.0", + "webpack-md5-hash": "^0.0.6", "xlsx": "^0.18.5" }, "devDependencies": { diff --git a/src/api/common.js b/src/api/common.js index d4ab267..792a635 100644 --- a/src/api/common.js +++ b/src/api/common.js @@ -1,31 +1,33 @@ -import request from '@/utils/request' +import request from '@/utils/request' -export function listCommondepartment(params) { - return request({ - url: '/api/admin/other/admin-department-list', - method: 'get', - params:params - }) +export function listCommondepartment(params) { + return request({ + url: '/api/admin/other/admin-department-list', + method: 'get', + params:params, + isLoading: false + }) } -export function listCommonuser(params) { - return request({ - url: '/api/admin/other/admin-user-list', - method: 'get', - params:params - }) +export function listCommonuser(params) { + return request({ + url: '/api/admin/other/admin-user-list', + method: 'get', + params:params, + isLoading: false + }) } -export function remoteStatistic(params) { - return request({ - url: '/api/admin/other/remot-statistic', - method: 'get', - params:params - }) +export function remoteStatistic(params) { + return request({ + url: '/api/admin/other/remot-statistic', + method: 'get', + params:params + }) } diff --git a/src/api/user.js b/src/api/user.js index e12d073..9fbdf50 100644 --- a/src/api/user.js +++ b/src/api/user.js @@ -4,7 +4,8 @@ export function login(data) { return request({ url: '/api/admin/auth/login', method: 'post', - data + data, + isLoading: false }) } @@ -12,7 +13,8 @@ export function getInfo(token) { return request({ url: '/api/admin/auth/me', method: 'post', - params: { token } + params: { token }, + isLoading: false }) } @@ -27,6 +29,7 @@ export function getAuthMenu(token) { return request({ url: '/api/admin/auth/permissions', method: 'get', - params: { token } + params: { token }, + isLoading: false }) -} \ No newline at end of file +} diff --git a/src/const/addProps.js b/src/const/addProps.js index edd8a70..246f47d 100644 --- a/src/const/addProps.js +++ b/src/const/addProps.js @@ -20,7 +20,7 @@ export const addPropsMap = new Map([ ["datetime", { type: 'datetime', clearable: true, - valueFormat: 'yyyy-MM-dd mm:hh:ss', + valueFormat: 'yyyy-MM-dd hh:mm:ss', pickerOptions: { shortcuts: [{ text: '今天', diff --git a/src/const/validation.js b/src/const/validation.js new file mode 100644 index 0000000..edb4d35 --- /dev/null +++ b/src/const/validation.js @@ -0,0 +1,10 @@ +const validation = new Map([ + ['integer',/^-?\d+$/],//整数 + ['date',/(^\d{10})|(^\d{13})|(^((\d\d\d\d(.+)|\d\d(.+))?(0?[1-9](.+)|1[012](.+))?((0?[1-9]|[12]\d|3[01])(.+))?\s?)((0?[0-9]|1[0-9]|2[0-3])(.+))?((0?[0-9]|[1-5][0-9])(.+))?((0?[0-9]|[1-5][0-9])(.+))?)$/], + ['email',/^[^\s@]+@[^\s@]+\.[^\s@]+$/], + ['idcard',/(^([1-6][1-9]|50)\d{4}\d{2}((0[1-9])|10|11|12)(([0-2][1-9])|10|20|30|31)\d{3})|(^([1-6][1-9]|50)\d{4}(18|19|20)\d{2}((0[1-9])|10|11|12)(([0-2][1-9])|10|20|30|31)\d{3}[0-9Xx])$/], + ['mobile',/(^1[3456789]\d{9})|(^(0\d{2,3}(-)*)?\d{7})$/], + ['numeric',/^-?\d+(.\d+)?$/], +]) + +export default validation diff --git a/src/permission.js b/src/permission.js index c5e41fa..21a7aa1 100644 --- a/src/permission.js +++ b/src/permission.js @@ -5,11 +5,9 @@ import NProgress from 'nprogress' // progress bar import 'nprogress/nprogress.css' // progress bar style import { getToken } from '@/utils/auth' // get token from cookie import getPageTitle from '@/utils/get-page-title' - NProgress.configure({ showSpinner: false }) // NProgress Configuration const whiteList = ['/login'] // no redirect whitelist - router.beforeEach(async(to, from, next) => { // start progress bar NProgress.start() diff --git a/src/settings.js b/src/settings.js index 7a4be47..8c81eae 100644 --- a/src/settings.js +++ b/src/settings.js @@ -1,7 +1,7 @@ module.exports = { title: '朗业基础平台', - + TOKEN_KEY: 'starter_token', /** * @type {boolean} true | false * @description Whether fix the header diff --git a/src/store/modules/form.js b/src/store/modules/form.js index 0c2fa4e..6f274c7 100644 --- a/src/store/modules/form.js +++ b/src/store/modules/form.js @@ -1,7 +1,93 @@ -import {index} from "@/api/system/customFormField"; +import {index,destroy} from "@/api/system/customFormField"; import {show,save} from "@/api/system/customForm"; import {Message} from "element-ui"; +const uploadField = [ + { + "field": "original_name", + "name": "源名称", + "search_input": "text", + "edit_input": "text", + "admin_id": null, + "department_id": null, + "sort": 1, + "help": null, + "validation": [], + "select_item": [], + "list_show": 1, + "form_show": 1, + }, + { + "field": "name", + "name": "名称", + "search_input": "text", + "edit_input": "text", + "admin_id": null, + "department_id": null, + "sort": 2, + "help": null, + "validation": [], + "select_item": [], + "list_show": 1, + "form_show": 1, + }, + { + "field": "extension", + "name": "后缀名", + "search_input": "text", + "edit_input": "text", + "admin_id": null, + "department_id": null, + "sort": 3, + "help": null, + "validation": [], + "select_item": [], + "list_show": 1, + "form_show": 1, + }, + { + "field": "size", + "name": "大小", + "search_input": "text", + "edit_input": "text", + "admin_id": null, + "department_id": null, + "sort": 4, + "help": null, + "validation": [], + "select_item": [], + "list_show": 1, + "form_show": 1, + }, + { + "field": "url", + "name": "地址", + "search_input": "text", + "edit_input": "text", + "admin_id": null, + "department_id": null, + "sort": 5, + "help": null, + "validation": [], + "select_item": [], + "list_show": 1, + "form_show": 1, + }, + { + "field": "folder", + "name": "类型", + "search_input": "text", + "edit_input": "text", + "admin_id": null, + "department_id": null, + "sort": 6, + "help": null, + "validation": [], + "select_item": [], + "list_show": 1, + "form_show": 1, + } +] const state = { formList: [], //更个表单配置信息 copyFormListId: [], //备份原始的字段id数组,以做删除 @@ -39,6 +125,25 @@ const mutations = { }; const actions = { + submitUpload: ({ state, commit }, tableId) => { + return new Promise((resolve, reject) => { + show({ id: tableId }).then(res => { + res.fields = uploadField + save(res).then(res1 => { + Message({ + type: 'success', + message: res1.msg + }) + resolve(res1) + }).catch(err1 => { + reject(err1) + }) + }).catch(err => { + reject(err) + }) + }) + }, + submit: ({ state, commit }, tableId) => { return new Promise((resolve, reject) => { show({ id: tableId }).then(res => { @@ -113,6 +218,24 @@ const actions = { }); }); }, + deleteField: ({ state, commit, dispatch }) => { + if (state.selectedForm?.id) { + return new Promise((resolve, reject) => { + destroy({ id: state.selectedForm.id }).then(res => { + resolve(res) + commit('CLEAR_SELECTED') + commit('CLEAR_SELECTED_INDEX') + }).catch(err => { + reject(err) + }) + }) + } else { + return new Promise((resolve, reject) => { + state.formList.splice(state.selectedIndex, 1); + resolve(false) + }) + } + } }; export default { diff --git a/src/styles/element-ui.scss b/src/styles/element-ui.scss index 0062411..4956c3b 100644 --- a/src/styles/element-ui.scss +++ b/src/styles/element-ui.scss @@ -47,3 +47,22 @@ .el-range-separator { box-sizing: content-box; } + +.el-dialog { + background-color: #fff; + border: 0; + border-radius: 6px; + background-clip: padding-box; + box-shadow: 0 4px 12px rgba(0, 0, 0, .15); + + &__header { + border-bottom: 1px solid #e8eaec; + padding: 14px 16px; + line-height: 1; + } + &__footer { + border-top: 1px solid #e8eaec; + padding: 12px 18px; + text-align: right; + } +} diff --git a/src/styles/sidebar.scss b/src/styles/sidebar.scss index e260bcf..0968334 100644 --- a/src/styles/sidebar.scss +++ b/src/styles/sidebar.scss @@ -229,7 +229,7 @@ >.el-menu--popup { max-height: 100vh; overflow-y: auto; - background: #0077CC !important; + background: $primaryColor !important; &::-webkit-scrollbar-track-piece { background: #d3dce6; diff --git a/src/utils/auth.js b/src/utils/auth.js index d1a9d7c..7ce33e8 100644 --- a/src/utils/auth.js +++ b/src/utils/auth.js @@ -1,15 +1,14 @@ import Cookies from 'js-cookie' - -const TokenKey = 'starter_token' +import { TOKEN_KEY } from '@/settings' export function getToken() { - return Cookies.get(TokenKey) + return Cookies.get(TOKEN_KEY) } export function setToken(token) { - return Cookies.set(TokenKey, token) + return Cookies.set(TOKEN_KEY, token) } export function removeToken() { - return Cookies.remove(TokenKey) + return Cookies.remove(TOKEN_KEY) } diff --git a/src/utils/table.js b/src/utils/table.js new file mode 100644 index 0000000..3dcc7f9 --- /dev/null +++ b/src/utils/table.js @@ -0,0 +1,242 @@ +import { show } from "@/api/system/customForm"; +import { listCommondepartment, listCommonuser } from "@/api/common"; +import { primaryColor } from "@/styles/variables.scss" +import { download } from "@/utils/downloadRequest"; + +function down (url) { + download(url) +} +function preview (url) { + let codeUri = `${process.env.VUE_APP_PREVIEW_API}?url=${encodeURIComponent( + new Buffer(url).toString("base64") + )}` + + window.open(codeUri,'_blank') +} + +const baseTable = new Map([ + ['departments', async () => { + return (await listCommondepartment()) + }], + ['admins',async () => { + return (await listCommonuser()) + }] +]) +export async function getForm (customFormId) { + let selectItemMap = new Map(); + if (!customFormId) { + console.warn("customFormId is required!") + return + } + const res = await show({ id: customFormId }, false); + + const { fields, relation } = res; + + let fieldRes = fields.sort((a,b) => a.sort - b.sort); + + if ( + !fields || + !relation || + !fields instanceof Array || + !relation instanceof Array + ) { + throw new Error("fields或relation参数错误"); + } + + fieldRes?.forEach((i, index) => { + i._relations = relation.find((j) => j.custom_form_field === i.field); + if (i.select_item && typeof i.select_item === 'object') { + let keys = Object.keys(i.select_item) + if (keys.length > 0) { + i._params = keys.map((key) => { + return { + key, + value: /^\d*$/.test(i.select_item[key]) + ? Number(i.select_item[key]) + : i.select_item[key], + }; + }); + + selectItemMap.set(i.field, i._params); + + //有select,radio + i.edit_input = 'radio' + } + } + }) + + return { fieldRes, selectItemMap }; +} + +export function getRenderTable (ctx, fields, replaces) { + const h = ctx.$createElement; + if (replaces && !(replaces instanceof Map)) { + throw new Error("replaces参数错误,需要Map类型"); + } + return fields.map((field, index) => { + //自定义替换 + if (replaces instanceof Map && replaces.get(field.field)) { + return replaces.get(field.field) + } + //文件 + if (field.edit_input === 'file' || field.edit_input === 'files') { + let renderFn = () => {} + const { link_relation, foreign_key, link_with_name } = field._relations; + if (link_relation === 'hasOne' || link_relation === 'newHasOne') { + renderFn = row => { + if (!row[link_with_name]?.url) { + return '' + } + return ( +
+ { + ['jpg','jpeg','png','gif','svg','webp','bmp'].indexOf(row[link_with_name]?.extension) === -1 ? + ( + {row[link_with_name]?.original_name} + ) : () + } + + down(row[link_with_name]?.url) + }}/> + preview(row[link_with_name]?.url) + }}/> +
+ ) + } + } else { + renderFn = row => ( +
+ {row[link_with_name]?.map((o,oi) => ( +
+ { + ['jpg','jpeg','png','gif','svg','webp','bmp'].indexOf(o?.extension) === -1 ? + ( + {oi+1}. { o?.original_name || o?.name } + ) : () + } + + down(o?.url) + }}/> + preview(o?.url) + }}/> +
+ ))} +
+ ) + } + + return { + prop: field.field, + label: field.name, + width: field.width, + align: "left", + showOverflowTooltip: false, + customFn: row => renderFn(row) + } + } + + //关联 + if (field._relations && typeof field._relations === 'object') { + let renderFn = () => {} + const { link_relation, foreign_key, link_with_name } = field._relations; + if (link_relation === 'hasOne' || link_relation === 'newHasOne') { + renderFn = row => ( + + {row[link_with_name]?.name || + row[link_with_name]?.title || + row[link_with_name]?.no || + row[link_with_name]?.value || + row[link_with_name]?.biaoti || + row[link_with_name]?.mingcheng} + + ) + } + if (link_relation === 'hasMany' || link_relation === 'newHasMany') { + renderFn = row => ( +
+ {row[link_with_name]?.map((o) => ( +

+ {o?.name || + o?.title || + o?.no || + o?.value || + o?.biaoti || + o?.mingcheng} +

+ ))} +
+ ) + } + + return { + prop: field.field, + label: field.name, + width: field.width, + customFn: row => renderFn(row), + fixed: field.is_fixed + } + } + + //富文本 + if (field.edit_input === 'richtext') { + return { + prop: field.field, + label: field.name, + width: field.width, + showOverflowTooltip: false, + customFn: row => ( + + { + row[field.field] ?
:
暂无内容
+ } + + 查看 +
+ ), + fixed: field.is_fixed + } + } + + //select内容 + if ( + field._params && field._params instanceof Array + ) { + + return { + prop: field.field, + label: field.name, + width: field.width, + customFn: row => ( + { field._params.find(param => param.value == row[field.field])?.key } + ), + fixed: field.is_fixed + } + } + + return { + prop: field.field, + label: field.name, + width: field.width, + fixed: field.is_fixed + } + }) +} diff --git a/src/views/component/detail.vue b/src/views/component/detail.vue index 8139a21..47d082d 100644 --- a/src/views/component/detail.vue +++ b/src/views/component/detail.vue @@ -37,7 +37,7 @@ -