Merge remote-tracking branch 'origin/develop' into develop

# Conflicts:
#	web/src/settings.ts
This commit is contained in:
李强
2023-12-26 15:37:08 +08:00
15 changed files with 3102 additions and 371 deletions

View File

@@ -13,7 +13,7 @@ import {FsExtendsEditor, FsExtendsUploader} from '@fast-crud/fast-extends';
import '@fast-crud/fast-extends/dist/style.css';
import {successMessage, successNotification} from '/@/utils/message';
import XEUtils from "xe-utils";
import {commonCrudConfig} from "/@/utils/commonCrud";
export default {
async install(app: any, options: any) {
// 先安装ui
@@ -110,7 +110,7 @@ export default {
successHandle(ret) {
// 上传完成后的结果处理, 此处应返回格式为{url:xxx,key:xxx}
return {
url: getBaseURL() + ret.data.url,
url: getBaseURL(ret.data.url),
key: ret.data.id,
...ret.data
};

View File

@@ -256,6 +256,13 @@
.el-button.is-text {
padding: 0;
}
th.el-table__cell{
-webkit-user-select: text !important;
-moz-user-select: text !important;
-ms-user-select: text !important;
user-select:text !important;
}
}
/* scrollbar

File diff suppressed because one or more lines are too long

Binary file not shown.

Binary file not shown.

File diff suppressed because it is too large Load Diff

After

Width:  |  Height:  |  Size: 434 KiB

Binary file not shown.

Binary file not shown.

Binary file not shown.

View File

@@ -5,3 +5,4 @@
@import './media/media.scss';
@import './waves.scss';
@import './dark.scss';
@import './fa/css/font-awesome.min.css';

View File

@@ -3,9 +3,9 @@ import { pluginsAll } from '/@/views/plugins/index';
/**
* @description 校验是否为租户模式。租户模式把域名替换成 域名 加端口
*/
export const getBaseURL = function () {
var baseURL = import.meta.env.VITE_API_URL as any;
var param = baseURL.split('/')[3] || '';
export const getBaseURL = function (url:string) {
let baseURL = import.meta.env.VITE_API_URL as any;
let param = baseURL.split('/')[3] || '';
// @ts-ignore
if (pluginsAll && pluginsAll.indexOf('dvadmin3-tenants-web') !== -1 && (!param || baseURL.startsWith('/'))) {
// 1.把127.0.0.1 替换成和前端一样域名
@@ -26,6 +26,16 @@ export const getBaseURL = function () {
baseURL = location.protocol + '//' + location.hostname + (location.port ? ':' : '') + location.port + baseURL;
}
}
if(url){
const regex = /^(http|https):\/\//;
if(regex.test(url)){
return url
}else{
if(url.startsWith('/')){
return baseURL + url;
}
}
}
if (!baseURL.endsWith('/')) {
baseURL += '/';
}

View File

@@ -50,6 +50,17 @@ const getAwesomeIconfont = () => {
const styles: any = document.styleSheets;
let sheetsList = [];
let sheetsIconList = [];
// 判断fontFamily是否是本地加载
for (let i = 0; i < styles.length; i++) {
const rules = styles[i].cssRules || styles[i].rules;
if (rules) {
for (let j = 0; j < rules.length; j++) {
if (rules[j].style && rules[j].style.fontFamily === 'FontAwesome') {
sheetsList.push(styles[i])
}
}
}
}
for (let i = 0; i < styles.length; i++) {
if (styles[i].href && styles[i].href.indexOf('netdna.bootstrapcdn.com') > -1) {
sheetsList.push(styles[i]);

View File

@@ -2,7 +2,7 @@
const cssCdnUrlList: Array<string> = [
'//at.alicdn.com/t/font_2298093_y6u00apwst.css',
'//at.alicdn.com/t/c/font_3882322_9ah7y8m9175.css', //dvadmin3项目用icon
'//netdna.bootstrapcdn.com/font-awesome/4.7.0/css/font-awesome.min.css'
//'//netdna.bootstrapcdn.com/font-awesome/4.7.0/css/font-awesome.min.css'
];
// 第三方 js url
const jsCdnUrlList: Array<string> = [];

View File

@@ -48,9 +48,9 @@
|
<a :href="getSystemConfig['login.help_url']?getSystemConfig['login.help_url']:'https://django-vue-admin.com'" target="_blank">帮助</a>
|
<a :href="getSystemConfig['login.privacy_url']?getSystemConfig['login.privacy_url']:'#'">隐私</a>
<a :href="getSystemConfig['login.privacy_url']?getBaseURL(getSystemConfig['login.privacy_url']):'#'">隐私</a>
|
<a :href="getSystemConfig['login.clause_url']?getSystemConfig['login.clause_url']:'#'">条款</a>
<a :href="getSystemConfig['login.clause_url']?getBaseURL(getSystemConfig['login.clause_url']):'#'">条款</a>
</p>
</div>
</div>
@@ -65,6 +65,7 @@ import logoMini from '/@/assets/logo-mini.svg';
import loginMain from '/@/assets/login-main.svg';
import loginBg from '/@/assets/login-bg.svg';
import {SystemConfigStore} from '/@/stores/systemConfig'
import {getBaseURL} from "/@/utils/baseUrl";
// 引入组件
const Account = defineAsyncComponent(() => import('/@/views/system/login/component/account.vue'));
const Mobile = defineAsyncComponent(() => import('/@/views/system/login/component/mobile.vue'));

View File

@@ -1,370 +1,396 @@
import * as api from './api';
import { dict, UserPageQuery, AddReq, DelReq, EditReq, compute, CreateCrudOptionsProps, CreateCrudOptionsRet } from '@fast-crud/fast-crud';
import { request } from '/@/utils/service';
import { dictionary } from '/@/utils/dictionary';
import { successMessage } from '/@/utils/message';
import { auth } from '/@/utils/authFunction';
import {
dict,
UserPageQuery,
AddReq,
DelReq,
EditReq,
compute,
CreateCrudOptionsProps,
CreateCrudOptionsRet
} from '@fast-crud/fast-crud';
import {request} from '/@/utils/service';
import {dictionary} from '/@/utils/dictionary';
import {successMessage} from '/@/utils/message';
import {auth} from '/@/utils/authFunction';
import {SystemConfigStore} from "/@/stores/systemConfig";
import {storeToRefs} from "pinia";
import {computed} from "vue";
import { Md5 } from 'ts-md5';
export const createCrudOptions = function ({crudExpose}: CreateCrudOptionsProps): CreateCrudOptionsRet {
const pageRequest = async (query: UserPageQuery) => {
return await api.GetList(query);
};
const editRequest = async ({form, row}: EditReq) => {
form.id = row.id;
return await api.UpdateObj(form);
};
const delRequest = async ({row}: DelReq) => {
return await api.DelObj(row.id);
};
const addRequest = async ({form}: AddReq) => {
return await api.AddObj(form);
};
export const createCrudOptions = function ({ crudExpose }: CreateCrudOptionsProps): CreateCrudOptionsRet {
const pageRequest = async (query: UserPageQuery) => {
return await api.GetList(query);
};
const editRequest = async ({ form, row }: EditReq) => {
form.id = row.id;
return await api.UpdateObj(form);
};
const delRequest = async ({ row }: DelReq) => {
return await api.DelObj(row.id);
};
const addRequest = async ({ form }: AddReq) => {
return await api.AddObj(form);
};
const exportRequest = async (query: UserPageQuery) => {
return await api.exportData(query)
}
const exportRequest = async (query: UserPageQuery) => {
return await api.exportData(query)
}
const systemConfigStore = SystemConfigStore()
const {systemConfig} = storeToRefs(systemConfigStore)
const getSystemConfig = computed(() => {
console.log(systemConfig.value)
return systemConfig.value
})
return {
crudOptions: {
table: {
remove: {
confirmMessage: '是否删除该用户?',
},
},
request: {
pageRequest,
addRequest,
editRequest,
delRequest,
},
actionbar: {
buttons: {
add: {
show: auth('user:Create')
},
export:{
text:"导出",//按钮文字
title:"导出",//鼠标停留显示的信息
click(){
return exportRequest(crudExpose!.getSearchFormData())
}
}
}
},
rowHandle: {
//固定右侧
fixed: 'right',
width: 200,
buttons: {
view: {
show: false,
},
edit: {
iconRight: 'Edit',
type: 'text',
show: auth('user:Update'),
},
remove: {
iconRight: 'Delete',
type: 'text',
show: auth('user:Delete'),
},
custom: {
text: '重设密码',
type: 'text',
show: auth('user:ResetPassword'),
tooltip: {
placement: 'top',
content: '重设密码',
},
//@ts-ignore
click: (ctx: any) => {
const { row } = ctx;
},
},
},
},
columns: {
_index: {
title: '序号',
form: { show: false },
column: {
type: 'index',
align: 'center',
width: '70px',
columnSetDisabled: true, //禁止在列设置中选择
},
},
username: {
title: '账号',
search: {
show: true,
},
type: 'input',
column: {
minWidth: 100, //最小列宽
},
form: {
rules: [
// 表单校验规则
{
required: true,
message: '账号必填项',
},
],
component: {
placeholder: '请输入账号',
},
},
},
password: {
title: '密码',
type: 'input',
column: {
show: false,
},
editForm: {
show: false,
},
form: {
rules: [
// 表单校验规则
{
required: true,
message: '密码必填项',
},
],
component: {
span: 12,
showPassword: true,
placeholder: '请输入密码',
},
// value: vm.systemConfig('base.default_password'),
},
/* valueResolve(row, key) {
if (row.password) {
row.password = vm.$md5(row.password)
return {
crudOptions: {
table: {
remove: {
confirmMessage: '是否删除该用户?',
},
},
request: {
pageRequest,
addRequest,
editRequest,
delRequest,
},
form: {
initialForm: {
password: computed(() => {
return systemConfig.value['base.default_password']
}),
}
},
actionbar: {
buttons: {
add: {
show: auth('user:Create')
},
export: {
text: "导出",//按钮文字
title: "导出",//鼠标停留显示的信息
click() {
return exportRequest(crudExpose!.getSearchFormData())
}
} */
},
name: {
title: '姓名',
search: {
show: true,
},
type: 'input',
column: {
minWidth: 100, //最小列宽
},
form: {
rules: [
// 表单校验规则
{
required: true,
message: '姓名必填项',
},
],
component: {
span: 12,
placeholder: '请输入姓名',
},
},
},
dept: {
title: '部门',
search: {
disabled: true,
},
type: 'dict-tree',
dict: dict({
isTree: true,
url: '/api/system/dept/all_dept/',
value: 'id',
label: 'name',
getData: async ({ url }: { url: string }) => {
return request({
url: url,
}).then((ret: any) => {
return ret.data;
});
},
}),
column: {
minWidth: 150, //最小列宽
},
form: {
rules: [
// 表单校验规则
{
required: true,
message: '必填项',
},
],
component: {
filterable: true,
placeholder: '请选择',
props: {
props: {
value: 'id',
label: 'name',
},
},
},
},
},
role: {
title: '角色',
search: {
disabled: true,
},
type: 'dict-select',
dict: dict({
url: '/api/system/role/',
value: 'id',
label: 'name',
isTree: true,
getData: async ({ url }: { url: string }) => {
return request({
url: url,
params: {
page: 1,
limit: 10,
},
}).then((ret: any) => {
return ret.data;
});
},
}),
column: {
minWidth: 100, //最小列宽
},
form: {
rules: [
// 表单校验规则
{
required: true,
message: '必填项',
},
],
component: {
multiple: true,
filterable: true,
placeholder: '请选择角色',
},
},
},
mobile: {
title: '手机号码',
search: {
show: true,
},
type: 'input',
column: {
minWidth: 120, //最小列宽
},
form: {
rules: [
{
max: 20,
message: '请输入正确的手机号码',
trigger: 'blur',
},
{
pattern: /^1[3-9]\d{9}$/,
message: '请输入正确的手机号码',
},
],
component: {
placeholder: '请输入手机号码',
},
},
},
email: {
title: '邮箱',
column: {
width: 260,
},
form: {
rules: [
{
type: 'email',
message: '请输入正确的邮箱地址',
trigger: ['blur', 'change'],
},
],
component: {
placeholder: '请输入邮箱',
},
},
},
gender: {
title: '性别',
type: 'dict-select',
dict: dict({
data: dictionary('gender'),
}),
form: {
value: 1,
component: {
span: 12,
},
},
component: { props: { color: 'auto' } }, // 自动染色
},
user_type: {
title: '用户类型',
search: {
show: true,
},
type: 'dict-select',
dict: dict({
data: dictionary('user_type'),
}),
column: {
minWidth: 100, //最小列宽
},
form: {
show: false,
value: 0,
component: {
span: 12,
},
},
},
is_active: {
title: '锁定',
search: {
show: true,
},
type: 'dict-radio',
column: {
component: {
name: 'fs-dict-switch',
activeText: '',
inactiveText: '',
style: '--el-switch-on-color: var(--el-color-primary); --el-switch-off-color: #dcdfe6',
onChange: compute((context) => {
return () => {
api.UpdateObj(context.row).then((res: APIResponseData) => {
successMessage(res.msg as string);
});
};
}),
},
},
dict: dict({
data: dictionary('button_status_bool'),
}),
},
avatar: {
title: '头像',
type: 'avatar-cropper',
form: {
show: false,
},
},
},
},
};
}
}
},
rowHandle: {
//固定右侧
fixed: 'right',
width: 200,
buttons: {
view: {
show: false,
},
edit: {
iconRight: 'Edit',
type: 'text',
show: auth('user:Update'),
},
remove: {
iconRight: 'Delete',
type: 'text',
show: auth('user:Delete'),
},
custom: {
text: '重设密码',
type: 'text',
show: auth('user:ResetPassword'),
tooltip: {
placement: 'top',
content: '重设密码',
},
//@ts-ignore
click: (ctx: any) => {
const {row} = ctx;
},
},
},
},
columns: {
_index: {
title: '序号',
form: {show: false},
column: {
type: 'index',
align: 'center',
width: '70px',
columnSetDisabled: true, //禁止在列设置中选择
},
},
username: {
title: '账号',
search: {
show: true,
},
type: 'input',
column: {
minWidth: 100, //最小列宽
},
form: {
rules: [
// 表单校验规则
{
required: true,
message: '账号必填项',
},
],
component: {
placeholder: '请输入账号',
},
},
},
password: {
title: '密码',
type: 'password',
column: {
show: false,
},
editForm: {
show: false,
},
form: {
rules: [
// 表单校验规则
{
required: true,
message: '密码必填项',
},
],
component: {
span: 12,
showPassword: true,
placeholder: '请输入密码',
},
},
valueResolve({form}) {
if (form.password) {
form.password = Md5.hashStr(form.password)
}
}
},
name: {
title: '姓名',
search: {
show: true,
},
type: 'input',
column: {
minWidth: 100, //最小列宽
},
form: {
rules: [
// 表单校验规则
{
required: true,
message: '姓名必填项',
},
],
component: {
span: 12,
placeholder: '请输入姓名',
},
},
},
dept: {
title: '部门',
search: {
disabled: true,
},
type: 'dict-tree',
dict: dict({
isTree: true,
url: '/api/system/dept/all_dept/',
value: 'id',
label: 'name',
getData: async ({url}: { url: string }) => {
return request({
url: url,
}).then((ret: any) => {
return ret.data;
});
},
}),
column: {
minWidth: 150, //最小列宽
},
form: {
rules: [
// 表单校验规则
{
required: true,
message: '必填项',
},
],
component: {
filterable: true,
placeholder: '请选择',
props: {
props: {
value: 'id',
label: 'name',
},
},
},
},
},
role: {
title: '角色',
search: {
disabled: true,
},
type: 'dict-select',
dict: dict({
url: '/api/system/role/',
value: 'id',
label: 'name',
isTree: true,
getData: async ({url}: { url: string }) => {
return request({
url: url,
params: {
page: 1,
limit: 10,
},
}).then((ret: any) => {
return ret.data;
});
},
}),
column: {
minWidth: 100, //最小列宽
},
form: {
rules: [
// 表单校验规则
{
required: true,
message: '必填项',
},
],
component: {
multiple: true,
filterable: true,
placeholder: '请选择角色',
},
},
},
mobile: {
title: '手机号码',
search: {
show: true,
},
type: 'input',
column: {
minWidth: 120, //最小列宽
},
form: {
rules: [
{
max: 20,
message: '请输入正确的手机号码',
trigger: 'blur',
},
{
pattern: /^1[3-9]\d{9}$/,
message: '请输入正确的手机号码',
},
],
component: {
placeholder: '请输入手机号码',
},
},
},
email: {
title: '邮箱',
column: {
width: 260,
},
form: {
rules: [
{
type: 'email',
message: '请输入正确的邮箱地址',
trigger: ['blur', 'change'],
},
],
component: {
placeholder: '请输入邮箱',
},
},
},
gender: {
title: '性别',
type: 'dict-select',
dict: dict({
data: dictionary('gender'),
}),
form: {
value: 1,
component: {
span: 12,
},
},
component: {props: {color: 'auto'}}, // 自动染色
},
user_type: {
title: '用户类型',
search: {
show: true,
},
type: 'dict-select',
dict: dict({
data: dictionary('user_type'),
}),
column: {
minWidth: 100, //最小列宽
},
form: {
show: false,
value: 0,
component: {
span: 12,
},
},
},
is_active: {
title: '锁定',
search: {
show: true,
},
type: 'dict-radio',
column: {
component: {
name: 'fs-dict-switch',
activeText: '',
inactiveText: '',
style: '--el-switch-on-color: var(--el-color-primary); --el-switch-off-color: #dcdfe6',
onChange: compute((context) => {
return () => {
api.UpdateObj(context.row).then((res: APIResponseData) => {
successMessage(res.msg as string);
});
};
}),
},
},
dict: dict({
data: dictionary('button_status_bool'),
}),
},
avatar: {
title: '头像',
type: 'avatar-cropper',
form: {
show: false,
},
},
},
},
};
};