Merge branch 'master' of https://gitee.com/meibe/yudao-ui-admin-vue3
This commit is contained in:
commit
ece4cf2760
19
.env.front
Normal file
19
.env.front
Normal file
@ -0,0 +1,19 @@
|
||||
# 本地开发环境
|
||||
NODE_ENV=development
|
||||
|
||||
VITE_DEV=true
|
||||
|
||||
# 请求路径
|
||||
VITE_BASE_URL='http://api-dashboard.yudao.iocoder.cn'
|
||||
|
||||
# 上传路径
|
||||
VITE_UPLOAD_URL='http://api-dashboard.yudao.iocoder.cn/admin-api/infra/file/upload'
|
||||
|
||||
# 接口前缀
|
||||
VITE_API_BASEPATH=/dev-api
|
||||
|
||||
# 接口地址
|
||||
VITE_API_URL=/admin-api
|
||||
|
||||
# 打包路径
|
||||
VITE_BASE_PATH=/
|
31
.env.static
Normal file
31
.env.static
Normal file
@ -0,0 +1,31 @@
|
||||
# 开发环境
|
||||
NODE_ENV=production
|
||||
|
||||
VITE_DEV=false
|
||||
|
||||
# 请求路径
|
||||
VITE_BASE_URL='http://localhost:48080'
|
||||
|
||||
# 上传路径
|
||||
VITE_UPLOAD_URL='http://localhost:48080/admin-api/infra/file/upload'
|
||||
|
||||
# 接口前缀
|
||||
VITE_API_BASEPATH=
|
||||
|
||||
# 接口地址
|
||||
VITE_API_URL=/admin-api
|
||||
|
||||
# 是否删除debugger
|
||||
VITE_DROP_DEBUGGER=true
|
||||
|
||||
# 是否删除console.log
|
||||
VITE_DROP_CONSOLE=true
|
||||
|
||||
# 是否sourcemap
|
||||
VITE_SOURCEMAP=false
|
||||
|
||||
# 打包路径
|
||||
VITE_BASE_PATH=/admin-ui-vue3/
|
||||
|
||||
# 输出路径
|
||||
VITE_OUT_DIR=dist-dev
|
@ -7,10 +7,12 @@
|
||||
"scripts": {
|
||||
"i": "pnpm install",
|
||||
"dev": "vite --mode base",
|
||||
"front": "vite --mode front",
|
||||
"ts:check": "vue-tsc --noEmit",
|
||||
"build:pro": "node --max_old_space_size=8000 ./node_modules/vite/bin/vite.js build --mode pro",
|
||||
"build:dev": "node --max_old_space_size=8000 ./node_modules/vite/bin/vite.js build --mode dev",
|
||||
"build:test": "node --max_old_space_size=8000 ./node_modules/vite/bin/vite.js build --mode test",
|
||||
"build:static": "node --max_old_space_size=8000 ./node_modules/vite/bin/vite.js build --mode static",
|
||||
"serve:pro": "vite preview --mode pro",
|
||||
"serve:dev": "vite preview --mode dev",
|
||||
"serve:test": "vite preview --mode test",
|
||||
|
@ -13,7 +13,6 @@ import { useDesign } from '@/hooks/web/useDesign'
|
||||
import { XTableProps } from './type'
|
||||
import { isBoolean, isFunction } from '@/utils/is'
|
||||
import styleCss from './style/dark.scss'
|
||||
|
||||
import download from '@/utils/download'
|
||||
|
||||
const { t } = useI18n()
|
||||
@ -26,14 +25,13 @@ const prefixCls = getPrefixCls('x-vxe-table')
|
||||
|
||||
const attrs = useAttrs()
|
||||
const emit = defineEmits(['register'])
|
||||
|
||||
const removeStyles = () => {
|
||||
var filename = 'cssTheme'
|
||||
const filename = 'cssTheme'
|
||||
//移除引入的文件名
|
||||
var targetelement = 'style'
|
||||
var targetattr = 'id'
|
||||
var allsuspects = document.getElementsByTagName(targetelement)
|
||||
for (var i = allsuspects.length; i >= 0; i--) {
|
||||
const targetelement = 'style'
|
||||
const targetattr = 'id'
|
||||
let allsuspects = document.getElementsByTagName(targetelement)
|
||||
for (let i = allsuspects.length; i >= 0; i--) {
|
||||
if (
|
||||
allsuspects[i] &&
|
||||
allsuspects[i].getAttribute(targetattr) != null &&
|
||||
@ -45,13 +43,12 @@ const removeStyles = () => {
|
||||
}
|
||||
}
|
||||
const reImport = () => {
|
||||
var head = document.getElementsByTagName('head')[0]
|
||||
var style = document.createElement('style')
|
||||
let head = document.getElementsByTagName('head')[0]
|
||||
let style = document.createElement('style')
|
||||
style.innerText = styleCss
|
||||
style.id = 'cssTheme'
|
||||
head.appendChild(style)
|
||||
}
|
||||
|
||||
watch(
|
||||
() => appStore.getIsDark,
|
||||
() => {
|
||||
|
@ -80,7 +80,8 @@ const resetFlowCondition = () => {
|
||||
if (
|
||||
bpmnElementSourceRef.value &&
|
||||
bpmnElementSourceRef.value.default &&
|
||||
bpmnElementSourceRef.value.default.id === bpmnElement.value.id
|
||||
bpmnElementSourceRef.value.default.id === bpmnElement.value.id &&
|
||||
flowConditionForm.value.type == 'default'
|
||||
) {
|
||||
// 默认
|
||||
flowConditionForm.value = { type: 'default' }
|
||||
@ -176,11 +177,13 @@ onBeforeUnmount(() => {
|
||||
watch(
|
||||
() => props.businessObject,
|
||||
(val) => {
|
||||
if (val) {
|
||||
console.log(val, 'val')
|
||||
nextTick(() => {
|
||||
resetFlowCondition()
|
||||
})
|
||||
}
|
||||
},
|
||||
{
|
||||
immediate: true
|
||||
}
|
||||
)
|
||||
</script>
|
||||
|
@ -3,9 +3,21 @@
|
||||
<!-- 表单设计器 -->
|
||||
<fc-designer ref="designer" height="780px">
|
||||
<template #handle>
|
||||
<XButton type="primary" title="生成JSON" @click="showJson" />
|
||||
<XButton type="primary" title="生成Options" @click="showOption" />
|
||||
<XButton type="primary" :title="t('action.save')" @click="handleSave" />
|
||||
</template>
|
||||
</fc-designer>
|
||||
<Dialog :title="dialogTitle" v-model="dialogVisible1" maxHeight="600">
|
||||
<div ref="editor" v-if="dialogVisible1">
|
||||
<XTextButton style="float: right" :title="t('common.copy')" @click="copy(formValue)" />
|
||||
<el-scrollbar height="580">
|
||||
<pre>
|
||||
{{ formValue }}
|
||||
</pre>
|
||||
</el-scrollbar>
|
||||
</div>
|
||||
</Dialog>
|
||||
<!-- 表单保存的弹窗 -->
|
||||
<XModal v-model="dialogVisible" title="保存表单">
|
||||
<el-form ref="formRef" :model="formValues" :rules="formRules" label-width="80px">
|
||||
@ -48,13 +60,18 @@ import { DICT_TYPE, getIntDictOptions } from '@/utils/dict'
|
||||
import { CommonStatusEnum } from '@/utils/constants'
|
||||
import * as FormApi from '@/api/bpm/form'
|
||||
import { encodeConf, encodeFields, setConfAndFields } from '@/utils/formCreate'
|
||||
import { useClipboard } from '@vueuse/core'
|
||||
|
||||
const { t } = useI18n() // 国际化
|
||||
const message = useMessage() // 消息
|
||||
const { query } = useRoute() // 路由
|
||||
|
||||
const designer = ref() // 表单设计器
|
||||
|
||||
const type = ref(-1)
|
||||
const formValue = ref('')
|
||||
const dialogTitle = ref('')
|
||||
const dialogVisible = ref(false) // 弹窗是否展示
|
||||
const dialogVisible1 = ref(false) // 弹窗是否展示
|
||||
const dialogLoading = ref(false) // 弹窗的加载中
|
||||
const formRef = ref<FormInstance>()
|
||||
const formRules = reactive({
|
||||
@ -98,7 +115,32 @@ const submitForm = async () => {
|
||||
dialogLoading.value = false
|
||||
}
|
||||
}
|
||||
|
||||
const showJson = () => {
|
||||
openModel('生成JSON')
|
||||
type.value = 0
|
||||
formValue.value = designer.value.getRule()
|
||||
}
|
||||
const showOption = () => {
|
||||
openModel('生成Options')
|
||||
type.value = 1
|
||||
formValue.value = designer.value.getOption()
|
||||
}
|
||||
const openModel = (title: string) => {
|
||||
dialogVisible1.value = true
|
||||
dialogTitle.value = title
|
||||
}
|
||||
/** 复制 **/
|
||||
const copy = async (text: string) => {
|
||||
const { copy, copied, isSupported } = useClipboard({ source: text })
|
||||
if (!isSupported) {
|
||||
message.error(t('common.copyError'))
|
||||
} else {
|
||||
await copy()
|
||||
if (unref(copied)) {
|
||||
message.success(t('common.copySuccess'))
|
||||
}
|
||||
}
|
||||
}
|
||||
// ========== 初始化 ==========
|
||||
onMounted(() => {
|
||||
// 场景一:新增表单
|
||||
|
@ -16,6 +16,7 @@ const crudSchemas = reactive<VxeCrudSchema>({
|
||||
primaryType: 'id',
|
||||
primaryTitle: '编号',
|
||||
action: true,
|
||||
searchSpan: 8,
|
||||
columns: [
|
||||
{
|
||||
title: '组名',
|
||||
|
@ -2,6 +2,7 @@
|
||||
<ContentWrap>
|
||||
<!-- 详情 -->
|
||||
<Descriptions :schema="allSchemas.detailSchema" :data="formData" />
|
||||
<el-button @click="routerReturn" type="primary">返回</el-button>
|
||||
</ContentWrap>
|
||||
</template>
|
||||
|
||||
@ -9,7 +10,8 @@
|
||||
// 业务相关的 import
|
||||
import * as LeaveApi from '@/api/bpm/leave'
|
||||
import { allSchemas } from '@/views/bpm/oa/leave/leave.data'
|
||||
|
||||
import { useRouter } from 'vue-router'
|
||||
const router = useRouter()
|
||||
const { query } = useRoute() // 查询参数
|
||||
const message = useMessage() // 消息弹窗
|
||||
|
||||
@ -22,6 +24,10 @@ const formData = ref({
|
||||
reason: undefined
|
||||
})
|
||||
|
||||
const routerReturn = () => {
|
||||
router.back()
|
||||
}
|
||||
|
||||
onMounted(() => {
|
||||
id.value = query.id
|
||||
if (!id.value) {
|
||||
|
@ -16,6 +16,7 @@ const crudSchemas = reactive<VxeCrudSchema>({
|
||||
primaryTitle: '申请编号',
|
||||
action: true,
|
||||
actionWidth: '260',
|
||||
searchSpan: 8,
|
||||
columns: [
|
||||
{
|
||||
title: t('common.status'),
|
||||
|
@ -3,6 +3,10 @@
|
||||
<!-- 第一步,通过流程定义的列表,选择对应的流程 -->
|
||||
<div v-if="!selectProcessInstance">
|
||||
<XTable @register="registerTable">
|
||||
<!-- 流程分类 -->
|
||||
<template #category_default="{ row }">
|
||||
<DictTag :type="DICT_TYPE.BPM_MODEL_CATEGORY" :value="Number(row?.category)" />
|
||||
</template>
|
||||
<template #version_default="{ row }">
|
||||
<el-tag v-if="row">v{{ row.version }}</el-tag>
|
||||
</template>
|
||||
@ -56,6 +60,7 @@ import * as DefinitionApi from '@/api/bpm/definition'
|
||||
import * as ProcessInstanceApi from '@/api/bpm/processInstance'
|
||||
import { setConfAndFields2 } from '@/utils/formCreate'
|
||||
import { ApiAttrs } from '@form-create/element-ui/types/config'
|
||||
import { DICT_TYPE } from '@/utils/dict'
|
||||
|
||||
const router = useRouter() // 路由
|
||||
const message = useMessage() // 消息
|
||||
|
@ -14,7 +14,12 @@ const crudSchemas = reactive<VxeCrudSchema>({
|
||||
title: '流程分类',
|
||||
field: 'category',
|
||||
dictType: DICT_TYPE.BPM_MODEL_CATEGORY,
|
||||
dictClass: 'number'
|
||||
dictClass: 'number',
|
||||
table: {
|
||||
slots: {
|
||||
default: 'category_default'
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
title: '流程版本',
|
||||
|
@ -7,6 +7,7 @@ const crudSchemas = reactive<VxeCrudSchema>({
|
||||
primaryKey: 'id',
|
||||
primaryType: null,
|
||||
action: true,
|
||||
searchSpan: 8,
|
||||
columns: [
|
||||
{
|
||||
title: '任务编号',
|
||||
|
@ -1,7 +1,7 @@
|
||||
<template>
|
||||
<ContentWrap>
|
||||
<!-- 列表 -->
|
||||
<XTable @register="registerTable">
|
||||
<XTable @register="registerTable" ref="xGrid">
|
||||
<template #options_default="{ row }">
|
||||
<span :key="option" v-for="option in row.options">
|
||||
<el-tag>
|
||||
@ -145,11 +145,12 @@ import { listSimpleUserGroupsApi } from '@/api/bpm/userGroup'
|
||||
import { listSimpleDeptApi } from '@/api/system/dept'
|
||||
import { DICT_TYPE, getDictOptions } from '@/utils/dict'
|
||||
import { handleTree, defaultProps } from '@/utils/tree'
|
||||
import { allSchemas, rules } from './taskAssignRule.data'
|
||||
import { allSchemas, rules, idShowActionClick } from './taskAssignRule.data'
|
||||
|
||||
const { t } = useI18n() // 国际化
|
||||
const message = useMessage() // 消息弹窗
|
||||
const { query } = useRoute()
|
||||
const xGrid = ref()
|
||||
|
||||
// ========== 列表相关 ==========
|
||||
|
||||
@ -165,6 +166,8 @@ const taskAssignScriptDictDatas = getDictOptions(DICT_TYPE.BPM_TASK_ASSIGN_SCRIP
|
||||
const modelId = query.modelId
|
||||
// 流程定义的编号。如果 processDefinitionId 非空,则用于流程定义的查看,不支持配置
|
||||
const processDefinitionId = query.processDefinitionId
|
||||
let isShow = idShowActionClick(modelId)
|
||||
|
||||
// 查询参数
|
||||
const queryParams = reactive({
|
||||
modelId: modelId,
|
||||
@ -346,5 +349,10 @@ onMounted(() => {
|
||||
listSimpleUserGroupsApi().then((data) => {
|
||||
userGroupOptions.value.push(...data)
|
||||
})
|
||||
if (!isShow) {
|
||||
setTimeout(() => {
|
||||
xGrid.value.Ref.hideColumn('actionbtns')
|
||||
}, 100)
|
||||
}
|
||||
})
|
||||
</script>
|
||||
|
@ -43,4 +43,12 @@ const crudSchemas = reactive<VxeCrudSchema>({
|
||||
}
|
||||
]
|
||||
})
|
||||
|
||||
export const idShowActionClick = (modelId?: any) => {
|
||||
if (modelId) {
|
||||
return true
|
||||
} else {
|
||||
return false
|
||||
}
|
||||
}
|
||||
export const { allSchemas } = useVxeCrudSchemas(crudSchemas)
|
||||
|
@ -6,7 +6,15 @@ const { t } = useI18n() // 国际化
|
||||
export const rules = reactive({
|
||||
name: [required],
|
||||
sort: [required],
|
||||
email: [required],
|
||||
// email: [required],
|
||||
email: [
|
||||
{ required: true, message: t('profile.rules.mail'), trigger: 'blur' },
|
||||
{
|
||||
type: 'email',
|
||||
message: t('profile.rules.truemail'),
|
||||
trigger: ['blur', 'change']
|
||||
}
|
||||
],
|
||||
phone: [
|
||||
{
|
||||
len: 11,
|
||||
|
@ -1,8 +1,18 @@
|
||||
import type { VxeCrudSchema } from '@/hooks/web/useVxeCrudSchemas'
|
||||
|
||||
const { t } = useI18n() // 国际化
|
||||
|
||||
// 表单校验
|
||||
export const rules = reactive({
|
||||
mail: [required],
|
||||
// mail: [required],
|
||||
mail: [
|
||||
{ required: true, message: t('profile.rules.mail'), trigger: 'blur' },
|
||||
{
|
||||
type: 'email',
|
||||
message: t('profile.rules.truemail'),
|
||||
trigger: ['blur', 'change']
|
||||
}
|
||||
],
|
||||
username: [required],
|
||||
password: [required],
|
||||
host: [required],
|
||||
|
@ -131,7 +131,6 @@
|
||||
ref="treeRef"
|
||||
node-key="id"
|
||||
show-checkbox
|
||||
:default-checked-keys="defaultCheckedKeys"
|
||||
:check-strictly="!checkStrictly"
|
||||
:props="defaultProps"
|
||||
:data="treeOptions"
|
||||
@ -255,7 +254,6 @@ const dialogScopeVisible = ref(false)
|
||||
const dialogScopeTitle = ref('数据权限')
|
||||
const actionScopeType = ref('')
|
||||
const dataScopeDictDatas = ref()
|
||||
const defaultCheckedKeys = ref()
|
||||
// 选项
|
||||
const checkStrictly = ref(true)
|
||||
const treeNodeAll = ref(false)
|
||||
@ -268,13 +266,16 @@ const handleScope = async (type: string, row: RoleApi.RoleVO) => {
|
||||
dataScopeForm.id = row.id
|
||||
dataScopeForm.name = row.name
|
||||
dataScopeForm.code = row.code
|
||||
actionScopeType.value = type
|
||||
dialogScopeVisible.value = true
|
||||
if (type === 'menu') {
|
||||
const menuRes = await listSimpleMenusApi()
|
||||
treeOptions.value = handleTree(menuRes)
|
||||
const role = await PermissionApi.listRoleMenusApi(row.id)
|
||||
if (role) {
|
||||
// treeRef.value!.setCheckedKeys(role as unknown as Array<number>)
|
||||
defaultCheckedKeys.value = role
|
||||
role?.forEach((item: any) => {
|
||||
unref(treeRef)?.setChecked(item, true, false)
|
||||
})
|
||||
}
|
||||
} else if (type === 'data') {
|
||||
const deptRes = await listSimpleDeptApi()
|
||||
@ -282,12 +283,11 @@ const handleScope = async (type: string, row: RoleApi.RoleVO) => {
|
||||
const role = await RoleApi.getRoleApi(row.id)
|
||||
dataScopeForm.dataScope = role.dataScope
|
||||
if (role.dataScopeDeptIds) {
|
||||
// treeRef.value!.setCheckedKeys(role.dataScopeDeptIds as unknown as Array<number>, false)
|
||||
defaultCheckedKeys.value = role.dataScopeDeptIds
|
||||
role.dataScopeDeptIds?.forEach((item: any) => {
|
||||
unref(treeRef)?.setChecked(item, true, false)
|
||||
})
|
||||
}
|
||||
}
|
||||
actionScopeType.value = type
|
||||
dialogScopeVisible.value = true
|
||||
}
|
||||
// 保存权限
|
||||
const submitScope = async () => {
|
||||
|
@ -9,12 +9,19 @@ export const rules = reactive({
|
||||
})
|
||||
// CrudSchema
|
||||
const crudSchemas = reactive<VxeCrudSchema>({
|
||||
primaryKey: 'id',
|
||||
primaryTitle: '角色编号',
|
||||
primaryType: 'seq',
|
||||
// primaryKey: 'id',
|
||||
// primaryTitle: '角色编号',
|
||||
// primaryType: 'seq',
|
||||
action: true,
|
||||
actionWidth: '400px',
|
||||
columns: [
|
||||
{
|
||||
title: '角色编号',
|
||||
field: 'id',
|
||||
table: {
|
||||
width: 200
|
||||
}
|
||||
},
|
||||
{
|
||||
title: '角色名称',
|
||||
field: 'name',
|
||||
|
@ -27,6 +27,24 @@ export const rules = reactive({
|
||||
contactMobile: [required],
|
||||
accountCount: [required],
|
||||
expireTime: [required],
|
||||
username: [
|
||||
required,
|
||||
{
|
||||
min: 4,
|
||||
max: 30,
|
||||
trigger: 'blur',
|
||||
message: '用户名称长度为 4-30 个字符'
|
||||
}
|
||||
],
|
||||
password: [
|
||||
required,
|
||||
{
|
||||
min: 4,
|
||||
max: 16,
|
||||
trigger: 'blur',
|
||||
message: '密码长度为 4-16 位'
|
||||
}
|
||||
],
|
||||
domain: [required],
|
||||
status: [required]
|
||||
})
|
||||
|
@ -135,7 +135,9 @@ const handleUpdate = async (rowId: number) => {
|
||||
const res = await TenantPackageApi.getTenantPackageApi(rowId)
|
||||
unref(formRef)?.setValues(res)
|
||||
// 设置选中
|
||||
unref(treeRef)?.setCheckedKeys(res.menuIds)
|
||||
res.menuIds?.forEach((item: any) => {
|
||||
unref(treeRef)?.setChecked(item, true, false)
|
||||
})
|
||||
}
|
||||
|
||||
// 提交按钮
|
||||
|
@ -332,7 +332,6 @@ const getPostOptions = async () => {
|
||||
const res = await listSimplePostsApi()
|
||||
postOptions.value.push(...res)
|
||||
}
|
||||
|
||||
const dataFormater = (val) => {
|
||||
return deptFormater(deptOptions.value, val)
|
||||
}
|
||||
@ -409,15 +408,20 @@ const handleDetail = async (rowId: number) => {
|
||||
|
||||
// 提交按钮
|
||||
const submitForm = async () => {
|
||||
loading.value = true
|
||||
// 提交请求
|
||||
const elForm = unref(formRef)?.getElFormRef()
|
||||
if (!elForm) return
|
||||
elForm.validate(async (valid) => {
|
||||
if (valid) {
|
||||
try {
|
||||
const data = unref(formRef)?.formModel as UserApi.UserVO
|
||||
if (actionType.value === 'create') {
|
||||
await UserApi.createUserApi(data)
|
||||
loading.value = true
|
||||
message.success(t('common.createSuccess'))
|
||||
} else {
|
||||
await UserApi.updateUserApi(data)
|
||||
loading.value = true
|
||||
message.success(t('common.updateSuccess'))
|
||||
}
|
||||
dialogVisible.value = false
|
||||
@ -427,6 +431,8 @@ const submitForm = async () => {
|
||||
await reload()
|
||||
loading.value = false
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
// 改变用户状态操作
|
||||
const handleStatusChange = async (row: UserApi.UserVO) => {
|
||||
|
@ -5,6 +5,8 @@ const { t } = useI18n()
|
||||
export const rules = reactive({
|
||||
username: [required],
|
||||
nickname: [required],
|
||||
password: [required],
|
||||
deptId: [required],
|
||||
email: [
|
||||
{ required: true, message: t('profile.rules.mail'), trigger: 'blur' },
|
||||
{
|
||||
|
1
types/global.d.ts
vendored
1
types/global.d.ts
vendored
@ -1,4 +1,3 @@
|
||||
import type { CSSProperties } from 'vue'
|
||||
declare global {
|
||||
declare interface Fn<T = any> {
|
||||
(...arg: T[]): T
|
||||
|
Loading…
Reference in New Issue
Block a user