refactor: 升级Vue SFC深度选择器语法为::v-deep

本次提交将项目中所有使用`::deep`的CSS深度选择器统一替换为Vue 3官方推荐的`::v-deep`语法,修复了旧版语法在新版本Vue生态中的兼容性问题,同时修正了部分组件的响应式表单定义方式,将`reactive`配合`Object.assign`的写法调整为更符合Vue 3组合式API规范的`ref`响应式状态写法,整体优化了代码的可维护性和兼容性。
This commit is contained in:
zhangtao
2026-05-11 15:46:18 +08:00
parent 4112942a14
commit 80d4f18e8b
64 changed files with 510 additions and 501 deletions
@@ -22,8 +22,8 @@ defineEmits<{ link: [] }>();
<style scoped lang="scss">
.login-auth-link-row {
::deep(.el-link),
::deep(.el-link__inner) {
::v-deep(.el-link),
::v-deep(.el-link__inner) {
line-height: inherit;
}
}
@@ -246,11 +246,11 @@ html.dark {
/* EP 全局规则:相邻 .el-button { margin-left: 12px },纵向叠放时仍会命中,导致第二颗按钮横向错位 */
.login-mobile-actions {
::deep(.el-button + .el-button) {
::v-deep(.el-button + .el-button) {
margin-left: 0 !important;
}
::deep(.el-button) {
::v-deep(.el-button) {
box-sizing: border-box;
width: 100%;
min-width: 0;
@@ -78,7 +78,7 @@ const qrPayload = computed(() => {
/* EP:相邻按钮横向间距;单列返回按钮无需处理 */
.login-mobile-actions {
::deep(.el-button) {
::v-deep(.el-button) {
box-sizing: border-box;
width: 100%;
min-width: 0;
@@ -661,68 +661,68 @@ async function submitForget() {
<style lang="scss" scoped>
.login-page-panel {
::deep(.btn) {
::v-deep(.btn) {
border-radius: 8px;
}
}
html.dark .login-page-panel {
::deep(.text-g-800) {
::v-deep(.text-g-800) {
color: rgb(255 255 255 / 78%) !important;
}
}
/* 副标题与表单块间距(login-page-form 在子组件内,须 :deep) */
::deep(.login-page-form) {
::v-deep(.login-page-form) {
margin-top: 1rem;
}
::deep(.login-page-form .el-form-item) {
::v-deep(.login-page-form .el-form-item) {
margin-bottom: 1.1rem;
}
::deep(.el-select__wrapper) {
::v-deep(.el-select__wrapper) {
min-height: 42px !important;
}
/* 仅账号登录底部「手机号 / 扫码」双列按钮需要 42px;手机号登录页的返回钮与主按钮同为 h-11,勿全局压高度 */
::deep(.login-secondary-actions .login-secondary-btn) {
::v-deep(.login-secondary-actions .login-secondary-btn) {
height: 42px;
border-radius: 8px;
}
html.dark {
::deep(.login-page-form .el-input__wrapper) {
::v-deep(.login-page-form .el-input__wrapper) {
background-color: rgb(255 255 255 / 6%) !important;
box-shadow: 0 0 0 1px rgb(255 255 255 / 10%) inset !important;
}
::deep(.login-page-form .el-input__inner) {
::v-deep(.login-page-form .el-input__inner) {
color: rgb(255 255 255 / 92%);
}
::deep(.login-page-form .el-input__inner::placeholder) {
::v-deep(.login-page-form .el-input__inner::placeholder) {
color: rgb(255 255 255 / 35%);
}
::deep(.login-page-form .el-select .el-select__wrapper) {
::v-deep(.login-page-form .el-select .el-select__wrapper) {
background-color: rgb(255 255 255 / 6%) !important;
box-shadow: 0 0 0 1px rgb(255 255 255 / 10%) inset !important;
}
::deep(.login-page-form .el-select__placeholder) {
::v-deep(.login-page-form .el-select__placeholder) {
color: rgb(255 255 255 / 40%);
}
::deep(.login-page-form .el-select__selected-item) {
::v-deep(.login-page-form .el-select__selected-item) {
color: rgb(255 255 255 / 92%);
}
::deep(.login-remember .el-checkbox__label) {
::v-deep(.login-remember .el-checkbox__label) {
color: rgb(255 255 255 / 65%);
}
::deep(.login-secondary-btn) {
::v-deep(.login-secondary-btn) {
color: rgb(255 255 255 / 85%) !important;
background: transparent !important;
border-color: rgb(255 255 255 / 22%) !important;
@@ -735,7 +735,7 @@ html.dark {
}
}
::deep(.login-secondary-actions .login-secondary-btn) {
::v-deep(.login-secondary-actions .login-secondary-btn) {
height: 42px;
}
}
@@ -362,7 +362,7 @@ const { columnChecks, columns } = useTableColumns<DeptTable>(() => [
const detailFormData = ref<DeptTable>({ code: "" });
const formData = reactive<DeptForm>({
const formData = ref<DeptForm>({
id: undefined,
name: undefined,
code: "",
@@ -515,10 +515,10 @@ async function handleOpenDialog(
}
} else {
dialogVisible.title = "新增部门";
Object.assign(formData, initialFormData);
formData.id = undefined;
Object.assign(formData.value, initialFormData);
formData.value.id = undefined;
if (parentId) {
formData.parent_id = parentId;
formData.value.parent_id = parentId;
}
}
deptFormRenderKey.value += 1;
@@ -528,12 +528,12 @@ async function handleOpenDialog(
async function handleSubmit() {
dataFormRef.value?.validate(async (valid: boolean) => {
if (!valid) return;
const id = formData.id;
const id = formData.value.id;
try {
if (id) {
await DeptAPI.updateDept(id, { id, ...formData });
await DeptAPI.updateDept(id, { id, ...formData.value });
} else {
await DeptAPI.createDept(formData);
await DeptAPI.createDept(formData.value);
}
dialogVisible.visible = false;
await resetForm();
@@ -614,15 +614,15 @@ onMounted(() => {
</script>
<style scoped lang="scss">
.crud-dialog-art-form ::deep(.el-row > .el-col:last-child) {
.crud-dialog-art-form ::v-deep(.el-row > .el-col:last-child) {
display: none;
}
.crud-dialog-art-form ::deep(.el-form-item__content) {
.crud-dialog-art-form ::v-deep(.el-form-item__content) {
max-width: 100%;
}
::deep(.dept-table-actions .inline-flex) {
::v-deep(.dept-table-actions .inline-flex) {
vertical-align: middle;
}
</style>
@@ -541,7 +541,7 @@ const dialogVisible = reactive({
const detailFormData = ref<DictDataTable>({});
const formData = reactive<DictDataForm>({
const formData = ref<DictDataForm>({
id: undefined,
dict_sort: 1,
dict_label: "",
@@ -715,11 +715,11 @@ async function handleOpenDialog(type: "create" | "update" | "detail", id?: numbe
}
} else {
dialogVisible.title = "新增字典数据";
Object.assign(formData, initialFormData);
formData.dict_type = props.dictType;
formData.dict_type_id = props.dictTypeId;
formData.status = "0";
formData.id = undefined;
Object.assign(formData.value, initialFormData);
formData.value.dict_type = props.dictType;
formData.value.dict_type_id = props.dictTypeId;
formData.value.status = "0";
formData.value.id = undefined;
}
dictDataFormRenderKey.value += 1;
dialogVisible.visible = true;
@@ -728,20 +728,20 @@ async function handleOpenDialog(type: "create" | "update" | "detail", id?: numbe
async function handleSubmit() {
dataFormRef.value?.validate(async (valid: boolean) => {
if (!valid) return;
const id = formData.id;
const id = formData.value.id;
try {
if (id) {
await DictAPI.updateDictData(id, { id, ...formData });
await DictAPI.updateDictData(id, { id, ...formData.value });
await refreshUpdate();
} else {
await DictAPI.createDictData(formData);
await DictAPI.createDictData(formData.value);
await refreshCreate();
}
dialogVisible.visible = false;
await resetForm();
dictStore.clearDictData();
if (formData.dict_type) {
await dictStore.getDict([formData.dict_type]);
if (formData.value.dict_type) {
await dictStore.getDict([formData.value.dict_type]);
}
} catch (error: unknown) {
console.error(error);
@@ -890,11 +890,11 @@ function openExportModal() {
border-color: var(--el-border-color-lighter);
}
.crud-dialog-art-form ::deep(.el-row > .el-col:last-child) {
.crud-dialog-art-form ::v-deep(.el-row > .el-col:last-child) {
display: none;
}
.crud-dialog-art-form ::deep(.el-form-item__content) {
.crud-dialog-art-form ::v-deep(.el-form-item__content) {
max-width: 100%;
}
</style>
@@ -359,7 +359,7 @@ const dialogVisible = reactive({
const detailFormData = ref<DictTable>({});
const formData = reactive<DictForm>({
const formData = ref<DictForm>({
id: undefined,
dict_name: "",
dict_type: "",
@@ -529,8 +529,8 @@ async function handleOpenDialog(type: "create" | "update" | "detail", id?: numbe
}
} else {
dialogVisible.title = "新增字典";
Object.assign(formData, initialFormData);
formData.id = undefined;
Object.assign(formData.value, initialFormData);
formData.value.id = undefined;
}
dictFormRenderKey.value += 1;
dialogVisible.visible = true;
@@ -539,20 +539,20 @@ async function handleOpenDialog(type: "create" | "update" | "detail", id?: numbe
async function handleSubmit() {
dataFormRef.value?.validate(async (valid: boolean) => {
if (!valid) return;
const id = formData.id;
const id = formData.value.id;
try {
if (id) {
await DictAPI.updateDictType(id, { id, ...formData });
await DictAPI.updateDictType(id, { id, ...formData.value });
await refreshUpdate();
} else {
await DictAPI.createDictType(formData);
await DictAPI.createDictType(formData.value);
await refreshCreate();
}
dialogVisible.visible = false;
await resetForm();
dictStore.clearDictData();
if (formData.dict_type) {
await dictStore.getDict([formData.dict_type]);
if (formData.value.dict_type) {
await dictStore.getDict([formData.value.dict_type]);
}
} catch (error: unknown) {
console.error(error);
@@ -636,11 +636,11 @@ function openExportModal() {
</script>
<style scoped lang="scss">
.crud-dialog-art-form ::deep(.el-row > .el-col:last-child) {
.crud-dialog-art-form ::v-deep(.el-row > .el-col:last-child) {
display: none;
}
.crud-dialog-art-form ::deep(.el-form-item__content) {
.crud-dialog-art-form ::v-deep(.el-form-item__content) {
max-width: 100%;
}
</style>
@@ -446,7 +446,7 @@ function onResetSearch() {
}
async function resetForm() {
formData.value = {};
Object.assign(formData, {});
}
async function handleCloseDialog() {
@@ -457,7 +457,7 @@ async function handleCloseDialog() {
async function handleOpenDialog(id: number) {
dialogVisible.value.title = "日志详情";
const response = await LogAPI.detailLog(id);
Object.assign(formData.value, response.data.data ?? {});
Object.assign(formData, response.data.data ?? {});
dialogVisible.value.visible = true;
}
@@ -692,7 +692,7 @@ const createParentLocked = ref(false);
const detailFormData = ref<MenuTable>({});
const formData = reactive<MenuForm>({
const formData = ref<MenuForm>({
id: undefined,
name: undefined,
type: MenuTypeEnum.CATALOG,
@@ -959,7 +959,7 @@ const rules = reactive({
redirect: [
{
validator: (_rule: unknown, value: string | undefined, callback: (e?: Error) => void) => {
if (formData.type === MenuTypeEnum.CATALOG) {
if (formData.value.type === MenuTypeEnum.CATALOG) {
if (value === undefined || value === null || String(value).trim() === "") {
callback(new Error("目录类型必须填写重定向地址"));
return;
@@ -1012,7 +1012,7 @@ async function handleRowClick(row: MenuTable) {
}
const allowedMenuTypeValues = computed(() => {
const pid = formData.parent_id;
const pid = formData.value.parent_id;
const parentNode = findMenuNodeById(pid);
if (!parentNode?.type) {
return [MenuTypeEnum.CATALOG, MenuTypeEnum.MENU, MenuTypeEnum.EXTLINK];
@@ -1046,28 +1046,28 @@ async function handleOpenDialog(
dialogVisible.title = "新增菜单";
Object.assign(formData, initialFormData);
if (parentRow?.id != null) {
formData.parent_id = parentRow.id;
formData.client = (parentRow.client as MenuClientEnum) || menuClientTab.value;
formData.value.parent_id = parentRow.id;
formData.value.client = (parentRow.client as MenuClientEnum) || menuClientTab.value;
if (parentRow.type === MenuTypeEnum.MENU) {
createParentLocked.value = true;
formData.type = MenuTypeEnum.BUTTON;
formData.value.type = MenuTypeEnum.BUTTON;
} else if (parentRow.type === MenuTypeEnum.CATALOG) {
formData.type = MenuTypeEnum.MENU;
formData.value.type = MenuTypeEnum.MENU;
}
} else {
formData.client = menuClientTab.value;
formData.value.client = menuClientTab.value;
}
}
dialogVisible.visible = true;
}
function handleMenuTypeChange() {
if (formData.type === MenuTypeEnum.MENU) {
formData.component_path = "";
if (formData.value.type === MenuTypeEnum.MENU) {
formData.value.component_path = "";
}
nextTick(() => {
dataFormRef.value?.clearValidate("redirect");
if (formData.type === MenuTypeEnum.CATALOG) {
if (formData.value.type === MenuTypeEnum.CATALOG) {
dataFormRef.value?.validateField("redirect").catch(() => {});
}
});
@@ -1076,19 +1076,19 @@ function handleMenuTypeChange() {
async function handleSubmit() {
const allowed = allowedMenuTypeValues.value;
if (!allowed.length) return;
const t = formData.type as MenuTypeEnum;
const t = formData.value.type as MenuTypeEnum;
if (!allowed.includes(t)) {
formData.type = allowed[0] as MenuForm["type"];
formData.value.type = allowed[0] as MenuForm["type"];
}
dataFormRef.value?.validate(async (valid: boolean) => {
if (!valid) return;
submitLoading.value = true;
const id = formData.id;
const id = formData.value.id;
try {
if (id) {
await MenuAPI.updateMenu(id, { id, ...formData });
await MenuAPI.updateMenu(id, { id, ...formData.value });
} else {
await MenuAPI.createMenu(formData);
await MenuAPI.createMenu(formData.value);
}
dialogVisible.visible = false;
await resetForm();
@@ -1153,7 +1153,7 @@ onMounted(() => {
</script>
<style scoped lang="scss">
::deep(.menu-table-actions .inline-flex) {
::v-deep(.menu-table-actions .inline-flex) {
vertical-align: middle;
}
</style>
@@ -450,7 +450,7 @@ const detailHasRenderableContent = computed(() => {
return plain.length > 0;
});
const formData = reactive<NoticeForm>({
const formData = ref<NoticeForm>({
id: undefined,
notice_title: "",
notice_type: "",
@@ -606,8 +606,8 @@ async function handleOpenDialog(type: "create" | "update" | "detail", id?: numbe
}
} else {
dialogVisible.title = "新增公告通知";
Object.assign(formData, initialFormData);
formData.id = undefined;
Object.assign(formData.value, initialFormData);
formData.value.id = undefined;
}
noticeFormRenderKey.value += 1;
dialogVisible.visible = true;
@@ -617,13 +617,13 @@ async function handleSubmit() {
dataFormRef.value?.validate(async (valid: boolean) => {
if (!valid) return;
submitLoading.value = true;
const id = formData.id;
const id = formData.value.id;
try {
if (id) {
await NoticeAPI.updateNotice(id, { id, ...formData });
await NoticeAPI.updateNotice(id, { id, ...formData.value });
await refreshUpdate();
} else {
await NoticeAPI.createNotice(formData);
await NoticeAPI.createNotice(formData.value);
await refreshCreate();
}
dialogVisible.visible = false;
@@ -747,11 +747,11 @@ onMounted(async () => {
<style scoped lang="scss">
/* FaForm 底部预留的操作栏列在弹窗内不需要占位 */
.crud-dialog-art-form ::deep(.el-row > .el-col:last-child) {
.crud-dialog-art-form ::v-deep(.el-row > .el-col:last-child) {
display: none;
}
.crud-dialog-art-form ::deep(.el-form-item__content) {
.crud-dialog-art-form ::v-deep(.el-form-item__content) {
max-width: 100%;
}
@@ -773,27 +773,27 @@ onMounted(async () => {
color: var(--el-text-color-placeholder);
}
.notice-html-preview ::deep(h1),
.notice-html-preview ::deep(h2),
.notice-html-preview ::deep(h3) {
.notice-html-preview ::v-deep(h1),
.notice-html-preview ::v-deep(h2),
.notice-html-preview ::v-deep(h3) {
margin: 12px 0 8px;
}
.notice-html-preview ::deep(p) {
.notice-html-preview ::v-deep(p) {
margin: 8px 0;
line-height: 1.6;
}
.notice-html-preview ::deep(table) {
.notice-html-preview ::v-deep(table) {
margin: 12px 0;
}
.notice-html-preview ::deep(table th),
.notice-html-preview ::deep(table td) {
.notice-html-preview ::v-deep(table th),
.notice-html-preview ::v-deep(table td) {
padding: 8px 12px;
}
.notice-html-preview ::deep(pre) {
.notice-html-preview ::v-deep(pre) {
padding: 12px;
margin: 12px 0;
overflow-x: auto;
@@ -801,14 +801,14 @@ onMounted(async () => {
border-radius: 4px;
}
.notice-html-preview ::deep(blockquote) {
.notice-html-preview ::v-deep(blockquote) {
padding-left: 16px;
margin: 12px 0;
color: var(--el-text-color-regular);
border-left: 4px solid var(--el-color-primary);
}
.notice-html-preview ::deep(img) {
.notice-html-preview ::v-deep(img) {
max-width: 100%;
height: auto;
}
@@ -357,7 +357,7 @@ const paramExportContentConfig = computed(() => ({
const detailFormData = ref<ConfigTable>({} as ConfigTable);
const formData = reactive<ConfigForm>({
const formData = ref<ConfigForm>({
id: undefined,
config_name: "",
config_key: "",
@@ -478,8 +478,8 @@ async function handleOpenDialog(type: "create" | "update" | "detail", id?: numbe
}
} else {
dialogVisible.title = "新增系统配置";
Object.assign(formData, initialFormData);
formData.id = undefined;
Object.assign(formData.value, initialFormData);
formData.value.id = undefined;
}
paramFormRenderKey.value += 1;
dialogVisible.visible = true;
@@ -489,13 +489,13 @@ async function handleSubmit() {
dataFormRef.value?.validate(async (valid: boolean) => {
if (!valid) return;
submitLoading.value = true;
const id = formData.id;
const id = formData.value.id;
try {
if (id) {
await ParamsAPI.updateParams(id, { id, ...formData });
await ParamsAPI.updateParams(id, { id, ...formData.value });
await refreshUpdate();
} else {
await ParamsAPI.createParams(formData);
await ParamsAPI.createParams(formData.value);
await refreshCreate();
}
dialogVisible.visible = false;
@@ -598,11 +598,11 @@ function openExportModal() {
</script>
<style scoped lang="scss">
.crud-dialog-art-form ::deep(.el-row > .el-col:last-child) {
.crud-dialog-art-form ::v-deep(.el-row > .el-col:last-child) {
display: none;
}
.crud-dialog-art-form ::deep(.el-form-item__content) {
.crud-dialog-art-form ::v-deep(.el-form-item__content) {
max-width: 100%;
}
</style>
@@ -524,7 +524,7 @@ const positionExportContentConfig = computed(() => ({
const detailFormData = ref<PositionTable>({});
const formData = reactive<PositionForm>({
const formData = ref<PositionForm>({
id: undefined,
name: undefined,
order: 1,
@@ -649,8 +649,8 @@ async function handleOpenDialog(type: "create" | "update" | "detail", id?: numbe
}
} else {
dialogVisible.title = "新增岗位";
Object.assign(formData, initialFormData);
formData.id = undefined;
Object.assign(formData.value, initialFormData);
formData.value.id = undefined;
}
positionFormRenderKey.value += 1;
dialogVisible.visible = true;
@@ -660,13 +660,13 @@ async function handleSubmit() {
dataFormRef.value?.validate(async (valid: boolean) => {
if (!valid) return;
submitLoading.value = true;
const id = formData.id;
const id = formData.value.id;
try {
if (id) {
await PositionAPI.updatePosition(id, { id, ...formData });
await PositionAPI.updatePosition(id, { id, ...formData.value });
await refreshUpdate();
} else {
await PositionAPI.createPosition(formData);
await PositionAPI.createPosition(formData.value);
await refreshCreate();
}
dialogVisible.visible = false;
@@ -728,15 +728,15 @@ function handleMoreClick(status: string) {
</script>
<style scoped lang="scss">
.crud-dialog-art-form ::deep(.el-row > .el-col:last-child) {
.crud-dialog-art-form ::v-deep(.el-row > .el-col:last-child) {
display: none;
}
.crud-dialog-art-form ::deep(.el-form-item__content) {
.crud-dialog-art-form ::v-deep(.el-form-item__content) {
max-width: 100%;
}
::deep(.position-table-actions .inline-flex) {
::v-deep(.position-table-actions .inline-flex) {
vertical-align: middle;
}
</style>
@@ -547,7 +547,7 @@ const roleExportContentConfig = computed(() => ({
const detailFormData = ref<RoleTable>({} as RoleTable);
const formData = reactive<RoleForm>({
const formData = ref<RoleForm>({
id: undefined,
name: undefined,
order: 1,
@@ -684,8 +684,8 @@ async function handleOpenDialog(type: "create" | "update" | "detail", id?: numbe
}
} else {
dialogVisible.title = "新增角色";
Object.assign(formData, initialFormData);
formData.id = undefined;
Object.assign(formData.value, initialFormData);
formData.value.id = undefined;
}
roleFormRenderKey.value += 1;
dialogVisible.visible = true;
@@ -695,13 +695,13 @@ async function handleSubmit() {
dataFormRef.value?.validate(async (valid: boolean) => {
if (!valid) return;
submitLoading.value = true;
const id = formData.id;
const id = formData.value.id;
try {
if (id) {
await RoleAPI.updateRole(id, { id, ...formData });
await RoleAPI.updateRole(id, { id, ...formData.value });
await refreshUpdate();
} else {
await RoleAPI.createRole(formData);
await RoleAPI.createRole(formData.value);
await refreshCreate();
}
dialogVisible.visible = false;
@@ -766,15 +766,15 @@ function openExportModal() {
</script>
<style scoped lang="scss">
.crud-dialog-art-form ::deep(.el-row > .el-col:last-child) {
.crud-dialog-art-form ::v-deep(.el-row > .el-col:last-child) {
display: none;
}
.crud-dialog-art-form ::deep(.el-form-item__content) {
.crud-dialog-art-form ::v-deep(.el-form-item__content) {
max-width: 100%;
}
::deep(.role-table-actions .inline-flex) {
::v-deep(.role-table-actions .inline-flex) {
vertical-align: middle;
}
</style>
@@ -440,7 +440,7 @@ const detailFormData = ref<TenantTable>({ code: "", name: "", status: "0" });
const currentEditId = ref<number | null>(null);
const formData = reactive<TenantForm>({
const formData = ref<TenantForm>({
name: "",
code: "",
status: "0",
@@ -458,7 +458,11 @@ const dialogVisible = reactive({
const CODE_PATTERN = /^[A-Za-z0-9]+$/;
const validateTimeRange = (rule: unknown, value: unknown, callback: (e?: Error) => void) => {
if (formData.start_time && formData.end_time && formData.start_time > formData.end_time) {
if (
formData.value.start_time &&
formData.value.end_time &&
formData.value.start_time > formData.value.end_time
) {
callback(new Error("结束时间不能早于开始时间"));
} else {
callback();
@@ -618,18 +622,18 @@ async function handleSubmit() {
try {
if (id) {
const payload: TenantUpdateForm = {
name: formData.name,
start_time: formData.start_time,
end_time: formData.end_time,
name: formData.value.name,
start_time: formData.value.start_time,
end_time: formData.value.end_time,
};
await TenantAPI.updateTenant(id, payload);
await refreshUpdate();
} else {
const payload: TenantCreateForm = {
name: formData.name as string,
code: formData.code as string,
start_time: formData.start_time,
end_time: formData.end_time,
name: formData.value.name as string,
code: formData.value.code as string,
start_time: formData.value.start_time,
end_time: formData.value.end_time,
};
await TenantAPI.createTenant(payload);
await refreshCreate();
@@ -668,15 +672,15 @@ function handleBatchDelete() {
</script>
<style scoped lang="scss">
.crud-dialog-art-form ::deep(.el-row > .el-col:last-child) {
.crud-dialog-art-form ::v-deep(.el-row > .el-col:last-child) {
display: none;
}
.crud-dialog-art-form ::deep(.el-form-item__content) {
.crud-dialog-art-form ::v-deep(.el-form-item__content) {
max-width: 100%;
}
::deep(.tenant-table-actions .inline-flex) {
::v-deep(.tenant-table-actions .inline-flex) {
vertical-align: middle;
}
</style>
@@ -1,6 +1,6 @@
<!-- 列表选择器 -->
<template>
<table-select
<FaTableSelect
:text="text"
:select-config="selectConfig"
@confirm-click="handleConfirm"
@@ -11,7 +11,7 @@
{{ scope.row[scope.prop] === "0" ? "启用" : "停用" }}
</ElTag>
</template>
</table-select>
</FaTableSelect>
</template>
<script setup lang="ts">
@@ -731,7 +731,7 @@ const userExportContentConfig = computed(() => ({
},
}));
const formData = reactive<UserForm>({
const formData = ref<UserForm>({
id: undefined,
username: undefined,
name: undefined,
@@ -882,13 +882,15 @@ async function handleOpenDialog(type: "create" | "update" | "detail", id?: numbe
Object.assign(detailFormData.value, response.data.data ?? {});
} else if (type === "update") {
dialogVisible.title = "修改用户";
Object.assign(formData, response.data.data);
formData.role_ids = (response.data.data.roles || []).map((item) => item.id as number);
formData.position_ids = (response.data.data.positions || []).map((item) => item.id as number);
Object.assign(formData.value, response.data.data);
formData.value.role_ids = (response.data.data.roles || []).map((item) => item.id as number);
formData.value.position_ids = (response.data.data.positions || []).map(
(item) => item.id as number
);
}
} else {
dialogVisible.title = "新增用户";
formData.id = undefined;
formData.value.id = undefined;
}
dialogVisible.visible = true;
await nextTick();
@@ -926,13 +928,13 @@ async function handleSubmit() {
dataFormRef.value.validate(async (valid: boolean) => {
if (!valid) return;
submitLoading.value = true;
const id = formData.id;
const id = formData.value.id;
try {
if (id) {
await UserAPI.updateUser(id, { id, ...formData });
await UserAPI.updateUser(id, { id, ...formData.value });
await refreshUpdate();
} else {
await UserAPI.createUser(formData);
await UserAPI.createUser(formData.value);
await refreshCreate();
}
dialogVisible.visible = false;
@@ -1002,7 +1004,7 @@ function handleMoreClick(status: string) {
<style lang="scss" scoped>
/* 左侧部门树内容区:card body 纵向 flex + 滚动条占满剩余高度(布局在 index,内边距在 DeptTree) */
.tree-card ::deep(.el-card__body) {
.tree-card ::v-deep(.el-card__body) {
display: flex;
flex: 1;
flex-direction: column;