Parcourir la source

✨ feat(card and login ):

xjy il y a 3 mois
Parent
commit
135a8009b2

+ 131 - 0
.history/src/pages/login/index_20240801164911.vue

@@ -0,0 +1,131 @@
+<template>
+  <div class="h-screen w-full flex flex-1 flex-col justify-center items-center overflow-hidden">
+    <div class="login-layout-container overflow-hidden">
+      <!-- S LOGO -->
+      <!-- <div class="flex justify-start px-2 fixed" style="top: 32px; left: 36px; cursor: pointer; app-region: no-drag">
+        <div class="logo-text ml-1" style="width: 115px">
+          <img src="@/assets/logo-st.png" class="h-54px" />
+        </div>
+      </div> -->
+      <!-- E LOGO -->
+      <div class="left absolute left-192px p-r-60px">
+        <div class="login-img"></div>
+        <User @login="onLoginClick($event)"></User>
+      </div>
+      <div
+        class="right overflow-hidden absolute right-0 flex flex-1 flex-justify-start h-100% border-0 box-border w-800px border-l border-solid border-l-gray-300"
+      >
+        <div class="top-img w-250px h-130px absolute top-20px right--20px"></div>
+        <div class="bg w-800px h-800px"></div>
+      </div>
+    </div>
+  </div>
+</template>
+
+<route lang="yaml">
+meta:
+  title: 登录
+  layout: false
+</route>
+
+<script lang="ts" setup>
+import { useRouter } from 'vue-router';
+import type { FormInstance } from 'element-plus';
+import { useUserStore } from '@/stores/modules/user';
+import { HOME_URL, ST_CONFIG } from '@/config';
+import User from './mod/user.vue';
+
+const router = useRouter();
+const userStore = useUserStore();
+
+const APP_TITLE = ST_CONFIG.APP_TITLE;
+
+const autoLogin = ref(false);
+const loginButLoading = ref(false);
+
+// 登录
+const onLoginClick = async (formEl: FormInstance | undefined) => {
+  console.log(formEl, 'ss');
+
+  if (!formEl) return;
+  loginButLoading.value = true;
+  await formEl.validate(valid => {
+    loginButLoading.value = false;
+    if (valid) {
+      userStore.setToken('st-token');
+      router.push(HOME_URL);
+    }
+  });
+};
+</script>
+
+<style lang="scss" scope>
+// @media screen and (max-width: 1920px) {
+//   login-layout-container {
+//     transform: scale(0.8);
+//   }
+// }
+.left {
+  display: flex;
+  flex-direction: column;
+  justify-content: center;
+  height: 100%;
+  .input {
+  }
+}
+
+.right {
+  display: flex;
+  align-items: center;
+  .top-img {
+    background: url('@/assets/login/login1.png') no-repeat center 100%/100%;
+    // width: 350px;
+    // height: 210px;
+    // position: absolute;
+    // right: -100px;
+    // top: 20px;
+  }
+  .bg {
+    background: url('@/assets/login/bg.png') no-repeat center 100%/100%;
+  }
+}
+.login-img {
+  background: url('@/assets/login/login2.png') no-repeat center 100%/100%;
+  width: 300.49px;
+  height: 208.5px;
+}
+.login-layout-container {
+  position: relative;
+  display: flex;
+  // flex-direction: column;
+  // align-content: center;
+  // justify-content: center;
+  width: 100vw;
+  height: 100vh;
+  overflow: auto;
+}
+.Wd-login {
+  width: 470px;
+}
+.logo-text {
+  color: #c2cad1;
+}
+
+.form-wrapper-content {
+  -webkit-app-region: no-drag;
+}
+.login-main {
+  // margin: 0 auto;
+  -webkit-app-region: no-drag;
+}
+
+.dark .login-card {
+}
+
+.login-card {
+}
+::v-deep(.el-input) {
+  border: 1px solid rgba(1, 1, 1, 0.3);
+  border-radius: 48px !important;
+}
+</style>

+ 131 - 0
.history/src/pages/login/index_20240805105839.vue

@@ -0,0 +1,131 @@
+<template>
+  <div class="h-screen w-full flex flex-1 flex-col justify-center items-center overflow-hidden">
+    <div class="login-layout-container overflow-hidden">
+      <!-- S LOGO -->
+      <!-- <div class="flex justify-start px-2 fixed" style="top: 32px; left: 36px; cursor: pointer; app-region: no-drag">
+        <div class="logo-text ml-1" style="width: 115px">
+          <img src="@/assets/logo-st.png" class="h-54px" />
+        </div>
+      </div> -->
+      <!-- E LOGO -->
+      <div class="left absolute left-192px p-r-60px">
+        <div class="login-img"></div>
+        <User @login="onLoginClick($event)"></User>
+      </div>
+      <div
+        class="right overflow-hidden absolute right-0 flex flex-1 flex-justify-start h-100% border-0 box-border w-800px border-l border-solid border-l-gray-300"
+      >
+        <div class="top-img w-250px h-130px absolute top-20px right--20px"></div>
+        <div class="bg w-800px h-800px"></div>
+      </div>
+    </div>
+  </div>
+</template>
+
+<route lang="yaml">
+meta:
+  title: 登录
+  layout: false
+</route>
+
+<script lang="ts" setup>
+import { useRouter } from 'vue-router';
+import type { FormInstance } from 'element-plus';
+import { useUserStore } from '@/stores/modules/user';
+import { HOME_URL, ST_CONFIG } from '@/config';
+import User from './commponents/user.vue';
+
+const router = useRouter();
+const userStore = useUserStore();
+
+const APP_TITLE = ST_CONFIG.APP_TITLE;
+
+const autoLogin = ref(false);
+const loginButLoading = ref(false);
+
+// 登录
+const onLoginClick = async (formEl: FormInstance | undefined) => {
+  console.log(formEl, 'ss');
+
+  if (!formEl) return;
+  loginButLoading.value = true;
+  await formEl.validate(valid => {
+    loginButLoading.value = false;
+    if (valid) {
+      userStore.setToken('st-token');
+      router.push(HOME_URL);
+    }
+  });
+};
+</script>
+
+<style lang="scss" scope>
+// @media screen and (max-width: 1920px) {
+//   login-layout-container {
+//     transform: scale(0.8);
+//   }
+// }
+.left {
+  display: flex;
+  flex-direction: column;
+  justify-content: center;
+  height: 100%;
+  .input {
+  }
+}
+
+.right {
+  display: flex;
+  align-items: center;
+  .top-img {
+    background: url('@/assets/login/login1.png') no-repeat center 100%/100%;
+    // width: 350px;
+    // height: 210px;
+    // position: absolute;
+    // right: -100px;
+    // top: 20px;
+  }
+  .bg {
+    background: url('@/assets/login/bg.png') no-repeat center 100%/100%;
+  }
+}
+.login-img {
+  background: url('@/assets/login/login2.png') no-repeat center 100%/100%;
+  width: 300.49px;
+  height: 208.5px;
+}
+.login-layout-container {
+  position: relative;
+  display: flex;
+  // flex-direction: column;
+  // align-content: center;
+  // justify-content: center;
+  width: 100vw;
+  height: 100vh;
+  overflow: auto;
+}
+.Wd-login {
+  width: 470px;
+}
+.logo-text {
+  color: #c2cad1;
+}
+
+.form-wrapper-content {
+  -webkit-app-region: no-drag;
+}
+.login-main {
+  // margin: 0 auto;
+  -webkit-app-region: no-drag;
+}
+
+.dark .login-card {
+}
+
+.login-card {
+}
+::v-deep(.el-input) {
+  border: 1px solid rgba(1, 1, 1, 0.3);
+  border-radius: 48px !important;
+}
+</style>

+ 131 - 0
.history/src/pages/login/index_20240805105846.vue

@@ -0,0 +1,131 @@
+<template>
+  <div class="h-screen w-full flex flex-1 flex-col justify-center items-center overflow-hidden">
+    <div class="login-layout-container overflow-hidden">
+      <!-- S LOGO -->
+      <!-- <div class="flex justify-start px-2 fixed" style="top: 32px; left: 36px; cursor: pointer; app-region: no-drag">
+        <div class="logo-text ml-1" style="width: 115px">
+          <img src="@/assets/logo-st.png" class="h-54px" />
+        </div>
+      </div> -->
+      <!-- E LOGO -->
+      <div class="left absolute left-192px p-r-60px">
+        <div class="login-img"></div>
+        <User @login="onLoginClick($event)"></User>
+      </div>
+      <div
+        class="right overflow-hidden absolute right-0 flex flex-1 flex-justify-start h-100% border-0 box-border w-800px border-l border-solid border-l-gray-300"
+      >
+        <div class="top-img w-250px h-130px absolute top-20px right--20px"></div>
+        <div class="bg w-800px h-800px"></div>
+      </div>
+    </div>
+  </div>
+</template>
+
+<route lang="yaml">
+meta:
+  title: 登录
+  layout: false
+</route>
+
+<script lang="ts" setup>
+import { useRouter } from 'vue-router';
+import type { FormInstance } from 'element-plus';
+import { useUserStore } from '@/stores/modules/user';
+import { HOME_URL, ST_CONFIG } from '@/config';
+import User from './commponents/user.vue';
+
+const router = useRouter();
+const userStore = useUserStore();
+
+const APP_TITLE = ST_CONFIG.APP_TITLE;
+
+const autoLogin = ref(false);
+const loginButLoading = ref(false);
+
+// 登录
+const onLoginClick = async (formEl: FormInstance | undefined) => {
+  console.log(formEl, 'ss');
+
+  if (!formEl) return;
+  loginButLoading.value = true;
+  await formEl.validate(valid => {
+    loginButLoading.value = false;
+    if (valid) {
+      userStore.setToken('st-token');
+      router.push(HOME_URL);
+    }
+  });
+};
+</script>
+
+<style lang="scss" scope>
+// @media screen and (max-width: 1920px) {
+//   login-layout-container {
+//     transform: scale(0.8);
+//   }
+// }
+.left {
+  display: flex;
+  flex-direction: column;
+  justify-content: center;
+  height: 100%;
+  .input {
+  }
+}
+
+.right {
+  display: flex;
+  align-items: center;
+  .top-img {
+    background: url('@/assets/login/login1.png') no-repeat center 100%/100%;
+    // width: 350px;
+    // height: 210px;
+    // position: absolute;
+    // right: -100px;
+    // top: 20px;
+  }
+  .bg {
+    background: url('@/assets/login/bg.png') no-repeat center 100%/100%;
+  }
+}
+.login-img {
+  background: url('@/assets/login/login2.png') no-repeat center 100%/100%;
+  width: 300.49px;
+  height: 208.5px;
+}
+.login-layout-container {
+  position: relative;
+  display: flex;
+  // flex-direction: column;
+  // align-content: center;
+  // justify-content: center;
+  width: 100vw;
+  height: 100vh;
+  overflow: auto;
+}
+.Wd-login {
+  width: 470px;
+}
+.logo-text {
+  color: #c2cad1;
+}
+
+.form-wrapper-content {
+  -webkit-app-region: no-drag;
+}
+.login-main {
+  // margin: 0 auto;
+  -webkit-app-region: no-drag;
+}
+
+.dark .login-card {
+}
+
+.login-card {
+}
+::v-deep(.el-input) {
+  border: 1px solid rgba(1, 1, 1, 0.3);
+  border-radius: 48px !important;
+}
+</style>

+ 131 - 0
.history/src/pages/login/index_20240805105857.vue

@@ -0,0 +1,131 @@
+<template>
+  <div class="h-screen w-full flex flex-1 flex-col justify-center items-center overflow-hidden">
+    <div class="login-layout-container overflow-hidden">
+      <!-- S LOGO -->
+      <!-- <div class="flex justify-start px-2 fixed" style="top: 32px; left: 36px; cursor: pointer; app-region: no-drag">
+        <div class="logo-text ml-1" style="width: 115px">
+          <img src="@/assets/logo-st.png" class="h-54px" />
+        </div>
+      </div> -->
+      <!-- E LOGO -->
+      <div class="left absolute left-192px p-r-60px">
+        <div class="login-img"></div>
+        <User @login="onLoginClick($event)"></User>
+      </div>
+      <div
+        class="right overflow-hidden absolute right-0 flex flex-1 flex-justify-start h-100% border-0 box-border w-800px border-l border-solid border-l-gray-300"
+      >
+        <div class="top-img w-250px h-130px absolute top-20px right--20px"></div>
+        <div class="bg w-800px h-800px"></div>
+      </div>
+    </div>
+  </div>
+</template>
+
+<route lang="yaml">
+meta:
+  title: 登录
+  layout: false
+</route>
+
+<script lang="ts" setup>
+import { useRouter } from 'vue-router';
+import type { FormInstance } from 'element-plus';
+import { useUserStore } from '@/stores/modules/user';
+import { HOME_URL, ST_CONFIG } from '@/config';
+import User from './components/user.vue';
+
+const router = useRouter();
+const userStore = useUserStore();
+
+const APP_TITLE = ST_CONFIG.APP_TITLE;
+
+const autoLogin = ref(false);
+const loginButLoading = ref(false);
+
+// 登录
+const onLoginClick = async (formEl: FormInstance | undefined) => {
+  console.log(formEl, 'ss');
+
+  if (!formEl) return;
+  loginButLoading.value = true;
+  await formEl.validate(valid => {
+    loginButLoading.value = false;
+    if (valid) {
+      userStore.setToken('st-token');
+      router.push(HOME_URL);
+    }
+  });
+};
+</script>
+
+<style lang="scss" scope>
+// @media screen and (max-width: 1920px) {
+//   login-layout-container {
+//     transform: scale(0.8);
+//   }
+// }
+.left {
+  display: flex;
+  flex-direction: column;
+  justify-content: center;
+  height: 100%;
+  .input {
+  }
+}
+
+.right {
+  display: flex;
+  align-items: center;
+  .top-img {
+    background: url('@/assets/login/login1.png') no-repeat center 100%/100%;
+    // width: 350px;
+    // height: 210px;
+    // position: absolute;
+    // right: -100px;
+    // top: 20px;
+  }
+  .bg {
+    background: url('@/assets/login/bg.png') no-repeat center 100%/100%;
+  }
+}
+.login-img {
+  background: url('@/assets/login/login2.png') no-repeat center 100%/100%;
+  width: 300.49px;
+  height: 208.5px;
+}
+.login-layout-container {
+  position: relative;
+  display: flex;
+  // flex-direction: column;
+  // align-content: center;
+  // justify-content: center;
+  width: 100vw;
+  height: 100vh;
+  overflow: auto;
+}
+.Wd-login {
+  width: 470px;
+}
+.logo-text {
+  color: #c2cad1;
+}
+
+.form-wrapper-content {
+  -webkit-app-region: no-drag;
+}
+.login-main {
+  // margin: 0 auto;
+  -webkit-app-region: no-drag;
+}
+
+.dark .login-card {
+}
+
+.login-card {
+}
+::v-deep(.el-input) {
+  border: 1px solid rgba(1, 1, 1, 0.3);
+  border-radius: 48px !important;
+}
+</style>

+ 131 - 0
.history/src/pages/login/index_20240805105858.vue

@@ -0,0 +1,131 @@
+<template>
+  <div class="h-screen w-full flex flex-1 flex-col justify-center items-center overflow-hidden">
+    <div class="login-layout-container overflow-hidden">
+      <!-- S LOGO -->
+      <!-- <div class="flex justify-start px-2 fixed" style="top: 32px; left: 36px; cursor: pointer; app-region: no-drag">
+        <div class="logo-text ml-1" style="width: 115px">
+          <img src="@/assets/logo-st.png" class="h-54px" />
+        </div>
+      </div> -->
+      <!-- E LOGO -->
+      <div class="left absolute left-192px p-r-60px">
+        <div class="login-img"></div>
+        <User @login="onLoginClick($event)"></User>
+      </div>
+      <div
+        class="right overflow-hidden absolute right-0 flex flex-1 flex-justify-start h-100% border-0 box-border w-800px border-l border-solid border-l-gray-300"
+      >
+        <div class="top-img w-250px h-130px absolute top-20px right--20px"></div>
+        <div class="bg w-800px h-800px"></div>
+      </div>
+    </div>
+  </div>
+</template>
+
+<route lang="yaml">
+meta:
+  title: 登录
+  layout: false
+</route>
+
+<script lang="ts" setup>
+import { useRouter } from 'vue-router';
+import type { FormInstance } from 'element-plus';
+import { useUserStore } from '@/stores/modules/user';
+import { HOME_URL, ST_CONFIG } from '@/config';
+import User from './components/user.vue';
+
+const router = useRouter();
+const userStore = useUserStore();
+
+const APP_TITLE = ST_CONFIG.APP_TITLE;
+
+const autoLogin = ref(false);
+const loginButLoading = ref(false);
+
+// 登录
+const onLoginClick = async (formEl: FormInstance | undefined) => {
+  console.log(formEl, 'ss');
+
+  if (!formEl) return;
+  loginButLoading.value = true;
+  await formEl.validate(valid => {
+    loginButLoading.value = false;
+    if (valid) {
+      userStore.setToken('st-token');
+      router.push(HOME_URL);
+    }
+  });
+};
+</script>
+
+<style lang="scss" scope>
+// @media screen and (max-width: 1920px) {
+//   login-layout-container {
+//     transform: scale(0.8);
+//   }
+// }
+.left {
+  display: flex;
+  flex-direction: column;
+  justify-content: center;
+  height: 100%;
+  .input {
+  }
+}
+
+.right {
+  display: flex;
+  align-items: center;
+  .top-img {
+    background: url('@/assets/login/login1.png') no-repeat center 100%/100%;
+    // width: 350px;
+    // height: 210px;
+    // position: absolute;
+    // right: -100px;
+    // top: 20px;
+  }
+  .bg {
+    background: url('@/assets/login/bg.png') no-repeat center 100%/100%;
+  }
+}
+.login-img {
+  background: url('@/assets/login/login2.png') no-repeat center 100%/100%;
+  width: 300.49px;
+  height: 208.5px;
+}
+.login-layout-container {
+  position: relative;
+  display: flex;
+  // flex-direction: column;
+  // align-content: center;
+  // justify-content: center;
+  width: 100vw;
+  height: 100vh;
+  overflow: auto;
+}
+.Wd-login {
+  width: 470px;
+}
+.logo-text {
+  color: #c2cad1;
+}
+
+.form-wrapper-content {
+  -webkit-app-region: no-drag;
+}
+.login-main {
+  // margin: 0 auto;
+  -webkit-app-region: no-drag;
+}
+
+.dark .login-card {
+}
+
+.login-card {
+}
+::v-deep(.el-input) {
+  border: 1px solid rgba(1, 1, 1, 0.3);
+  border-radius: 48px !important;
+}
+</style>

+ 284 - 0
.history/src/styles/element_20240805103738.scss

@@ -0,0 +1,284 @@
+/* 设置 notification、message 层级在 loading 之上 */
+.el-message,
+.el-notification {
+  z-index: 2058 !important;
+}
+
+/* el-alert */
+.el-alert {
+  border: 1px solid;
+}
+
+/* 当前页面最大化 css */
+.main-maximize {
+
+  .aside-split,
+  .el-aside,
+  .el-header,
+  .el-footer,
+  .tabs-box {
+    display: none !important;
+  }
+}
+
+/* custom card */
+.card {
+  box-sizing: border-box;
+  padding: 20px;
+  overflow-x: hidden;
+  background-color: var(--el-bg-color);
+  border: 1px solid var(--el-border-color-light);
+  border-radius: 6px;
+  box-shadow: 0 0 12px rgb(0 0 0 / 5%);
+}
+
+/* ProTable 不需要 card 样式(在组件内使用 ProTable 会使用到) */
+.no-card {
+  .card {
+    padding: 0;
+    background-color: transparent;
+    border: none;
+    border-radius: 0;
+    box-shadow: none;
+  }
+
+  .table-search {
+    padding: 18px 0 0 !important;
+    margin-bottom: 0 !important;
+  }
+}
+
+/* content-box (常用内容盒子) */
+.content-box {
+  display: flex;
+  flex-direction: column;
+  align-items: center;
+  height: 100%;
+
+  .text {
+    margin: 20px 0 30px;
+    font-size: 23px;
+    font-weight: bold;
+    color: var(--el-text-color-regular);
+  }
+
+  .el-descriptions {
+    width: 100%;
+    padding: 40px 0 0;
+
+    .el-descriptions__title {
+      font-size: 18px;
+    }
+
+    .el-descriptions__label {
+      width: 200px;
+    }
+  }
+}
+
+/* main-box (树形表格 treeFilter 页面会使用,左右布局 flex) */
+.main-box {
+  display: flex;
+  width: 100%;
+  height: 100%;
+
+  .table-box {
+    // 这里减去的是 treeFilter 组件宽度
+    width: calc(100% - 230px);
+  }
+}
+
+/* proTable */
+.table-box,
+.table-main {
+  display: flex;
+  flex: 1;
+  flex-direction: column;
+  width: 100%;
+  height: 100%;
+
+  // table-search 表格搜索样式
+  .table-search {
+    padding: 18px 18px 0;
+    margin-bottom: 10px;
+
+    .el-form {
+      .el-form-item__content>* {
+        width: 100%;
+      }
+
+      // 去除时间选择器上下 padding
+      .el-range-editor.el-input__wrapper {
+        padding: 0 10px;
+      }
+    }
+
+    .operation {
+      display: flex;
+      align-items: center;
+      justify-content: flex-end;
+      margin-bottom: 18px;
+    }
+  }
+
+  // 表格 header 样式
+  .table-header {
+    .header-button-lf {
+      float: left;
+    }
+
+    .header-button-ri {
+      float: right;
+    }
+
+    .el-button {
+      margin-bottom: 15px;
+    }
+  }
+
+  // el-table 表格样式
+  .el-table {
+    flex: 1;
+
+    // 修复 safari 浏览器表格错位 https://github.com/HalseySpicy/Geeker-Admin/issues/83
+    table {
+      width: 100%;
+    }
+
+    .el-table__header th {
+      height: 45px;
+      font-size: 15px;
+      font-weight: bold;
+      color: var(--el-text-color-primary);
+      background: var(--el-fill-color-light);
+    }
+
+    .el-table__row {
+      height: 45px;
+      font-size: 14px;
+
+      .el-table__placeholder {
+        display: inline;
+      }
+    }
+
+    // 设置 el-table 中 header 文字不换行,并省略
+    .el-table__header .el-table__cell>.cell {
+      white-space: nowrap;
+    }
+
+    // 解决表格数据为空时样式不居中问题(仅在element-plus中)
+    .el-table__empty-block {
+      position: absolute;
+      top: 50%;
+      left: 50%;
+      transform: translate(-50%, -50%);
+
+      .table-empty {
+        line-height: 30px;
+      }
+    }
+
+    // table 中 image 图片样式
+    .table-image {
+      width: 50px;
+      height: 50px;
+      border-radius: 50%;
+    }
+  }
+
+  // 表格 pagination 样式
+  .el-pagination {
+    display: flex;
+    justify-content: flex-end;
+    margin-top: 20px;
+  }
+}
+
+/* el-table 组件大小 */
+.el-table--small {
+  .el-table__header th {
+    height: 40px !important;
+    font-size: 14px !important;
+  }
+
+  .el-table__row {
+    height: 40px !important;
+    font-size: 13px !important;
+  }
+}
+
+.el-table--large {
+  .el-table__header th {
+    height: 50px !important;
+    font-size: 16px !important;
+  }
+
+  .el-table__row {
+    height: 50px !important;
+    font-size: 15px !important;
+  }
+}
+
+/* el-drawer */
+.el-drawer {
+  .el-drawer__header {
+    padding: 16px 20px;
+    margin-bottom: 0;
+    border-bottom: 1px solid var(--el-border-color-lighter);
+
+    span {
+      font-size: 17px;
+      line-height: 17px;
+      color: var(--el-text-color-primary) !important;
+    }
+  }
+
+  .el-drawer__footer {
+    border-top: 1px solid var(--el-border-color-lighter);
+  }
+
+  // select 样式
+  .el-select {
+    width: 100%;
+  }
+
+  // drawer-form 中存在两列 form-item 样式
+  .drawer-multiColumn-form {
+    display: flex;
+    flex-wrap: wrap;
+
+    .el-form-item {
+      width: 47%;
+
+      &:nth-child(2n-1) {
+        margin-right: 5%;
+      }
+    }
+  }
+}
+
+/* el-dialog */
+.el-dialog {
+  padding: 0;
+
+  .el-dialog__header {
+    padding: 12px 20px;
+    margin: 0;
+    border-bottom: 1px solid var(--el-border-color-lighter);
+
+    .el-dialog__title {
+      font-size: 17px;
+    }
+  }
+
+  .el-dialog__body,
+  .el-dialog__footer {
+    padding: 12px 20px;
+  }
+}
+
+/* el-upload */
+.el-upload {
+  --el-upload-picture-card-size: 120px;
+}

+ 298 - 0
.history/src/styles/element_20240805105502.scss

@@ -0,0 +1,298 @@
+/* 设置 notification、message 层级在 loading 之上 */
+.el-message,
+.el-notification {
+  z-index: 2058 !important;
+}
+
+/* el-alert */
+.el-alert {
+  border: 1px solid;
+}
+
+/* 当前页面最大化 css */
+.main-maximize {
+  .aside-split,
+  .el-aside,
+  .el-header,
+  .el-footer,
+  .tabs-box {
+    display: none !important;
+  }
+}
+
+/* custom card */
+.card {
+  box-sizing: border-box;
+  padding: 20px;
+  overflow-x: hidden;
+  background-color: var(--el-bg-color);
+  border: 1px solid var(--el-border-color-light);
+  border-radius: 6px;
+  box-shadow: 0 0 12px rgb(0 0 0 / 5%);
+}
+
+/* ProTable 不需要 card 样式(在组件内使用 ProTable 会使用到) */
+.no-card {
+  .card {
+    padding: 0;
+    background-color: transparent;
+    border: none;
+    border-radius: 0;
+    box-shadow: none;
+  }
+
+  .table-search {
+    padding: 18px 0 0 !important;
+    margin-bottom: 0 !important;
+  }
+}
+//normal button stylea
+.button-normal {
+  display: flex;
+  align-items: center;
+  justify-content: center;
+  padding: 4px;
+  color: white;
+  font-size: 16px;
+  box-sizing: border-box;
+  border-radius: 48px;
+  background-color: #949b85;
+}
+.input-normal .el-input__wrapper {
+  padding: 4px 16px;
+  border-radius: 48px;
+}
+/* content-box (常用内容盒子) */
+.content-box {
+  display: flex;
+  flex-direction: column;
+  align-items: center;
+  height: 100%;
+
+  .text {
+    margin: 20px 0 30px;
+    font-size: 23px;
+    font-weight: bold;
+    color: var(--el-text-color-regular);
+  }
+
+  .el-descriptions {
+    width: 100%;
+    padding: 40px 0 0;
+
+    .el-descriptions__title {
+      font-size: 18px;
+    }
+
+    .el-descriptions__label {
+      width: 200px;
+    }
+  }
+}
+
+/* main-box (树形表格 treeFilter 页面会使用,左右布局 flex) */
+.main-box {
+  display: flex;
+  width: 100%;
+  height: 100%;
+
+  .table-box {
+    // 这里减去的是 treeFilter 组件宽度
+    width: calc(100% - 230px);
+  }
+}
+
+/* proTable */
+.table-box,
+.table-main {
+  display: flex;
+  flex: 1;
+  flex-direction: column;
+  width: 100%;
+  height: 100%;
+
+  // table-search 表格搜索样式
+  .table-search {
+    padding: 18px 18px 0;
+    margin-bottom: 10px;
+
+    .el-form {
+      .el-form-item__content > * {
+        width: 100%;
+      }
+
+      // 去除时间选择器上下 padding
+      .el-range-editor.el-input__wrapper {
+        padding: 0 10px;
+      }
+    }
+
+    .operation {
+      display: flex;
+      align-items: center;
+      justify-content: flex-end;
+      margin-bottom: 18px;
+    }
+  }
+
+  // 表格 header 样式
+  .table-header {
+    .header-button-lf {
+      float: left;
+    }
+
+    .header-button-ri {
+      float: right;
+    }
+
+    .el-button {
+      margin-bottom: 15px;
+    }
+  }
+
+  // el-table 表格样式
+  .el-table {
+    flex: 1;
+
+    // 修复 safari 浏览器表格错位 https://github.com/HalseySpicy/Geeker-Admin/issues/83
+    table {
+      width: 100%;
+    }
+
+    .el-table__header th {
+      height: 45px;
+      font-size: 15px;
+      font-weight: bold;
+      color: var(--el-text-color-primary);
+      background: var(--el-fill-color-light);
+    }
+
+    .el-table__row {
+      height: 45px;
+      font-size: 14px;
+
+      .el-table__placeholder {
+        display: inline;
+      }
+    }
+
+    // 设置 el-table 中 header 文字不换行,并省略
+    .el-table__header .el-table__cell > .cell {
+      white-space: nowrap;
+    }
+
+    // 解决表格数据为空时样式不居中问题(仅在element-plus中)
+    .el-table__empty-block {
+      position: absolute;
+      top: 50%;
+      left: 50%;
+      transform: translate(-50%, -50%);
+
+      .table-empty {
+        line-height: 30px;
+      }
+    }
+
+    // table 中 image 图片样式
+    .table-image {
+      width: 50px;
+      height: 50px;
+      border-radius: 50%;
+    }
+  }
+
+  // 表格 pagination 样式
+  .el-pagination {
+    display: flex;
+    justify-content: flex-end;
+    margin-top: 20px;
+  }
+}
+
+/* el-table 组件大小 */
+.el-table--small {
+  .el-table__header th {
+    height: 40px !important;
+    font-size: 14px !important;
+  }
+
+  .el-table__row {
+    height: 40px !important;
+    font-size: 13px !important;
+  }
+}
+
+.el-table--large {
+  .el-table__header th {
+    height: 50px !important;
+    font-size: 16px !important;
+  }
+
+  .el-table__row {
+    height: 50px !important;
+    font-size: 15px !important;
+  }
+}
+
+/* el-drawer */
+.el-drawer {
+  .el-drawer__header {
+    padding: 16px 20px;
+    margin-bottom: 0;
+    border-bottom: 1px solid var(--el-border-color-lighter);
+
+    span {
+      font-size: 17px;
+      line-height: 17px;
+      color: var(--el-text-color-primary) !important;
+    }
+  }
+
+  .el-drawer__footer {
+    border-top: 1px solid var(--el-border-color-lighter);
+  }
+
+  // select 样式
+  .el-select {
+    width: 100%;
+  }
+
+  // drawer-form 中存在两列 form-item 样式
+  .drawer-multiColumn-form {
+    display: flex;
+    flex-wrap: wrap;
+
+    .el-form-item {
+      width: 47%;
+
+      &:nth-child(2n-1) {
+        margin-right: 5%;
+      }
+    }
+  }
+}
+
+/* el-dialog */
+.el-dialog {
+  padding: 0;
+
+  .el-dialog__header {
+    padding: 12px 20px;
+    margin: 0;
+    border-bottom: 1px solid var(--el-border-color-lighter);
+
+    .el-dialog__title {
+      font-size: 17px;
+    }
+  }
+
+  .el-dialog__body,
+  .el-dialog__footer {
+    padding: 12px 20px;
+  }
+}
+
+/* el-upload */
+.el-upload {
+  --el-upload-picture-card-size: 120px;
+}

BIN
src/assets/login/bg.png


BIN
src/assets/login/login1.png


BIN
src/assets/login/login2.png


+ 54 - 0
src/components/Card/index.vue

@@ -0,0 +1,54 @@
+<!--
+ * @Author: WORK\arche archerspapa@gmail
+ * @Date: 2024-08-01 17:51:32
+ * @LastEditors: WORK\arche archerspapa@gmail
+ * @LastEditTime: 2024-08-02 14:36:25
+ * @FilePath: \af-sub-pc\src\components\Card\index.vue
+ * @Description: 这是默认设置,请设置`customMade`, 打开koroFileHeader查看配置 进行设置: https://github.com/OBKoro1/koro1FileHeader/wiki/%E9%85%8D%E7%BD%AE
+-->
+<template>
+  <div class="border border-1px border-solid rounded-12px overflow-hidden ma-16px border-#E8E5E0">
+    <div class="head bg-#E8E5E0 font-16 font-bold py-12px px-24px">{{ props.title }}</div>
+    <div class="warp">
+      <slot></slot>
+    </div>
+  </div>
+</template>
+
+<script setup lang="ts">
+import { ref, reactive, toRefs, onBeforeMount, onMounted, watchEffect, computed } from 'vue';
+import { useRoute, useRouter } from 'vue-router';
+/**
+ * 仓库
+ * 路由对象
+ */
+const route = useRoute();
+/**
+ * 路由实例
+ */
+const props = defineProps({
+  title: {
+    type: String,
+    default: ''
+  }
+});
+const router = useRouter();
+//console.log('1-开始创建组件-setup')
+/**
+ * 数据部分
+ */
+const data = reactive({});
+onBeforeMount(() => {
+  //console.log('2.组件挂载页面之前执行----onBeforeMount')
+});
+onMounted(() => {
+  //console.log('3.-组件挂载到页面之后执行-------onMounted')
+});
+watchEffect(() => {});
+// 使用toRefs解构
+// let { } = { ...toRefs(data) }
+defineExpose({
+  ...toRefs(data)
+});
+</script>
+<style scoped lang="scss"></style>

+ 0 - 0
src/pages/login/components/code.vue


+ 0 - 0
src/pages/login/components/qrcode.vue


+ 103 - 0
src/pages/login/components/user.vue

@@ -0,0 +1,103 @@
+<!--
+ * @Author: WORK\arche archerspapa@gmail
+ * @Date: 2024-07-31 11:12:28
+ * @LastEditors: WORK\arche archerspapa@gmail
+ * @LastEditTime: 2024-08-05 09:54:02
+ * @FilePath: \af-sub-pc\src\pages\login\mod\user.vue
+ * @Description: 这是默认设置,请设置`customMade`, 打开koroFileHeader查看配置 进行设置: https://github.com/OBKoro1/koro1FileHeader/wiki/%E9%85%8D%E7%BD%AE
+-->
+<template>
+  <div class="form-wrapper-content">
+    <div class="login-main flex input-normal">
+      <el-form ref="formRef" :model="loginForm" :rules="rules" size="large" autocomplete="on">
+        <div v-if="!isFirstLogin">
+          <el-form-item prop="username">
+            <el-input v-model="loginForm.username" placeholder="Please Your Username" class="input"> </el-input>
+          </el-form-item>
+          <el-form-item prop="password">
+            <el-input
+              v-model="loginForm.password"
+              type="password"
+              placeholder="Password"
+              show-password
+              @keyup.enter="onLoginClick(formRef)"
+            >
+            </el-input>
+          </el-form-item>
+        </div>
+
+        <el-form-item>
+          <div v-if="isFirstLogin" class="button-normal w-420px" @click="onLoginClick(formRef)">Login</div>
+          <div v-else class="button-normal w-420px" @click="onSignClick(formRef)">Sign in</div>
+        </el-form-item>
+      </el-form>
+    </div>
+  </div>
+</template>
+
+<script setup lang="ts">
+import { ref, reactive, toRefs, onBeforeMount, onMounted, watchEffect, computed } from 'vue';
+import { useRoute, useRouter } from 'vue-router';
+import type { FormInstance, FormRules } from 'element-plus';
+
+/**
+ * 仓库
+ */
+// 登录表单
+interface RuleForm {
+  username: string;
+  password: string;
+}
+const isFirstLogin = ref(true);
+const formRef = ref<FormInstance>();
+const loginForm = reactive<RuleForm>({
+  username: '',
+  password: ''
+});
+const rules = reactive<FormRules<RuleForm>>({
+  username: [{ required: true, message: 'Please Your Username', trigger: 'blur' }],
+  password: [{ required: true, message: 'Please Your Password', trigger: 'blur' }]
+});
+/**
+ * 路由对象
+ */
+const emit = defineEmits(['login']);
+const onLoginClick = () => {
+  isFirstLogin.value = false;
+};
+const onSignClick = () => {
+  emit('login', formRef.value);
+};
+const route = useRoute();
+/**
+ * 路由实例
+ */
+const router = useRouter();
+//console.log('1-开始创建组件-setup')
+/**f
+ * 数据部分
+ */
+const data = reactive({});
+onBeforeMount(() => {
+  //console.log('2.组件挂载页面之前执行----onBeforeMount')
+});
+onMounted(() => {
+  //console.log('3.-组件挂载到页面之后执行-------onMounted')
+});
+watchEffect(() => {});
+// 使用toRefs解构
+// let { } = { ...toRefs(data) }
+defineExpose({
+  ...toRefs(data)
+});
+</script>
+<style scoped lang="scss">
+// @keyframes logChange {
+//   0% {
+//     transform: translateY(-50%, -50%);
+//   }
+//   100% {
+//     transform: translateY(0, 0);
+//   }
+// }
+</style>

+ 60 - 87
src/pages/login/index.vue

@@ -1,6 +1,6 @@
 <template>
   <div class="h-screen w-full flex flex-1 flex-col justify-center items-center overflow-hidden">
-    <div class="login-layout-container bg-[#fff] dark:bg-[#101014]">
+    <div class="login-layout-container overflow-hidden">
       <!-- S LOGO -->
       <!-- <div class="flex justify-start px-2 fixed" style="top: 32px; left: 36px; cursor: pointer; app-region: no-drag">
         <div class="logo-text ml-1" style="width: 115px">
@@ -8,54 +8,15 @@
         </div>
       </div> -->
       <!-- E LOGO -->
-      <div class="form-wrapper-content">
-        <div class="login-main flex flex-col items-center justify-center px-6">
-          <el-card class="w-440px login-card" body-style="padding: 48px;">
-            <div class="flex justify-center mt-16px">
-              <h3 class="text-3xl app-text-fg-high mt-0 mb-24px" style="align-self: flex-start; font-weight: 500">
-                欢迎使用 {{ APP_TITLE }}
-              </h3>
-            </div>
-            <el-form ref="formRef" :model="loginForm" :rules="rules" size="large" autocomplete="on">
-              <el-form-item prop="username">
-                <el-input v-model="loginForm.username" placeholder="请输入账号">
-                  <template #prefix>
-                    <el-icon class="el-input__icon">
-                      <nova-i-people theme="outline" size="24" />
-                    </el-icon>
-                  </template>
-                </el-input>
-              </el-form-item>
-              <el-form-item prop="password">
-                <el-input
-                  v-model="loginForm.password"
-                  type="password"
-                  placeholder="请输入密码"
-                  show-password
-                  @keyup.enter="onLoginClick(formRef)"
-                >
-                  <template #prefix>
-                    <el-icon class="el-input__icon">
-                      <nova-i-lock theme="outline" size="24" />
-                    </el-icon>
-                  </template>
-                </el-input>
-              </el-form-item>
-              <el-form-item>
-                <div class="flex justify-between">
-                  <div class="flex-initial">
-                    <el-checkbox v-model="autoLogin">自动登录</el-checkbox>
-                  </div>
-                </div>
-              </el-form-item>
-              <el-form-item>
-                <el-button type="primary" :loading="loginButLoading" class="w-full" @click="onLoginClick(formRef)">
-                  登录
-                </el-button>
-              </el-form-item>
-            </el-form>
-          </el-card>
-        </div>
+      <div class="left absolute left-192px p-r-60px">
+        <div class="login-img"></div>
+        <User @login="onLoginClick($event)"></User>
+      </div>
+      <div
+        class="right overflow-hidden absolute right-0 flex flex-1 flex-justify-start h-100% border-0 box-border w-800px border-l border-solid border-l-gray-300"
+      >
+        <div class="top-img w-250px h-130px absolute top-20px right--20px"></div>
+        <div class="bg w-800px h-800px"></div>
       </div>
     </div>
   </div>
@@ -69,41 +30,29 @@ meta:
 
 <script lang="ts" setup>
 import { useRouter } from 'vue-router';
-import type { FormInstance, FormRules } from 'element-plus';
+import type { FormInstance } from 'element-plus';
 import { useUserStore } from '@/stores/modules/user';
 import { HOME_URL, ST_CONFIG } from '@/config';
-
-interface RuleForm {
-  username: string;
-  password: string;
-}
+import User from './components/user.vue';
 
 const router = useRouter();
 const userStore = useUserStore();
 
 const APP_TITLE = ST_CONFIG.APP_TITLE;
 
-// 登录表单
-const formRef = ref<FormInstance>();
-const loginForm = reactive<RuleForm>({
-  username: '',
-  password: ''
-});
-const rules = reactive<FormRules<RuleForm>>({
-  username: [{ required: true, message: '请输入账号', trigger: 'blur' }],
-  password: [{ required: true, message: '请输入密码', trigger: 'blur' }]
-});
 const autoLogin = ref(false);
 const loginButLoading = ref(false);
 
 // 登录
 const onLoginClick = async (formEl: FormInstance | undefined) => {
+  console.log(formEl, 'ss');
+
   if (!formEl) return;
   loginButLoading.value = true;
   await formEl.validate(valid => {
     loginButLoading.value = false;
     if (valid) {
-      userStore.setToken('nova-token');
+      userStore.setToken('st-token');
       router.push(HOME_URL);
     }
   });
@@ -111,21 +60,53 @@ const onLoginClick = async (formEl: FormInstance | undefined) => {
 </script>
 
 <style lang="scss" scope>
-.login-layout-container {
-  position: relative;
+// @media screen and (max-width: 1920px) {
+//   login-layout-container {
+//     transform: scale(0.8);
+//   }
+// }
+.left {
   display: flex;
   flex-direction: column;
-  align-content: center;
   justify-content: center;
+  height: 100%;
+  .input {
+  }
+}
+
+.right {
+  display: flex;
+  align-items: center;
+  .top-img {
+    background: url('@/assets/login/login1.png') no-repeat center 100%/100%;
+    // width: 350px;
+    // height: 210px;
+    // position: absolute;
+    // right: -100px;
+    // top: 20px;
+  }
+  .bg {
+    background: url('@/assets/login/bg.png') no-repeat center 100%/100%;
+  }
+}
+.login-img {
+  background: url('@/assets/login/login2.png') no-repeat center 100%/100%;
+  width: 300.49px;
+  height: 208.5px;
+}
+.login-layout-container {
+  position: relative;
+  display: flex;
+  // flex-direction: column;
+  // align-content: center;
+  // justify-content: center;
   width: 100vw;
   height: 100vh;
   overflow: auto;
-  background-image: url('@/assets/images/bg.svg');
-  background-size: cover;
-  background-position: center center;
-  background-repeat: no-repeat;
 }
-
+.Wd-login {
+  width: 470px;
+}
 .logo-text {
   color: #c2cad1;
 }
@@ -134,25 +115,17 @@ const onLoginClick = async (formEl: FormInstance | undefined) => {
   -webkit-app-region: no-drag;
 }
 .login-main {
-  margin: 0 auto;
+  // margin: 0 auto;
   -webkit-app-region: no-drag;
 }
 
 .dark .login-card {
-  border: 1px solid #272835;
-  box-shadow:
-    rgba(22, 14, 45, 0.02) 0px 0px 40px,
-    rgba(22, 14, 45, 0.06) 0px 0px 104px !important;
-  border-radius: 8px;
-  background: #191a23;
 }
 
 .login-card {
-  border: 1px solid #eaecf0;
-  box-shadow:
-    rgba(22, 14, 45, 0.02) 0px 0px 40px,
-    rgba(22, 14, 45, 0.06) 0px 0px 104px !important;
-  border-radius: 8px;
-  background: #fff;
+}
+::v-deep(.el-input) {
+  border: 1px solid rgba(1, 1, 1, 0.3);
+  border-radius: 48px !important;
 }
 </style>

+ 18 - 4
src/styles/element.scss

@@ -11,7 +11,6 @@
 
 /* 当前页面最大化 css */
 .main-maximize {
-
   .aside-split,
   .el-aside,
   .el-header,
@@ -47,7 +46,22 @@
     margin-bottom: 0 !important;
   }
 }
-
+//normal button stylea
+.button-normal {
+  display: flex;
+  align-items: center;
+  justify-content: center;
+  padding: 4px;
+  color: white;
+  font-size: 16px;
+  box-sizing: border-box;
+  border-radius: 48px;
+  background-color: #949b85;
+}
+.input-normal .el-input__wrapper {
+  padding: 4px 16px;
+  border-radius: 48px;
+}
 /* content-box (常用内容盒子) */
 .content-box {
   display: flex;
@@ -103,7 +117,7 @@
     margin-bottom: 10px;
 
     .el-form {
-      .el-form-item__content>* {
+      .el-form-item__content > * {
         width: 100%;
       }
 
@@ -163,7 +177,7 @@
     }
 
     // 设置 el-table 中 header 文字不换行,并省略
-    .el-table__header .el-table__cell>.cell {
+    .el-table__header .el-table__cell > .cell {
       white-space: nowrap;
     }
 

+ 1 - 0
src/types/components.d.ts

@@ -7,6 +7,7 @@ export {}
 
 declare module 'vue' {
   export interface GlobalComponents {
+    Card: typeof import('./../components/Card/index.vue')['default']
     RouterLink: typeof import('vue-router')['RouterLink']
     RouterView: typeof import('vue-router')['RouterView']
   }