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 @@
-
+
{{ contentFormat(item) }}
{
if (item.edit_input !== 'files') {
let dataTable = this.allTables.find(t => t.table_name === res[1].relation[0].link_table_name);
- formShow({ id: dataTable.id }).then(res1 => {
+ if (dataTable) {
+ formShow({ id: dataTable?.id }).then(res1 => {
+ this.linkTableList.push({
+ value: res[0].data?.map(o => o[res[1]?.relation[0]?.link_with_name]),
+ field: this.formatColumn(res1),
+ title: res[1]?.name
+ })
+ })
+ } else {
this.linkTableList.push({
- value: res[0].data?.map(o => o[res[1]?.relation[0]?.link_with_name]),
- field: this.formatColumn(res1),
+ value: this.detail[item?._relations?.link_with_name],
+ field: this.formatColumn(res[1]),
title: res[1]?.name
})
- })
+ }
} else {
this.linkTableList.push({
value: res[0].data?.map(o => o[res[1]?.relation[0]?.link_with_name]),
diff --git a/src/views/component/dialog.vue b/src/views/component/dialog.vue
index 2cdf3e3..c7dab24 100644
--- a/src/views/component/dialog.vue
+++ b/src/views/component/dialog.vue
@@ -34,195 +34,208 @@ export default {
},
[
h(
- "el-form",
+ "el-scrollbar",
{
- ref: "elForm",
- props: {
- model: this.form,
- labelWidth: "80px",
- rules: this.rules,
- labelPosition: "right",
- size: "small",
+ style: {
+ height: "58vh",
},
},
- (() => {
- let dom = [];
- this.formInfo
- .filter((i) => i.form_show)
- .forEach((i, index) => {
- dom.push(
- h(
- "el-form-item",
- {
- ref: `elFormItem${i.field}`,
- style: {
- width: "100%",
- },
- props: {
- label: i.name,
- prop: i.field,
- required:
- i.validation instanceof Array
- ? !!i.validation.find((i) => i === "required")
- : false,
- },
- },
- this.$scopedSlots[i.field]
- ? this.$scopedSlots[i.field]({
- fieldInfo: i,
- form: this.form,
- file: this.file,
- })
- : (i._relations && i.edit_input !== 'file' && i.edit_input !== 'files')
- ? [
- h(
- "el-input",
- {
- props: {
- readonly: true,
- value:
- i._relations.link_relation ===
- "newHasOne" ||
- i._relations.link_relation === "hasOne"
- ? this.originalForm[
- i._relations.link_with_name
- ]?.name ||
- this.originalForm[
- i._relations.link_with_name
- ]?.mingcheng ||
- this.originalForm[
- i._relations.link_with_name
- ]?.no ||
- this.originalForm[
- i._relations.link_with_name
- ]?.id
- : this.originalForm[
- i._relations.link_with_name
- ]
- ?.map(
- (j) =>
- j[i._relations.custom_form_field]
- )
- ?.toString(),
- },
- on: {
- // ['focus']:e => {
- // this.$refs['linkPickModal'].show()
- // }
- },
- },
- [
- h("el-button", {
- props: {
- icon: "el-icon-arrow-right",
- },
- slot: "append",
- on: {
- click: (e) => {
- this.pickedLinkField.field = i.field;
- this.pickedLinkField.linkType =
- i._relations.link_relation;
- this.pickedLinkField.linkTableName =
- i._relations.link_table_name;
- this.pickedLinkField.originalRows =
- this.originalForm[
- i._relations.link_with_name
- ];
- this.$refs["linkPickModal"].show();
+
+ [
+ h(
+ "el-form",
+ {
+ ref: "elForm",
+ class: "form-body",
+ props: {
+ model: this.form,
+ labelWidth: "80px",
+ rules: this.rules,
+ labelPosition: "right",
+ size: "small",
+ },
+ },
+ (() => {
+ let dom = [];
+ this.formInfo
+ .filter((i) => i.form_show)
+ .forEach((i, index) => {
+ dom.push(
+ h(
+ "el-form-item",
+ {
+ ref: `elFormItem${i.field}`,
+ style: {
+ width: "100%",
+ },
+ props: {
+ label: i.name,
+ prop: i.field,
+ required:
+ i.validation instanceof Array
+ ? !!i.validation.find((i) => i === "required")
+ : false,
+ },
+ },
+ this.$scopedSlots[i.field]
+ ? this.$scopedSlots[i.field]({
+ fieldInfo: i,
+ form: this.form,
+ file: this.file,
+ })
+ : i._relations &&
+ i.edit_input !== "file" &&
+ i.edit_input !== "files"
+ ? [
+ h(
+ "el-input",
+ {
+ props: {
+ readonly: true,
+ value:
+ (this.pickModalText[i.field]) || (i._relations.link_relation ===
+ "newHasOne" ||
+ i._relations.link_relation === "hasOne"
+ ? this.originalForm[
+ i._relations.link_with_name
+ ]?.name ||
+ this.originalForm[
+ i._relations.link_with_name
+ ]?.mingcheng ||
+ this.originalForm[
+ i._relations.link_with_name
+ ]?.no ||
+ this.originalForm[
+ i._relations.link_with_name
+ ]?.id || this.form[i.field]
+ : this.originalForm[
+ i._relations.link_with_name
+ ]
+ ?.map(
+ (j) =>
+ j[
+ i._relations
+ .custom_form_field
+ ]
+ )
+ ?.toString()),
},
- },
- }),
+ on: {
+ ['focus']:e => {
+ this.pickedLinkField.field = i.field;
+ this.pickedLinkField.linkType =
+ i._relations.link_relation;
+ this.pickedLinkField.linkTableName =
+ i._relations.link_table_name;
+ this.pickedLinkField.originalRows =
+ this.originalForm[
+ i._relations.link_with_name
+ ];
+ this.$refs["linkPickModal"].show();
+ }
+ },
+ }
+ ),
]
- ),
- ]
- : [
- h(
- domMap.get(i.edit_input),
- {
- ref: `elEdit_${i.field}`,
- style: {
- width: "100%",
- },
- props: {
- ...addPropsMap.get(i.edit_input),
- ...this.extraProps(i),
- placeholder: i.help,
- value: this.form[i.field],
- },
- attrs: {
- placeholder: i.help || `请填写${i.name}`,
- },
- on: {
- [this.getEventType(i.edit_input)]: (e) => {
- if (i.field) {
- this.form[i.field] = e;
- this.form = Object.assign({}, this.form);
- }
- },
- },
- scopedSlots:
- i.edit_input === "file" ||
- i.edit_input === "files"
- ? {
- file: (scope) => {
- let { file } = scope;
- return [
- h("div", {}, [
- h("i", {
- class: {
- "el-icon-circle-check":
- file.status === "success",
- "el-icon-loading":
- file.status === "uploading",
- },
- style: {
- color:
- file.status === "success"
- ? "green"
- : "",
- },
- }),
- h(
- "a",
- {
- attrs: {
- href: file.url,
- download: file.name,
- },
+ : [
+ h(
+ domMap.get(i.edit_input),
+ {
+ ref: `elEdit_${i.field}`,
+ style: {
+ width: "100%",
+ },
+ props: {
+ ...addPropsMap.get(i.edit_input),
+ ...this.extraProps(i),
+ placeholder: i.help,
+ value: this.form[i.field],
+ },
+ attrs: {
+ placeholder: i.help || `请填写${i.name}`,
+ },
+ on: {
+ [this.getEventType(i.edit_input)]: (
+ e
+ ) => {
+ if (i.field) {
+ this.form[i.field] = e;
+ this.form = Object.assign(
+ {},
+ this.form
+ );
+ }
+ },
+ },
+ scopedSlots:
+ i.edit_input === "file" ||
+ i.edit_input === "files"
+ ? {
+ file: (scope) => {
+ let { file } = scope;
+ return [
+ h("div", {}, [
+ h("i", {
class: {
- "uploaded-a":
- file.status === "success",
+ "el-icon-circle-check":
+ file.status ===
+ "success",
+ "el-icon-loading":
+ file.status ===
+ "uploading",
},
style: {
- padding: "0 4px",
+ color:
+ file.status ===
+ "success"
+ ? "green"
+ : "",
},
+ }),
+ h(
+ "a",
+ {
+ attrs: {
+ href: file.url,
+ download: file.name,
+ },
+ class: {
+ "uploaded-a":
+ file.status ===
+ "success",
+ },
+ style: {
+ padding: "0 4px",
+ },
+ },
+ file.name
+ ),
+ ]),
+ h("i", {
+ class: "el-icon-close",
+ on: {
+ ["click"]: () =>
+ this.fileRemoveHandler(
+ file,
+ i.field
+ ),
},
- file.name
- ),
- ]),
- h("i", {
- class: "el-icon-close",
- on: {
- ["click"]: () =>
- this.fileRemoveHandler(
- file,
- i.field
- ),
- },
- }),
- ];
- },
- }
- : "",
- },
- this.optionsRender(h, i)
- ),
- ]
- )
- );
- });
- return dom;
- })()
+ }),
+ ];
+ },
+ }
+ : "",
+ },
+ this.optionsRender(h, i)
+ ),
+ ]
+ )
+ );
+ });
+ return dom;
+ })()
+ ),
+ ]
),
h("template", { slot: "footer" }, [
h(
@@ -271,8 +284,9 @@ export default {
originalRows: this.pickedLinkField.originalRows,
},
on: {
- ["confirm"]: ({ field, value }) => {
+ ["confirm"]: ({ field, value, text }) => {
this.form[field] = value;
+ this.pickModalText[field] = text;
},
},
}),
@@ -294,6 +308,7 @@ export default {
field: "",
originalRows: [],
},
+ pickModalText: {}
};
},
methods: {
@@ -314,16 +329,16 @@ export default {
if (info.edit_input === "checkbox" || info.edit_input === "radio") {
return info._params && info._params instanceof Array
? info._params.map((i) =>
- h("el-option", {
- props: {
- label:
- i.key || i.value || i.name || i.no || i.mingcheng || i.id,
- value: info._relations
- ? i[info._relations.foreign_key]
- : i.value,
- },
- })
- )
+ h("el-option", {
+ props: {
+ label:
+ i.key || i.value || i.name || i.no || i.mingcheng || i.id,
+ value: info._relations
+ ? i[info._relations.foreign_key]
+ : i.value,
+ },
+ })
+ )
: [];
}
if (info.edit_input === "file" || info.edit_input === "files") {
@@ -443,21 +458,21 @@ export default {
if (i && (i.edit_input === "file" || i.edit_input === "files")) {
res[i._relations.link_with_name]
? (this.file[i.field] =
- res[i._relations.link_with_name] instanceof Array
- ? res[i._relations.link_with_name].map((i) => {
- return {
- name: i?.original_name,
- url: i?.url,
- response: i,
- };
- })
- : [
- {
- name: res[i._relations.link_with_name]?.original_name,
- url: res[i._relations.link_with_name]?.url,
- response: res[i._relations.link_with_name],
- },
- ])
+ res[i._relations.link_with_name] instanceof Array
+ ? res[i._relations.link_with_name].map((i) => {
+ return {
+ name: i?.original_name,
+ url: i?.url,
+ response: i,
+ };
+ })
+ : [
+ {
+ name: res[i._relations.link_with_name]?.original_name,
+ url: res[i._relations.link_with_name]?.url,
+ response: res[i._relations.link_with_name],
+ },
+ ])
: (this.file[i.field] = []);
return
@@ -515,10 +530,10 @@ export default {
if (info.edit_input === "files") {
copyForm[info._relations.link_with_name] = this.file[
info.field
- ]?.map((i) => {
+ ]?.map((i) => {
return {
upload_id: i?.response?.id,
- original_name: i?.response?.original_name
+ ...i?.response
};
});
} else {
@@ -526,7 +541,7 @@ export default {
info.field
] instanceof Array ? copyForm[
info.field
- ]?.map((i) => {
+ ]?.map((i) => {
return {
[info._relations.custom_form_field]: i,
//...copyRelation,
@@ -606,12 +621,29 @@ export default {
this.form[i.field] = "";
if (
i.validation instanceof Array &&
- i.validation.length > 0 &&
- !!i.validation.find((i) => i === "required")
+ i.validation.length > 0
) {
- this.rules[i.field] = [
- { required: true, message: `请填写${i.name}` },
- ];
+ this.rules[i.field] = []
+ i.validation.forEach((j) => {
+ if (j === "required") {
+ this.rules[i.field].push({ required: true, message: `请填写${i.name}` })
+ } else {
+ this.rules[i.field].push({
+ validator: (rule, value, callback) => {
+ if (value === '') {
+ callback()
+ return
+ }
+ if (validation.get(j).test(value)) {
+ callback()
+ } else {
+ callback(new Error(`${i.name}验证不通过`))
+ }
+ },
+ trigger: 'blur'
+ })
+ }
+ })
}
if (i.edit_input === "files") {
this.form[i.field] = [];
@@ -626,7 +658,7 @@ export default {
});
document.documentElement.style.setProperty(
"--column-num",
- Math.floor(newVal.length / 8).toString()
+ newVal.length > 8 ? "2" : "1"
);
},
//immediate: true,
@@ -664,4 +696,9 @@ export default {
color: red;
text-decoration: underline;
}
+.form-body {
+ display: grid;
+ grid-gap: 10px;
+ grid-template-columns: repeat(var(--column-num), 1fr);
+}
diff --git a/src/views/component/linkPickModal.vue b/src/views/component/linkPickModal.vue
index 64c84b9..26ae071 100644
--- a/src/views/component/linkPickModal.vue
+++ b/src/views/component/linkPickModal.vue
@@ -9,8 +9,8 @@
placeholder="搜索条目"
>
+ item.name
+ }}
inputStartHandler(e, select.filter[0])"
/>
至至
查询查询
取 消取 消
确 定确 定
@@ -92,7 +92,7 @@ export default {
field: String,
originalRows: {
default: () => [],
- type: Array,
+ type: [Array,Object],
},
},
data() {
@@ -249,18 +249,19 @@ export default {
confirm() {
this.linkType === "hasMany" || this.linkType === "newHasMany"
? this.$emit("confirm", {
- field: this.field,
- value: Array.from(
- new Set([
- ...this.$refs["table"].getSelection()?.map((i) => i.id),
- ...this.originalRowIds,
- ])
- ),
- })
+ field: this.field,
+ value: Array.from(
+ new Set([
+ ...this.$refs["table"].getSelection()?.map((i) => i.id),
+ ...this.originalRowIds,
+ ])
+ ),
+ })
: this.$emit("confirm", {
- field: this.field,
- value: this.tempRow.id,
- });
+ field: this.field,
+ value: this.tempRow.id,
+ text: this.tempRow.name || this.tempRow.value || this.tempRow.mingcheng || this.tempRow.no || this.tempRow.id
+ });
this.dialogVisible = false;
},
},
diff --git a/src/views/component/table.vue b/src/views/component/table.vue
index 7d8a8eb..0d68895 100644
--- a/src/views/component/table.vue
+++ b/src/views/component/table.vue
@@ -22,7 +22,7 @@
v-for="item in form"
:key="item.id"
:value="item.field"
- >{{ item.name }}{{ item.name }}
{{
+ >{{
item.key || item.value || item.name || item.no || item.mingcheng || item.id
}}
@@ -83,7 +83,7 @@
display: flex;
align-items: center;
"
- >至至
查询查询
{{ item.name }}{{ item.name }}
{{
+ >{{
item.key || item.value || item.name || item.no || item.mingcheng || item.id
}}
@@ -215,19 +215,19 @@
@click="
$refs['dialog'].setType('add'), $refs['dialog'].show()
"
- >新增新增
导入
导出
@@ -235,8 +235,8 @@
-
+
{
- const res = await listdept()
- return res
- }],
- ['admins',[]]
- ])
- let { 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)
- i._params = keys.map(key => {
- return {
- key,
- value: i.select_item[key]
- }
- })
- }
- if (i.edit_input === 'file' || i.edit_input === 'files') {
- return
- }
- if (i._relations) {
- if (baseTable.get(i._relations.link_table_name)) {
- baseTable.get(i._relations.link_table_name)().then(res => i._params = res)
- } else {
- i._params = i._relations.parameter_id
- ? getparameter({ id: i._relations.parameter_id },false).then((res) => {
- i._params = res.detail;
- })
- : this.index({
- table_name: i._relations.link_table_name,
- page: 1,
- page_size: 9999,
- }).then((res) => {
- i._params = res.data;
- });
- }
+ if (this.$route.meta.params?.select) {
+ try {
+ this.selectQuery = JSON.parse(decodeURIComponent(this.$route.meta.params?.select));
+ } catch (err) {
+ console.warn(err);
}
- });
- this.form = fields;
- console.log(111, this.form);
- this.form
- ?.filter((i) => i.list_show)
- .forEach((i) => {
- if (i._relations) return
- let linkOb = {};
+ }
- if (i.edit_input === "richtext") {
- linkOb.customFn = (row) => {
- return (
-
- );
- };
- }
- if (
- i.select_item &&
- typeof i.select_item === "object" &&
- !(i.select_item instanceof Array)
- ) {
- let keys = Object.keys(i.select_item);
- linkOb.customFn = (row) => {
- let paramMap = new Map();
- keys.forEach((key) => {
- paramMap.set(i.select_item[key], key);
- });
+ const { fieldRes, selectItemMap } = await getForm(this.customForm.customFormId);
+ this.form = fieldRes;
+ this.table = getRenderTable(this, this.form);
+ },
- return {paramMap.get(row[i.field]?.toString())};
- };
- }
- if (i._relations) {
- let { link_relation, foreign_key, link_with_name } = i._relations;
- if (link_relation === "newHasOne" || link_relation === "hasOne") {
- linkOb.customFn = (row) => {
- if (i.edit_input === "file") {
- return (
-
- {row[link_with_name]?.original_name}
-
- );
- } else {
- return (
-
- {row[link_with_name]?.name ||
- row[link_with_name]?.no ||
- row[link_with_name]?.value}
-
- );
- }
- };
+ adjustAlignment () {
+ if (this.firstAdjustTable) {
+ const data = this.$refs['xyTable'].getListData();
+ if (data.length < 2) return;
+ try {
+ this.form.filter(i => i.list_show).forEach((i) => {
+ let maxLength = -Infinity;
+ let minLength = Infinity;
+ let numberLength = 0;
+ let temp = 0;
+ while (temp < data.length) {
+ maxLength = Math.max(maxLength, data[temp][i.field]?.length??0);
+ minLength = Math.min(minLength, data[temp][i.field]?.length??0);
+ numberLength += /^-?[0-9]+(\.[0-9]+)?$/.test(data[temp][i.field]) ? 1 : 0;
+ temp++;
}
-
- if (link_relation === "hasMany" || link_relation === "newHasMany") {
- linkOb.customFn = (row) => {
- if (i.edit_input === "files") {
- return (
-
- )
- } else {
- return (
-
- {row[link_with_name]?.map((o) => (
-
- {o?.name ||
- o?.no ||
- o?.value ||
- o?.biaoti ||
- o?.mingcheng}
-
- ))}
-
- );
- }
- };
+ if (numberLength === temp) {
+ this.table.find(a => a.prop === i.field).align = 'right';
}
- }
-
- let alignLeft = []
- this.table.push(
- Object.assign(
- {
- prop: i.field,
- label: i.name,
- width: i.width,
- align: alignLeft.find(m => m === i.field) ? 'left' : 'center',
- fixed: i.is_fixed,
- },
- linkOb
- )
- );
- });
- this.table.unshift({
- type: "index",
- width: 60,
- label: "序号",
- });
-
- },
+ else if (Math.abs(maxLength - minLength) > 4) {
+ this.table.find(a => a.prop === i.field).align = 'left';
+ }
+ })
+ console.log(this.table)
+ } catch (e) {
+ console.error(e)
+ }
+ this.$nextTick(() => {
+ this.$refs['xyTable'].doLayout();
+ this.firstAdjustTable = false;
+ })
+ }
+ }
},
computed: {
@@ -587,6 +471,14 @@ export default {
? this.form.find((i) => i.field === field)._params
: [];
};
+ },
+
+ tableSelect () {
+ let filter = [...this.select.filter,...this.selectQuery]
+ return {
+ ...this.select,
+ filter
+ }
}
},
created() {
@@ -619,15 +511,4 @@ export default {
padding: 0 10px;
}
}
-
-a {
- color: red;
- text-decoration: none;
- transition: all 0.2s;
-}
-
-a:hover {
- color: red;
- text-decoration: underline;
-}
diff --git a/src/views/system/components/editPane.vue b/src/views/system/components/editPane.vue
index 0d4b795..cab8ea9 100644
--- a/src/views/system/components/editPane.vue
+++ b/src/views/system/components/editPane.vue
@@ -139,15 +139,7 @@
确定
@@ -236,6 +228,10 @@ export default {
this.$store.commit("form/CLEAR_SELECTED");
this.$store.commit("form/CLEAR_SELECTED_INDEX");
},
+
+ destroyField () {
+ this.$store.dispatch('form/deleteField').then((res) => res ? this.$emit('refresh') : '')
+ }
},
computed: {
...mapState("form", ["selectedForm", "formList", "selectedIndex"]),
diff --git a/src/views/system/components/formEditor.vue b/src/views/system/components/formEditor.vue
index 3333018..0ba58b9 100644
--- a/src/views/system/components/formEditor.vue
+++ b/src/views/system/components/formEditor.vue
@@ -9,6 +9,14 @@
{{ custom_form.name }}
+
{{ item.name }}
@@ -101,7 +109,7 @@
-
+
@@ -233,11 +241,32 @@ export default {
}
},
+ submitUpload () {
+ this.$store.dispatch("form/submitUpload",this.custom_form_id).then((res) => {
+ setTimeout(() => {
+ update({ id: this.custom_form_id })
+ .then((res) => {
+ this.$message({
+ type: "success",
+ message: "数据库同步成功",
+ });
+ })
+ .catch((err) => {
+ this.$message({
+ type: "error",
+ message: "数据库同步失败,请手动同步",
+ });
+ });
+ }, 2000);
+ });
+ },
+
submit() {
this.$store.dispatch("form/submit",this.custom_form_id).then((res) => {
setTimeout(() => {
update({ id: this.custom_form_id })
.then((res) => {
+ this.$store.dispatch("form/getFormList", this.custom_form_id);
this.$message({
type: "success",
message: "数据库同步成功",
diff --git a/src/views/system/components/linkWith.vue b/src/views/system/components/linkWith.vue
index 488143c..12ba68e 100644
--- a/src/views/system/components/linkWith.vue
+++ b/src/views/system/components/linkWith.vue
@@ -1,29 +1,29 @@
-
+
-
+
+
-
-
-
-
-
-
+
+
+
-
+
@@ -197,6 +197,7 @@ export default {
{
prop: 'operate',
label: '操作',
+ width: 180,
align: 'left',
customFn:(row, scope) => {
return [(
diff --git a/src/views/system/permission.vue b/src/views/system/permission.vue
index 9fd2a58..0ed51dd 100644
--- a/src/views/system/permission.vue
+++ b/src/views/system/permission.vue
@@ -1,6 +1,6 @@
-
+
@@ -44,8 +44,8 @@
{{ data.name }}
- {}"
+ {tree = Object.assign([], tree)}"
>
{{ item.name }}
@@ -116,10 +116,10 @@ export default {
for (let mod of response) {
mod.rowid = mod.id.toString()
- console.log(mod)
if (cur == 0) {
that.activeRole = mod.rowid
- that.loadPermisstions(0, that.activeRole)
+ that.togglePermission(0, that.activeRole)
+ //TODO: that.loadPermisstions(0, that.activeRole)
}
cur++
}
@@ -137,7 +137,7 @@ export default {
let children = tree.children
children.forEach((menu, index3) => {
- menu.auth_node_tags_array.map((m, index4) => {
+ menu.auth_node_tags_array.forEach((m, index4) => {
m.checked = false
that.$forceUpdate()
@@ -149,7 +149,35 @@ export default {
})
},
roleChange(tab, event) {
- this.loadPermisstions(parseInt(tab.index), tab.name)
+ this.togglePermission(parseInt(tab.index), tab.name)
+ // TODO: this.loadPermisstions(parseInt(tab.index), tab.name)
+ },
+ togglePermission (index, name) {
+ let select = this.rolelist[index].permissions;
+ this.$refs.tree.setCheckedKeys([]);
+ this.activeRole = name;
+ this.$refs["tree"].setCheckedKeys(select.map(item => item.id));
+ const toggleAuth = (arr, findId, selectItem) => {
+ for (let i of arr) {
+ if (i.id === findId) {
+ console.log(i)
+ if (i.auth_node_tags) {
+ i.auth_node_tags_array.forEach(item => {
+ this.$set(item, "checked", selectItem.has_auth_node_tags.indexOf(item.tag) > -1);
+ })
+ }
+ } else {
+ if (i.children && i.children.length > 0) {
+ toggleAuth(i.children, findId, selectItem)
+ }
+ }
+ }
+ }
+ select.filter(i => i.auth_node_tags && i.auth_node_tags.length > 0).forEach(i => {
+ toggleAuth(this.tree, i.id, i)
+ })
+
+ this.tree = Object.assign([], this.tree)
},
loadPermisstions(index, name) {
let select = this.rolelist[index].permissions
@@ -157,13 +185,27 @@ export default {
this.activeRole = name
let that = this
+ const resolveChildren = (arr) => {
+ let temp = [];
+ if (arr.children && arr.children.length > 0) {
+ arr.children.forEach((child) => {
+ temp.push(child)
+ resolveChildren(child)
+ })
+ }
+ return temp;
+ }
this.tree.forEach((tree, index1) => {
- let children = tree.children
+ if (tree.auth_node_tags) {
+ tree.auth_node_tags_array.forEach((auth) => {
+ this.$set(auth, "checked", true)
+ })
+ }
+ let children = resolveChildren(tree)
select.forEach((item, index2) => {
let selectMenu = children.filter(m => {
return m.id == item.id
})
-
selectMenu.forEach((menu, index3) => {
if (item.has_auth_node_tags.length > 0) {
menu.auth_node_tags_array.forEach((m, index4) => {
@@ -226,6 +268,10 @@ export default {
+
diff --git a/vue.config.js b/vue.config.js
index 17e208d..e16b92c 100644
--- a/vue.config.js
+++ b/vue.config.js
@@ -24,8 +24,8 @@ module.exports = {
* In most cases please use '/' !!!
* Detail: https://cli.vuejs.org/config/#publicpath
*/
- publicPath: '/admin/',
- outputDir: '/Users/liuxiangyu/Work/z-zhongjia/app/zhongjia-finance-service/public/admin',
+ publicPath: process.env.ENV === 'staging' ? '/admin_test' : '/admin',
+ outputDir: './dist',
assetsDir: 'static',
css: {
loaderOptions: { // 向 CSS 相关的 loader 传递选项