@@ -1 +0,0 @@ | |||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 261.76 226.69"><path d="M161.096.001l-30.225 52.351L100.647.001H-.005l130.877 226.688L261.749.001z" fill="#41b883"/><path d="M161.096.001l-30.225 52.351L100.647.001H52.346l78.526 136.01L209.398.001z" fill="#34495e"/></svg> |
@@ -0,0 +1,38 @@ | |||
.filter { | |||
box-sizing: border-box; | |||
min-width: 220px; | |||
height: 100%; | |||
padding: 18px; | |||
margin-right: 10px; | |||
.title { | |||
margin: 0 0 15px; | |||
font-size: 18px; | |||
font-weight: bold; | |||
color: var(--el-text-color-regular); | |||
letter-spacing: 0.5px; | |||
} | |||
.el-input { | |||
margin: 0 0 15px; | |||
} | |||
.el-scrollbar { | |||
:deep(.el-tree) { | |||
height: 80%; | |||
overflow: auto; | |||
.el-tree-node__content { | |||
height: 33px; | |||
} | |||
} | |||
:deep(.el-tree--highlight-current) { | |||
.el-tree-node.is-current > .el-tree-node__content { | |||
background-color: var(--el-color-primary); | |||
.el-tree-node__label, | |||
.el-tree-node__expand-icon { | |||
color: white; | |||
} | |||
.is-leaf { | |||
color: transparent; | |||
} | |||
} | |||
} | |||
} | |||
} |
@@ -0,0 +1,201 @@ | |||
<template> | |||
<div class="card filter"> | |||
<h4 v-if="title" class="title sle"> | |||
{{ title }} | |||
</h4> | |||
<el-input v-model="filterText" placeholder="输入关键字进行过滤" clearable /> | |||
<el-scrollbar :style="{ height: title ? `calc(100% - 95px)` : `calc(100% - 56px)` }"> | |||
<el-tree | |||
ref="treeRef" | |||
default-expand-all | |||
:node-key="id" | |||
:data="multiple ? treeData : treeAllData" | |||
:show-checkbox="multiple" | |||
:check-strictly="false" | |||
:current-node-key="!multiple ? selected : ''" | |||
:highlight-current="!multiple" | |||
:expand-on-click-node="false" | |||
:check-on-click-node="multiple" | |||
:props="defaultProps" | |||
:filter-node-method="filterNode" | |||
:default-checked-keys="multiple ? selected : []" | |||
@node-click="handleNodeClick" | |||
@check="handleCheckChange" | |||
> | |||
<!-- <template #default="scope"> | |||
<span class="el-tree-node__label"> | |||
<slot :row="scope"> | |||
{{ scope.node.label }} | |||
</slot> | |||
</span> | |||
</template> --> | |||
<template #default="{ node, data }"> | |||
<span class="custom-tree-node"> | |||
{{ node.label }} | |||
<!-- <template v-else> | |||
<el-input v-model="editingNodeLabel" @blur="cancelEdit" @keyup.enter="updateNodeLabel(data)"></el-input> | |||
</template> --> | |||
<span v-if="operate"> | |||
<a :style="{ marginRight: '0.5rem' }" @click.stop="edit(node, data)"> | |||
<el-icon :style="{ color: '#0000FF' }"> | |||
<Edit /> | |||
</el-icon> | |||
</a> | |||
<a :style="{ marginRight: '0.5rem' }" @click.stop="remove(node, data)"> | |||
<el-icon :style="{ color: '#DA3434' }"> | |||
<Delete /> | |||
</el-icon> | |||
</a> | |||
</span> | |||
</span> | |||
</template> | |||
<!-- <span slot-scope="{ node, data }"> | |||
<span class="el-tree-node__label"> | |||
{{ node.label }} | |||
</span> | |||
</span> --> | |||
</el-tree> | |||
</el-scrollbar> | |||
<ClassifyDialog ref="dialogRef"></ClassifyDialog> | |||
</div> | |||
</template> | |||
<script setup lang="ts" name="BookListFilter"> | |||
import { ref, watch, onBeforeMount, nextTick } from "vue"; | |||
import { ElTree } from "element-plus"; | |||
import ClassifyDialog from "@/views/books/bookListManage/components/ClassifyDialog.vue"; | |||
// 接收父组件参数并设置默认值 | |||
interface TreeFilterProps { | |||
requestApi?: (data?: any) => Promise<any>; // 请求分类数据的 api ==> 非必传 | |||
data?: { [key: string]: any }[]; // 分类数据,如果有分类数据,则不会执行 api 请求 ==> 非必传 | |||
title?: string; // treeFilter 标题 ==> 非必传 | |||
id?: string; // 选择的id ==> 非必传,默认为 “id” | |||
label?: string; // 显示的label ==> 非必传,默认为 “label” | |||
multiple?: boolean; // 是否为多选 ==> 非必传,默认为 false | |||
defaultValue?: any; // 默认选中的值 ==> 非必传 | |||
operate?: boolean; // 是否展示编辑删除 默认false | |||
} | |||
const props = withDefaults(defineProps<TreeFilterProps>(), { | |||
id: "id", | |||
label: "label", | |||
multiple: false, | |||
operate: false | |||
}); | |||
const defaultProps = { | |||
children: "children", | |||
label: props.label | |||
}; | |||
/** 树形结构数据 */ | |||
interface Tree { | |||
[key: string]: any; | |||
} | |||
const treeRef = ref<InstanceType<typeof ElTree>>(); | |||
const treeData = ref<{ [key: string]: any }[]>([]); | |||
const treeAllData = ref<{ [key: string]: any }[]>([]); | |||
const selected = ref(); | |||
const setSelected = () => { | |||
if (props.multiple) selected.value = Array.isArray(props.defaultValue) ? props.defaultValue : [props.defaultValue]; | |||
else selected.value = typeof props.defaultValue === "string" ? props.defaultValue : ""; | |||
}; | |||
const dialogRef = ref<InstanceType<typeof ClassifyDialog> | null>(null); | |||
const edit = (node: Node, data: Tree) => { | |||
console.log("node", node); | |||
console.log("data", data); | |||
console.log("打开弹窗"); | |||
dialogRef.value?.open().then(); | |||
// const newChild = { id: id++, label: "testtest", children: [] }; | |||
// if (!data.children) { | |||
// data.children = []; | |||
// } | |||
// data.children.push(newChild); | |||
// dataSource.value = [...dataSource.value]; | |||
}; | |||
/** 删除树节点 */ | |||
const remove = (node: Node, data: Tree) => { | |||
console.log("node", node); | |||
console.log("data", data); | |||
const parent = node?.parent; | |||
const children: Tree[] = parent.data.children || parent.data; | |||
const index = children.findIndex(d => d.id === data.id); | |||
children.splice(index, 1); | |||
const dataResult = props.multiple ? treeData : treeAllData; | |||
dataResult.value = [...dataResult.value]; | |||
}; | |||
onBeforeMount(async () => { | |||
setSelected(); | |||
if (props.requestApi) { | |||
const { data } = await props.requestApi!(); | |||
treeData.value = data; | |||
treeAllData.value = [...data]; | |||
// treeAllData.value = [{ id: "", [props.label]: "全部" }, ...data]; | |||
} | |||
}); | |||
// 使用 nextTick 防止打包后赋值不生效,开发环境是正常的 | |||
watch( | |||
() => props.defaultValue, | |||
() => nextTick(() => setSelected()), | |||
{ deep: true, immediate: true } | |||
); | |||
watch( | |||
() => props.data, | |||
() => { | |||
if (props.data?.length) { | |||
treeData.value = props.data; | |||
treeAllData.value = [...props.data]; | |||
// treeAllData.value = [{ id: "", [props.label]: "全部" }, ...props.data]; | |||
} | |||
}, | |||
{ deep: true, immediate: true } | |||
); | |||
const filterText = ref(""); | |||
watch(filterText, val => { | |||
treeRef.value!.filter(val); | |||
}); | |||
// 过滤 | |||
const filterNode = (value: string, data: { [key: string]: any }, node: any) => { | |||
if (!value) return true; | |||
let parentNode = node.parent, | |||
labels = [node.label], | |||
level = 1; | |||
while (level < node.level) { | |||
labels = [...labels, parentNode.label]; | |||
parentNode = parentNode.parent; | |||
level++; | |||
} | |||
return labels.some(label => label.indexOf(value) !== -1); | |||
}; | |||
// emit | |||
const emit = defineEmits<{ | |||
change: [value: any]; | |||
}>(); | |||
// 单选 | |||
const handleNodeClick = (data: { [key: string]: any }) => { | |||
if (props.multiple) return; | |||
emit("change", data[props.id]); | |||
}; | |||
// 多选 | |||
const handleCheckChange = () => { | |||
emit("change", treeRef.value?.getCheckedKeys()); | |||
}; | |||
// 暴露给父组件使用 | |||
defineExpose({ treeData, treeAllData, treeRef }); | |||
</script> | |||
<style scoped lang="scss"> | |||
@import "./index.scss"; | |||
</style> |
@@ -22,48 +22,21 @@ | |||
@node-click="handleNodeClick" | |||
@check="handleCheckChange" | |||
> | |||
<!-- <template #default="scope"> | |||
<template #default="scope"> | |||
<span class="el-tree-node__label"> | |||
<slot :row="scope"> | |||
{{ scope.node.label }} | |||
</slot> | |||
</span> | |||
</template> --> | |||
<template #default="{ node, data }"> | |||
<span class="custom-tree-node"> | |||
{{ node.label }} | |||
<!-- <template v-else> | |||
<el-input v-model="editingNodeLabel" @blur="cancelEdit" @keyup.enter="updateNodeLabel(data)"></el-input> | |||
</template> --> | |||
<span v-if="operate"> | |||
<a :style="{ marginRight: '0.5rem' }" @click.stop="edit(node, data)"> | |||
<el-icon :style="{ color: '#0000FF' }"> | |||
<Edit /> | |||
</el-icon> | |||
</a> | |||
<a :style="{ marginRight: '0.5rem' }" @click.stop="remove(node, data)"> | |||
<el-icon :style="{ color: '#DA3434' }"> | |||
<Delete /> | |||
</el-icon> | |||
</a> | |||
</span> | |||
</span> | |||
</template> | |||
<!-- <span slot-scope="{ node, data }"> | |||
<span class="el-tree-node__label"> | |||
{{ node.label }} | |||
</span> | |||
</span> --> | |||
</el-tree> | |||
</el-scrollbar> | |||
<ClassifyDialog ref="dialogRef"></ClassifyDialog> | |||
</div> | |||
</template> | |||
<script setup lang="ts" name="TreeFilter"> | |||
import { ref, watch, onBeforeMount, nextTick } from "vue"; | |||
import { ElTree } from "element-plus"; | |||
import ClassifyDialog from "@/views/books/bookListManage/components/ClassifyDialog.vue"; | |||
// 接收父组件参数并设置默认值 | |||
interface TreeFilterProps { | |||
@@ -74,13 +47,11 @@ interface TreeFilterProps { | |||
label?: string; // 显示的label ==> 非必传,默认为 “label” | |||
multiple?: boolean; // 是否为多选 ==> 非必传,默认为 false | |||
defaultValue?: any; // 默认选中的值 ==> 非必传 | |||
operate?: boolean; // 是否展示编辑删除 默认false | |||
} | |||
const props = withDefaults(defineProps<TreeFilterProps>(), { | |||
id: "id", | |||
label: "label", | |||
multiple: false, | |||
operate: false | |||
multiple: false | |||
}); | |||
const defaultProps = { | |||
@@ -88,11 +59,6 @@ const defaultProps = { | |||
label: props.label | |||
}; | |||
/** 树形结构数据 */ | |||
interface Tree { | |||
[key: string]: any; | |||
} | |||
const treeRef = ref<InstanceType<typeof ElTree>>(); | |||
const treeData = ref<{ [key: string]: any }[]>([]); | |||
const treeAllData = ref<{ [key: string]: any }[]>([]); | |||
@@ -102,39 +68,13 @@ const setSelected = () => { | |||
if (props.multiple) selected.value = Array.isArray(props.defaultValue) ? props.defaultValue : [props.defaultValue]; | |||
else selected.value = typeof props.defaultValue === "string" ? props.defaultValue : ""; | |||
}; | |||
const dialogRef = ref<InstanceType<typeof ClassifyDialog> | null>(null); | |||
const edit = (node: Node, data: Tree) => { | |||
console.log("node", node); | |||
console.log("data", data); | |||
console.log("打开弹窗"); | |||
dialogRef.value?.open().then(); | |||
// const newChild = { id: id++, label: "testtest", children: [] }; | |||
// if (!data.children) { | |||
// data.children = []; | |||
// } | |||
// data.children.push(newChild); | |||
// dataSource.value = [...dataSource.value]; | |||
}; | |||
/** 删除树节点 */ | |||
const remove = (node: Node, data: Tree) => { | |||
console.log("node", node); | |||
console.log("data", data); | |||
const parent = node?.parent; | |||
const children: Tree[] = parent.data.children || parent.data; | |||
const index = children.findIndex(d => d.id === data.id); | |||
children.splice(index, 1); | |||
const dataResult = props.multiple ? treeData : treeAllData; | |||
dataResult.value = [...dataResult.value]; | |||
}; | |||
onBeforeMount(async () => { | |||
setSelected(); | |||
if (props.requestApi) { | |||
const { data } = await props.requestApi!(); | |||
treeData.value = data; | |||
treeAllData.value = [...data]; | |||
// treeAllData.value = [{ id: "", [props.label]: "全部" }, ...data]; | |||
treeAllData.value = [{ id: "", [props.label]: "全部" }, ...data]; | |||
} | |||
}); | |||
@@ -150,8 +90,7 @@ watch( | |||
() => { | |||
if (props.data?.length) { | |||
treeData.value = props.data; | |||
treeAllData.value = [...props.data]; | |||
// treeAllData.value = [{ id: "", [props.label]: "全部" }, ...props.data]; | |||
treeAllData.value = [{ id: "", [props.label]: "全部" }, ...props.data]; | |||
} | |||
}, | |||
{ deep: true, immediate: true } | |||
@@ -7,7 +7,7 @@ export const HOME_URL: string = "/"; | |||
export const LOGIN_URL: string = "/login"; | |||
// 默认主题颜色 | |||
export const DEFAULT_PRIMARY: string = "#BA7D45"; // #0C655D | |||
export const DEFAULT_PRIMARY: string = "#0C655D"; // #BA7D45 | |||
// 路由白名单地址(本地存在的路由 staticRouter.ts 中) | |||
export const ROUTER_WHITE_LIST: string[] = ["/500"]; | |||
@@ -3,7 +3,7 @@ import { Theme } from "@/hooks/interface"; | |||
export const menuTheme: Record<Theme.ThemeType, { [key: string]: string }> = { | |||
light: { | |||
"--el-bg-color-page": "#F8F7F5", | |||
"--el-menu-bg-color": "#ECD8BE", | |||
"--el-menu-bg-color": "#fffff", | |||
"--el-menu-hover-bg-color": "rgba(255, 255, 255, .7)", | |||
"--el-menu-active-bg-color": "#FFFFFF", | |||
"--el-menu-text-color": "#340D00", | |||
@@ -1,206 +0,0 @@ | |||
<!-- 新增/编辑书目 --> | |||
<template> | |||
<el-dialog | |||
v-model="dialogVisible" | |||
:title="isAdd ? '添加' : '编辑'" | |||
:width="500" | |||
center | |||
align-center | |||
:close-on-click-modal="false" | |||
@closed="handleBeforeClose" | |||
> | |||
<el-form :model="formData" ref="formRef" label-width="150px" :rules="formRules" class="mt20"> | |||
<el-form-item label="所属分类" prop="knowledgeCellName"> | |||
<el-tree-select v-model="formData.knowledgeCellName" :data="data" filterable /> | |||
</el-form-item> | |||
<el-form-item label="书名名称" prop="isKnowledgeName" maxlength="50"> | |||
<el-input v-model="formData.annotation" placeholder="请输入分类名称" :maxlength="50" /> | |||
</el-form-item> | |||
<el-form-item label="作者" prop="author"> | |||
<el-input v-model="formData.author" placeholder="请输入作者" :maxlength="50" /> | |||
</el-form-item> | |||
<el-form-item label="出版时间" prop="time"> | |||
<el-input v-model="formData.time" placeholder="请输入出版时间" :maxlength="50" /> | |||
</el-form-item> | |||
<el-form-item label="提要" prop="annotation"> | |||
<el-input v-model="formData.annotation" placeholder="请输入提要" :maxlength="1000" /> | |||
</el-form-item> | |||
</el-form> | |||
<template #footer> | |||
<span class="dialog-footer"> | |||
<el-button @click="handleCancel">取消</el-button> | |||
<el-button type="primary" class="ml30" v-throttle="handleSubmit">确定</el-button> | |||
</span> | |||
</template> | |||
</el-dialog> | |||
</template> | |||
<script lang="ts" setup name="editBookList"> | |||
import { ref, reactive, nextTick } from "vue"; | |||
import { FormInstance, FormRules, ElMessage } from "element-plus"; | |||
//* 接收注入 | |||
const dialogVisible = ref(false); | |||
//* data | |||
//* ref | |||
const formRef = ref<FormInstance>(); | |||
const openPromise = ref<any>({}); | |||
const isAdd = ref(false); | |||
const formData = reactive<FormData>(getFormDefaultValue()); | |||
const sourceData = [ | |||
{ | |||
value: "1", | |||
label: "Level one 1", | |||
children: [ | |||
{ | |||
value: "1-1", | |||
label: "Level two 1-1", | |||
children: [ | |||
{ | |||
value: "1-1-1", | |||
label: "Level three 1-1-1" | |||
} | |||
] | |||
} | |||
] | |||
}, | |||
{ | |||
value: "2", | |||
label: "Level one 2", | |||
children: [ | |||
{ | |||
value: "2-1", | |||
label: "Level two 2-1", | |||
children: [ | |||
{ | |||
value: "2-1-1", | |||
label: "Level three 2-1-1" | |||
} | |||
] | |||
}, | |||
{ | |||
value: "2-2", | |||
label: "Level two 2-2", | |||
children: [ | |||
{ | |||
value: "2-2-1", | |||
label: "Level three 2-2-1" | |||
} | |||
] | |||
} | |||
] | |||
}, | |||
{ | |||
value: "3", | |||
label: "Level one 3", | |||
children: [ | |||
{ | |||
value: "3-1", | |||
label: "Level two 3-1", | |||
children: [ | |||
{ | |||
value: "3-1-1", | |||
label: "Level three 3-1-1" | |||
} | |||
] | |||
}, | |||
{ | |||
value: "3-2", | |||
label: "Level two 3-2", | |||
children: [ | |||
{ | |||
value: "3-2-1", | |||
label: "Level three 3-2-1" | |||
} | |||
] | |||
} | |||
] | |||
} | |||
]; | |||
const data = ref(sourceData); | |||
interface FormData { | |||
[key: string]: any; | |||
} | |||
function getFormDefaultValue(): FormData { | |||
return { | |||
knowledgeId: undefined, | |||
isKnowledgeName: 0, | |||
knowledgeCellName: undefined, | |||
annotation: undefined | |||
}; | |||
} | |||
//* 方法 | |||
// 校验规则 | |||
let formRules = reactive<FormRules>({ | |||
isKnowledgeName: [ | |||
{ | |||
required: true, | |||
message: "是否做为知识体名称", | |||
trigger: "change" | |||
} | |||
], | |||
knowledgeCellName: [ | |||
{ | |||
required: true, | |||
message: "请选择上级分类", | |||
trigger: "change" | |||
} | |||
], | |||
annotation: [{ required: true, message: "分类名称不能为空", trigger: "blur" }] | |||
}); | |||
// 取消 | |||
function handleCancel() { | |||
dialogVisible.value = false; | |||
} | |||
function handleBeforeClose() { | |||
dialogVisible.value = false; | |||
const defaultValue = getFormDefaultValue(); | |||
for (const key of Object.keys(defaultValue)) { | |||
formData[key] = defaultValue[key]; | |||
} | |||
nextTick(formRef.value?.clearValidate); | |||
} | |||
//提交 | |||
function handleSubmit() { | |||
console.log("提交"); | |||
ElMessage.success("新增成功"); | |||
openPromise.value.resolve(); | |||
dialogVisible.value = false; | |||
// formRef.value?.validate(async valid => { | |||
// if (!valid) return; | |||
// const params = { | |||
// ...formData | |||
// }; | |||
// if (isAdd.value) { | |||
// await addMenu(params); | |||
// ElMessage.success("新增成功"); | |||
// } else { | |||
// await editMenu(params); | |||
// ElMessage.success("编辑成功"); | |||
// } | |||
// openPromise.value.resolve(); | |||
// dialogVisible.value = false; | |||
// } | |||
} | |||
function open(params?: FormData) { | |||
isAdd.value = !params?.knowledgeId; | |||
dialogVisible.value = true; | |||
if (params) { | |||
if (params.knowledgeId) { | |||
for (const key of Object.keys(formData)) { | |||
formData[key] = params[key]; | |||
} | |||
} else { | |||
formData.parentId = params.parentId; | |||
} | |||
} | |||
return new Promise(resolve => { | |||
openPromise.value.resolve = resolve; | |||
}); | |||
} | |||
defineExpose({ | |||
open | |||
}); | |||
</script> |
@@ -2,7 +2,7 @@ | |||
<div class="main-box"> | |||
<div class="class-book"> | |||
<div>书目分类</div> | |||
<TreeFilter | |||
<BookListFilter | |||
ref="treeFilterRef" | |||
:request-api="getUserDepartment" | |||
:default-value="initParam.deptId" | |||
@@ -30,19 +30,17 @@ | |||
</template> | |||
</ProTable> | |||
<ClassifyDialog ref="dialogRef"></ClassifyDialog> | |||
<BookListDialog ref="dialogRefBookList"></BookListDialog> | |||
</div> | |||
</div> | |||
</template> | |||
<script setup lang="ts" name="BookListManage"> | |||
import { ref, reactive } from "vue"; | |||
import { getUserDepartment } from "@/api/modules/system/user"; | |||
import TreeFilter from "@/components/TreeFilter/index.vue"; | |||
import BookListFilter from "@/components/BookListFilter/index.vue"; | |||
import ProTable from "@/components/ProTable/index.vue"; | |||
import { ProTableInstance, ColumnProps } from "@/components/ProTable/interface"; | |||
import { Delete, EditPen, Rank, Upload } from "@element-plus/icons-vue"; | |||
import ClassifyDialog from "./components/ClassifyDialog.vue"; | |||
import BookListDialog from "./components/BookListDialog.vue"; | |||
import { useRouter } from "vue-router"; | |||
const initParam = reactive({ deptId: "" }); | |||
@@ -92,11 +90,6 @@ function viewAction(row) { | |||
} | |||
}); | |||
} | |||
// 打开 drawer | |||
// const dialogRefBookList = ref<InstanceType<typeof BookListDialog> | null>(null); | |||
// const openDialogBookList = () => { | |||
// dialogRefBookList.value?.open().then(proTable.value?.getTableList); | |||
// }; | |||
</script> | |||
<style lang="scss" scoped> | |||
.main-box { | |||
@@ -26,6 +26,11 @@ | |||
<el-button v-if="false" :icon="CircleClose" round size="large" @click="resetForm(loginFormRef)"> 重置 </el-button> | |||
<el-button size="large" type="primary" :loading="loading" @click="login(loginFormRef)"> 登录 </el-button> | |||
</div> | |||
<div class="login-tips mt30"> | |||
<p>温馨提示:</p> | |||
<p>1、登录时请注意区分登录账号的角色</p> | |||
<p>2、登录后请完善基本信息并及时修改密码</p> | |||
</div> | |||
</template> | |||
<script setup lang="ts"> | |||
@@ -13,69 +13,76 @@ | |||
flex-direction: column; | |||
align-items: center; | |||
justify-content: center; | |||
.dark { | |||
position: absolute; | |||
top: 13px; | |||
right: 18px; | |||
} | |||
.login-logo { | |||
text-align: center; | |||
.logo-text { | |||
margin: 0; | |||
font-weight: bold; | |||
} | |||
h1.logo-text { | |||
font-family: STSongti-SC-Bold, STSongti-SC; | |||
font-size: 52px; | |||
line-height: 73px; | |||
color: #340d00; | |||
} | |||
h2.logo-text { | |||
font-family: STKaitiSC-Bold, STKaitiSC; | |||
font-size: 42px; | |||
line-height: 59px; | |||
color: #6a330c; | |||
} | |||
} | |||
.login-form { | |||
width: 300px; | |||
padding: 55px 66px; | |||
margin-top: 40px; | |||
display: flex; | |||
padding-left: 66px; | |||
text-align: center; | |||
background-image: url("@/assets/images/login_form_bg.png"); | |||
background-size: 100% 100%; | |||
.login-form-text { | |||
width: 220px; | |||
height: 30px; | |||
} | |||
:deep(.el-form-item) { | |||
margin-top: 26px; | |||
margin-bottom: 0; | |||
.el-input__wrapper { | |||
padding: 0; | |||
background: transparent; | |||
border-bottom: 1px solid #dccfc3; | |||
border-radius: 0; | |||
box-shadow: none !important; | |||
.el-input__inner { | |||
height: 47px; | |||
font-family: STKaitiSC-Regular, STKaitiSC; | |||
font-size: 22px; | |||
&::placeholder { | |||
color: #cdb299; | |||
} | |||
} | |||
.el-input__suffix { | |||
.el-input__icon { | |||
font-size: 20px; | |||
color: #eeddce; | |||
} | |||
} | |||
background: #ffffff; | |||
border: 1px solid #9bf4ec; | |||
border-radius: 24px; | |||
box-shadow: 17px 34px 51px 0 #2a4c44; | |||
.login-left { | |||
display: flex; | |||
flex: 1; | |||
flex-direction: column; | |||
padding-bottom: 100px; | |||
.login_title { | |||
width: 412px; | |||
height: 44px; | |||
margin-top: 100px; | |||
margin-bottom: 91px; | |||
} | |||
&.is-error .el-input__wrapper { | |||
border-color: var(--el-color-danger); | |||
.logo { | |||
width: 517px; | |||
height: 364px; | |||
} | |||
} | |||
.login-right { | |||
flex: 1; | |||
padding: 86px 84px; | |||
background: #ecfffd; | |||
border-left: 1px solid #9bf4ec; | |||
border-radius: 0 24px 24px 0; | |||
.login-form-text { | |||
font-family: STKaitiSC-Regular, STKaitiSC; | |||
font-size: 27px; | |||
font-weight: bold; | |||
color: var(--el-color-primary); | |||
text-align: left; | |||
} | |||
} | |||
:deep(.el-form) { | |||
width: 428px; | |||
} | |||
// :deep(.el-form-item) { | |||
// margin-top: 26px; | |||
// margin-bottom: 0; | |||
// .el-input__wrapper { | |||
// padding: 0; | |||
// background: transparent; | |||
// border-bottom: 1px solid #dccfc3; | |||
// border-radius: 0; | |||
// box-shadow: none !important; | |||
// .el-input__inner { | |||
// height: 47px; | |||
// font-family: STKaitiSC-Regular, STKaitiSC; | |||
// font-size: 22px; | |||
// &::placeholder { | |||
// color: #cdb299; | |||
// } | |||
// } | |||
// .el-input__suffix { | |||
// .el-input__icon { | |||
// font-size: 20px; | |||
// color: #eeddce; | |||
// } | |||
// } | |||
// } | |||
// &.is-error .el-input__wrapper { | |||
// border-color: var(--el-color-danger); | |||
// } | |||
// } | |||
.login-code { | |||
float: right; | |||
margin-left: 30px; | |||
@@ -86,21 +93,23 @@ | |||
} | |||
} | |||
.login-btn { | |||
width: 100%; | |||
margin-top: 48px; | |||
margin-bottom: 35px; | |||
white-space: nowrap; | |||
.el-button { | |||
width: 100%; | |||
height: 60px; | |||
height: 52px; | |||
font-family: STSongti-SC-Bold, STSongti-SC; | |||
font-size: 22px; | |||
font-weight: bold; | |||
background: url("@/assets/images/login_form_btn.png"); | |||
background-size: 100% 100%; | |||
border: none; | |||
background: linear-gradient(180deg, #00786c 0%, #07524b 100%); | |||
border-radius: 6px; | |||
} | |||
} | |||
.login-tips { | |||
color: var(--el-color-primary); | |||
text-align: left; | |||
} | |||
} | |||
} | |||
} | |||
@@ -1,14 +1,15 @@ | |||
<template> | |||
<div class="login-container flx-center"> | |||
<div class="login-box"> | |||
<!-- <SwitchDark class="dark" /> --> | |||
<div class="login-logo"> | |||
<h1 class="logo-text">中国中医科学院针灸研究所</h1> | |||
<h2 class="logo-text">{{ title }}</h2> | |||
</div> | |||
<div class="login-form"> | |||
<img class="login-form-text" src="@/assets/images/login_form_text.png" alt="" /> | |||
<LoginForm /> | |||
<div class="login-left"> | |||
<img class="login_title" src="@/assets/images/login_title.png" alt="" /> | |||
<img class="logo" src="@/assets/images/logo.png" alt="" /> | |||
</div> | |||
<div class="login-right"> | |||
<div class="login-form-text mb40">欢迎登录</div> | |||
<LoginForm /> | |||
</div> | |||
</div> | |||
</div> | |||
</div> | |||
@@ -17,7 +18,7 @@ | |||
<script setup lang="ts" name="login"> | |||
import LoginForm from "./components/LoginForm.vue"; | |||
// import SwitchDark from "@/components/SwitchDark/index.vue"; | |||
const title = import.meta.env.VITE_GLOB_APP_TITLE; | |||
// const title = import.meta.env.VITE_GLOB_APP_TITLE; | |||
</script> | |||
<style scoped lang="scss"> | |||