stylus 语法换成 saas 语法

This commit is contained in:
GeekMaster
2025-08-01 17:32:06 +08:00
parent 068b5ddeef
commit 54f8494b5c
145 changed files with 8445 additions and 8446 deletions

View File

@@ -78,8 +78,9 @@ console.log(
) )
</script> </script>
<style lang="stylus"> <style lang="scss">
html, body { html,
body {
margin: 0; margin: 0;
padding: 0; padding: 0;
} }
@@ -87,33 +88,45 @@ html, body {
#app { #app {
margin: 0 !important; margin: 0 !important;
padding: 0 !important; padding: 0 !important;
font-family: Helvetica Neue, Helvetica, PingFang SC, Hiragino Sans GB, Microsoft YaHei, Arial, sans-serif font-family: Helvetica Neue, Helvetica, PingFang SC, Hiragino Sans GB, Microsoft YaHei, Arial,
sans-serif;
-webkit-font-smoothing: antialiased; -webkit-font-smoothing: antialiased;
text-rendering: optimizeLegibility; text-rendering: optimizeLegibility;
// --primary-color: #21aa93 // --primary-color: #21aa93
h1 { font-size: 2em; } /* 通常是 2em */ h1 {
h2 { font-size: 1.5em; } /* 通常是 1.5em */ font-size: 2em;
h3 { font-size: 1.17em; } /* 通常是 1.17em */ } /* 通常是 2em */
h4 { font-size: 1em; } /* 通常是 1em */ h2 {
h5 { font-size: 0.83em; } /* 通常是 0.83em */ font-size: 1.5em;
h6 { font-size: 0.67em; } /* 通常是 0.67em */ } /* 通常是 1.5em */
h3 {
font-size: 1.17em;
} /* 通常是 1.17em */
h4 {
font-size: 1em;
} /* 通常是 1em */
h5 {
font-size: 0.83em;
} /* 通常是 0.83em */
h6 {
font-size: 0.67em;
} /* 通常是 0.67em */
} }
.el-overlay-dialog { .el-overlay-dialog {
display flex display: flex;
justify-content center justify-content: center;
align-items center align-items: center;
overflow hidden overflow: hidden;
.el-dialog { .el-dialog {
margin 0; margin: 0;
.el-dialog__body { .el-dialog__body {
//max-height 80vh //max-height 80vh
overflow-y auto overflow-y: auto;
} }
} }
} }
@@ -122,7 +135,7 @@ html, body {
/* 设置内边距以保证高度为32px */ /* 设置内边距以保证高度为32px */
padding: 6px 12px; padding: 6px 12px;
background: linear-gradient(180deg, #e1bee7, #7e57c2); background: linear-gradient(180deg, #e1bee7, #7e57c2);
color #fff color: #fff;
} }
.el-popper.is-customized .el-popper__arrow::before { .el-popper.is-customized .el-popper__arrow::before {
@@ -138,12 +151,12 @@ html, body {
} }
.van-toast--fail { .van-toast--fail {
background #fef0f0 background: #fef0f0;
color #f56c6c color: #f56c6c;
} }
.van-toast--success { .van-toast--success {
background #D6FBCC background: #d6fbcc;
color #07C160 color: #07c160;
} }
</style> </style>

View File

@@ -0,0 +1,73 @@
.form {
.el-form-item__label {
.label-title {
display: flex;
align-items: center;
.el-icon {
margin-left: 5px;
cursor: pointer;
}
}
}
.el-form-item__content {
width: 100%;
.uploader-icon {
font-size: 24px;
position: relative;
top: 3px;
}
.tip-input-line {
.tip {
margin-top: 10px;
color: #c1c1c1;
font-size: 12px;
line-height: 1.5;
}
}
}
.el-input {
width: 100%;
}
.text {
font-size: 14px;
}
.active-info {
line-height: 1.5;
padding: 10px 0 30px 0;
}
.el-descriptions {
margin-bottom: 20px;
.el-icon {
font-size: 18px;
}
.selected {
color: #0bc15f;
}
.closed {
color: #da0d54;
}
.text {
margin-left: 10px;
font-size: 12px;
color: #999999;
position: relative;
top: -5px;
}
}
.el-alert {
margin-bottom: 15px;
}
}

View File

@@ -1,74 +0,0 @@
.form {
.el-form-item__label {
.label-title {
display flex
align-items center
.el-icon {
margin-left 5px
cursor pointer
}
}
}
.el-form-item__content {
width 100%
.uploader-icon {
font-size 24px
position relative
top 3px
}
.tip-input-line {
.tip {
margin-top 10px
color #c1c1c1
font-size 12px;
line-height 1.5;
}
}
}
.el-input {
width 100%
}
.text {
font-size 14px
}
.active-info {
line-height 1.5
padding 10px 0 30px 0
}
.el-descriptions {
margin-bottom 20px
.el-icon {
font-size 18px
}
.selected {
color #0bc15f
}
.closed {
color #da0d54
}
.text {
margin-left 10px
font-size 12px
color #999999
position: relative;
top -5px
}
}
.el-alert {
margin-bottom 15px;
}
}

View File

@@ -0,0 +1,137 @@
.page-apps {
// background-color: #282c34;
height: 100%;
.apps-type-nav {
height: 50px;
padding: 8px 0;
margin: 10px auto;
}
.scrollbar-type-nav {
display: flex;
align-items: center;
padding: 2px;
background-color: #f4f1f7;
width: fit-content;
border: 1px solid rgba(79, 89, 102, 0.078);
border-radius: 20px;
margin: 0 auto;
// background: var(--chat-bg);
// width: 100%;
li {
flex-shrink: 0;
display: flex;
align-items: center;
justify-content: center;
margin: 5px 8px;
height: 26px;
border-radius: 4px;
// border: 1px solid rgb(80, 80, 80);
padding: 2px 12px;
// background: rgba(60, 60, 60, 0.9);
color: var(--theme-text-tertiary);
font-weight: bold;
font-size: 14px;
cursor: pointer;
.image {
width: 22px;
height: 22px;
overflow: hidden;
margin-right: 5px;
border-radius: 50%;
}
&.active {
background: #fff;
color: var(--el-color-primary);
border-radius: 20px;
}
}
}
.app-list-container {
display: flex;
color: #ffffff;
padding: 2px 15px;
overflow-y: visible;
overflow-x: hidden;
.item__list-box {
.item {
display: flex;
flex-flow: row;
// border: 1px solid rgb(80, 80, 80);
padding: 10px;
background: var(--chat-bg);
border-radius: 8px;
.image {
width: 80px;
height: 80px;
min-width: 80px;
border-radius: 50%;
overflow: hidden;
object-fit: contain;
display: flex;
align-items: center;
justify-content: center;
flex-shrink: 0;
border: 2px solid #f5f7fd;
background: #fff;
}
.inner {
display: flex;
flex-flow: column;
padding: 0 0 0 10px;
width: 100%;
.info {
text-align: left;
.info-title {
color: var(--text-theme-color);
font-size: 1.25rem;
line-height: 1.75rem;
letter-spacing: 0.025em;
font-weight: 600;
word-break: break-all;
overflow: hidden;
display: -webkit-box;
-webkit-box-orient: vertical;
-webkit-line-clamp: 1;
}
.info-text {
padding: 8px 0;
overflow: hidden;
display: -webkit-box;
-webkit-box-orient: vertical;
-webkit-line-clamp: 2;
word-break: break-all;
height: 50px;
font-size: 0.875rem;
color: var(--text-fb);
}
}
.btn {
margin-top: 10px;
display: flex;
justify-content: right;
.el-button {
margin-left: 10px;
.el-icon {
margin-right: 5px;
}
}
}
}
}
}
}
}

View File

@@ -1,142 +0,0 @@
.page-apps {
// background-color: #282c34;
height 100%
.apps-type-nav{
height 50px
padding 8px 0;
margin 10px auto
}
.scrollbar-type-nav{
display flex
align-items center
padding 2px
background-color #f4f1f7
width fit-content
border 1px solid rgba(79,89,102,.078)
border-radius: 20px
margin: 0 auto
// background: var(--chat-bg);
// width 100%
li{
flex-shrink 0
display flex
align-items center
justify-content center
margin 5px 8px
height 26px
border-radius 4px
// border 1px solid rgb(80,80,80)
padding 2px 12px
// background rgba(60,60,60 0.9)
color var(--theme-text-tertiary)
font-weight: bold
font-size 14px
cursor pointer
.image {
width 22px
height 22px
overflow hidden
margin-right 5px
border-radius 50%
}
&.active{
background #fff;
color: var(--el-color-primary);
border-radius 20px
}
}
}
.app-list-container {
display flex
color #ffffff
padding 2px 15px;
overflow-y visible
overflow-x hidden
.item__list-box {
.item {
display flex
flex-flow row
// border 1px solid rgb(80,80,80)
padding 10px
background: var(--chat-bg);
border-radius 8px
.image {
width 80px
height 80px
min-width 80px
border-radius 50%
overflow hidden
object-fit: contain
display: flex
align-items center
justify-content center
flex-shrink 0
border: 2px solid #f5f7fd
background: #fff
}
.inner {
display flex
flex-flow column
padding 0 0 0 10px
width 100%
.info {
text-align left
.info-title {
color: var(--text-theme-color)
font-size 1.25rem
line-height 1.75rem
letter-spacing: .025em;
font-weight: 600;
word-break: break-all;
overflow: hidden;
display: -webkit-box;
-webkit-box-orient: vertical;
-webkit-line-clamp: 1;
}
.info-text {
padding 8px 0
overflow: hidden;
display: -webkit-box;
-webkit-box-orient: vertical;
-webkit-line-clamp: 2;
word-break: break-all;
height 50px
font-size: .875rem;
color var(--text-fb)
}
}
.btn {
margin-top 10px
display flex
justify-content right
.el-button {
margin-left 10px
.el-icon {
margin-right 5px
}
}
}
}
}
}
}
}

View File

@@ -1,49 +1,47 @@
#app { #app {
height: 100%; height: 100%;
.chat-page { .chat-page {
height: 100%; height: 100%;
:deep(.el-message-box__message){ :deep(.el-message-box__message) {
font-size: 18px !important font-size: 18px !important;
} }
.newChat{ .newChat {
margin-bottom: 10px margin-bottom: 10px;
} }
// left side // left side
.el-container{ .el-container {
height: 100%; height: 100%;
} }
.el-aside { .el-aside {
padding 10px padding: 10px;
width var(--el-aside-width, 320px) width: var(--el-aside-width, 320px);
.chat-list-container { .chat-list-container {
display: flex display: flex;
flex-flow: column flex-flow: column;
border-radius 10px border-radius: 10px;
padding 10px 0 padding: 10px 0;
.search-box { .search-box {
flex-wrap: wrap flex-wrap: wrap;
margin-bottom: 10px margin-bottom: 10px;
} }
.content { .content {
width: 100% width: 100%;
overflow-y: scroll overflow-y: scroll;
.chat-list-item { .chat-list-item {
display: flex display: flex;
width: 100% width: 100%;
justify-content: flex-start justify-content: flex-start;
padding: 8px 12px padding: 8px 12px;
//border: 1px solid #3c3c3c // border: 1px solid #3c3c3c;
cursor: pointer cursor: pointer;
border: 1px solid var(--theme-bg-color) border: 1px solid var(--theme-bg-color);
margin-bottom 6px margin-bottom: 6px;
border-radius 5px border-radius: 5px;
&:hover { &:hover {
border: 1px solid var(--border-active); border: 1px solid var(--border-active);
@@ -68,48 +66,45 @@
.chat-title { .chat-title {
color: var(--el-text-color-regular); color: var(--el-text-color-regular);
padding: 5px 10px; padding: 5px 10px;
max-width 220px; max-width: 220px;
font-size 14px; font-size: 14px;
overflow: hidden; overflow: hidden;
white-space: nowrap; white-space: nowrap;
text-overflow: ellipsis; text-overflow: ellipsis;
} }
.chat-opt { .chat-opt {
position: absolute; position: absolute;
right: 2px; right: 2px;
top: 16px; top: 16px;
color var(--text-fb) color: var(--text-fb);
.el-dropdown-link { .el-dropdown-link {
color var(--text-fb) color: var(--text-fb);
} }
.el-icon { .el-icon {
margin-right 8px; margin-right: 8px;
} }
} }
} }
.chat-list-item.active { .chat-list-item.active {
background-color :var(--theme-bg); background-color: var(--theme-bg);
box-shadow: 0 3px 9px rgba(112, 144, 176, 0.12); box-shadow: 0 3px 9px rgba(112, 144, 176, 0.12);
border: 1px solid var(--border-active); border: 1px solid var(--border-active);
} }
} }
} }
.tool-box { .tool-box {
display: flex; display: flex;
justify-content: center; justify-content: center;
padding-top 12px padding-top: 12px;
// border-top 0.5px solid var(--el-border-color); // border-top: 0.5px solid var(--el-border-color);
.iconfont { .iconfont {
margin-right 5px margin-right: 5px;
} }
} }
} }
@@ -122,53 +117,53 @@
.chat-container { .chat-container {
min-width: 0; min-width: 0;
flex: 1; flex: 1;
background-color: var(--chat-bg) background-color: var(--chat-bg);
color var(--text-fb) color: var(--text-fb);
.chat-config { .chat-config {
height 50px height: 50px;
padding 10px 30px padding: 10px 30px;
display flex display: flex;
justify-content center justify-content: center;
justify-items center justify-items: center;
// border-bottom 1px solid var(--el-border-color); // border-bottom: 1px solid var(--el-border-color);
.role-select-label { .role-select-label {
color #ffffff color: #ffffff;
} }
.el-select { .el-select {
max-width 150px; max-width: 150px;
margin-right 10px; margin-right: 10px;
} }
.role-select { .role-select {
max-width 130px; max-width: 130px;
} }
.setting { .setting {
// padding 5px // padding: 5px;
border-radius 5px border-radius: 5px;
cursor pointer cursor: pointer;
width: 26px; width: 26px;
height: 26px; height: 26px;
text-align: center; text-align: center;
line-height: 26px; line-height: 26px;
// background-color #f2f2f2 // background-color: #f2f2f2;
// margin-right 10px // margin-right: 10px;
.iconfont { .iconfont {
font-size 16px font-size: 16px;
color var(--el-color-primary) color: var(--el-color-primary);
} }
&:hover { &:hover {
background-color var(--text--hover) background-color: var(--text--hover);
} }
} }
.el-button { .el-button {
.el-icon { .el-icon {
margin-right 5px; margin-right: 5px;
} }
} }
} }
@@ -176,11 +171,11 @@
#container { #container {
overflow: hidden; overflow: hidden;
width: 100%; width: 100%;
position relative position: relative;
background: var(--chat-bg) background: var(--chat-bg);
display: flex; display: flex;
justify-content: center; justify-content: center;
padding 0 20px padding: 0 20px;
max-width: 960px; max-width: 960px;
.chat-box { .chat-box {
@@ -190,7 +185,7 @@
--content-color: #c1c1c1; --content-color: #c1c1c1;
font-family: 'Microsoft YaHei', '微软雅黑', Arial, sans-serif; font-family: 'Microsoft YaHei', '微软雅黑', Arial, sans-serif;
//padding: 0 0 50px 0; // padding: 0 0 50px 0;
width: 100%; width: 100%;
.chat-line { .chat-line {
@@ -201,33 +196,33 @@
} }
.input-box { .input-box {
position absolute position: absolute;
bottom 0 bottom: 0;
width 100% width: 100%;
max-width: 800px; max-width: 800px;
.input-box-inner { .input-box-inner {
display flex display: flex;
background-color:var(--chat-bg); background-color: var(--chat-bg);
justify-content: center; justify-content: center;
align-items: center; align-items: center;
// box-shadow: 0 2px 15px rgba(0, 0, 0, 0.1); // box-shadow: 0 2px 15px rgba(0, 0, 0, 0.1);
padding 0 15px; padding: 0 15px;
.tool-item { .tool-item {
margin-right 15px margin-right: 15px;
border-radius: 6px; border-radius: 6px;
color: #19c37d; color: #19c37d;
display flex display: flex;
justify-content center justify-content: center;
justify-items center justify-items: center;
padding 6px padding: 6px;
cursor pointer cursor: pointer;
// background #F2F2F2 // background: #f2f2f2;
&:hover { &:hover {
background #D5FAD3 background: #d5fad3;
} }
.iconfont { .iconfont {
@@ -236,44 +231,44 @@
} }
.input-body { .input-body {
width 100% width: 100%;
margin: 0; margin: 0;
border: none; border: none;
padding: 10px 0; padding: 10px 0;
display flex display: flex;
justify-content center justify-content: center;
position relative position: relative;
.hide-div { .hide-div {
white-space: pre-wrap; /* 保持文本换行 */ white-space: pre-wrap; /* 保持文本换行 */
visibility: hidden; /* 隐藏 div */ visibility: hidden; /* 隐藏 div */
position: absolute; /* 脱离文档流 */ position: absolute; /* 脱离文档流 */
line-height: 24px line-height: 24px;
font-size 14px font-size: 14px;
word-wrap: break-word; /* 允许单词换行 */ word-wrap: break-word; /* 允许单词换行 */
overflow-wrap: break-word; /* 允许长单词换行,适用于现代浏览器 */ overflow-wrap: break-word; /* 允许长单词换行,适用于现代浏览器 */
} }
.input-border { .input-border {
// display flex // display: flex;
width 100% width: 100%;
overflow hidden overflow: hidden;
border: 2px solid var( --theme-border-primary) border: 2px solid var(--theme-border-primary);
border-radius 10px border-radius: 10px;
padding 10px padding: 10px;
// background-color #F4F4F4 // background-color: #f4f4f4;
&:hover{ &:hover {
border-color var(--theme-border-hover) border-color: var(--theme-border-hover);
} }
.input-inner { .input-inner {
display flex display: flex;
flex-flow column flex-flow: column;
width 100% width: 100%;
.file-list { .file-list {
padding-bottom 10px padding-bottom: 10px;
} }
.prompt-input::-webkit-scrollbar { .prompt-input::-webkit-scrollbar {
width: 0; width: 0;
@@ -282,56 +277,53 @@
.prompt-input { .prompt-input {
min-height: 58px; min-height: 58px;
width 100% width: 100%;
line-height: 24px line-height: 24px;
border none border: none;
font-size 14px font-size: 14px;
background none background: none;
resize: none resize: none;
white-space: pre-wrap; /* 保持文本换行 */ white-space: pre-wrap; /* 保持文本换行 */
word-wrap: break-word; /* 允许单词换行 */ word-wrap: break-word; /* 允许单词换行 */
overflow-wrap: break-word; /* 允许长单词换行,适用于现代浏览器 */ overflow-wrap: break-word; /* 允许长单词换行,适用于现代浏览器 */
} }
} }
.send-btn { .send-btn {
width 32px width: 32px;
margin-left 10px margin-left: 10px;
.el-button { .el-button {
padding 8px 5px; padding: 8px 5px;
border-radius 6px; border-radius: 6px;
font-size 20px; font-size: 20px;
} }
} }
.little-btns{ .little-btns {
display: flex; display: flex;
justify-content: flex-end; justify-content: flex-end;
align-items: center; align-items: center;
gap: 8px; gap: 8px;
.iconfont{ .iconfont {
font-size: 19px; font-size: 19px;
cursor pointer cursor: pointer;
background-color: var(--chat-content-bg); background-color: var(--chat-content-bg);
padding: 5px; padding: 5px;
border-radius: 6px; border-radius: 6px;
} }
} }
.add-new{ .add-new {
.el-icon{ .el-icon {
font-size: 20px; font-size: 20px;
color: #754ff6; color: #754ff6;
} }
cursor:pointer cursor: pointer;
} }
} }
} }
} }
} }
} }
} }
@@ -352,66 +344,65 @@
.el-select-dropdown__wrap { .el-select-dropdown__wrap {
.el-select-dropdown__item { .el-select-dropdown__item {
.role-option { .role-option {
display flex display: flex;
flex-flow row flex-flow: row;
margin-top 8px; margin-top: 8px;
.el-image { .el-image {
width 20px width: 20px;
height 20px height: 20px;
border-radius 50% border-radius: 50%;
} }
span { span {
margin-left 5px; margin-left: 5px;
height 20px; height: 20px;
line-height 20px; line-height: 20px;
} }
} }
} }
} }
.account { .account {
display flex display: flex;
background-color #90FFC2 background-color: #90ffc2;
color #000000 color: #000000;
width 100% width: 100%;
border-radius 10px border-radius: 10px;
padding 10px padding: 10px;
.vip-logo { .vip-logo {
.el-image { .el-image {
width 40px width: 40px;
height 40px height: 40px;
border-radius 100% border-radius: 100%;
background-color:var(--chat-content-bg); background-color: var(--chat-content-bg);
color:var(--theme-text-color-primary); color: var(--theme-text-color-primary);
} }
} }
.vip-info { .vip-info {
padding: 0 10px 0 10px padding: 0 10px 0 10px;
h4, p { h4, p {
margin 0 margin: 0;
} }
h4 { h4 {
font-weight bold font-weight: bold;
font-size 16px; font-size: 16px;
} }
p { p {
color #333333 color: #333333;
} }
} }
.pay-btn { .pay-btn {
width 100% width: 100%;
display flex display: flex;
justify-content right justify-content: right;
align-items center align-items: center;
} }
} }
@@ -419,31 +410,29 @@
.el-dialog { .el-dialog {
.el-dialog__body { .el-dialog__body {
.notice { .notice {
line-height 1.8 line-height: 1.8;
font-size 16px font-size: 16px;
overflow auto overflow: auto;
height: 70vh height: 70vh;
} }
} }
.dialog-footer{ .dialog-footer {
margin-right: 22px; margin-right: 22px;
} }
} }
} }
.dialog-service { .dialog-service {
text-align center text-align: center;
.el-image { .el-image {
width 360px; width: 360px;
} }
} }
.tools-dropdown { .tools-dropdown {
width auto width: auto;
.el-icon { .el-icon {
margin-left 5px; margin-left: 5px;
} }
} }

View File

@@ -49,36 +49,36 @@
--el-bg-color-page: #0a0a0a; --el-bg-color-page: #0a0a0a;
--el-bg-color: #141414; --el-bg-color: #141414;
--el-bg-color-overlay: #1d1e1f; --el-bg-color-overlay: #1d1e1f;
--el-text-color-primary: #E5EAF3; --el-text-color-primary: #e5eaf3;
--el-text-color-regular: #CFD3DC; --el-text-color-regular: #cfd3dc;
--el-text-color-secondary: #A3A6AD; --el-text-color-secondary: #a3a6ad;
--el-text-color-placeholder: #8D9095; --el-text-color-placeholder: #8d9095;
--el-text-color-disabled: #6C6E72; --el-text-color-disabled: #6c6e72;
--el-border-color-darker: #636466; --el-border-color-darker: #636466;
--el-border-color-dark: #58585B; --el-border-color-dark: #58585b;
--el-border-color: #4C4D4F; --el-border-color: #4c4d4f;
--el-border-color-light: #414243; --el-border-color-light: #414243;
--el-border-color-lighter: #363637; --el-border-color-lighter: #363637;
--el-border-color-extra-light: #2B2B2C; --el-border-color-extra-light: #2b2b2c;
--el-fill-color-darker: #424243; --el-fill-color-darker: #424243;
--el-fill-color-dark: #39393A; --el-fill-color-dark: #39393a;
--el-fill-color: #303030; --el-fill-color: #303030;
--el-fill-color-light: #262727; --el-fill-color-light: #262727;
--el-fill-color-lighter: #1D1D1D; --el-fill-color-lighter: #1d1d1d;
--el-fill-color-extra-light: #191919; --el-fill-color-extra-light: #191919;
--el-fill-color-blank: transparent; --el-fill-color-blank: transparent;
--el-mask-color: rgba(0, 0, 0, 0.8); --el-mask-color: rgba(0, 0, 0, 0.8);
--el-mask-color-extra-light: rgba(0, 0, 0, 0.3) --el-mask-color-extra-light: rgba(0, 0, 0, 0.3);
--el-menu-bg-color-dark: #39393A --el-menu-bg-color-dark: #39393a;
--el-menu-bg-color-darker: #424243 --el-menu-bg-color-darker: #424243;
} }
.dark .el-button { .dark .el-button {
--el-button-disabled-text-color: rgba(255, 255, 255, 0.5) --el-button-disabled-text-color: rgba(255, 255, 255, 0.5);
} }
.dark .el-card { .dark .el-card {
--el-card-bg-color: var(--el-bg-color-overlay) --el-card-bg-color: var(--el-bg-color-overlay);
} }
.dark .el-empty { .dark .el-empty {
@@ -91,5 +91,5 @@
--el-empty-fill-color-6: #212224; --el-empty-fill-color-6: #212224;
--el-empty-fill-color-7: #1b1c1f; --el-empty-fill-color-7: #1b1c1f;
--el-empty-fill-color-8: #1c1d1f; --el-empty-fill-color-8: #1c1d1f;
--el-empty-fill-color-9: #18181a --el-empty-fill-color-9: #18181a;
} }

View File

@@ -0,0 +1,151 @@
:root {
--sm-txt: rgba(163, 174, 208, 1);
--text-secondary: #8a939d;
--el-color-primary: rgb(107, 80, 225);
--van-primary-color: rgb(107, 80, 225);
--theme-textcolor-normal: #b0a0f8;
--el-border-radius-base: 5px;
--el-color-primary-light-5: rgb(107, 85, 255);
--el-color-primary-light-3: rgb(78, 51, 254);
--theme-btn-color: rgba(117, 81, 255, 1);
--common-text-color: #6e4ef9;
--el-component-size: 36px;
--el-color-primary-dark-2: rgb(169 152 247);
--el-button-active-border-color: rgb(169 152 247);
--el-color-success-light-9: #eafffc;
--el-color-success-light-8: #a7f0d9;
--el-message-text-color: #0ecd8b;
--el-color-success: #0ecd8b;
--text-fff: #fff;
--theme-border-primary: rgba(86, 86, 95, 0.322); //主题边框颜色
--theme-border-hover: rgb(107, 85, 255); //主题边框hover颜色
--text--hover: rgba(215, 211, 240, 0.581); //主题色hover色系
--el-input-focus-border-color: #b0a0f8;
--little-btn-bg: #e9d3f6;
--gray-btn-bg: #ededf591;
// --a-link-color: #3561ff
--a-link-color: #6e8eff;
--shadow-color: rgba(223, 71, 255, 0.6);
--sm-btn-bg: #6052ed;
--theme-text-tertiary: #595959;
--theme-btn-fill-tertiary: #f0ebff;
--theme-text-btn-tertiary: #6841ea;
// #e7e7e8
}
.el-dialog {
//--el-border-radius-base: calc(var(--el-component-size) / 2);
--el-dialog-border-radius: 10px;
}
.login-box {
--el-component-size: 48px;
}
.btn-go {
background: var(--btnColor);
color: #fff;
border-radius: 5px;
padding: 5px 10px;
&:hover {
color: #fff;
}
}
.btn-normal {
background: var(--theme-btn-color);
color: #fff;
border-radius: 5px;
padding: 5px 10px;
&:hover {
color: #fff;
}
}
.flex {
display: flex;
align-items: center;
}
.flex-center {
display: flex;
align-items: center;
justify-content: center;
}
.flex-between {
display: flex;
align-items: center;
justify-content: space-between;
}
.theme-color-primary {
color: var(--el-color-primary);
}
.text-color-primary {
color: var(--text-color-primary);
}
.w100 {
width: 100%;
}
.el-input__wrapper {
background: var(--card-bg);
}
.el-dialog__title {
font-weight: bold;
line-height: 28px;
}
.el-button--primary {
border-radius: 5px;
}
.el-button {
height: auto;
}
/* 设置滚动条的宽度 */
::-webkit-scrollbar {
width: 12px; /* 垂直滚动条宽度 */
height: 12px; /* 水平滚动条高度 */
}
/* 滚动条的轨道背景颜色 */
::-webkit-scrollbar-track {
background: #f1f1f1 !important; /* 滚动条轨道颜色 */
border-radius: 6px; /* 可选:轨道圆角 */
}
/* 滚动条滑块的颜色 */
::-webkit-scrollbar-thumb {
background: #888 !important; /* 滑块颜色 */
border-radius: 6px; /* 可选:滑块圆角 */
}
/* 鼠标悬停在滑块上的颜色 */
::-webkit-scrollbar-thumb:hover {
background: #555; /* 悬停时的滑块颜色 */
}
//.el-message-box
.el-message-box {
--el-messagebox-border-radius: 10px;
--el-messagebox-padding-primary: 24px;
}
.el-message-box__container {
//border-top: 1px solid #dbd3f4;
padding-top: 7px;
.el-message-box__message {
--text-color: var(--theme-text-color-primary);
font-size: 16px;
}
}
.sm-btn-theme {
background-color: var(--theme-btn-fill-tertiary) !important;
color: var(--theme-text-btn-tertiary) !important;
border: none;
}
.el-tag, .el-tag.el-tag--primary {
--el-tag-bg-color: #f0ebff;
}
.box-card {
padding: 20px;
background-color: var(--chat-bg);
border-radius: 8px;
}
.el-table th.el-table__cell {
background-color: var(--chat-bg);
}

View File

@@ -1,154 +0,0 @@
:root{
--sm-txt:rgba(163, 174, 208, 1);
--text-secondary: #8a939d;
--el-color-primary: rgb(107, 80, 225);
--van-primary-color:rgb(107, 80, 225);
--theme-textcolor-normal:#b0a0f8;
--el-border-radius-base: 5px;
--el-color-primary-light-5:rgb(107, 85, 255);
--el-color-primary-light-3:rgb(78, 51, 254);
--theme-btn-color:rgba(117, 81, 255, 1)
--common-text-color:#6e4ef9;
--el-component-size: 36px;
--el-color-primary-dark-2:rgb(169 152 247);
--el-button-active-border-color:rgb(169 152 247);
--el-color-success-light-9:#EAFFFC;
--el-color-success-light-8:#A7F0D9;
--el-message-text-color:#0ECD8B;
--el-color-success:#0ECD8B;
--text-fff:#fff
--theme-border-primary: rgba(86, 86, 95, .322); //
--theme-border-hover: rgb(107, 85, 255);//hover
--text--hover:rgba(215, 211, 240, 0.581) //hover
--el-input-focus-border-color: #b0a0f8;
--little-btn-bg:#e9d3f6;
--gray-btn-bg:#ededf591;
// --a-link-color: #3561ff
--a-link-color: #6e8eff
--shadow-color:rgba(223,71,255,0.6)
--sm-btn-bg:#6052ed;
--theme-text-tertiary: #595959;
--theme-btn-fill-tertiary: #f0ebff;
--theme-text-btn-tertiary: #6841ea;
// #e7e7e8
}
.el-dialog{
//--el-border-radius-base: calc(var(--el-component-size) / 2);
--el-dialog-border-radius: 10px
}
.login-box{
--el-component-size: 48px;
}
.btn-go{
background: var(--btnColor);
color: #fff;
border-radius: 5px;
padding: 5px 10px;
&:hover{
color: #fff;
}
}
.btn-normal{
background: var(--theme-btn-color);
color: #fff;
border-radius: 5px;
padding: 5px 10px;
&:hover{
color: #fff;
}
}
.flex{
display: flex;
align-items: center;
}
.flex-center{
display: flex;
align-items: center;
justify-content: center;
}
.flex-between{
display: flex;
align-items: center;
justify-content: space-between;
}
.theme-color-primary{
color: var(--el-color-primary);
}
.text-color-primary{
color:var(--text-color-primary)
}
.w100{
width: 100%;
}
.el-input__wrapper{
background: var( --card-bg)
}
.el-dialog__title{
font-weight: bold;
line-height: 28px;
}
.el-button--primary{
border-radius: 5px;
}
.el-button {
height auto
}
/* */
::-webkit-scrollbar {
width: 12px; /* */
height: 12px; /* */
}
/* */
::-webkit-scrollbar-track {
background: #f1f1f1 !important; /* */
border-radius: 6px; /* */
}
/* */
::-webkit-scrollbar-thumb {
background: #888 !important; /* */
border-radius: 6px; /* */
}
/* */
::-webkit-scrollbar-thumb:hover {
background: #555; /* */
}
//.el-message-box
.el-message-box{
--el-messagebox-border-radius: 10px
--el-messagebox-padding-primary: 24px
}
.el-message-box__container{
//border-top: 1px solid #dbd3f4;
padding-top: 7px;
.el-message-box__message{
--text-color:var(--theme-text-color-primary)
font-size: 16px
}
}
.sm-btn-theme{
background-color: var(--theme-btn-fill-tertiary) !important;
color: var(--theme-text-btn-tertiary) !important;
border: none;
}
.el-tag, .el-tag.el-tag--primary{
--el-tag-bg-color:#f0ebff
}
.box-card{
padding: 20px;
background-color: var(--chat-bg);
border-radius: 8px;
}
.el-table th.el-table__cell {
background-color: var(--chat-bg)
}

View File

@@ -8,14 +8,14 @@
/* 修改滚动条轨道的背景颜色 */ /* 修改滚动条轨道的背景颜色 */
::-webkit-scrollbar-track { ::-webkit-scrollbar-track {
background-color: #282C34; background-color: #282c34;
} }
/* 修改滚动条的滑块颜色 */ /* 修改滚动条的滑块颜色 */
::-webkit-scrollbar-thumb { ::-webkit-scrollbar-thumb {
background-color: #444444; background-color: #444444;
border-radius 8px border-radius: 8px;
} }
/* 修改滚动条的滑块的悬停颜色 */ /* 修改滚动条的滑块的悬停颜色 */

View File

@@ -10,8 +10,8 @@
font-weight: normal; font-weight: normal;
font-style: normal; font-style: normal;
} }
$font-regular = "OPlusSans3-Regular", "PingFangSC-Regular", "Roboto", "sans-serif"; $font-regular: "OPlusSans3-Regular", "PingFangSC-Regular", "Roboto", "sans-serif";
$font-medium = "OPlusSans3-Medium", "PingFangSC-Medium", "Roboto", "sans-serif"; $font-medium: "OPlusSans3-Medium", "PingFangSC-Medium", "Roboto", "sans-serif";
.font-regular { .font-regular {
font-family: $font-regular; font-family: $font-regular;

View File

@@ -8,64 +8,61 @@
} }
.top-collapse { .top-collapse {
padding-top: 10px padding-top: 10px;
img { img {
width 24px !important width: 24px !important;
height: 24px !important height: 24px !important;
} }
} }
.tab-box { .tab-box {
align-items: center align-items: center;
background-color: var(--card-bg) background-color: var(--card-bg);
border-right: 1px solid var(--line-box); border-right: 1px solid var(--line-box);
// height: 100% // height: 100%;
// position: fixed; // position: fixed;
height: 100vh; height: 100vh;
.title { .title {
font-size: 28px font-size: 28px;
height: 40px height: 40px;
width 120px width: 120px;
text-align: center; text-align: center;
word-wrap break-all; word-wrap: break-all;
overflow hidden overflow: hidden;
font-weight: 700 font-weight: 700;
color: var(--text-theme-color) color: var(--text-theme-color);
} }
img { img {
height: 44px height: 44px;
object-fit: cover object-fit: cover;
border-radius: 50% border-radius: 50%;
border: 2px solid #754ff6; border: 2px solid #754ff6;
background: #fff background: #fff;
} }
.marr { .marr {
margin-right: 4px; margin-right: 4px;
} }
} }
} }
.flex-center-col { .flex-center-col {
display flex display: flex;
align-items center align-items: center;
flex-direction column flex-direction: column;
.iconfont { .iconfont {
font-size 24px font-size: 24px;
cursor pointer cursor: pointer;
color var(--text-color) color: var(--text-color);
} }
.icon-new-chat { .icon-new-chat {
color #ffffff color: #ffffff;
} }
} }
.menu-list-collapse { .menu-list-collapse {
@@ -74,20 +71,17 @@
} }
.menu-list-item { .menu-list-item {
height: 38px; height: 38px;
line-height: 38px; line-height: 38px;
.iconfont { .iconfont {
font-size 16px font-size: 16px;
} }
} }
.menu-list-item:hover, .menu-list-item:hover,
.active { .active {
background: rgba(79, 89, 102, .122); background: rgba(79, 89, 102, 0.122);
border-radius: 8px; border-radius: 8px;
.el-icon { .el-icon {
@@ -120,9 +114,8 @@
&:hover { &:hover {
.el-icon { .el-icon {
background: rgba(79, 89, 102, .122); background: rgba(79, 89, 102, 0.122);
} }
} }
.el-icon { .el-icon {
@@ -138,37 +131,31 @@
color: var(--text-theme-color); color: var(--text-theme-color);
font-weight: 700; font-weight: 700;
} }
} }
.bot { .bot {
position: absolute; position: absolute;
bottom: 6px; bottom: 6px;
width 65px; width: 65px;
} }
.bot-line { .bot-line {
width: 100%; width: 100%;
height: 1px; height: 1px;
background: var(--line-box) background: var(--line-box);
margin: 20px 0 10px 0; margin: 20px 0 10px 0;
} }
.menu-title { .menu-title {
font-size: 12px; font-size: 12px;
margin-bottom: 6px; margin-bottom: 6px;
} }
.icon-house, .icon-house,
.icon-github { .icon-github {
font-size: 20px; font-size: 20px;
color: #754ff6; color: #754ff6;
cursor pointer cursor: pointer;
} }
.menu-bot-item { .menu-bot-item {
@@ -199,7 +186,7 @@
right: 8px; right: 8px;
z-index: 999; z-index: 999;
top: 0; top: 0;
// width 100%; // width: 100%;
align-items: center; align-items: center;
justify-content: flex-end; justify-content: flex-end;
} }
@@ -210,7 +197,6 @@
} }
} }
.el-popper { .el-popper {
.more-menus { .more-menus {
li { li {
@@ -222,9 +208,9 @@
line-height: 38px; line-height: 38px;
.el-image { .el-image {
position: relative position: relative;
top 5px top: 5px;
right 5px right: 5px;
} }
&:hover { &:hover {
@@ -244,8 +230,8 @@
.el-icon, .el-icon,
.iconfont { .iconfont {
font-size: 18px font-size: 18px;
margin-right: 6px margin-right: 6px;
} }
color: var(--text-theme-color); color: var(--text-theme-color);
} }
@@ -256,15 +242,12 @@
overflow: hidden; overflow: hidden;
-webkit-line-clamp: 1; -webkit-line-clamp: 1;
} }
} }
.rightHeightMax { .rightHeightMax {
height: 100vh; height: 100vh;
max-height: 100vh; max-height: 100vh;
overflow: hidden; overflow: hidden;
} }
.rightHeight { .rightHeight {

View File

@@ -5,25 +5,24 @@
display: flex; display: flex;
.sd-box { .sd-box {
margin 10px margin: 10px;
// background-color #262626 // background-color: #262626;
// border 1px solid #454545 // border: 1px solid #454545;
min-width 300px min-width: 300px;
max-width 300px max-width: 300px;
padding 10px padding: 10px;
border-radius 10px border-radius: 10px;
color var(--text-theme-color); color: var(--text-theme-color);
font-size 14px font-size: 14px;
h2 { h2 {
font-weight: bold; font-weight: bold;
font-size 20px font-size: 20px;
text-align center text-align: center;
color#b0a0f8 color: #b0a0f8;
} }
// 隐藏滚动条 // 隐藏滚动条
::-webkit-scrollbar { ::-webkit-scrollbar {
width: 0; width: 0;
height: 0; height: 0;
@@ -31,59 +30,55 @@
} }
.sd-params { .sd-params {
margin-top 10px margin-top: 10px;
overflow auto overflow: auto;
.param-line { .param-line {
padding 0 10px padding: 0 10px;
.grid-content .grid-content,
.form-item-inner { .form-item-inner {
display flex display: flex;
.info-icon { .info-icon {
margin-left 10px margin-left: 10px;
position relative position: relative;
top 8px top: 8px;
} }
} }
} }
.param-line.pt { .param-line.pt {
padding-top 5px padding-top: 5px;
padding-bottom 5px padding-bottom: 5px;
} }
.text-info { .text-info {
padding 10px padding: 10px;
} }
} }
.submit-btn { .submit-btn {
padding 10px 15px 0 15px padding: 10px 15px 0 15px;
text-align center text-align: center;
.el-button { .el-button {
width 200px width: 200px;
} }
} }
} }
.el-form { .el-form {
.el-form-item__label { .el-form-item__label {
color var(--text-theme-color) color: var(--text-theme-color);
} }
} }
.task-list-box { .task-list-box {
background: var(--chat-bg); background: var(--chat-bg);
width 100% width: 100%;
color var(--text-theme-color) color: var(--text-theme-color);
overflow-x hidden overflow-x: hidden;
.task-list-inner { .task-list-inner {
.el-tabs { .el-tabs {
@@ -96,16 +91,16 @@
} }
.title-tabs .el-tabs__item.is-active { .title-tabs .el-tabs__item.is-active {
color:#b0a0f8; color: #b0a0f8;
font-size: 18px; font-size: 18px;
} }
.title-tabs .el-tabs__active-bar { .title-tabs .el-tabs__active-bar {
background-color:#b0a0f8; background-color: #b0a0f8;
} }
.el-textarea { .el-textarea {
// --el-input-focus-border-color:#b0a0f8; // --el-input-focus-border-color: #b0a0f8;
} }
.el-textarea__inner { .el-textarea__inner {
@@ -115,37 +110,36 @@
.el-input__wrapper { .el-input__wrapper {
background: transparent; background: transparent;
padding 5px padding: 5px;
} }
.text { .text {
margin-bottom: 10px; margin-bottom: 10px;
color: #6b778c; color: #6b778c;
font-size: 15px font-size: 15px;
} }
.param-line.pt { .param-line.pt {
padding-top 5px padding-top: 5px;
padding-bottom 5px padding-bottom: 5px;
} }
.form-item-inner { .form-item-inner {
display flex display: flex;
align-items: center align-items: center;
.el-icon { .el-icon {
margin-left 10px margin-left: 10px;
} }
} }
.el-form-item__label { .el-form-item__label {
color var(--text-theme-color) color: var(--text-theme-color);
} }
// 图片上传样式 // 图片上传样式
.img-inline { .img-inline {
display flex display: flex;
.img-uploader { .img-uploader {
.el-upload { .el-upload {
@@ -154,7 +148,7 @@
cursor: pointer; cursor: pointer;
position: relative; position: relative;
overflow: hidden; overflow: hidden;
width 120px; width: 120px;
transition: var(--el-transition-duration-fast); transition: var(--el-transition-duration-fast);
margin-bottom: 20px; margin-bottom: 20px;
@@ -163,71 +157,67 @@
} }
.el-icon.uploader-icon { .el-icon.uploader-icon {
font-size: 28px font-size: 28px;
color: #8c939d color: #8c939d;
width 100% width: 100%;
height: 120px height: 120px;
text-align: center text-align: center;
} }
} }
} }
.img-list-box { .img-list-box {
display flex display: flex;
.img-item { .img-item {
width 120px width: 120px;
position relative position: relative;
margin-right 10px margin-right: 10px;
.el-image { .el-image {
width 120px width: 120px;
height 120px height: 120px;
border-radius 5px border-radius: 5px;
} }
.el-button { .el-button {
position absolute position: absolute;
right 5px right: 5px;
top 5px top: 5px;
width 20px width: 20px;
height 20px height: 20px;
} }
} }
} }
} }
.el-row.text-info { .el-row.text-info {
width 100% width: 100%;
padding 10px 0 padding: 10px 0;
.el-tag { .el-tag {
margin-right 10px margin-right: 10px;
} }
} }
// 提交按钮 // 提交按钮
.submit-btn { .submit-btn {
display flex display: flex;
margin: 20px 0 margin: 20px 0;
.el-button { .el-button {
width 200px width: 200px;
} }
} }
// 任务列表 // 任务列表
@import "waterfall-list.styl" @import 'waterfall-list.scss';
} }
.no-more-data { .no-more-data {
text-align center text-align: center;
padding 30px padding: 30px;
} }
} }
} }
} }

View File

@@ -0,0 +1,488 @@
.page-mj {
// background-color: #282c34;
height: 100%;
.inner {
display: flex;
// height: 100%;
.mj-box {
margin: 10px;
// background-color: #262626;
// border: 1px solid #454545;
// height: calc(100vh - 50px);
// overflow: scroll;
min-width: 300px;
max-width: 300px;
padding: 10px;
border-radius: 10px;
color: var(--text-theme-color);
font-size: 14px;
overflow: auto;
h2 {
font-weight: bold;
font-size: 20px;
text-align: center;
color: var(--theme-textcolor-normal);
}
// 隐藏滚动条
::-webkit-scrollbar {
width: 0;
height: 0;
background-color: transparent;
}
.mj-params {
margin-top: 10px;
overflow: auto;
.param-line {
padding: 0 10px;
.el-icon {
position: relative;
}
.grid-content {
// background-color: #383838;
background: var(--card-bg);
border-radius: 8px;
padding: 8px 14px;
display: flex;
cursor: pointer;
margin-bottom: 10px;
// border: 1px solid #383838;
border: 1px solid var(--chat-bg);
&:hover {
border: 1px solid var(--theme-border-hover);
}
.icon {
width: 20px;
height: 20px;
margin-bottom: 5px;
}
.text {
margin-left: 5px;
margin-top: 2px;
}
}
.grid-content.active {
// color: #47fff1;
// background-color: #585858;
border: 1px solid var(--theme-border-hover);
}
.model {
background: var(--card-bg);
// border: 1px solid #454545;
border-radius: 8px;
padding: 5px;
margin-bottom: 10px;
display: flex;
flex-flow: column;
align-items: center;
cursor: pointer;
border: 1px solid var(--chat-bg);
&:hover {
border: 1px solid var(--theme-border-hover);
}
.el-image {
height: 40px;
width: 100%;
}
.text {
margin-top: 4px;
font-size: 12px;
}
}
.model.active {
// color: #47fff1;
// background-color: #585858;
border: 1px solid var(--theme-border-hover);
}
.form-item-inner {
display: flex;
align-items: center;
.el-select {
--el-select-input-focus-border-color: var(--el-color-primary);
--el-input-focus-border-color: var(--el-color-primary);
}
.el-input__wrapper {
background: var(--chat-bg);
}
.el-input__inner {
color: var(--text-theme-color);
}
.el-icon {
margin-left: 10px;
}
}
.img-uploader {
.el-upload {
border: 1px dashed var(--el-border-color);
border-radius: 6px;
cursor: pointer;
position: relative;
overflow: hidden;
width: 100%;
transition: var(--el-transition-duration-fast);
&:hover {
border-color: var(--el-color-primary);
}
.el-icon.uploader-icon {
font-size: 28px;
color: #8c939d;
width: 100%;
height: 120px;
text-align: center;
}
}
}
}
.param-line.pt {
display: flex;
align-items: center;
padding-top: 5px;
padding-bottom: 5px;
}
}
}
.el-form {
.el-form-item__label {
color: var(--text-theme-color);
}
.el-input,
.el-slider {
width: 180px;
}
.uploader-icon {
font-size: 24px;
position: relative;
top: 3px;
}
}
.task-list-box {
background: var(--chat-bg);
width: 100%;
// padding: 0 10px 10px 10px;
color: var(--text-theme-color);
overflow-x: hidden;
.task-list-inner {
.el-tabs {
--el-tabs-header-height: 55px;
}
.el-tabs__item {
color: var(--text-theme-color);
font-size: 18px;
}
.title-tabs .el-tabs__item.is-active {
color: var(--theme-textcolor-normal);
font-size: 18px;
}
.title-tabs .el-tabs__active-bar {
background-color: var(--theme-textcolor-normal);
}
.el-textarea {
--el-input-focus-border-color: var(--el-color-primary);
}
.el-textarea__inner {
background: transparent;
color: var(--text-theme-color);
}
.el-input__wrapper {
background: transparent;
padding: 5px;
}
.text {
margin-bottom: 10px;
color: #6b778c;
font-size: 15px;
}
.param-line.pt {
padding-top: 5px;
padding-bottom: 5px;
}
.form-item-inner {
display: flex;
align-items: center;
.el-icon {
margin-left: 10px;
}
}
.el-form-item__label {
color: var(--text-theme-color);
}
// 图片上传样式
.img-inline {
display: flex;
.img-uploader {
.el-upload {
border: 1px dashed var(--el-border-color);
border-radius: 6px;
cursor: pointer;
position: relative;
overflow: hidden;
width: 120px;
transition: var(--el-transition-duration-fast);
margin-bottom: 20px;
&:hover {
border-color: var(--el-color-primary);
}
.el-icon.uploader-icon {
font-size: 28px;
color: #8c939d;
width: 100%;
height: 120px;
text-align: center;
}
}
}
.img-list-box {
display: flex;
.img-item {
width: 120px;
position: relative;
margin-right: 10px;
.el-image {
width: 120px;
height: 120px;
border-radius: 5px;
}
.el-button {
position: absolute;
right: 5px;
top: 5px;
width: 20px;
height: 20px;
}
}
}
}
.el-row.text-info {
width: 100%;
padding: 10px 0;
.el-tag {
margin-right: 10px;
}
}
// 提交按钮
.submit-btn {
display: flex;
margin: 20px 0;
.el-button {
width: 200px;
}
}
.job-list-box {
// 任务列表
@import 'running-job-list.scss';
.finish-job-list {
#waterfall {
display: flex;
justify-content: center;
padding-top: 20px;
flex-flow: column;
.waterfall-item {
overflow: visible;
.job-item {
width: 100%;
height: 100%;
border: 1px solid #666666;
padding: 6px;
border-radius: 6px;
// position: relative;
.el-image {
overflow: auto;
}
.opt {
padding-top: 5px;
.opt-line {
margin: 6px 0;
ul {
display: flex;
flex-flow: row;
li {
margin-right: 6px;
a {
padding: 3px 0;
width: 40px;
text-align: center;
border-radius: 5px;
display: block;
cursor: pointer;
background-color: #4e5058;
color: #fff;
&:hover {
background-color: #6d6f78;
}
}
}
.show-prompt {
font-size: 20px;
cursor: pointer;
}
}
}
}
.remove {
display: none;
position: absolute;
right: 10px;
top: 10px;
}
&:hover {
.remove {
display: block;
}
}
}
}
}
}
.el-image {
width: 100%;
height: 100%;
overflow: visible;
.el-image-viewer__wrapper {
img {
width: auto;
height: auto;
}
}
.image-slot {
display: flex;
flex-flow: column;
justify-content: center;
align-items: center;
min-height: 220px;
color: var(--text-theme-color);
overflow: hidden;
.err-msg-container {
overflow: hidden;
word-break: break-all;
padding: 15px;
.title {
font-size: 20px;
text-align: center;
font-weight: bold;
color: #f56c6c;
margin-bottom: 30px;
}
.opt {
display: flex;
justify-content: center;
}
}
.iconfont {
font-size: 50px;
margin-bottom: 10px;
}
}
}
.el-image.upscale {
img {
// height: 310px;
}
.image-slot {
min-height: 310px;
}
.el-image-viewer__wrapper {
img {
width: auto;
height: auto;
}
}
}
}
}
.no-more-data {
text-align: center;
padding: 30px;
}
}
.generate-btn {
.iconfont {
margin-right: 5px;
}
}
}
}
.mj-list-item-prompt {
.el-icon {
margin-left: 10px;
cursor: pointer;
position: relative;
}
}

View File

@@ -1,503 +0,0 @@
.page-mj {
// background-color: #282c34;
height 100%
.inner {
display: flex;
// height: 100%
.mj-box {
margin 10px
// background-color #262626
// border 1px solid #454545
// height: calc(100vh - 50px)
// overflow: scroll
min-width 300px
max-width 300px
padding 10px
border-radius 10px
color var(--text-theme-color);
font-size 14px
overflow auto
h2 {
font-weight: bold;
font-size 20px
text-align center
color var( --theme-textcolor-normal)
}
//
::-webkit-scrollbar {
width: 0;
height: 0;
background-color: transparent;
}
.mj-params {
margin-top 10px
overflow auto
.param-line {
padding 0 10px
.el-icon {
position relative
}
.grid-content {
// background-color #383838
background: var(--card-bg);
border-radius: 8px;
padding 8px 14px
display flex
cursor pointer
margin-bottom: 10px;
// border 1px solid #383838
border 1px solid var(--chat-bg)
&:hover {
border 1px solid var(--theme-border-hover)
}
.icon {
width 20px
height 20px
margin-bottom 5px
}
.text {
margin-left 5px
margin-top 2px
}
}
.grid-content.active {
// color #47fff1
// background-color #585858
border 1px solid var(--theme-border-hover)
}
.model {
background: var(--card-bg);
// border 1px solid #454545
border-radius 8px
padding 5px
margin-bottom 10px
display flex
flex-flow column
align-items center
cursor pointer
border 1px solid var(--chat-bg)
&:hover {
border 1px solid var(--theme-border-hover)
}
.el-image {
height 40px
width 100%
}
.text {
margin-top 4px
font-size 12px
}
}
.model.active {
// color #47fff1
// background-color #585858
border 1px solid var(--theme-border-hover)
}
.form-item-inner {
display flex
align-items: center
.el-select {
--el-select-input-focus-border-color: var(--el-color-primary)
--el-input-focus-border-color: var(--el-color-primary)
}
.el-input__wrapper {
background: var(--chat-bg)
}
.el-input__inner {
color: var(--text-theme-color)
}
.el-icon {
margin-left 10px
}
}
.img-uploader {
.el-upload {
border: 1px dashed var(--el-border-color);
border-radius: 6px;
cursor: pointer;
position: relative;
overflow: hidden;
width 100%
transition: var(--el-transition-duration-fast);
&:hover {
border-color: var(--el-color-primary);
}
.el-icon.uploader-icon {
font-size: 28px
color: #8c939d
width 100%
height: 120px
text-align: center
}
}
}
}
.param-line.pt {
display: flex
align-items: center
padding-top 5px
padding-bottom 5px
}
}
}
.el-form {
.el-form-item__label {
color var(--text-theme-color)
}
.el-input, .el-slider {
width 180px
}
.uploader-icon {
font-size 24px
position relative
top 3px
}
}
.task-list-box {
background: var(--chat-bg);
width 100%
//padding 0 10px 10px 10px
color var(--text-theme-color)
overflow-x hidden
.task-list-inner {
.el-tabs {
--el-tabs-header-height: 55px;
}
.el-tabs__item {
color: var(--text-theme-color);
font-size: 18px;
}
.title-tabs .el-tabs__item.is-active {
color: var( --theme-textcolor-normal);
font-size: 18px;
}
.title-tabs .el-tabs__active-bar {
background-color: var( --theme-textcolor-normal);
}
.el-textarea {
--el-input-focus-border-color: var(--el-color-primary)
}
.el-textarea__inner {
background: transparent;
color: var(--text-theme-color);
}
.el-input__wrapper {
background: transparent;
padding 5px
}
.text {
margin-bottom: 10px;
color: #6b778c;
font-size: 15px
}
.param-line.pt {
padding-top 5px
padding-bottom 5px
}
.form-item-inner {
display flex
align-items: center
.el-icon {
margin-left 10px
}
}
.el-form-item__label {
color var(--text-theme-color)
}
//
.img-inline {
display flex
.img-uploader {
.el-upload {
border: 1px dashed var(--el-border-color);
border-radius: 6px;
cursor: pointer;
position: relative;
overflow: hidden;
width 120px;
transition: var(--el-transition-duration-fast);
margin-bottom: 20px;
&:hover {
border-color: var(--el-color-primary);
}
.el-icon.uploader-icon {
font-size: 28px
color: #8c939d
width 100%
height: 120px
text-align: center
}
}
}
.img-list-box {
display flex
.img-item {
width 120px
position relative
margin-right 10px
.el-image {
width 120px
height 120px
border-radius 5px
}
.el-button {
position absolute
right 5px
top 5px
width 20px
height 20px
}
}
}
}
.el-row.text-info {
width 100%
padding 10px 0
.el-tag {
margin-right 10px
}
}
//
.submit-btn {
display flex
margin: 20px 0
.el-button {
width 200px
}
}
.job-list-box {
//
@import "running-job-list.styl"
.finish-job-list {
#waterfall {
display flex
justify-content center
padding-top 20px
flex-flow column
.waterfall-item {
overflow visible
.job-item {
width 100%
height 100%
border 1px solid #666666
padding 6px
border-radius 6px
//position relative
.el-image {
overflow auto
}
.opt {
padding-top 5px
.opt-line {
margin 6px 0
ul {
display flex
flex-flow row
li {
margin-right 6px
a {
padding 3px 0
width 40px
text-align center
border-radius 5px
display block
cursor pointer
background-color #4E5058
color #fff
&:hover {
background-color #6D6F78
}
}
}
.show-prompt {
font-size 20px
cursor pointer
}
}
}
}
.remove {
display none
position absolute
right 10px
top 10px
}
&:hover {
.remove {
display block
}
}
}
}
}
}
.el-image {
width 100%
height 100%
overflow visible
.el-image-viewer__wrapper {
img {
width auto
height auto
}
}
.image-slot {
display flex
flex-flow column
justify-content center
align-items center
min-height 220px
color var(--text-theme-color)
overflow hidden
.err-msg-container {
overflow hidden
word-break break-all
padding 15px
.title {
font-size 20px
text-align center
font-weight bold
color #f56c6c
margin-bottom 30px
}
.opt {
display flex
justify-content center
}
}
.iconfont {
font-size 50px
margin-bottom 10px
}
}
}
.el-image.upscale {
img {
//height 310px
}
.image-slot {
min-height 310px
}
.el-image-viewer__wrapper {
img {
width auto
height auto
}
}
}
}
}
.no-more-data {
text-align center
padding 30px
}
}
.generate-btn {
.iconfont {
margin-right 5px
}
}
}
}
.mj-list-item-prompt {
.el-icon {
margin-left 10px
cursor pointer
position relative
}
}

View File

@@ -5,27 +5,25 @@
display: flex; display: flex;
.sd-box { .sd-box {
margin 10px margin: 10px;
// background-color #262626 // background-color: #262626;
// border 1px solid #454545 // border: 1px solid #454545;
min-width 300px min-width: 300px;
max-width 300px max-width: 300px;
padding 10px 10px 20px 10px padding: 10px 10px 20px 10px;
border-radius 10px border-radius: 10px;
color var(--text-theme-color); color: var(--text-theme-color);
font-size 14px font-size: 14px;
overflow auto overflow: auto;
h2 { h2 {
font-weight: bold; font-weight: bold;
font-size 20px font-size: 20px;
text-align center text-align: center;
color var( --theme-textcolor-normal) color: var(--theme-textcolor-normal);
} }
// 隐藏滚动条 // 隐藏滚动条
::-webkit-scrollbar { ::-webkit-scrollbar {
width: 0; width: 0;
height: 0; height: 0;
@@ -33,59 +31,55 @@
} }
.sd-params { .sd-params {
margin-top 10px margin-top: 10px;
overflow auto overflow: auto;
.param-line { .param-line {
padding 0 10px padding: 0 10px;
.grid-content .grid-content,
.form-item-inner { .form-item-inner {
display flex display: flex;
.info-icon { .info-icon {
margin-left 10px margin-left: 10px;
position relative position: relative;
top 8px top: 8px;
} }
} }
} }
.param-line.pt { .param-line.pt {
padding-top 5px padding-top: 5px;
padding-bottom 5px padding-bottom: 5px;
} }
.text-info { .text-info {
padding 10px padding: 10px;
} }
} }
.submit-btn { .submit-btn {
padding 10px 15px 0 15px padding: 10px 15px 0 15px;
text-align center text-align: center;
.el-button { .el-button {
width 200px width: 200px;
} }
} }
} }
.el-form { .el-form {
.el-form-item__label { .el-form-item__label {
color: var(--text-theme-color) color: var(--text-theme-color);
} }
} }
.task-list-box { .task-list-box {
background: var(--chat-bg); background: var(--chat-bg);
width 100% width: 100%;
color: var(--text-theme-color) color: var(--text-theme-color);
overflow-x hidden overflow-x: hidden;
.task-list-inner { .task-list-inner {
.el-tabs { .el-tabs {
@@ -98,12 +92,12 @@
} }
.title-tabs .el-tabs__item.is-active { .title-tabs .el-tabs__item.is-active {
color: #47FFF1; color: #47fff1;
font-size: 18px; font-size: 18px;
} }
.title-tabs .el-tabs__active-bar { .title-tabs .el-tabs__active-bar {
background-color: #47FFF1; background-color: #47fff1;
} }
.el-textarea { .el-textarea {
@@ -117,37 +111,36 @@
.el-input__wrapper { .el-input__wrapper {
background: transparent; background: transparent;
padding 5px padding: 5px;
} }
.text { .text {
margin-bottom: 10px; margin-bottom: 10px;
color: #6b778c; color: #6b778c;
font-size: 15px font-size: 15px;
} }
.param-line.pt { .param-line.pt {
padding-top 5px padding-top: 5px;
padding-bottom 5px padding-bottom: 5px;
} }
.form-item-inner { .form-item-inner {
display flex display: flex;
align-items: center align-items: center;
.el-icon { .el-icon {
margin-left 10px margin-left: 10px;
} }
} }
.el-form-item__label { .el-form-item__label {
color: var(--text-theme-color) color: var(--text-theme-color);
} }
// 图片上传样式 // 图片上传样式
.img-inline { .img-inline {
display flex display: flex;
.img-uploader { .img-uploader {
.el-upload { .el-upload {
@@ -156,7 +149,7 @@
cursor: pointer; cursor: pointer;
position: relative; position: relative;
overflow: hidden; overflow: hidden;
width 120px; width: 120px;
transition: var(--el-transition-duration-fast); transition: var(--el-transition-duration-fast);
margin-bottom: 20px; margin-bottom: 20px;
@@ -165,82 +158,78 @@
} }
.el-icon.uploader-icon { .el-icon.uploader-icon {
font-size: 28px font-size: 28px;
color: #8c939d color: #8c939d;
width 100% width: 100%;
height: 120px height: 120px;
text-align: center text-align: center;
} }
} }
} }
.img-list-box { .img-list-box {
display flex display: flex;
.img-item { .img-item {
width 120px width: 120px;
position relative position: relative;
margin-right 10px margin-right: 10px;
.el-image { .el-image {
width 120px width: 120px;
height 120px height: 120px;
border-radius 5px border-radius: 5px;
} }
.el-button { .el-button {
position absolute position: absolute;
right 5px right: 5px;
top 5px top: 5px;
width 20px width: 20px;
height 20px height: 20px;
} }
} }
} }
} }
.el-row.text-info { .el-row.text-info {
width 100% width: 100%;
padding 10px 0 padding: 10px 0;
.el-tag { .el-tag {
margin-right 10px margin-right: 10px;
} }
} }
// 提交按钮 // 提交按钮
.submit-btn { .submit-btn {
display flex display: flex;
margin: 20px 0 margin: 20px 0;
.el-button { .el-button {
width 200px width: 200px;
} }
} }
// 任务列表 // 任务列表
@import "waterfall-list.styl" @import 'waterfall-list.scss';
} }
.no-more-data { .no-more-data {
text-align center text-align: center;
padding 30px padding: 30px;
} }
} }
} }
@import "sd-task-dialog.styl" @import 'sd-task-dialog.scss';
.mj-list-item-prompt { .mj-list-item-prompt {
.el-icon { .el-icon {
margin-left 10px margin-left: 10px;
cursor pointer cursor: pointer;
position relative position: relative;
top 2px top: 2px;
} }
} }
} }

View File

@@ -0,0 +1,128 @@
@keyframes expandUp {
0% {
transform: scaleY(0);
}
100% {
transform: scaleY(1);
}
}
.page-images-wall {
display: flex;
// background-color: #282c34;
.inner {
width: 100%;
color: var(--text-theme-color);
overflow: hidden;
.header {
display: flex;
padding: 0 40px;
h2 {
width: 300px;
}
.settings {
width: 100%;
display: flex;
justify-content: right;
.el-radio-group {
font-size: 16px;
.el-radio {
color: var(--text-theme-color);
}
}
}
}
.waterfall {
position: relative;
margin: 0 auto;
overflow-y: auto;
overflow-x: hidden;
.waterfall-over-message {
display: none;
}
.list-item {
display: flex;
.image {
overflow: hidden;
.el-image {
width: 100%;
transition: transform 0.3s;
cursor: pointer;
}
}
.opt {
display: none;
position: absolute;
width: 100%;
bottom: 0;
left: 0;
color: var(--text-theme-color);
padding: 8px 10px;
line-height: 1.2;
border-top-right-radius: 10px;
background-color: rgba(10, 10, 10, 0.7);
span {
word-break: break-all;
}
.iconfont {
}
.el-icon, .iconfont {
top: 2px;
cursor: pointer;
color: #fff !important;
border: 1px solid #fff !important;
border-radius: 5px;
padding: 2px;
font-size: 16px;
margin-right: 10px;
&:hover {
background-color: #444444;
}
}
}
&:hover {
.opt {
display: block;
animation: expandUp 0.3s ease-in-out forwards;
transform-origin: bottom center;
transform: scaleY(0); /* 初始状态元素高度为0 */
}
.image {
.el-image {
transform: scale(1.2); /* 放大图像到1.2倍大小 */
}
}
}
}
}
.footer {
display: flex;
padding: 20px;
align-items: center;
justify-content: center;
.iconfont {
margin-left: 6px;
}
}
}
@use "sd-task-dialog.scss" as *;
}

View File

@@ -1,134 +0,0 @@
@keyframes expandUp {
0% {
transform: scaleY(0);
}
100% {
transform: scaleY(1);
}
}
.page-images-wall {
display: flex;
// background-color: #282c34;
.inner {
width 100%
color var(--text-theme-color);
overflow hidden
.header {
display flex
padding 0 40px
h2 {
width 300px
}
.settings {
width 100%
display flex
justify-content right
.el-radio-group {
font-size 16px
.el-radio {
color var(--text-theme-color);
}
}
}
}
.waterfall {
position: relative;
margin: 0 auto;
overflow-y auto
overflow-x hidden
.waterfall-over-message {
display none
}
.list-item {
display flex
.image {
overflow hidden
.el-image {
width 100%
transition: transform 0.3s;
cursor pointer
}
}
.opt {
display none
position absolute
width 100%
bottom 0
left 0
color var(--text-theme-color);
padding 8px 10px
line-height 1.2
border-top-right-radius 10px
background-color rgba(10, 10, 10, 0.7)
span {
word-break break-all
}
.iconfont{
}
.el-icon, .iconfont {
top 2px
cursor pointer
color: #fff !important;
border 1px solid #fff !important;
border-radius 5px
padding 2px
font-size 16px;
margin-right 10px
&:hover {
background-color #444444
}
}
}
&:hover {
.opt {
display block
animation: expandUp 0.3s ease-in-out forwards;
transform-origin: bottom center;
transform: scaleY(0); /* 0 */
}
.image {
.el-image {
transform: scale(1.2); /* 1.2倍大小 */
}
}
}
}
}
.footer {
display flex
padding 20px
align-items center
justify-content center
.iconfont {
margin-left 6px
}
}
}
@import "sd-task-dialog.styl"
}

View File

@@ -0,0 +1,207 @@
.index-page {
margin: 0;
overflow: hidden;
color: var(--text-color);
display: flex;
align-items: center;
background: var(--theme-bg) !important;
flex-flow: column;
height: 100vh;
.color-bg {
position: absolute;
top: 0;
left: 0;
width: 100vw;
height: 100vh;
}
.image-bg {
filter: blur(8px);
background-size: cover;
background-position: center;
}
.shadow {
box-shadow: rgba(0, 0, 0, 0.3) 0px 0px 3px;
&:hover {
box-shadow: rgba(0, 0, 0, 0.3) 0px 0px 8px;
}
}
.menu-box {
width: 100%;
display: flex;
height: 80px;
align-items: center;
.el-menu {
padding: 0 30px;
width: 100%;
display: flex;
justify-content: space-between;
align-items: center;
background: none;
border: none;
.menu-item {
display: flex;
// padding: 20px 0;
height: 40px;
align-items: center;
color: var(--text-color);
.iconfont {
color: var(--text-color);
font-size: 28px;
}
.title {
color: var(--text-color);
font-size: 24px;
padding: 10px 10px 0 10px;
font-weight: 700;
}
.logo {
height: 60px;
border-radius: 50%;
background: #fff;
border: 2px solid #754ff6;
}
.el-button {
margin-left: 10px;
span {
margin-left: 5px;
}
}
}
}
}
.content {
text-align: center;
position: relative;
display: flex;
flex-flow: column;
align-items: center;
h1 {
font-size: 5rem;
margin-bottom: 1rem;
}
p {
font-size: 1.5rem;
margin-bottom: 2rem;
}
.navs {
display: flex;
max-width: 900px;
padding: 20px;
.el-space--horizontal {
justify-content: center;
}
.nav-item {
width: 200px;
.el-button {
width: 100%;
padding: 25px 20px;
font-size: 1.3rem;
transition: all 0.3s ease;
.iconfont {
font-size: 24px;
margin-right: 10px;
position: relative;
top: -2px;
}
}
}
.nav-item-box {
width: 100%;
border-radius: 8px;
cursor: pointer;
transition: all 0.2s cubic-bezier(0.645, 0.045, 0.355, 1);
aspect-ratio: 1.1028 / 1;
background: var(--card-bg);
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
min-width: 160px;
// min-height: 190px;
i {
display: inline-block;
min-width: 48px;
width: 48px;
height: 48px;
font-size: 38px;
border-radius: 24px;
color: var(--normal-color);
}
&:hover {
box-shadow: 0 4px 14px 0 rgba(17, 13, 83, 0.18);
transform: translateY(-8px);
}
}
}
}
.footer {
.el-link__inner {
color: #ffffff;
}
}
}
.cursor-ani {
position: relative;
}
.cursor-ani::after {
content: '';
position: absolute;
width: 1px;
height: 28px;
background: #333;
transform: translateX(3px) translateY(3px);
animation: cursor-blinks 0.8s infinite forwards;
}
@keyframes cursor-blinks {
from {
opacity: 0;
}
to {
opacity: 1;
}
}
.cursor-ani {
display: inline-block;
min-height: 34px;
font-size: 1.5em;
}
.msg-text span {
transition: color 0.3s ease; /* 平滑的颜色过渡 */
font-weight: bold;
}
.logo-box {
width: 60px;
height: 60px;
background: #fff;
border-radius: 50%;
img {
width: 100%;
object-fit: cover;
height: 100%;
}
}

View File

@@ -1,211 +0,0 @@
.index-page {
margin: 0
overflow hidden
color var(--text-color)
display flex
align-items center
background: var(--theme-bg) !important
flex-flow column
height: 100vh
.color-bg {
position absolute
top 0
left 0
width 100vw
height 100vh
}
.image-bg {
filter: blur(8px);
background-size: cover;
background-position: center;
}
.shadow {
box-shadow rgba(0, 0, 0, 0.3) 0px 0px 3px
&:hover {
box-shadow rgba(0, 0, 0, 0.3) 0px 0px 8px
}
}
.menu-box {
width 100%
display flex
height 80px
align-items center
.el-menu {
padding 0 30px
width 100%
display flex
justify-content space-between
align-items center
background none
border none
.menu-item {
display flex
// padding 20px 0
height 40px
align-items center
color var(--text-color);
.iconfont{
color var(--text-color);
font-size: 28px;
}
.title {
color var(--text-color);
font-size: 24px;
padding 10px 10px 0 10px
font-weight: 700;
}
.logo {
height 60px
border-radius 50%
background: #fff
border: 2px solid #754ff6
}
.el-button {
margin-left 10px
span {
margin-left 5px
}
}
}
}
}
.content {
text-align: center;
position relative
display flex
flex-flow: column;
align-items: center;
h1 {
font-size: 5rem;
margin-bottom: 1rem;
}
p {
font-size: 1.5rem;
margin-bottom: 2rem;
}
.navs {
display flex
max-width 900px
padding 20px
.el-space--horizontal {
justify-content center
}
.nav-item {
width 200px
.el-button {
width 100%
padding: 25px 20px;
font-size: 1.3rem;
transition: all 0.3s ease;
.iconfont {
font-size 24px
margin-right 10px
position relative
top -2px
}
}
}
.nav-item-box{
width: 100%;
border-radius: 8px;
cursor: pointer;
transition: all 0.2s cubic-bezier(0.645,0.045,0.355,1);
aspect-ratio: 1.1028 / 1;
background: var( --card-bg)
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
min-width: 160px
// min-height: 190px;
i{
display: inline-block
min-width: 48px;
width: 48px;
height: 48px;
font-size: 38px
border-radius: 24px;
color: var(--normal-color)
}
&:hover{
box-shadow: 0 4px 14px 0 rgba(17, 13, 83, .18);
transform: translateY(-8px);}
}
}
}
.footer {
.el-link__inner {
color #ffffff
}
}
}
.cursor-ani {
position: relative;
}
.cursor-ani::after {
content: '';
position: absolute;
width: 1px;
height: 28px;
background: #333;
transform: translateX(3px) translateY(3px);
animation: cursor-blinks 0.8s infinite forwards;
}
@keyframes cursor-blinks {
from {
opacity: 0;
}
to {
opacity: 1;
}
}
.cursor-ani {
display: inline-block;
min-height: 34px;
font-size: 1.5em;
}
.msg-text span {
transition: color 0.3s ease; /* */
font-weight: bold;
}
.logo-box{
width: 60px
height: 60px
background: #fff
border-radius: 50%
img{
width: 100%;
object-fit: cover;
height: 100%;
}
}

View File

@@ -11,7 +11,7 @@
padding: 20px; padding: 20px;
border-radius: 12px; border-radius: 12px;
background: var(--card-bg); background: var(--card-bg);
box-shadow: var(--card-shadow, 0 8px 24px rgba(0,0,0,0.12)); box-shadow: var(--card-shadow, 0 8px 24px rgba(0, 0, 0, 0.12));
color: var(--text-theme-color); color: var(--text-theme-color);
font-size: 14px; font-size: 14px;
overflow: auto; overflow: auto;
@@ -81,7 +81,7 @@
color: var(--primary-text-on-primary-dark, #fff); color: var(--primary-text-on-primary-dark, #fff);
} }
transform: translateY(-2px); transform: translateY(-2px);
box-shadow: var(--primary-shadow, 0 4px 12px rgba(88,101,242,0.3)); box-shadow: var(--primary-shadow, 0 4px 12px rgba(88, 101, 242, 0.3));
} }
.category-icon { .category-icon {
@@ -233,11 +233,11 @@
flex-direction: column; flex-direction: column;
background: var(--card-bg); background: var(--card-bg);
border-radius: 12px; border-radius: 12px;
box-shadow: var(--card-shadow, 0 2px 8px rgba(0,0,0,0.1)); box-shadow: var(--card-shadow, 0 2px 8px rgba(0, 0, 0, 0.1));
overflow: hidden; overflow: hidden;
transition: box-shadow 0.2s; transition: box-shadow 0.2s;
&:hover { &:hover {
box-shadow: 0 4px 24px rgba(88,101,242,0.12); box-shadow: 0 4px 24px rgba(88, 101, 242, 0.12);
} }
.task-left { .task-left {
width: 100%; width: 100%;

View File

@@ -0,0 +1,57 @@
.loginPage {
background: var(--card-bg) !important;
background-color: var(---card-bg) !important;
.form-title {
color: var(--text-theme-color);
}
}
.left {
width: 50%;
.login-box {
width: 410px;
margin: 0 auto;
min-height: calc(100vh - 48px);
}
.wechatLog {
width: 410px;
height: 50px;
line-height: 50px;
text-align: center;
background: var(--sign-bg);
a {
color: var(--text-theme-color);
}
font-size: 14px;
margin-bottom: 26px;
border-radius: 16px;
.icon-wechat {
color: #0bc15f;
margin-right: 9px;
font-size: 20px;
}
}
.text-color-primary {
cursor: pointer;
}
}
.login-btn {
width: 100%;
height: 40px;
border-radius: 16px;
}
.code-input {
width: 306px;
margin-right: 9px;
}
:deep(.el-tabs__item.is-active), :deep(.el-tabs__item:hover) {
color: var(--common-text-color) !important;
}
:deep(.el-tabs__item) {
color: var(--text-theme-color);
}

View File

@@ -1,62 +0,0 @@
.loginPage{
background: var(--card-bg) !important
background-color: var(---card-bg) !important
.form-title{
color:var( --text-theme-color)
}
}
.left{
width: 50%;
.login-box{
width: 410px;
margin: 0 auto;
min-height: calc(100vh - 48px);
}
.wechatLog{
width: 410px;
height: 50px;
line-height: 50px;
text-align: center
background: var( --sign-bg)
a{
color: var(--text-theme-color)
}
font-size: 14px;
margin-bottom: 26px
border-radius: 16px;
.icon-wechat{
color: #0bc15f
margin-right: 9px
font-size: 20px;
}
}
.text-color-primary{
cursor :pointer
}
}
.login-btn {
width :100%
height: 40px;
border-radius: 16px;
}
.code-input{
width: 306px;
margin-right: 9px;
}
:deep(.el-tabs__item.is-active), :deep(.el-tabs__item:hover) {
color: var(--common-text-color) !important
}
:deep(.el-tabs__item) {
color: var(--text-theme-color)
}

View File

@@ -18,12 +18,12 @@ body {
} }
.admin-home { .admin-home {
overflow hidden overflow: hidden;
position relative position: relative;
height 100vh height: 100vh;
a { a {
text-decoration: none text-decoration: none;
} }
.content-box { .content-box {
@@ -33,8 +33,8 @@ body {
top: 0; top: 0;
bottom: 0; bottom: 0;
padding-bottom: 30px; padding-bottom: 30px;
-webkit-transition: left .3s ease-in-out; -webkit-transition: left 0.3s ease-in-out;
transition: left .3s ease-in-out; transition: left 0.3s ease-in-out;
background: #f0f0f0; background: #f0f0f0;
::-webkit-scrollbar { ::-webkit-scrollbar {
@@ -43,7 +43,7 @@ body {
::-webkit-scrollbar-thumb { ::-webkit-scrollbar-thumb {
background-color: #666666; background-color: #666666;
border-radius 8px border-radius: 8px;
} }
::-webkit-scrollbar-thumb:hover { ::-webkit-scrollbar-thumb:hover {
@@ -58,8 +58,8 @@ body {
.container { .container {
padding: 15px 20px 30px 20px; padding: 15px 20px 30px 20px;
background: #ffffff; background: #ffffff;
margin-bottom 20px margin-bottom: 20px;
max-width 100% max-width: 100%;
} }
.crumbs { .crumbs {
@@ -96,7 +96,7 @@ body {
.move-enter-active, .move-enter-active,
.move-leave-active { .move-leave-active {
transition: opacity .1s ease; transition: opacity 0.1s ease;
} }
.move-enter-from, .move-enter-from,
@@ -123,7 +123,6 @@ body {
padding-bottom: 0; padding-bottom: 0;
} }
[class*=" el-icon-"], [class^=el-icon-] { [class*=" el-icon-"], [class^=el-icon-] {
speak: none; speak: none;
font-style: normal; font-style: normal;
@@ -164,7 +163,6 @@ body {
.el-table th { .el-table th {
background-color: var(--el-fill-color-darker); background-color: var(--el-fill-color-darker);
} }
} }
} }
@@ -176,31 +174,30 @@ body {
width: 100%; width: 100%;
.el-table__body-header { .el-table__body-header {
height 40px height: 40px;
} }
} }
} }
.w-100 { .w-100 {
width 100% width: 100%;
} }
.d-flex { .d-flex {
display flex !important display: flex !important;
} }
.justify-center { .justify-center {
justify-content center justify-content: center;
} }
.justify-between { .justify-between {
justify-content space-between justify-content: space-between;
} }
.justify-end { .justify-end {
justify-content flex-end justify-content: flex-end;
} }
.align-center { .align-center {
align-items center align-items: center;
} }

View File

@@ -0,0 +1,149 @@
.page-mark-map {
// background-color: #282c34;
height: 100%;
.inner {
display: flex;
.mark-map-box {
margin: 10px;
// background-color: #262626;
// border: 1px solid #454545;
min-width: 300px;
max-width: 300px;
padding: 10px;
border-radius: 10px;
color: var(--text-theme-color);
font-size: 14px;
h2 {
font-weight: bold;
font-size: 20px;
text-align: center;
color: var(--theme-textcolor-normal);
}
// 隐藏滚动条
::-webkit-scrollbar {
width: 0;
height: 0;
background-color: transparent;
}
.mark-map-params {
margin-top: 10px;
overflow: auto;
.param-line {
padding: 10px;
.el-button {
width: 100%;
span {
color: #fff;
}
}
}
.text-info {
padding: 10px;
.el-tag {
margin-right: 10px;
}
}
}
}
.el-form {
.el-form-item__label {
color: var(--text-theme-color);
}
}
.chat-box {
width: 100%;
background: var(--chat-bg);
.top-bar {
display: flex;
justify-content: right;
align-items: center;
padding: 10px 20px 10px 10px;
}
.markdown {
color: var(--text-theme-color);
display: flex;
justify-content: center;
align-items: center;
h1 {
color: var(--theme-textcolor-normal);
}
h2 {
color: #ffcc00;
}
ul {
list-style-type: disc;
margin-left: 20px;
li {
line-height: 1.5;
}
}
strong {
font-weight: bold;
}
em {
font-style: italic;
}
}
.body {
display: flex;
justify-content: center;
align-items: center;
position: relative;
.markmap {
width: 100%;
color: var(--text-theme-color);
font-size: 12px;
.markmap-foreign {
// height: 30px;
}
}
#toolbar {
position: absolute;
bottom: 10px;
right: 20px;
display: flex;
.mm-toolbar {
line-height: 36px;
display: flex;
flex-flow: row;
margin-left: 10px;
.mm-toolbar-brand {
display: none;
}
.mm-toolbar-item {
cursor: pointer;
color: var(--text-fb);
}
}
}
}
}
}
}

View File

@@ -1,156 +0,0 @@
.page-mark-map {
// background-color: #282c34;
height 100%
.inner {
display: flex;
.mark-map-box {
margin 10px
// background-color #262626
// border 1px solid #454545
min-width 300px
max-width 300px
padding 10px
border-radius 10px
color var(--text-theme-color);
font-size 14px
h2 {
font-weight: bold;
font-size 20px
text-align center
color var( --theme-textcolor-normal)
}
//
::-webkit-scrollbar {
width: 0;
height: 0;
background-color: transparent;
}
.mark-map-params {
margin-top 10px
overflow auto
.param-line {
padding 10px
.el-button {
width 100%
span {
color #fff
}
}
}
.text-info {
padding 10px
.el-tag {
margin-right 10px
}
}
}
}
.el-form {
.el-form-item__label {
color var(--text-theme-color)
}
}
.chat-box {
width 100%
background: var(--chat-bg);
.top-bar {
display flex
justify-content right
align-items center
padding 10px 20px 10px 10px
}
.markdown {
color var(--text-theme-color)
display flex
justify-content center
align-items center
h1 {
color: var( --theme-textcolor-normal);
}
h2 {
color: #ffcc00;
}
ul {
list-style-type: disc;
margin-left: 20px;
li {
line-height 1.5
}
}
strong {
font-weight: bold;
}
em {
font-style: italic;
}
}
.body {
display flex
justify-content center
align-items center
position relative
.markmap {
width 100%
color var(--text-theme-color)
font-size 12px
.markmap-foreign {
//height 30px
}
}
#toolbar {
position: absolute
bottom: 10px
right: 20px
display: flex;
.mm-toolbar {
line-height: 36px;
display flex
flex-flow row
margin-left: 10px;
.mm-toolbar-brand {
display none
}
.mm-toolbar-item {
cursor pointer
color var( --text-fb)
}
}
}
}
}
}
}

View File

@@ -0,0 +1,237 @@
.member {
height: 100%;
.title {
text-align: center;
background-color: #25272d;
font-size: 24px;
color: var(--text-theme-color);
padding: 10px;
border-bottom: 1px solid #3c3c3c;
}
.inner {
color: var(--text-theme-color);
padding: 15px 0 15px 15px;
overflow-x: hidden;
overflow-y: visible;
display: flex;
flex-flow: row;
.profile-card {
max-width: 300px;
border-radius: 18px;
box-shadow: 0 4px 8px rgba(0, 0, 0, 0.08);
padding: 24px 16px;
background: var(--panel-bg);
position: relative;
z-index: 1;
margin-bottom: 24px;
}
.profile-title {
font-size: 18px;
font-weight: bold;
margin-bottom: 18px;
color: #2d8cf0;
letter-spacing: 2px;
text-align: center;
}
.profile-btn {
width: 100%;
margin-bottom: 12px;
font-size: 16px;
font-weight: 500;
display: flex;
align-items: center;
justify-content: center;
border: none;
border-radius: 8px;
background: linear-gradient(90deg, #6dd5ed 0%, #2193b0 100%);
color: #fff;
transition: all 0.3s;
i {
margin-right: 8px;
font-size: 20px;
}
&:hover {
box-shadow: 0 2px 12px #2193b0aa;
transform: translateY(-2px) scale(1.03);
background: linear-gradient(90deg, #2193b0 0%, #6dd5ed 100%);
}
}
.profile-btn.email {
background: linear-gradient(90deg, #f7971e 0%, #ffd200 100%);
}
.profile-btn.mobile {
background: linear-gradient(90deg, #43cea2 0%, #185a9d 100%);
}
.profile-btn.third {
background: linear-gradient(90deg, #ff512f 0%, #dd2476 100%);
}
.profile-btn.password {
background: linear-gradient(90deg, #1d4350 0%, #a43931 100%);
}
.profile-btn.redeem {
background: linear-gradient(90deg, #00c6ff 0%, #0072ff 100%);
}
.profile-bg {
position: absolute;
left: 0;
top: 0;
width: 100%;
height: 100%;
z-index: 0;
background: url('data:image/svg+xml;utf8,<svg width="100%25" height="100%25" viewBox="0 0 400 200" fill="none" xmlns="http://www.w3.org/2000/svg"><circle cx="100" cy="100" r="80" fill="%23e0eaff"/><circle cx="300" cy="60" r="40" fill="%23f0f7ff"/><circle cx="320" cy="180" r="30" fill="%23e0eaff"/></svg>') no-repeat center/cover;
opacity: 0.08;
pointer-events: none;
}
.product-box {
padding: 0 20px;
width: 100%;
.info {
.el-alert__description {
font-size: 14px !important;
margin: 0;
}
padding: 0 0 20px 0;
}
.list-box {
.product-item {
// border: 1px solid #666666;
background-color: var(--chat-bg);
border-radius: 6px;
overflow: hidden;
cursor: pointer;
transition: all 0.3s ease; /* 添加过渡效果 */
margin-bottom: 20px;
.image-container {
display: flex;
justify-content: center;
.el-image {
padding: 6px;
.el-image__inner {
border-radius: 10px;
}
}
}
.product-title {
display: flex;
padding: 10px;
.name {
width: 100%;
text-align: center;
font-size: 16px;
font-weight: bold;
color: var(--el-color-primary);
}
}
.product-info {
padding: 10px 20px;
font-size: 14px;
color: #999999;
.info-line {
display: flex;
width: 100%;
padding: 5px 0;
.label {
display: flex;
width: 100%;
}
.price, .expire, calls {
display: flex;
width: 90px;
justify-content: right;
}
.discount {
color: #f56c6c;
font-size: 20px;
}
.expire {
color: #409eff;
}
.power {
color: #f2cb51;
}
}
.pay-way {
padding: 10px 0;
display: flex;
justify-content: center;
flex-wrap: wrap;
.el-button {
margin: 10px 5px 0 5px;
height: 32px;
filter: none;
.icon-alipay, .icon-wechat-pay {
color: #ffffff;
}
.icon-qq {
color: #15a6e8;
font-size: 24px;
}
.icon-jd-pay {
color: var(--text-theme-color);
font-size: 24px;
}
.icon-douyin {
color: #0a0a0a;
font-size: 22px;
}
.icon-paypal {
font-size: 14px;
color: #009cde;
}
}
}
}
&:hover {
// box-shadow: 0 0 10px rgba(71, 255, 241, 0.6); /* 添加阴影效果 */
transform: translateY(-10px); /* 向上移动10像素 */
box-shadow: 0 0 10px var(--shadow-color);
background-color: var(--hover-deep-color);
}
}
}
.headline {
padding: 0 20px 20px 0;
}
.user-order {
padding: 0 20px 20px 0;
}
}
}
}
.pay-dialog {
.product-info {
text-align: center;
color: #333333;
font-size: 16px;
.price {
color: #f56c6c;
font-weight: 700;
}
}
}

View File

@@ -1,239 +0,0 @@
.member {
height 100%
.title {
text-align center
background-color #25272d
font-size 24px
color var(--text-theme-color)
padding 10px
border-bottom 1px solid #3c3c3c
}
.inner {
color var(--text-theme-color)
padding 15px 0 15px 15px
overflow-x hidden
overflow-y visible
display flex
flex-flow row
.profile-card {
max-width 300px
border-radius 18px
box-shadow 0 4px 8px rgba(0,0,0,0.08)
padding 24px 16px
background var(--panel-bg)
position relative
z-index 1
margin-bottom 24px
}
.profile-title {
font-size 18px
font-weight bold
margin-bottom 18px
color #2d8cf0
letter-spacing 2px
text-align center
}
.profile-btn {
width 100%
margin-bottom 12px
font-size 16px
font-weight 500
display flex
align-items center
justify-content center
border none
border-radius 8px
background linear-gradient(90deg, #6dd5ed 0%, #2193b0 100%)
color #fff
transition all 0.3s
i {
margin-right 8px
font-size 20px
}
&:hover {
box-shadow 0 2px 12px #2193b0aa
transform translateY(-2px) scale(1.03)
background linear-gradient(90deg, #2193b0 0%, #6dd5ed 100%)
}
}
.profile-btn.email {
background linear-gradient(90deg, #f7971e 0%, #ffd200 100%)
}
.profile-btn.mobile {
background linear-gradient(90deg, #43cea2 0%, #185a9d 100%)
}
.profile-btn.third {
background linear-gradient(90deg, #ff512f 0%, #dd2476 100%)
}
.profile-btn.password {
background linear-gradient(90deg, #1d4350 0%, #a43931 100%)
}
.profile-btn.redeem {
background linear-gradient(90deg, #00c6ff 0%, #0072ff 100%)
}
.profile-bg {
position absolute
left 0
top 0
width 100%
height 100%
z-index 0
background url('data:image/svg+xml;utf8,<svg width="100%25" height="100%25" viewBox="0 0 400 200" fill="none" xmlns="http://www.w3.org/2000/svg"><circle cx="100" cy="100" r="80" fill="%23e0eaff"/><circle cx="300" cy="60" r="40" fill="%23f0f7ff"/><circle cx="320" cy="180" r="30" fill="%23e0eaff"/></svg>') no-repeat center/cover
opacity 0.08
pointer-events none
}
.product-box {
padding 0 20px
width 100%
.info {
.el-alert__description {
font-size 14px !important
margin 0
}
padding 0 0 20px 0
}
.list-box {
.product-item {
// border 1px solid #666666
background-color var(--chat-bg)
border-radius 6px
overflow hidden
cursor pointer
transition: all 0.3s ease; /* */
margin-bottom 20px
.image-container {
display flex
justify-content center
.el-image {
padding 6px
.el-image__inner {
border-radius 10px
}
}
}
.product-title {
display flex
padding 10px
.name {
width 100%
text-align center
font-size 16px
font-weight bold
color var( --el-color-primary)
}
}
.product-info {
padding 10px 20px
font-size 14px
color #999999
.info-line {
display flex
width 100%
padding 5px 0
.label {
display flex
width 100%
}
.price, .expire, calls {
display flex
width 90px
justify-content right
}
.discount {
color #f56c6c
font-size 20px
}
.expire {
color #409eff
}
.power {
color #F2CB51
}
}
.pay-way {
padding 10px 0
display flex
justify-content: center
flex-wrap wrap
.el-button {
margin 10px 5px 0 5px
height 32px
filter: none;
.icon-alipay,.icon-wechat-pay {
color #ffffff
}
.icon-qq {
color #15A6E8
font-size 24px
}
.icon-jd-pay {
color var(--text-theme-color)
font-size 24px
}
.icon-douyin {
color #0a0a0a
font-size 22px
}
.icon-paypal {
font-size 14px
color #009CDE
}
}
}
}
&:hover {
// box-shadow: 0 0 10px rgba(71, 255, 241, 0.6); /* */
transform: translateY(-10px); /* 10 */
box-shadow: 0 0 10px var(--shadow-color);
background-color: var(--hover-deep-color)
}
}
}
.headline {
padding 0 20px 20px 0
}
.user-order {
padding 0 20px 20px 0
}
}
}
}
.pay-dialog {
.product-info {
text-align center
color #333333
font-size 16px
.price {
color #f56c6c
font-weight 700
}
}
}

View File

@@ -0,0 +1,36 @@
.mobile-chat-list {
.content {
padding-top: 46px;
padding-bottom: 60px;
.van-list {
.van-cell__value {
.chat-list-item {
display: flex;
font-size: 14px;
.van-image {
min-width: 32px;
width: 32px;
height: 32px;
}
.van-ellipsis {
margin-top: 5px;
margin-left: 10px;
}
}
}
}
}
.van-nav-bar {
.van-nav-bar__right {
.van-icon {
font-size: 20px;
}
}
}
}
@use "model-select.scss" as *;

View File

@@ -1,37 +0,0 @@
.mobile-chat-list {
.content {
padding-top 46px
padding-bottom 60px
.van-list {
.van-cell__value {
.chat-list-item {
display flex
font-size 14px
.van-image {
min-width 32px
width 32px
height 32px
}
.van-ellipsis {
margin-top 5px;
margin-left 10px;
}
}
}
}
}
.van-nav-bar {
.van-nav-bar__right {
.van-icon {
font-size 20px;
}
}
}
}
@import "model-select.styl"

View File

@@ -1,51 +1,49 @@
.mobile-chat { .mobile-chat {
.van-nav-bar { .van-nav-bar {
position static position: static;
.setting { .setting {
font-size 18px font-size: 18px;
} }
} }
.chat-list-wrapper { .chat-list-wrapper {
padding 10px 0 10px 0 padding: 10px 0 10px 0;
background var(--van-background); background: var(--van-background);
overflow hidden overflow: hidden;
.message-list-box { .message-list-box {
overflow auto overflow: auto;
.van-cell { .van-cell {
background none background: none;
font-family: 'Microsoft YaHei', '微软雅黑', Arial, sans-serif; font-family: 'Microsoft YaHei', '微软雅黑', Arial, sans-serif;
} }
} }
} }
.chat-box-wrapper { .chat-box-wrapper {
.van-sticky { .van-sticky {
.van-cell-group--inset { .van-cell-group--inset {
margin 0 margin: 0;
.van-cell { .van-cell {
padding 10px padding: 10px;
.icon-box { .icon-box {
.van-icon { .van-icon {
font-size 24px font-size: 24px;
margin-left 10px margin-left: 10px;
} }
} }
.button-voice { .button-voice {
padding 0 2px padding: 0 2px;
.el-icon { .el-icon {
font-size 24px font-size: 24px;
} }
height 30px height: 30px;
} }
} }
} }
@@ -54,37 +52,37 @@
.van-nav-bar__title { .van-nav-bar__title {
.van-dropdown-menu__title { .van-dropdown-menu__title {
margin-right 10px margin-right: 10px;
} }
.van-cell__title { .van-cell__title {
text-align left text-align: left;
} }
} }
.van-nav-bar__right { .van-nav-bar__right {
.van-icon { .van-icon {
font-size 20px font-size: 20px;
} }
} }
} }
.van-overlay { .van-overlay {
.mic-wrapper { .mic-wrapper {
display flex display: flex;
height 100vh height: 100vh;
justify-content center justify-content: center;
align-items center align-items: center;
flex-flow column flex-flow: column;
} }
} }
// .van-theme-dark { // .van-theme-dark {
// .mobile-chat { // .mobile-chat {
// .chat-list-wrapper { // .chat-list-wrapper {
// background #232425; // background: #232425;
// } // }
// } // }
// } // }
@import "model-select.styl" @use "model-select.scss" as *;

View File

@@ -0,0 +1,216 @@
.mobile-mj {
.text-line {
padding: 6px;
font-size: 14px;
.van-row {
.van-col {
.rate {
display: flex;
justify-content: center;
background-color: var(--van-background-3);
padding: 5px 10px;
margin: 5px 0;
border-radius: 5px;
flex-flow: column;
.icon {
text-align: center;
.van-image {
max-width: 20px;
}
}
.text {
text-align: center;
color: var(--van-text-color);
}
}
.model {
display: flex;
justify-content: center;
background-color: var(--van-background-3);
padding: 6px;
margin: 5px 0;
border-radius: 5px;
flex-flow: column;
.icon {
text-align: center;
.van-image {
width: 100%;
height: 50px;
}
}
.text {
text-align: center;
color: var(--van-text-color);
}
}
.active {
background-color: var(--van-text-color-3);
}
}
}
.van-button {
position: relative;
.van-tag {
position: absolute;
right: 20px;
}
}
.align-right {
display: flex;
justify-content: right;
}
}
color: var(--van-text-color);
.pt-6 {
padding: 15px 10px;
}
.tip-text {
padding: 10px;
line-height: 1.5;
color: #c1c1c1;
}
.running-job-list {
.van-grid {
.van-grid-item {
.van-grid-item__content {
padding: 0;
position: relative;
.van-image, .task-in-queue {
min-height: 100px;
}
.progress {
display: flex;
justify-content: center;
align-items: center;
width: 100%;
height: 100%;
background: rgba(50, 50, 50, 0.5);
position: absolute;
left: 0;
top: 0;
.van-circle__text {
color: #ffffff;
}
}
// end progress
.task-in-queue {
display: flex;
flex-flow: column;
justify-content: center;
color: #c1c1c1;
.icon {
text-align: center;
.iconfont {
font-size: 24px;
}
}
.text {
font-size: 14px;
margin-top: 5px;
}
}
}
}
}
}
// end running jobs
.finish-job-list {
.van-grid {
.van-grid-item {
.van-grid-item__content {
padding: 0;
.job-item {
overflow: hidden;
border-radius: 6px;
position: relative;
height: 100%;
width: 100%;
.opt {
.opt-btn {
padding: 2px 0;
text-align: center;
border-radius: 5px;
margin: 3px 0;
display: block;
cursor: pointer;
background-color: #4e5058;
color: #ffffff;
font-size: 14px;
width: 100%;
}
}
.van-image {
width: 100%;
height: 200px;
}
.upscale {
height: 260px;
width: 100%;
}
.remove {
position: absolute;
right: 5px;
top: 5px;
.el-button {
margin-left: 5px;
height: auto;
padding: 5px;
}
}
}
.failed {
display: flex;
flex-flow: column;
justify-content: center;
.title {
margin-bottom: 20px;
text-align: center;
color: #ee0a24;
font-size: 18px;
}
.opt {
display: flex;
justify-content: center;
.van-button {
margin: 0 5px;
}
}
}
}
}
}
}
}

View File

@@ -1,217 +0,0 @@
.mobile-mj {
.text-line {
padding 6px
font-size 14px
.van-row {
.van-col {
.rate {
display: flex;
justify-content center
background-color var(--van-background-3)
padding 5px 10px
margin 5px 0
border-radius 5px
flex-flow column
.icon {
text-align center
.van-image {
max-width 20px
}
}
.text {
text-align center
color var(--van-text-color)
}
}
.model {
display: flex;
justify-content center
background-color var(--van-background-3)
padding 6px
margin 5px 0
border-radius 5px
flex-flow column
.icon {
text-align center
.van-image {
width 100%
height 50px
}
}
.text {
text-align center
color var(--van-text-color)
}
}
.active {
background-color var(--van-text-color-3)
}
}
}
.van-button {
position relative
.van-tag {
position absolute
right 20px
}
}
.align-right {
display flex
justify-content right
}
}
color var(--van-text-color)
.pt-6 {
padding 15px 10px
}
.tip-text {
padding 10px
line-height 1.5
color #c1c1c1
}
.running-job-list {
.van-grid {
.van-grid-item {
.van-grid-item__content {
padding 0
position relative
.van-image, .task-in-queue {
min-height 100px
}
.progress {
display flex
justify-content center
align-items center
width 100%
height 100%
background rgba(50, 50, 50, 0.5)
position absolute
left 0
top 0
.van-circle__text {
color #ffffff
}
}
// end progress
.task-in-queue {
display flex
flex-flow column
justify-content center
color #c1c1c1
.icon {
text-align center
.iconfont {
font-size 24px
}
}
.text {
font-size 14px
margin-top 5px
}
}
}
}
}
}
//end running jobs
.finish-job-list {
.van-grid {
.van-grid-item {
.van-grid-item__content {
padding 0
.job-item {
overflow hidden
border-radius 6px
position relative
height 100%
width 100%
.opt {
.opt-btn {
padding 2px 0
text-align center
border-radius 5px
margin 3px 0
display block
cursor pointer
background-color #4E5058
color #ffffff
font-size 14px
width 100%
}
}
.van-image {
width 100%
height 200px
}
.upscale {
height 260px
width 100%
}
.remove {
position absolute
right 5px
top 5px
.el-button {
margin-left 5px
height auto
padding 5px
}
}
}
.failed {
display flex
flex-flow column
justify-content center
.title {
margin-bottom 20px
text-align center
color #ee0a24
font-size 18px
}
.opt {
display flex
justify-content center
.van-button {
margin 0 5px
}
}
}
}
}
}
}
}

View File

@@ -0,0 +1,204 @@
.mobile-sd {
.text-line {
padding: 0 6px;
font-size: 14px;
.van-row {
width: 100%;
.van-col {
.rate {
display: flex;
justify-content: center;
background-color: #f5f5f5;
padding: 5px 10px;
margin: 5px 0;
border-radius: 5px;
flex-flow: column;
.icon {
text-align: center;
.van-image {
max-width: 20px;
}
}
.text {
text-align: center;
color: #555555;
}
}
.el-input__inner {
text-align: center;
}
.model {
display: flex;
justify-content: center;
background-color: #f5f5f5;
padding: 6px;
margin: 5px 0;
border-radius: 5px;
flex-flow: column;
.icon {
text-align: center;
.van-image {
width: 100%;
height: 50px;
}
}
.text {
text-align: center;
color: #555555;
}
}
.active {
background-color: #e5e5e5;
}
}
}
.van-button {
position: relative;
.van-tag {
position: absolute;
right: 20px;
}
}
.align-right {
display: flex;
justify-content: right;
}
}
color: var(--van-text-color);
.pt-6 {
padding: 15px 10px;
}
.tip-text {
padding: 10px;
line-height: 1.5;
color: #c1c1c1;
}
.running-job-list {
.van-grid {
.van-grid-item {
.van-grid-item__content {
padding: 0;
position: relative;
.van-image, .task-in-queue {
min-height: 100px;
}
.progress {
display: flex;
justify-content: center;
align-items: center;
width: 100%;
height: 100%;
background: rgba(50, 50, 50, 0.5);
position: absolute;
left: 0;
top: 0;
.van-circle__text {
color: #ffffff;
}
}
// end progress
.task-in-queue {
display: flex;
flex-flow: column;
justify-content: center;
color: #c1c1c1;
.icon {
text-align: center;
.iconfont {
font-size: 24px;
}
}
.text {
font-size: 14px;
margin-top: 5px;
}
}
}
}
}
}
// end running jobs
.finish-job-list {
.van-grid {
.van-grid-item {
.van-grid-item__content {
padding: 0;
.job-item {
overflow: hidden;
border-radius: 6px;
position: relative;
height: 100%;
width: 100%;
.van-image {
width: 100%;
height: 200px;
}
.remove {
position: absolute;
right: 5px;
top: 5px;
.el-button {
margin-left: 5px;
height: auto;
padding: 5px;
}
}
}
.failed {
display: flex;
flex-flow: column;
justify-content: center;
height: 200px;
.title {
margin-bottom: 20px;
text-align: center;
color: #ee0a24;
font-size: 18px;
}
.opt {
display: flex;
justify-content: center;
.van-button {
margin: 0 5px;
}
}
}
}
}
}
}
}

View File

@@ -1,207 +0,0 @@
.mobile-sd {
.text-line {
padding 0 6px
font-size 14px
.van-row {
width 100%
.van-col {
.rate {
display: flex;
justify-content center
background-color #f5f5f5
padding 5px 10px
margin 5px 0
border-radius 5px
flex-flow column
.icon {
text-align center
.van-image {
max-width 20px
}
}
.text {
text-align center
color #555555
}
}
.el-input__inner {
text-align center
}
.model {
display: flex;
justify-content center
background-color #f5f5f5
padding 6px
margin 5px 0
border-radius 5px
flex-flow column
.icon {
text-align center
.van-image {
width 100%
height 50px
}
}
.text {
text-align center
color #555555
}
}
.active {
background-color #e5e5e5
}
}
}
.van-button {
position relative
.van-tag {
position absolute
right 20px
}
}
.align-right {
display flex
justify-content right
}
}
color var(--van-text-color)
.pt-6 {
padding 15px 10px
}
.tip-text {
padding 10px
line-height 1.5
color #c1c1c1
}
.running-job-list {
.van-grid {
.van-grid-item {
.van-grid-item__content {
padding 0
position relative
.van-image, .task-in-queue {
min-height 100px
}
.progress {
display flex
justify-content center
align-items center
width 100%
height 100%
background rgba(50, 50, 50, 0.5)
position absolute
left 0
top 0
.van-circle__text {
color #ffffff
}
}
// end progress
.task-in-queue {
display flex
flex-flow column
justify-content center
color #c1c1c1
.icon {
text-align center
.iconfont {
font-size 24px
}
}
.text {
font-size 14px
margin-top 5px
}
}
}
}
}
}
//end running jobs
.finish-job-list {
.van-grid {
.van-grid-item {
.van-grid-item__content {
padding 0
.job-item {
overflow hidden
border-radius 6px
position relative
height 100%
width 100%
.van-image {
width 100%
height 200px
}
.remove {
position absolute
right 5px
top 5px
.el-button {
margin-left 5px
height auto
padding 5px
}
}
}
.failed {
display flex
flex-flow column
justify-content center
height 200px
.title {
margin-bottom 20px
text-align center
color #ee0a24
font-size 18px
}
.opt {
display flex
justify-content center
.van-button {
margin 0 5px
}
}
}
}
}
}
}
}

View File

@@ -0,0 +1,16 @@
.van-popup {
.picker-option {
display: flex;
width: 100%;
padding: 0 10px;
overflow: hidden;
height: 20px;
text-overflow: ellipsis;
.van-image {
width: 20px;
height: 20px;
margin-right: 5px;
}
}
}

View File

@@ -1,16 +0,0 @@
.van-popup {
.picker-option {
display flex
width 100%
padding 0 10px
overflow hidden
height 20px
text-overflow ellipsis
.van-image {
width 20px;
height 20px;
margin-right 5px
}
}
}

View File

@@ -9,7 +9,7 @@
margin: 0; margin: 0;
overflow: hidden; overflow: hidden;
font-family: Arial, sans-serif; font-family: Arial, sans-serif;
width 100% width: 100%;
.phone-container { .phone-container {
position: relative; position: relative;
@@ -85,15 +85,15 @@
.conversation-container { .conversation-container {
background: linear-gradient(to right, #2c3e50, #4a5568, #6b46c1); background: linear-gradient(to right, #2c3e50, #4a5568, #6b46c1);
display: flex; display: flex;
height 100% height: 100%;
flex-direction: column; flex-direction: column;
justify-content: space-between; justify-content: space-between;
align-items: center; align-items: center;
padding: 0; padding: 0;
width 100% width: 100%;
.wave-container { .wave-container {
padding 3rem padding: 3rem;
.wave-animation { .wave-animation {
display: flex; display: flex;
justify-content: center; justify-content: center;
@@ -144,17 +144,17 @@
} }
.voice-indicators { .voice-indicators {
display flex display: flex;
flex-flow row flex-flow: row;
justify-content: space-between; justify-content: space-between;
width 100% width: 100%;
} }
.call-controls { .call-controls {
display: flex; display: flex;
justify-content: center; justify-content: center;
gap: 3rem; gap: 3rem;
padding 3rem padding: 3rem;
.call-button { .call-button {
width: 60px; width: 60px;
@@ -169,7 +169,7 @@
cursor: pointer; cursor: pointer;
.iconfont { .iconfont {
font-size 24px font-size: 24px;
} }
} }
.hangup { .hangup {
@@ -184,6 +184,5 @@
font-size: 28px; font-size: 28px;
} }
} }
} }
} }

View File

@@ -0,0 +1,43 @@
.running-job-list {
.running-job-box {
width: 100%;
display: flex;
flex-flow: row;
.image-slot {
color: var(--theme-text-color-primary);
}
}
.job-item {
margin-right: 10px;
width: 200px;
height: 200px;
overflow: hidden;
padding: 2px;
background-color: var(--gray-btn-bg);
.job-item-inner {
position: relative;
height: 100%;
overflow: hidden;
.progress {
position: absolute;
width: 100%;
height: 100%;
top: 0;
left: 0;
display: flex;
justify-content: center;
align-items: center;
span {
font-size: 20px;
color: var(--theme-text-color-primary);
}
}
}
}
}

View File

@@ -1,44 +0,0 @@
.running-job-list {
.running-job-box {
width 100%
display flex
flex-flow row
.image-slot {
color var(--theme-text-color-primary)
}
}
.job-item {
margin-right 10px
width 200px
height 200px
overflow hidden
padding 2px
background-color var( --gray-btn-bg)
.job-item-inner {
position relative
height 100%
overflow hidden
.progress {
position absolute
width 100%
height 100%
top 0
left 0
display flex
justify-content center
align-items center
span {
font-size 20px
color var(--theme-text-color-primary)
}
}
}
}
}

View File

@@ -0,0 +1,94 @@
.el-overlay-dialog {
.el-dialog {
// background-color: #1a1b1e;
.el-dialog__header {
.el-dialog__title {
color: #f5f5f5;
}
}
.el-dialog__body {
padding: 0 0 0 15px !important;
display: flex;
height: 100%;
.el-row {
width: 100%;
.img-container {
display: flex;
justify-content: center;
.image-slot {
display: flex;
height: 100vh;
align-items: center;
justify-content: center;
.el-icon {
font-size: 60px;
}
}
}
.task-info {
// background-color: #25262b;
padding: 1rem 1.5rem;
.info-line {
width: 100%;
.prompt {
// background-color: #35363b;
padding: 10px;
color: #999999;
overflow: auto;
max-height: 100px;
min-height: 50px;
position: relative;
.el-icon {
position: absolute;
right: 10px;
bottom: 10px;
cursor: pointer;
}
}
.wrapper {
margin-top: 10px;
display: flex;
label {
display: flex;
width: 100px;
color: var(--text-fb);
}
.item-value {
display: flex;
width: 100%;
// background-color: #35363b;
padding: 2px 5px;
border-radius: 5px;
color: var(--text-theme-color);
}
}
}
.copy-params {
padding: 20px 0 10px 0;
.el-button {
width: 100%;
}
}
}
}
// end el-row
}
}
}

View File

@@ -1,97 +0,0 @@
.el-overlay-dialog {
.el-dialog {
// background-color #1a1b1e
.el-dialog__header {
.el-dialog__title {
color #F5F5F5
}
}
.el-dialog__body {
padding 0 0 0 15px !important
display flex
height 100%
.el-row {
width 100%
.img-container {
display flex
justify-content center
.image-slot {
display flex
height 100vh
align-items center
justify-content center
.el-icon {
font-size 60px
}
}
}
.task-info {
// background-color #25262b
padding 1rem 1.5rem
.info-line {
width 100%
.prompt {
// background-color #35363b
padding 10px
color #999999
overflow auto
max-height 100px
min-height 50px
position relative
.el-icon {
position absolute
right 10px
bottom 10px
cursor pointer
}
}
.wrapper {
margin-top 10px
display flex
label {
display flex
width 100px
color :var(--text-fb)
}
.item-value {
display flex
width 100%
// background-color #35363b
padding 2px 5px
border-radius 5px
color: var(--text-theme-color);
}
}
}
.copy-params {
padding 20px 0 10px 0
.el-button {
width 100%
}
}
}
}
// end el-row
}
}
}

View File

@@ -0,0 +1,86 @@
.page-song {
display: flex;
justify-content: center;
background-color: #0e0808;
height: 100vh;
.inner {
text-align: left;
color: rgb(250 247 245);
padding: 20px;
max-width: 600px;
width: 100%;
font-family: "Neue Montreal, ui-sans-serif, system-ui, sans-serif, Apple Color Emoji, Segoe UI Emoji, Segoe UI Symbol, Noto Color Emoji";
.title {
font-size: 40px;
font-weight: 500;
line-height: 1rem;
white-space: nowrap;
text-overflow: ellipsis;
}
.row {
padding: 8px 0;
}
.author {
display: flex;
align-items: center;
.nickname {
margin: 0 10px;
}
.btn {
margin-right: 10px;
background-color: #363030;
border: none;
border-radius: 5px;
padding: 5px 10px;
cursor: pointer;
&:hover {
background-color: #5f5958;
}
}
}
.date {
color: #999999;
display: flex;
align-items: center;
.version {
background-color: #1c1616;
border: 1px solid #8f8f8f;
font-weight: normal;
font-size: 14px;
padding: 1px 3px;
border-radius: 5px;
margin-left: 10px;
}
}
.prompt {
width: 100%;
background-color: transparent;
white-space: pre-wrap;
overflow-y: auto;
resize: none;
position: relative;
outline: 2px solid transparent;
outline-offset: 2px;
border: none;
font-size: 100%;
line-height: 2rem;
}
}
.music-player {
width: 100%;
position: fixed;
bottom: 0;
left: 50px;
padding: 20px 0;
}
}

View File

@@ -1,88 +0,0 @@
.page-song {
display: flex;
justify-content: center;
background-color: #0E0808;
height: 100vh;
.inner {
text-align left
color rgb(250 247 245)
padding 20px
max-width 600px
width 100%
font-family "Neue Montreal,ui-sans-serif,system-ui,sans-serif,Apple Color Emoji,Segoe UI Emoji,Segoe UI Symbol,Noto Color Emoji"
.title {
font-size 40px
font-weight: 500
line-height 1rem
white-space nowrap
text-overflow ellipsis
}
.row {
padding 8px 0
}
.author {
display flex
align-items center
.nickname {
margin 0 10px
}
.btn {
margin-right 10px
background-color #363030
border none
border-radius 5px
padding 5px 10px
cursor pointer
&:hover {
background-color #5F5958
}
}
}
.date {
color #999999
display flex
align-items center
.version {
background-color #1C1616
border 1px solid #8f8f8f
font-weight normal
font-size 14px
padding 1px 3px
border-radius 5px
margin-left 10px
}
}
.prompt {
width 100%
background-color transparent
white-space pre-wrap
overflow-y auto
resize none
position relative
outline 2px solid transparent
outline-offset 2px
border none
font-size 100%
line-height 2rem
}
}
.music-player {
width 100%
position: fixed;
bottom: 0;
left: 50px;
padding 20px 0
}
}

View File

@@ -0,0 +1,424 @@
.page-suno {
display: flex;
height: 100%;
// background-color: #0E0808;
overflow: auto;
.item-group {
scrollbar-width: auto !important; /* 恢复滚动条Firefox */
-ms-overflow-style: auto !important; /* 恢复滚动条IE、Edge */
::-webkit-scrollbar {
display: block !important;
}
}
.left-bar {
max-width: 340px;
min-width: 340px;
padding: 20px 30px;
.bar-top {
display: flex;
flex-flow: row;
justify-content: space-between;
align-items: center;
.upload-music {
.iconfont {
margin-right: 5px;
font-size: 14px;
}
}
}
.params {
padding: 20px 0;
color: var(--text-theme-color);
position: relative;
.pure-music {
position: absolute;
right: 0;
top: 24px;
display: flex;
.text {
margin-top: 5px;
margin-left: 5px;
}
}
.label {
padding: 10px 0;
.text {
margin-right: 10px;
}
.el-icon {
top: 2px;
}
}
.item {
margin-bottom: 20px;
position: relative;
.create-btn {
margin: 20px 0;
background-image: url("~@/assets/img/suno-create-bg.svg");
background-size: cover;
background-position: 50% 50%;
transition: background 1s ease-in-out;
overflow: hidden;
font-size: 16px;
width: 100%;
padding: 16px;
border-radius: 25px;
border: none;
cursor: pointer;
img {
position: relative;
top: 3px;
margin-right: 5px;
}
&:hover {
opacity: 0.9;
}
}
.song {
display: flex;
padding: 10px;
background-color: var(--el-bg-color);
border-radius: 10px;
margin-bottom: 10px;
font-size: 14px;
position: relative;
.el-image {
width: 50px;
height: 50px;
border-radius: 10px;
}
.icon-mp3 {
font-size: 42px;
color: #a85295;
}
.title {
display: flex;
margin-left: 10px;
align-items: center;
color: var(--el-color-primary);
}
.el-button--info {
position: absolute;
right: 20px;
top: 20px;
}
}
.extend-secs {
padding: 10px 0;
font-size: 14px;
input {
width: 50px;
text-align: center;
padding: 8px 10px;
font-size: 14px;
background: none;
border: 1px solid #8f8f8f;
margin: 0 10px;
border-radius: 10px;
outline: none;
transition: border-color 0.5s ease, box-shadow 0.5s ease;
&:focus {
border-color: #0f7a71;
box-shadow: 0 0 5px #0f7a71;
}
}
}
.btn-lyric {
position: absolute;
left: 10px;
bottom: 10px;
font-size: 12px;
padding: 2px 5px;
background-color: var(--sm-btn-bg);
color: #fff;
}
}
.tag-select {
position: relative;
overflow-x: auto;
overflow-y: hidden;
scrollbar-width: auto !important; /* 恢复滚动条Firefox */
-ms-overflow-style: auto !important; /* 恢复滚动条IE、Edge */
width: 100%;
::-webkit-scrollbar {
display: block !important;
}
.inner {
display: flex;
flex-flow: row;
padding-bottom: 10px;
.tag {
margin-right: 10px;
word-break: keep-all;
background: var(--card-bg);
color: var(--theme-text-color-primary);
opacity: 0.7;
border-radius: 8px;
padding: 3px 6px;
cursor: pointer;
font-size: 13px;
&:hover {
color: var(--el-color-primary);
}
}
}
}
}
}
.right-box {
width: 100%;
color: rgb(250 247 245);
overflow: auto;
background: var(--chat-bg);
.list-box {
padding: 20px;
.item {
display: flex;
flex-flow: row;
padding: 5px 0;
cursor: pointer;
margin-bottom: 10px;
&:hover {
background: rgba(188, 149, 236, 0.08);
}
.left {
.container {
width: 60px;
height: 90px;
position: relative;
.el-image {
height: 90px;
border-radius: 5px;
width: 100%;
}
.duration {
position: absolute;
bottom: 0;
right: 0;
background-color: rgba(14, 8, 8, 0.7);
padding: 0 3px;
font-family: 'Input Sans';
font-size: 14px;
font-weight: 700;
border-radius: 0.125rem;
}
.play {
position: absolute;
width: 56px;
height: 100%;
top: 0;
left: 50%;
border: none;
border-radius: 5px;
background: rgba(100, 100, 100, 0.3);
cursor: pointer;
color: #ffffff;
opacity: 0;
transform: translate(-50%, 0px);
transition: opacity 0.3s ease 0s;
display: flex;
justify-content: center;
align-items: center;
}
&:hover {
.play {
opacity: 1;
// display: block;
}
}
}
}
.center {
width: 100%;
// border: 1px solid saddlebrown;
display: flex;
justify-content: center;
align-items: flex-start;
flex-flow: column;
height: 90px;
padding: 0 20px;
.title {
padding: 6px 0;
font-size: 16px;
font-weight: 700;
a {
color: var(--a-link-color);
&:hover {
text-decoration: underline;
}
}
.model {
color: #8f8f8f;
background-color: var(--el-bg-color);
border: 1px solid var(--el-border-color-light);
font-weight: normal;
font-size: 12px;
padding: 1px 3px;
border-radius: 5px;
margin-left: 10px;
.iconfont {
font-size: 12px;
}
}
}
.tags {
font-size: 14px;
color: var(--text-fb);
padding: 3px 0;
}
}
.right {
min-width: 350px;
font-size: 14px;
padding: 0 0 0 15px;
display: flex;
justify-content: right;
.tools {
display: flex;
justify-content: right;
align-items: center;
flex-flow: row;
height: 90px;
.btn-publish {
padding: 2px 10px;
// .text {
// margin-right: 10px;
// }
}
.btn-icon {
background: none;
padding: 6px;
transition: background 0.6s ease 0s;
color: #919191;
&:hover {
// background: #5f5958;
// color: #e1e1e1;
color: var(--el-color-primary);
}
.downloading {
width: 16px;
}
}
}
}
}
.task {
height: 100px;
background-color: var(--el-bg-color);
border: 1px solid var(--el-border-color-light);
border-radius: 5px;
display: flex;
margin-bottom: 10px;
.left {
display: flex;
justify-content: left;
align-items: center;
padding: 20px;
width: 320px;
.title {
font-size: 14px;
color: var(--el-text-color-primary);
white-space: nowrap; /* 防止文字换行 */
overflow: hidden; /* 隐藏溢出的内容 */
text-overflow: ellipsis; /* 用省略号表示溢出的内容 */
}
}
.center {
display: flex;
width: 100%;
justify-content: center;
.failed {
display: flex;
align-items: center;
color: #e4696b;
font-size: 14px;
}
}
.right {
display: flex;
width: 100px;
justify-content: center;
align-items: center;
}
}
}
.pagination {
margin-top: 20px;
display: flex;
justify-content: center;
}
.music-player {
width: 100%;
position: fixed;
bottom: 0;
left: 50px;
padding: 20px 0;
}
}
.btn {
margin-right: 10px;
color: var((--theme-text-color-primary));
border: none;
border-radius: 5px;
padding: 5px 10px;
cursor: pointer;
background: var(--btn-bg);
&:hover {
opacity: 0.8;
}
}
}
.submit-btn {
display: flex;
align-items: center;
margin: 20px 0;
justify-content: center;
.el-button {
width: 200px;
}
}

View File

@@ -1,430 +0,0 @@
.page-suno {
display flex
height 100%
// background-color #0E0808
overflow auto
.item-group{
scrollbar-width: auto !important; /* Firefox */
-ms-overflow-style: auto !important; /* IEEdge */
::-webkit-scrollbar {
display: block !important;
}
}
.left-bar {
max-width 340px
min-width 340px
padding 20px 30px
.bar-top {
display flex
flex-flow row
justify-content: space-between;
align-items center
.upload-music {
.iconfont {
margin-right 5px
font-size 14px
}
}
}
.params {
padding 20px 0
color: var(--text-theme-color);
position relative
.pure-music {
position absolute
right 0
top 24px
display flex
.text {
margin-top 5px
margin-left 5px
}
}
.label {
padding 10px 0
.text {
margin-right 10px
}
.el-icon {
top 2px
}
}
.item {
margin-bottom: 20px
position relative
.create-btn {
margin 20px 0
background-image url("~@/assets/img/suno-create-bg.svg")
background-size: cover;
background-position: 50% 50%;
transition: background 1s ease-in-out;
overflow: hidden;
font-size 16px
width 100%
padding 16px
border-radius 25px
border none
cursor pointer
img {
position relative
top 3px
margin-right 5px
}
&:hover {
opacity: 0.9;
}
}
.song {
display flex
padding 10px
background-color var(--el-bg-color)
border-radius 10px
margin-bottom 10px
font-size 14px
position relative
.el-image {
width 50px
height 50px
border-radius 10px
}
.icon-mp3 {
font-size 42px
color #A85295
}
.title {
display flex
margin-left 10px
align-items center
color var(--el-color-primary)
}
.el-button--info {
position absolute
right 20px
top 20px
}
}
.extend-secs {
padding 10px 0
font-size 14px
input {
width 50px
text-align center
padding 8px 10px
font-size 14px
background none
border 1px solid #8f8f8f
margin 0 10px
border-radius 10px
outline: none;
transition: border-color 0.5s ease, box-shadow 0.5s ease;
&:focus {
border-color: #0F7A71;
box-shadow: 0 0 5px #0F7A71;
}
}
}
.btn-lyric {
position absolute
left 10px
bottom 10px
font-size 12px
padding 2px 5px
background-color var(--sm-btn-bg)
color: #fff
}
}
.tag-select {
position relative
overflow-x auto
overflow-y hidden
scrollbar-width: auto !important; /* Firefox */
-ms-overflow-style: auto !important; /* IEEdge */
width 100%
::-webkit-scrollbar {
display: block !important;
}
.inner {
display flex
flex-flow row
padding-bottom 10px
.tag {
margin-right 10px
word-break keep-all
background: var(--card-bg);
color:var(--theme-text-color-primary);
opacity 0.7
border-radius 8px
padding 3px 6px
cursor pointer
font-size 13px
&:hover{
color:var( --el-color-primary)
}
}
}
}
}
}
.right-box {
width 100%
color rgb(250 247 245)
overflow auto
background: var(--chat-bg)
.list-box {
padding 20px
.item {
display flex
flex-flow row
padding 5px 0
cursor pointer
margin-bottom 10px
&:hover {
background: rgba(188,149,236,0.08)
}
.left {
.container {
width 60px
height 90px
position relative
.el-image {
height 90px
border-radius 5px
width 100%
}
.duration {
position absolute
bottom 0
right 0
background-color rgba(14,8,8,.7)
padding 0 3px
font-family 'Input Sans'
font-size 14px
font-weight 700
border-radius .125rem
}
.play {
position absolute
width: 56px;
height 100%
top: 0;
left: 50%;
border none
border-radius 5px
background rgba(100, 100, 100, 0.3)
cursor pointer
color #ffffff
opacity 0
transform: translate(-50%, 0px);
transition opacity 0.3s ease 0s
display flex
justify-content center
align-items center
}
&:hover {
.play {
opacity 1
//display block
}
}
}
}
.center {
width 100%
//border 1px solid saddlebrown
display flex
justify-content center
align-items flex-start
flex-flow column
height 90px
padding 0 20px
.title {
padding 6px 0
font-size 16px
font-weight 700
a {
color var( --a-link-color)
&:hover {
text-decoration underline
}
}
.model {
color #8f8f8f
background-color var(--el-bg-color)
border 1px solid var(--el-border-color-light)
font-weight normal
font-size 12px
padding 1px 3px
border-radius 5px
margin-left 10px
.iconfont {
font-size 12px
}
}
}
.tags {
font-size 14px
color var(--text-fb)
padding 3px 0
}
}
.right {
min-width 350px;
font-size 14px
padding 0 0 0 15px
display flex
justify-content right
.tools {
display flex
justify-content right
align-items center
flex-flow row
height 90px
.btn-publish {
padding 2px 10px
// .text {
// margin-right 10px
// }
}
.btn-icon {
background none
padding 6px
transition background 0.6s ease 0s
color #919191
&:hover {
// background #5f5958
// color #e1e1e1
color:var(--el-color-primary)
}
.downloading {
width 16px
}
}
}
}
}
.task {
height 100px
background-color var(--el-bg-color)
border: 1px solid var(--el-border-color-light);
border-radius 5px
display flex
margin-bottom 10px
.left {
display flex
justify-content left
align-items center
padding 20px
width 320px
.title {
font-size 14px
color var(--el-text-color-primary)
white-space: nowrap; /* */
overflow: hidden; /* */
text-overflow: ellipsis; /* */
}
}
.center {
display flex
width 100%
justify-content center
.failed {
display flex
align-items center
color #E4696B
font-size 14px
}
}
.right {
display flex
width 100px
justify-content center
align-items center
}
}
}
.pagination {
margin-top 20px
display flex
justify-content center
}
.music-player {
width 100%
position: fixed;
bottom: 0;
left: 50px;
padding 20px 0
}
}
.btn {
margin-right 10px
color: var((--theme-text-color-primary))
border none
border-radius 5px
padding 5px 10px
cursor pointer
background: var(--btn-bg)
&:hover {
opacity :0.8
}
}
}
.submit-btn {
display flex
align-items: center
margin: 20px 0
justify-content: center;
.el-button {
width 200px
}
}

View File

@@ -1,77 +1,75 @@
@use 'font.scss' as *;
@import 'font.styl' :root[data-theme="dark"] {
:root[data-theme="dark"]{ --text-fb: #fff;
--text-fb:#fff;
--text-color: rgba(255, 255, 255, 1) !important; // 主要的文本颜色 --text-color: rgba(255, 255, 255, 1) !important; // 主要的文本颜色
--normal-color: rgba(163, 174, 208, 1); // 普通颜色 --normal-color: rgba(163, 174, 208, 1); // 普通颜色
--el-text-color-primary: #fff; --el-text-color-primary: #fff;
p, h1, h2, h3, h4, h5, h6, article { p, h1, h2, h3, h4, h5, h6, article {
// color: var(--text-color) !important; // color: var(--text-color) !important;
font-family: $font-regular; font-family: $font-regular;
} }
html, html,
body, body,
#app, #app,
.wrapper { .wrapper {
background: rgb(13, 20, 53) background: rgb(13, 20, 53);
background-color: rgb(13, 20, 53) background-color: rgb(13, 20, 53);
font-family: $font-regular; font-family: $font-regular;
} }
--btnColor: linear-gradient(88deg, #af61f0 1.44%, #5b62ce); --btnColor: linear-gradient(88deg, #af61f0 1.44%, #5b62ce);
--border-active:rgba(255, 255, 255, 0.1); --border-active: rgba(255, 255, 255, 0.1);
--card-bg:#252d58; --card-bg: #252d58;
--chat-bg:#1f243f --chat-bg: #1f243f;
--chat-wel-bg:#2d2f38; --chat-wel-bg: #2d2f38;
--card-bg-table: rgba(17, 28, 68, 1); --card-bg-table: rgba(17, 28, 68, 1);
--theme-bg:rgb(13, 20, 53); --theme-bg: rgb(13, 20, 53);
--theme-bg-color: rgb(13, 20, 53); --theme-bg-color: rgb(13, 20, 53);
--theme-bg-all:rgb(13, 20, 53); --theme-bg-all: rgb(13, 20, 53);
--sign-bg: rgba(27, 37, 75, 1); --sign-bg: rgba(27, 37, 75, 1);
--text-theme-color: #fff; --text-theme-color: #fff;
--text-color-primary: #d1c7ff; --text-color-primary: #d1c7ff;
--theme-text-color-secondary: #a3aed0; --theme-text-color-secondary: #a3aed0;
--theme-text-color-primary: #fff; --theme-text-color-primary: #fff;
--theme-text-primary: #f3f3f3; --theme-text-primary: #f3f3f3;
--line-box:rgba(255, 255, 255, 0.1); --line-box: rgba(255, 255, 255, 0.1);
--el-bg-color:#141a36; --el-bg-color: #141a36;
--el-fill-color-blank: rgba(17, 28, 68, 1); --el-fill-color-blank: rgba(17, 28, 68, 1);
--el-fill-color-light: rgba(86, 86, 95, .2); --el-fill-color-light: rgba(86, 86, 95, 0.2);
--el-color-primary-light-9:rgba(86, 86, 95, .2); --el-color-primary-light-9: rgba(86, 86, 95, 0.2);
--el-text-color-regular: rgba(163, 174, 208, 1) --el-text-color-regular: rgba(163, 174, 208, 1);
--el-border-color:rgb(79, 80, 85);//黑白切换 --el-border-color: rgb(79, 80, 85); //黑白切换
--el-bg-color-overlay: rgba(17, 28, 68, 1); --el-bg-color-overlay: rgba(17, 28, 68, 1);
--el-border-color-light: rgba(255, 255, 255, 0.2); --el-border-color-light: rgba(255, 255, 255, 0.2);
--chat-content-bg:rgba(86, 86, 95, .2); --chat-content-bg: rgba(86, 86, 95, 0.2);
--chat-user-content-bg: #762AA4; --chat-user-content-bg: #762aa4;
--hover-deep-color:#30323c; --hover-deep-color: #30323c;
--tab-title-bg:#525777;//顶部tab栏背景切换 --tab-title-bg: #525777; //顶部tab栏背景切换
--tab-title-color:#fff;//顶部tab栏文字切换 --tab-title-color: #fff; //顶部tab栏文字切换
//深黑色 //深黑色
--bg-deep-color:rgba(255,255,255,0.8); --bg-deep-color: rgba(255, 255, 255, 0.8);
//layout //layout
.more-menus li.moreTitle, .more-menus li.moreTitle,
.twoTittle .title, .twoTittle .title,
.setting-menus span.title, .setting-menus span.title,
.setting-menus li .el-icon, .setting-menus li .el-icon,
.setting-menus li .iconfont, .setting-menus li .iconfont,
.layout .tab-box .menu-list-item{ .layout .tab-box .menu-list-item {
//filter: invert(100%); //filter: invert(100%);
} }
.more-menus span.title{ .more-menus span.title {
color: var(--text-theme-color); color: var(--text-theme-color);
} }
// 操作按钮 // 操作按钮
--btn-bg: rgba(86, 86, 95, .5); --btn-bg: rgba(86, 86, 95, 0.5);
.el-table { .el-table {
// 表格表头背景 // 表格表头背景
--el-fill-color-darker: rgba(100, 100, 100, .5); --el-fill-color-darker: rgba(100, 100, 100, 0.5);
--el-border-color-darker: #73767a; --el-border-color-darker: #73767a;
--el-table-border-color: rgba(100, 100, 100, .5); --el-table-border-color: rgba(100, 100, 100, 0.5);
--el-table-row-hover-bg-color: rgba(16, 21, 43, .8); --el-table-row-hover-bg-color: rgba(16, 21, 43, 0.8);
--el-table-current-row-bg-color: rgba(16, 21, 43, .8); --el-table-current-row-bg-color: rgba(16, 21, 43, 0.8);
} }
// 加载动画 // 加载动画
@@ -87,11 +85,11 @@
--van-button-default-background: #141a36; --van-button-default-background: #141a36;
--van-background: #141a36; --van-background: #141a36;
--van-tabbar-background: #141a36; --van-tabbar-background: #141a36;
--van-nav-bar-background: #1B244A; --van-nav-bar-background: #1b244a;
--van-dropdown-menu-background: #141a36; --van-dropdown-menu-background: #141a36;
// 引用快样式 // 引用快样式
--quote-bg-color: #1F243F; --quote-bg-color: #1f243f;
--quote-text-color: #fff; --quote-text-color: #fff;
// el-dialog 阴影 // el-dialog 阴影

View File

@@ -1,11 +1,9 @@
@use 'font.scss' as *;
@import 'font.styl'
:root[data-theme="light"] { :root[data-theme="light"] {
--text-fb:#000; --text-fb: #000;
--text-color: #5b62ce; // 主要的文本颜色 --text-color: #5b62ce; // 主要的文本颜色
--normal-color: rgba(43, 54, 116, 1); // 普通颜色 --normal-color: rgba(43, 54, 116, 1); // 普通颜色
--theme-textcolor-normal:#5b62ce;; --theme-textcolor-normal: #5b62ce;
p, h1, h2, h3, h4, h5, h6, article { p, h1, h2, h3, h4, h5, h6, article {
font-family: $font-regular; font-family: $font-regular;
} }
@@ -17,36 +15,34 @@
} }
--btnColor: linear-gradient(88deg, #af61f0 1.44%, #5b62ce); --btnColor: linear-gradient(88deg, #af61f0 1.44%, #5b62ce);
--border-active:rgba(134, 140, 255, 1); --border-active: rgba(134, 140, 255, 1);
--code-btnColor: linear-gradient(88deg, #af61f0 1.44%, #5b62ce); --code-btnColor: linear-gradient(88deg, #af61f0 1.44%, #5b62ce);
--card-bg:#fff; --card-bg: #fff;
--chat-bg:#fff; --chat-bg: #fff;
--theme-bg:linear-gradient(88deg, #fff3f3 1.44%, #e7e8ff); --theme-bg: linear-gradient(88deg, #fff3f3 1.44%, #e7e8ff);
--theme-bg-all:#f5f7fd; --theme-bg-all: #f5f7fd;
--theme-bg-color: #f5f7fd; --theme-bg-color: #f5f7fd;
--sign-bg: rgba(244, 247, 254, 1); --sign-bg: rgba(244, 247, 254, 1);
--text-theme-color: rgba(43, 54, 116, 1) --text-theme-color: rgba(43, 54, 116, 1);
--text-color-primary: rgba(67, 24, 255, 1); --text-color-primary: rgba(67, 24, 255, 1);
--line-box:rgba(79, 89, 102, 0.122); --line-box: rgba(79, 89, 102, 0.122);
--theme-text-color-primary: #000; --theme-text-color-primary: #000;
--theme-text-primary: #000; --theme-text-primary: #000;
--theme-text-color-secondary: #666; --theme-text-color-secondary: #666;
--chat-content-bg:#f5f7fc; --chat-content-bg: #f5f7fc;
--chat-user-content-bg: #e0dfff; --chat-user-content-bg: #e0dfff;
--chat-list-bg: #0302020a; --chat-list-bg: #0302020a;
--chat-wel-bg:rgba(247, 247, 248, 1); --chat-wel-bg: rgba(247, 247, 248, 1);
--hover-deep-color:#fff; --hover-deep-color: #fff;
--el-bg-color-overlay: #fff; --el-bg-color-overlay: #fff;
--el-bg-color:#fff; --el-bg-color: #fff;
--el-fill-color-blank: #fff; --el-fill-color-blank: #fff;
--el-pagination-button-bg-color: rgba(86,86,95,0.2); --el-pagination-button-bg-color: rgba(86, 86, 95, 0.2);
--tab-title-bg:#fff;//顶部tab栏背景切换 --tab-title-bg: #fff; //顶部tab栏背景切换
--tab-title-color:#595959;//顶部tab栏文字切换 --tab-title-color: #595959; //顶部tab栏文字切换
// 操作按钮 // 操作按钮
--btn-bg: rgba(100, 100, 100, .1); --btn-bg: rgba(100, 100, 100, 0.1);
// 加载动画 // 加载动画
--el-mask-color: rgba(100, 100, 100, 0.2); --el-mask-color: rgba(100, 100, 100, 0.2);
@@ -60,5 +56,3 @@
// 面板背景 // 面板背景
--panel-bg: linear-gradient(135deg, #f5eafe 0%, #e9e6fc 100%); --panel-bg: linear-gradient(135deg, #f5eafe 0%, #e9e6fc 100%);
} }

View File

@@ -220,7 +220,6 @@
} }
} }
// KeLing 参数面板特有样式 // KeLing 参数面板特有样式
.params-container { .params-container {
// 任务类型标签页 // 任务类型标签页
@@ -268,7 +267,6 @@
color: #f56c6c; color: #f56c6c;
font-size: 20px; font-size: 20px;
} }
} }
.btn-swap { .btn-swap {
@@ -439,7 +437,7 @@
} }
.failed { .failed {
color: #E4696B; color: #e4696b;
} }
.pb-2 { .pb-2 {

View File

@@ -0,0 +1,139 @@
.job-list-box {
@import 'running-job-list.scss';
.finish-job-list {
#waterfall {
display: flex;
justify-content: center;
padding-top: 20px;
flex-flow: column;
.job-item {
width: 100%;
height: 100%;
border: 1px solid #666666;
padding: 6px;
overflow: hidden;
border-radius: 6px;
transition: all 0.3s ease; /* 添加过渡效果 */
position: relative;
.opt {
.opt-line {
margin: 6px 0;
ul {
display: flex;
flex-flow: row;
li {
margin-right: 6px;
a {
padding: 3px 0;
width: 40px;
text-align: center;
border-radius: 5px;
display: block;
cursor: pointer;
background-color: #4e5058;
color: #ffffff;
&:hover {
background-color: #6d6f78;
}
}
}
.show-prompt {
font-size: 20px;
cursor: pointer;
}
}
}
}
.remove {
display: none;
position: absolute;
right: 10px;
top: 10px;
}
&:hover {
.remove {
display: block;
}
}
}
.animate {
&:hover {
box-shadow: 0 0 10px var(--shadow-color); /* 添加阴影效果 */
transform: translateY(-10px); /* 向上移动10像素 */
}
}
}
}
.el-image {
width: 100%;
height: 100%;
overflow: visible;
.el-image-viewer__wrapper {
img {
width: auto;
height: auto;
}
}
.image-slot {
display: flex;
flex-flow: column;
justify-content: center;
align-items: center;
min-height: 220px;
color: #ffffff;
.err-msg-container {
overflow: hidden;
word-break: break-all;
padding: 15px;
.title {
font-size: 20px;
text-align: center;
font-weight: bold;
color: #f56c6c;
margin-bottom: 30px;
}
.opt {
display: flex;
justify-content: center;
}
}
.iconfont {
font-size: 50px;
margin-bottom: 10px;
}
}
}
.el-image.upscale {
img {
height: 310px;
}
.image-slot {
height: 310px;
}
.el-image-viewer__wrapper {
img {
width: auto;
height: auto;
}
}
}
}

View File

@@ -1,146 +0,0 @@
.job-list-box {
@import "running-job-list.styl"
.finish-job-list {
#waterfall {
display flex
justify-content center
padding-top 20px
flex-flow column
.job-item {
width 100%
height 100%
border 1px solid #666666
padding 6px
overflow hidden
border-radius 6px
transition: all 0.3s ease; /* */
position relative
.opt {
.opt-line {
margin 6px 0
ul {
display flex
flex-flow row
li {
margin-right 6px
a {
padding 3px 0
width 40px
text-align center
border-radius 5px
display block
cursor pointer
background-color #4E5058
color #ffffff
&:hover {
background-color #6D6F78
}
}
}
.show-prompt {
font-size 20px
cursor pointer
}
}
}
}
.remove {
display none
position absolute
right 10px
top 10px
}
&:hover {
.remove {
display block
}
}
}
.animate {
&:hover {
box-shadow: 0 0 10px var(--shadow-color); /* */
transform: translateY(-10px); /* 10 */
}
}
}
}
.el-image {
width 100%
height 100%
overflow visible
.el-image-viewer__wrapper {
img {
width auto
height auto
}
}
.image-slot {
display flex
flex-flow column
justify-content center
align-items center
min-height 220px
color #ffffff
.err-msg-container {
overflow hidden
word-break break-all
padding 15px
.title {
font-size 20px
text-align center
font-weight bold
color #f56c6c
margin-bottom 30px
}
.opt {
display flex
justify-content center
}
}
.iconfont {
font-size 50px
margin-bottom 10px
}
}
}
.el-image.upscale {
img {
height 310px
}
.image-slot {
height 310px
}
.el-image-viewer__wrapper {
img {
width auto
height auto
}
}
}
}

View File

@@ -1,7 +1,12 @@
<template> <template>
<div class="right flex-center"> <div class="right flex-center">
<div class="logo"> <div class="logo">
<el-image :src="logo" alt="" style="max-width: 300px; max-height: 300px" class="rounded-full" /> <el-image
:src="logo"
alt=""
style="max-width: 300px; max-height: 300px"
class="rounded-full"
/>
</div> </div>
<div>welcome</div> <div>welcome</div>
<footer-bar /> <footer-bar />
@@ -9,42 +14,43 @@
</template> </template>
<script setup> <script setup>
import FooterBar from "@/components/FooterBar.vue"; import FooterBar from '@/components/FooterBar.vue'
import { getSystemInfo } from "@/store/cache"; import { getSystemInfo } from '@/store/cache'
import { ref } from "vue"; import { ref } from 'vue'
const logo = ref(""); const logo = ref('')
const title = ref(""); const title = ref('')
getSystemInfo() getSystemInfo()
.then((res) => { .then((res) => {
logo.value = res.data.logo; logo.value = res.data.logo
title.value = res.data.title; title.value = res.data.title
}) })
.catch((err) => { .catch((err) => {
console.log(err); console.log(err)
logo.value = "/images/logo.png"; logo.value = '/images/logo.png'
title.value = "Geek-AI"; title.value = 'Geek-AI'
}); })
</script> </script>
<style lang="stylus" scoped> <style lang="scss" scoped>
.right{ .right {
font-size: 40px font-size: 40px;
font-weight: bold font-weight: bold;
color:#fff color: #fff;
flex-direction: column flex-direction: column;
background-image url("~@/assets/img/login-bg.png") background-image: url('~@/assets/img/login-bg.png');
background-size cover background-size: cover;
background-position center background-position: center;
width: 50%; width: 50%;
min-height: 100vh min-height: 100vh;
max-height: 100vh max-height: 100vh;
background-repeat: no-repeat; background-repeat: no-repeat;
position: relative; position: relative;
overflow: hidden; overflow: hidden;
z-index: 1; z-index: 1;
:deep(.foot-container){
:deep(.foot-container) {
position: absolute; position: absolute;
bottom: 20px; bottom: 20px;
width: 100%; width: 100%;
@@ -53,21 +59,23 @@ getSystemInfo()
font-size: 12px; font-size: 12px;
text-align: center; text-align: center;
.footer{ .footer {
a, a,
span{ span {
color: var(--text-fff) color: var(--text-fff);
} }
} }
} }
} }
.logo{
.logo {
margin-bottom: 26px; margin-bottom: 26px;
width: 200px width: 200px;
height: 200px height: 200px;
background: #fff background: #fff;
border-radius: 50% border-radius: 50%;
img{
img {
width: 100%; width: 100%;
object-fit: cover; object-fit: cover;
height: 100%; height: 100%;

View File

@@ -1,18 +1,14 @@
<template> <template>
<div> <div>
<ThemeChange /> <ThemeChange />
<div <div @click="goBack" class="flex back animate__animated animate__pulse animate__infinite">
@click="goBack" <el-icon><ArrowLeftBold /></el-icon>{{ title === '注册' ? '首页' : '返回' }}
class="flex back animate__animated animate__pulse animate__infinite"
>
<el-icon><ArrowLeftBold /></el-icon
>{{ title === "注册" ? "首页" : "返回" }}
</div> </div>
<div class="title">{{ title }}</div> <div class="title">{{ title }}</div>
<div class="smTitle" v-if="title !== '重置密码'"> <div class="smTitle" v-if="title !== '重置密码'">
{{ title === "登录" ? "没有账号" : "已有账号" {{ title === '登录' ? '没有账号' : '已有账号'
}}<span @click="goPageFun" class="text-color-primary sign" }}<span @click="goPageFun" class="text-color-primary sign"
>赶紧{{ title === "登录" ? "注册" : "登录" }}</span >赶紧{{ title === '登录' ? '注册' : '登录' }}</span
> >
</div> </div>
<slot></slot> <slot></slot>
@@ -25,77 +21,82 @@
</template> </template>
<script setup> <script setup>
import { ArrowLeftBold } from "@element-plus/icons-vue"; import ThemeChange from '@/components/ThemeChange.vue'
import ThemeChange from "@/components/ThemeChange.vue"; import { ArrowLeftBold } from '@element-plus/icons-vue'
import { defineProps } from "vue"; import { defineProps } from 'vue'
import { useRouter } from "vue-router"; import { useRouter } from 'vue-router'
const props = defineProps({ const props = defineProps({
title: { title: {
type: String, type: String,
default: "登录" default: '登录',
}, },
smTitle: { type: String, default: "没有账号?" }, smTitle: { type: String, default: '没有账号?' },
goPage: { goPage: {
type: String, type: String,
default: "/register" default: '/register',
} },
}); })
const router = useRouter(); const router = useRouter()
const goBack = () => { const goBack = () => {
if (props.title === "注册") { if (props.title === '注册') {
router.push("/"); router.push('/')
} else { } else {
router.go(-1); router.go(-1)
} }
}; }
const goPageFun = () => { const goPageFun = () => {
if (props.title === "登录") { if (props.title === '登录') {
router.push("/register"); router.push('/register')
} else { } else {
router.push("/login"); router.push('/login')
} }
}; }
</script> </script>
<style lang="stylus" scoped> <style lang="scss" scoped>
.back{ .back {
color:var(--sm-txt) color: var(--sm-txt);
font-size: 14px; font-size: 14px;
margin-bottom: 140px margin-bottom: 140px;
margin-top: 18px margin-top: 18px;
cursor: pointer cursor: pointer;
.el-icon{
margin-right: 6px
}
}
.title{
font-size: 36px
margin-bottom: 16px
color: var(--text-color)
.el-icon {
margin-right: 6px;
} }
.smTitle{ }
color: var(--text-color)
.title {
font-size: 36px;
margin-bottom: 16px;
color: var(--text-color);
}
.smTitle {
color: var(--text-color);
font-size: 14px; font-size: 14px;
margin-bottom: 36px margin-bottom: 36px;
} }
.sign{
.sign {
text-decoration: underline; text-decoration: underline;
cursor :pointer cursor: pointer;
} }
.orline{
color:var(--text-secondary) .orline {
span{ color: var(--text-secondary);
span {
font-size: 14px; font-size: 14px;
margin: 0 10px margin: 0 10px;
}
.lineor {
width: 182px;
height: 1px;
background: var(--text-secondary);
} }
.lineor{ }
width: 182px; height: 1px;
background: var(--text-secondary)
}
}
</style> </style>

View File

@@ -6,7 +6,7 @@
:style="{ :style="{
bottom: bottom + 'px', bottom: bottom + 'px',
right: right + 'px', right: right + 'px',
backgroundColor: bgColor backgroundColor: bgColor,
}" }"
> >
<el-icon><ArrowUpBold /></el-icon> <el-icon><ArrowUpBold /></el-icon>
@@ -14,56 +14,56 @@
</template> </template>
<script> <script>
import { ArrowUpBold } from "@element-plus/icons-vue"; import { ArrowUpBold } from '@element-plus/icons-vue'
export default { export default {
name: "BackTop", name: 'BackTop',
components: { ArrowUpBold }, components: { ArrowUpBold },
props: { props: {
bottom: { bottom: {
type: Number, type: Number,
default: 155 default: 155,
}, },
right: { right: {
type: Number, type: Number,
default: 30 default: 30,
}, },
bgColor: { bgColor: {
type: String, type: String,
default: "#b6aaf9" default: '#b6aaf9',
} },
}, },
data() { data() {
return { return {
showButton: false showButton: false,
}; }
}, },
mounted() { mounted() {
this.checkScroll(); this.checkScroll()
window.addEventListener("resize", this.checkScroll); window.addEventListener('resize', this.checkScroll)
this.$el.parentElement.addEventListener("scroll", this.checkScroll); this.$el.parentElement.addEventListener('scroll', this.checkScroll)
}, },
beforeUnmount() { beforeUnmount() {
window.removeEventListener("resize", this.checkScroll); window.removeEventListener('resize', this.checkScroll)
this.$el.parentElement.removeEventListener("scroll", this.checkScroll); this.$el.parentElement.removeEventListener('scroll', this.checkScroll)
}, },
methods: { methods: {
scrollToTop() { scrollToTop() {
const container = this.$el.parentElement; const container = this.$el.parentElement
container.scrollTo({ container.scrollTo({
top: 0, top: 0,
behavior: "smooth" behavior: 'smooth',
}); })
}, },
checkScroll() { checkScroll() {
const container = this.$el.parentElement; const container = this.$el.parentElement
this.showButton = container.scrollTop > 50; this.showButton = container.scrollTop > 50
} },
} },
}; }
</script> </script>
<style scoped lang="stylus"> <style scoped lang="scss">
.scroll-to-top { .scroll-to-top {
position: fixed; position: fixed;
color: white; color: white;
@@ -72,12 +72,12 @@ export default {
cursor: pointer; cursor: pointer;
outline: none; outline: none;
transition: opacity 0.3s; transition: opacity 0.3s;
width 30px width: 30px;
height 30px height: 30px;
display flex display: flex;
justify-content center justify-content: center;
align-items center align-items: center;
font-size 18px font-size: 18px;
&:hover { &:hover {
opacity: 0.6; opacity: 0.6;

View File

@@ -11,15 +11,15 @@
<el-form label-position="top"> <el-form label-position="top">
<el-form-item label="邮箱地址"> <el-form-item label="邮箱地址">
<el-input v-model="form.email"/> <el-input v-model="form.email" />
</el-form-item> </el-form-item>
<el-form-item label="验证码"> <el-form-item label="验证码">
<el-row :gutter="0"> <el-row :gutter="0">
<el-col :span="16"> <el-col :span="16">
<el-input v-model="form.code" maxlength="6"/> <el-input v-model="form.code" maxlength="6" />
</el-col> </el-col>
<el-col :span="8" style="padding-left: 10px"> <el-col :span="8" style="padding-left: 10px">
<send-msg :receiver="form.email" type="email"/> <send-msg :receiver="form.email" type="email" />
</el-col> </el-col>
</el-row> </el-row>
</el-form-item> </el-form-item>
@@ -28,24 +28,22 @@
<template #footer> <template #footer>
<span class="dialog-footer"> <span class="dialog-footer">
<el-button type="primary" @click="save"> <el-button type="primary" @click="save"> 提交绑定 </el-button>
提交绑定
</el-button>
</span> </span>
</template> </template>
</el-dialog> </el-dialog>
</template> </template>
<script setup> <script setup>
import {computed, ref, watch} from "vue"; import SendMsg from '@/components/SendMsg.vue'
import SendMsg from "@/components/SendMsg.vue"; import { checkSession } from '@/store/cache'
import {ElMessage} from "element-plus"; import { httpPost } from '@/utils/http'
import {httpPost} from "@/utils/http"; import { ElMessage } from 'element-plus'
import {checkSession} from "@/store/cache"; import { computed, ref, watch } from 'vue'
const props = defineProps({ const props = defineProps({
show: Boolean, show: Boolean,
}); })
const showDialog = computed(() => { const showDialog = computed(() => {
return props.show return props.show
@@ -55,52 +53,54 @@ const title = ref('绑定邮箱')
const email = ref('') const email = ref('')
const form = ref({ const form = ref({
email: '', email: '',
code: '' code: '',
}) })
watch(showDialog, (val) => { watch(showDialog, (val) => {
if (val) { if (val) {
form.value.code = '' form.value.code = ''
form.value.email = '' form.value.email = ''
checkSession().then(user => { checkSession().then((user) => {
email.value = user.email email.value = user.email
}) })
} }
}) })
const emits = defineEmits(['hide']); const emits = defineEmits(['hide'])
const save = () => { const save = () => {
if (form.value.code === '') { if (form.value.code === '') {
return ElMessage.error("请输入验证码"); return ElMessage.error('请输入验证码')
} }
httpPost('/api/user/bind/email', form.value).then(() => { httpPost('/api/user/bind/email', form.value)
ElMessage.success("绑定成功") .then(() => {
ElMessage.success('绑定成功')
emits('hide') emits('hide')
}).catch(e => { })
ElMessage.error("绑定失败:" + e.message); .catch((e) => {
ElMessage.error('绑定失败:' + e.message)
}) })
} }
const close = function () { const close = function () {
emits('hide'); emits('hide')
} }
</script> </script>
<style lang="stylus" scoped> <style lang="scss" scoped>
.form { .form {
.text-center { .text-center {
text-align center text-align: center;
padding-bottom 15px padding-bottom: 15px;
font-size 14px font-size: 14px;
color #a1a1a1 color: #a1a1a1;
font-weight 700 font-weight: 700;
} }
.el-form-item__content { .el-form-item__content {
.el-row { .el-row {
width 100% width: 100%;
} }
} }
} }

View File

@@ -11,15 +11,15 @@
<el-form label-position="top"> <el-form label-position="top">
<el-form-item label="手机号"> <el-form-item label="手机号">
<el-input v-model="form.mobile"/> <el-input v-model="form.mobile" />
</el-form-item> </el-form-item>
<el-form-item label="验证码"> <el-form-item label="验证码">
<el-row :gutter="0"> <el-row :gutter="0">
<el-col :span="16"> <el-col :span="16">
<el-input v-model="form.code" maxlength="6"/> <el-input v-model="form.code" maxlength="6" />
</el-col> </el-col>
<el-col :span="8" style="padding-left: 10px"> <el-col :span="8" style="padding-left: 10px">
<send-msg :receiver="form.mobile" size="default" type="mobile"/> <send-msg :receiver="form.mobile" size="default" type="mobile" />
</el-col> </el-col>
</el-row> </el-row>
</el-form-item> </el-form-item>
@@ -28,24 +28,22 @@
<template #footer> <template #footer>
<span class="dialog-footer"> <span class="dialog-footer">
<el-button type="primary" @click="save"> <el-button type="primary" @click="save"> 提交绑定 </el-button>
提交绑定
</el-button>
</span> </span>
</template> </template>
</el-dialog> </el-dialog>
</template> </template>
<script setup> <script setup>
import {computed, ref, watch} from "vue"; import SendMsg from '@/components/SendMsg.vue'
import SendMsg from "@/components/SendMsg.vue"; import { checkSession } from '@/store/cache'
import {ElMessage} from "element-plus"; import { httpPost } from '@/utils/http'
import {httpPost} from "@/utils/http"; import { ElMessage } from 'element-plus'
import {checkSession} from "@/store/cache"; import { computed, ref, watch } from 'vue'
const props = defineProps({ const props = defineProps({
show: Boolean, show: Boolean,
}); })
const showDialog = computed(() => { const showDialog = computed(() => {
return props.show return props.show
@@ -55,55 +53,57 @@ const title = ref('绑定手机')
const mobile = ref('') const mobile = ref('')
const form = ref({ const form = ref({
mobile: '', mobile: '',
code: '' code: '',
}) })
watch(showDialog, (val) => { watch(showDialog, (val) => {
if (val) { if (val) {
form.value = { form.value = {
mobile: '', mobile: '',
code: '' code: '',
} }
checkSession().then(user => { checkSession().then((user) => {
mobile.value = user.mobile mobile.value = user.mobile
}) })
} }
}) })
const emits = defineEmits(['hide']); const emits = defineEmits(['hide'])
const save = () => { const save = () => {
if (form.value.code === '') { if (form.value.code === '') {
return ElMessage.error("请输入验证码"); return ElMessage.error('请输入验证码')
} }
httpPost('/api/user/bind/mobile', form.value).then(() => { httpPost('/api/user/bind/mobile', form.value)
ElMessage.success("绑定成功") .then(() => {
ElMessage.success('绑定成功')
emits('hide') emits('hide')
}).catch(e => { })
ElMessage.error("绑定失败:" + e.message); .catch((e) => {
ElMessage.error('绑定失败:' + e.message)
}) })
} }
const close = function () { const close = function () {
emits('hide'); emits('hide')
} }
</script> </script>
<style lang="stylus" scoped> <style lang="scss" scoped>
.form { .form {
.text-center { .text-center {
text-align center text-align: center;
padding-bottom 15px padding-bottom: 15px;
font-size 14px font-size: 14px;
color #a1a1a1 color: #a1a1a1;
font-weight 700 font-weight: 700;
} }
.el-form-item__content { .el-form-item__content {
.el-row { .el-row {
width 100% width: 100%;
} }
} }
} }

View File

@@ -1,6 +1,6 @@
<template> <template>
<!--拨号组件--> <!--拨号组件-->
<el-container class="calling-container" :style="{height: height}"> <el-container class="calling-container" :style="{ height: height }">
<div class="phone-container"> <div class="phone-container">
<div class="signal"></div> <div class="signal"></div>
<div class="signal"></div> <div class="signal"></div>
@@ -12,40 +12,38 @@
</template> </template>
<script setup> <script setup>
import {onMounted, ref} from "vue"; import { onMounted, ref } from 'vue'
const fullText = "正在接通中..."; const fullText = '正在接通中...'
const text = ref("") const text = ref('')
let index = 0; let index = 0
const props = defineProps({ const props = defineProps({
height: { height: {
type: String, type: String,
default: '100vh' default: '100vh',
} },
}) })
function typeText() { function typeText() {
if (index < fullText.length) { if (index < fullText.length) {
text.value += fullText[index]; text.value += fullText[index]
index++; index++
setTimeout(typeText, 300); // 每300毫秒显示一个字 setTimeout(typeText, 300) // 每300毫秒显示一个字
} else { } else {
setTimeout(() => { setTimeout(() => {
text.value = ''; text.value = ''
index = 0; index = 0
typeText(); typeText()
}, 1000); // 等待1秒后重新开始 }, 1000) // 等待1秒后重新开始
} }
} }
onMounted(() => { onMounted(() => {
typeText() typeText()
}) })
</script> </script>
<style scoped lang="stylus"> <style scoped lang="scss">
.calling-container { .calling-container {
background-color: #000; background-color: #000;
display: flex; display: flex;
@@ -55,7 +53,7 @@ onMounted(() => {
margin: 0; margin: 0;
overflow: hidden; overflow: hidden;
font-family: Arial, sans-serif; font-family: Arial, sans-serif;
width 100vw width: 100vw;
.phone-container { .phone-container {
position: relative; position: relative;
@@ -71,9 +69,11 @@ onMounted(() => {
width: 60px; width: 60px;
height: 60px; height: 60px;
background-color: #00ffcc; background-color: #00ffcc;
mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Cpath d='M20 15.5c-1.25 0-2.45-.2-3.57-.57a1.02 1.02 0 0 0-1.02.24l-2.2 2.2a15.074 15.074 0 0 1-6.59-6.59l2.2-2.2c.27-.27.35-.68.24-1.02a11.36 11.36 0 0 1-.57-3.57c0-.55-.45-1-1-1H4c-.55 0-1 .45-1 1 0 9.39 7.61 17 17 17 .55 0 1-.45 1-1v-3.5c0-.55-.45-1-1-1zM5.03 5h1.5c.07.89.22 1.76.46 2.59l-1.2 1.2c-.41-1.2-.67-2.47-.76-3.79zM19 18.97c-1.32-.09-2.59-.35-3.8-.75l1.2-1.2c.85.24 1.72.39 2.6.45v1.5z'/%3E%3C/svg%3E") no-repeat 50% 50%; mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Cpath d='M20 15.5c-1.25 0-2.45-.2-3.57-.57a1.02 1.02 0 0 0-1.02.24l-2.2 2.2a15.074 15.074 0 0 1-6.59-6.59l2.2-2.2c.27-.27.35-.68.24-1.02a11.36 11.36 0 0 1-.57-3.57c0-.55-.45-1-1-1H4c-.55 0-1 .45-1 1 0 9.39 7.61 17 17 17 .55 0 1-.45 1-1v-3.5c0-.55-.45-1-1-1zM5.03 5h1.5c.07.89.22 1.76.46 2.59l-1.2 1.2c-.41-1.2-.67-2.47-.76-3.79zM19 18.97c-1.32-.09-2.59-.35-3.8-.75l1.2-1.2c.85.24 1.72.39 2.6.45v1.5z'/%3E%3C/svg%3E")
no-repeat 50% 50%;
mask-size: cover; mask-size: cover;
-webkit-mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Cpath d='M20 15.5c-1.25 0-2.45-.2-3.57-.57a1.02 1.02 0 0 0-1.02.24l-2.2 2.2a15.074 15.074 0 0 1-6.59-6.59l2.2-2.2c.27-.27.35-.68.24-1.02a11.36 11.36 0 0 1-.57-3.57c0-.55-.45-1-1-1H4c-.55 0-1 .45-1 1 0 9.39 7.61 17 17 17 .55 0 1-.45 1-1v-3.5c0-.55-.45-1-1-1zM5.03 5h1.5c.07.89.22 1.76.46 2.59l-1.2 1.2c-.41-1.2-.67-2.47-.76-3.79zM19 18.97c-1.32-.09-2.59-.35-3.8-.75l1.2-1.2c.85.24 1.72.39 2.6.45v1.5z'/%3E%3C/svg%3E") no-repeat 50% 50%; -webkit-mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Cpath d='M20 15.5c-1.25 0-2.45-.2-3.57-.57a1.02 1.02 0 0 0-1.02.24l-2.2 2.2a15.074 15.074 0 0 1-6.59-6.59l2.2-2.2c.27-.27.35-.68.24-1.02a11.36 11.36 0 0 1-.57-3.57c0-.55-.45-1-1-1H4c-.55 0-1 .45-1 1 0 9.39 7.61 17 17 17 .55 0 1-.45 1-1v-3.5c0-.55-.45-1-1-1zM5.03 5h1.5c.07.89.22 1.76.46 2.59l-1.2 1.2c-.41-1.2-.67-2.47-.76-3.79zM19 18.97c-1.32-.09-2.59-.35-3.8-.75l1.2-1.2c.85.24 1.72.39 2.6.45v1.5z'/%3E%3C/svg%3E")
no-repeat 50% 50%;
-webkit-mask-size: cover; -webkit-mask-size: cover;
animation: shake 0.5s ease-in-out infinite; animation: shake 0.5s ease-in-out infinite;
} }
@@ -108,9 +108,16 @@ onMounted(() => {
} }
@keyframes shake { @keyframes shake {
0%, 100% { transform: translate(-50%, -50%) rotate(0deg); } 0%,
25% { transform: translate(-52%, -48%) rotate(-5deg); } 100% {
75% { transform: translate(-48%, -52%) rotate(5deg); } transform: translate(-50%, -50%) rotate(0deg);
}
25% {
transform: translate(-52%, -48%) rotate(-5deg);
}
75% {
transform: translate(-48%, -52%) rotate(5deg);
}
} }
@keyframes signal { @keyframes signal {
@@ -126,5 +133,4 @@ onMounted(() => {
} }
} }
} }
</style> </style>

View File

@@ -1,8 +1,17 @@
<template> <template>
<el-container class="captcha-box"> <el-container class="captcha-box">
<el-dialog v-model="show" :close-on-click-modal="true" :show-close="isMobileInternal" style="width: 360px; --el-dialog-padding-primary: 5px 15px 15px 15px"> <el-dialog
v-model="show"
:close-on-click-modal="true"
:show-close="isMobileInternal"
style="width: 360px; --el-dialog-padding-primary: 5px 15px 15px 15px"
>
<template #header> <template #header>
<div class="text-center p-3" style="color: var(--el-text-color-primary)" v-if="isMobileInternal"> <div
class="text-center p-3"
style="color: var(--el-text-color-primary)"
v-if="isMobileInternal"
>
<span>人机验证</span> <span>人机验证</span>
</div> </div>
</template> </template>
@@ -31,113 +40,111 @@
</template> </template>
<script setup> <script setup>
import { ref } from "vue"; import CaptchaPlus from '@/components/CaptchaPlus.vue'
import lodash from "lodash"; import SlideCaptcha from '@/components/SlideCaptcha.vue'
import { validateEmail, validateMobile } from "@/utils/validate"; import { showMessageError } from '@/utils/dialog'
import { httpGet, httpPost } from "@/utils/http"; import { httpGet, httpPost } from '@/utils/http'
import CaptchaPlus from "@/components/CaptchaPlus.vue"; import { isMobile } from '@/utils/libs'
import SlideCaptcha from "@/components/SlideCaptcha.vue"; import lodash from 'lodash'
import { isMobile } from "@/utils/libs"; import { ref } from 'vue'
import { showMessageError, showMessageOK } from "@/utils/dialog";
const show = ref(false); const show = ref(false)
const maxDot = ref(5); const maxDot = ref(5)
const imageBase64 = ref(""); const imageBase64 = ref('')
const thumbBase64 = ref(""); const thumbBase64 = ref('')
const captKey = ref(""); const captKey = ref('')
const dots = ref(null); const dots = ref(null)
const isMobileInternal = isMobile(); const isMobileInternal = isMobile()
const emits = defineEmits(["success"]); const emits = defineEmits(['success'])
const handleRequestCaptCode = () => { const handleRequestCaptCode = () => {
httpGet("/api/captcha/get") httpGet('/api/captcha/get')
.then((res) => { .then((res) => {
const data = res.data; const data = res.data
imageBase64.value = data.image; imageBase64.value = data.image
thumbBase64.value = data.thumb; thumbBase64.value = data.thumb
captKey.value = data.key; captKey.value = data.key
}) })
.catch((e) => { .catch((e) => {
showMessageError("获取人机验证数据失败:" + e.message); showMessageError('获取人机验证数据失败:' + e.message)
}); })
}; }
const handleConfirm = (dts) => { const handleConfirm = (dts) => {
if (lodash.size(dts) <= 0) { if (lodash.size(dts) <= 0) {
return showMessageError("请进行人机验证再操作"); return showMessageError('请进行人机验证再操作')
} }
let dotArr = []; let dotArr = []
lodash.forEach(dts, (dot) => { lodash.forEach(dts, (dot) => {
dotArr.push(dot.x, dot.y); dotArr.push(dot.x, dot.y)
}); })
dots.value = dotArr.join(","); dots.value = dotArr.join(',')
httpPost("/api/captcha/check", { httpPost('/api/captcha/check', {
dots: dots.value, dots: dots.value,
key: captKey.value, key: captKey.value,
}) })
.then(() => { .then(() => {
// ElMessage.success('人机验证成功') // ElMessage.success('人机验证成功')
show.value = false; show.value = false
emits("success", { key: captKey.value, dots: dots.value }); emits('success', { key: captKey.value, dots: dots.value })
}) })
.catch(() => { .catch(() => {
showMessageError("人机验证失败"); showMessageError('人机验证失败')
handleRequestCaptCode(); handleRequestCaptCode()
}); })
}; }
const loadCaptcha = () => { const loadCaptcha = () => {
show.value = true; show.value = true
// 手机用滑动验证码 // 手机用滑动验证码
if (isMobile()) { if (isMobile()) {
getSlideCaptcha(); getSlideCaptcha()
} else { } else {
handleRequestCaptCode(); handleRequestCaptCode()
} }
}; }
// 滑动验证码 // 滑动验证码
const bgImg = ref(""); const bgImg = ref('')
const bkImg = ref(""); const bkImg = ref('')
const result = ref(0); const result = ref(0)
const getSlideCaptcha = () => { const getSlideCaptcha = () => {
result.value = 0; result.value = 0
httpGet("/api/captcha/slide/get") httpGet('/api/captcha/slide/get')
.then((res) => { .then((res) => {
bkImg.value = res.data.bkImg; bkImg.value = res.data.bkImg
bgImg.value = res.data.bgImg; bgImg.value = res.data.bgImg
captKey.value = res.data.key; captKey.value = res.data.key
}) })
.catch((e) => { .catch((e) => {
showMessageError("获取人机验证数据失败:" + e.message); showMessageError('获取人机验证数据失败:' + e.message)
}); })
}; }
const handleSlideConfirm = (x) => { const handleSlideConfirm = (x) => {
httpPost("/api/captcha/slide/check", { httpPost('/api/captcha/slide/check', {
key: captKey.value, key: captKey.value,
x: x, x: x,
}) })
.then(() => { .then(() => {
result.value = 1; result.value = 1
show.value = false; show.value = false
emits("success", { key: captKey.value, x: x }); emits('success', { key: captKey.value, x: x })
}) })
.catch(() => { .catch(() => {
result.value = 2; result.value = 2
}); })
}; }
// 导出方法以便父组件调用 // 导出方法以便父组件调用
defineExpose({ defineExpose({
loadCaptcha, loadCaptcha,
}); })
</script> </script>
<style lang="stylus"> <style lang="scss">
.captcha-box { .captcha-box {
.el-dialog { .el-dialog {
.el-dialog__header { .el-dialog__header {

View File

@@ -5,13 +5,24 @@
<img class="wg-cap-wrap__thumb" v-if="thumbBase64Code" :src="thumbBase64Code" alt=" " /> <img class="wg-cap-wrap__thumb" v-if="thumbBase64Code" :src="thumbBase64Code" alt=" " />
</div> </div>
<div class="wg-cap-wrap__body"> <div class="wg-cap-wrap__body">
<img class="wg-cap-wrap__picture" v-if="imageBase64Code" :src="imageBase64Code" alt=" " @click="handleClickPos($event)" /> <img
class="wg-cap-wrap__picture"
v-if="imageBase64Code"
:src="imageBase64Code"
alt=" "
@click="handleClickPos($event)"
/>
<img <img
class="wg-cap-wrap__loading" class="wg-cap-wrap__loading"
src="data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0idXRmLTgiPz4KPHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHhtbG5zOnhsaW5rPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5L3hsaW5rIiBzdHlsZT0ibWFyZ2luOiBhdXRvOyBiYWNrZ3JvdW5kOiByZ2JhKDI0MSwgMjQyLCAyNDMsIDApOyBkaXNwbGF5OiBibG9jazsgc2hhcGUtcmVuZGVyaW5nOiBhdXRvOyIgd2lkdGg9IjY0cHgiIGhlaWdodD0iNjRweCIgdmlld0JveD0iMCAwIDEwMCAxMDAiIHByZXNlcnZlQXNwZWN0UmF0aW89InhNaWRZTWlkIj4KICA8Y2lyY2xlIGN4PSI1MCIgY3k9IjM2LjgxMDEiIHI9IjEzIiBmaWxsPSIjM2U3Y2ZmIj4KICAgIDxhbmltYXRlIGF0dHJpYnV0ZU5hbWU9ImN5IiBkdXI9IjFzIiByZXBlYXRDb3VudD0iaW5kZWZpbml0ZSIgY2FsY01vZGU9InNwbGluZSIga2V5U3BsaW5lcz0iMC40NSAwIDAuOSAwLjU1OzAgMC40NSAwLjU1IDAuOSIga2V5VGltZXM9IjA7MC41OzEiIHZhbHVlcz0iMjM7Nzc7MjMiPjwvYW5pbWF0ZT4KICA8L2NpcmNsZT4KPC9zdmc+" src="data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0idXRmLTgiPz4KPHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHhtbG5zOnhsaW5rPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5L3hsaW5rIiBzdHlsZT0ibWFyZ2luOiBhdXRvOyBiYWNrZ3JvdW5kOiByZ2JhKDI0MSwgMjQyLCAyNDMsIDApOyBkaXNwbGF5OiBibG9jazsgc2hhcGUtcmVuZGVyaW5nOiBhdXRvOyIgd2lkdGg9IjY0cHgiIGhlaWdodD0iNjRweCIgdmlld0JveD0iMCAwIDEwMCAxMDAiIHByZXNlcnZlQXNwZWN0UmF0aW89InhNaWRZTWlkIj4KICA8Y2lyY2xlIGN4PSI1MCIgY3k9IjM2LjgxMDEiIHI9IjEzIiBmaWxsPSIjM2U3Y2ZmIj4KICAgIDxhbmltYXRlIGF0dHJpYnV0ZU5hbWU9ImN5IiBkdXI9IjFzIiByZXBlYXRDb3VudD0iaW5kZWZpbml0ZSIgY2FsY01vZGU9InNwbGluZSIga2V5U3BsaW5lcz0iMC40NSAwIDAuOSAwLjU1OzAgMC40NSAwLjU1IDAuOSIga2V5VGltZXM9IjA7MC41OzEiIHZhbHVlcz0iMjM7Nzc7MjMiPjwvYW5pbWF0ZT4KICA8L2NpcmNsZT4KPC9zdmc+"
alt="正在加载中..." alt="正在加载中..."
/> />
<div v-for="(dot, key) in dots" :key="key" class="wg-cap-wrap__dot" :style="`top: ${dot.y}px; left:${dot.x}px;`"> <div
v-for="(dot, key) in dots"
:key="key"
class="wg-cap-wrap__dot"
:style="`top: ${dot.y}px; left:${dot.x}px;`"
>
<span>{{ dot.index }}</span> <span>{{ dot.index }}</span>
</div> </div>
</div> </div>
@@ -37,20 +48,20 @@
<script> <script>
export default { export default {
name: "CaptchaPlus", name: 'CaptchaPlus',
mounted() { mounted() {
this.$emit("refresh"); this.$emit('refresh')
}, },
props: { props: {
value: Boolean, value: Boolean,
width: { width: {
type: String, type: String,
default: "300px", default: '300px',
}, },
calcPosType: { calcPosType: {
type: String, type: String,
default: "dom", default: 'dom',
validator: (value) => ["dom", "screen"].includes(value), validator: (value) => ['dom', 'screen'].includes(value),
}, },
maxDot: { maxDot: {
type: Number, type: Number,
@@ -63,23 +74,23 @@ export default {
data() { data() {
return { return {
dots: [], dots: [],
imageBase64Code: "", imageBase64Code: '',
thumbBase64Code: "", thumbBase64Code: '',
}; }
}, },
watch: { watch: {
value() { value() {
this.dots = []; this.dots = []
this.imageBase64Code = ""; this.imageBase64Code = ''
this.thumbBase64Code = ""; this.thumbBase64Code = ''
}, },
imageBase64(val) { imageBase64(val) {
this.dots = []; this.dots = []
this.imageBase64Code = val; this.imageBase64Code = val
}, },
thumbBase64(val) { thumbBase64(val) {
this.dots = []; this.dots = []
this.thumbBase64Code = val; this.thumbBase64Code = val
}, },
}, },
methods: { methods: {
@@ -87,7 +98,7 @@ export default {
* @Description: 处理关闭事件 * @Description: 处理关闭事件
*/ */
handleCloseEvent() { handleCloseEvent() {
this.$emit("close"); this.$emit('close')
// this.dots = [] // this.dots = []
// this.imageBase64Code = '' // this.imageBase64Code = ''
// this.thumbBase64Code = '' // this.thumbBase64Code = ''
@@ -96,14 +107,14 @@ export default {
* @Description: 处理刷新事件 * @Description: 处理刷新事件
*/ */
handleRefreshEvent() { handleRefreshEvent() {
this.dots = []; this.dots = []
this.$emit("refresh"); this.$emit('refresh')
}, },
/** /**
* @Description: 处理确认事件 * @Description: 处理确认事件
*/ */
handleConfirmEvent() { handleConfirmEvent() {
this.$emit("confirm", this.dots); this.$emit('confirm', this.dots)
}, },
/** /**
* @Description: 处理dot * @Description: 处理dot
@@ -111,107 +122,105 @@ export default {
*/ */
handleClickPos(ev) { handleClickPos(ev) {
if (this.dots.length >= this.maxDot) { if (this.dots.length >= this.maxDot) {
return; return
} }
const e = ev || window.event; const e = ev || window.event
e.preventDefault(); e.preventDefault()
const dom = e.currentTarget; const dom = e.currentTarget
const { domX, domY } = this.getDomXY(dom); const { domX, domY } = this.getDomXY(dom)
// =============================================== // ===============================================
// @notice 如 getDomXY 不准确可尝试使用 calcLocationLeft 或 calcLocationTop // @notice 如 getDomXY 不准确可尝试使用 calcLocationLeft 或 calcLocationTop
// const domX = this.calcLocationLeft(dom) // const domX = this.calcLocationLeft(dom)
// const domY = this.calcLocationTop(dom) // const domY = this.calcLocationTop(dom)
// =============================================== // ===============================================
let mouseX = navigator.vendor === "Netscape" ? e.pageX : e.x + document.body.offsetTop; let mouseX = navigator.vendor === 'Netscape' ? e.pageX : e.x + document.body.offsetTop
let mouseY = navigator.vendor === "Netscape" ? e.pageY : e.y + document.body.offsetTop; let mouseY = navigator.vendor === 'Netscape' ? e.pageY : e.y + document.body.offsetTop
// 兼容移动触摸事件 // 兼容移动触摸事件
if (e.touches && e.touches.length > 0) { if (e.touches && e.touches.length > 0) {
mouseX = e.touches[0].clientX; mouseX = e.touches[0].clientX
mouseY = e.touches[0].clientY; mouseY = e.touches[0].clientY
} else { } else {
mouseX = e.clientX; mouseX = e.clientX
mouseY = e.clientY; mouseY = e.clientY
} }
// 计算点击的相对位置 // 计算点击的相对位置
const xPos = mouseX - domX; const xPos = mouseX - domX
const yPos = mouseY - domY; const yPos = mouseY - domY
// 转整形 // 转整形
const xp = parseInt(xPos.toString()); const xp = parseInt(xPos.toString())
const yp = parseInt(yPos.toString()); const yp = parseInt(yPos.toString())
// 减去点的一半 // 减去点的一半
this.dots.push({ this.dots.push({
x: xp - 11, x: xp - 11,
y: yp - 11, y: yp - 11,
index: this.dots.length + 1, index: this.dots.length + 1,
}); })
return false; return false
}, },
/** /**
* @Description: 找到元素的屏幕位置 * @Description: 找到元素的屏幕位置
* @param el * @param el
*/ */
calcLocationLeft(el) { calcLocationLeft(el) {
let tmp = el.offsetLeft; let tmp = el.offsetLeft
let val = el.offsetParent; let val = el.offsetParent
while (val != null) { while (val != null) {
tmp += val.offsetLeft; tmp += val.offsetLeft
val = val.offsetParent; val = val.offsetParent
} }
return tmp; return tmp
}, },
/** /**
* @Description: 找到元素的屏幕位置 * @Description: 找到元素的屏幕位置
* @param el * @param el
*/ */
calcLocationTop(el) { calcLocationTop(el) {
let tmp = el.offsetTop; let tmp = el.offsetTop
let val = el.offsetParent; let val = el.offsetParent
while (val != null) { while (val != null) {
tmp += val.offsetTop; tmp += val.offsetTop
val = val.offsetParent; val = val.offsetParent
} }
return tmp; return tmp
}, },
/** /**
* @Description: 找到元素的屏幕位置 * @Description: 找到元素的屏幕位置
* @param dom * @param dom
*/ */
getDomXY(dom) { getDomXY(dom) {
let x = 0; let x = 0
let y = 0; let y = 0
if (dom.getBoundingClientRect) { if (dom.getBoundingClientRect) {
let box = dom.getBoundingClientRect(); let box = dom.getBoundingClientRect()
let D = document.documentElement; let D = document.documentElement
x = box.left + Math.max(D.scrollLeft, document.body.scrollLeft) - D.clientLeft; x = box.left + Math.max(D.scrollLeft, document.body.scrollLeft) - D.clientLeft
y = box.top + Math.max(D.scrollTop, document.body.scrollTop) - D.clientTop; y = box.top + Math.max(D.scrollTop, document.body.scrollTop) - D.clientTop
} else { } else {
while (dom !== document.body) { while (dom !== document.body) {
x += dom.offsetLeft; x += dom.offsetLeft
y += dom.offsetTop; y += dom.offsetTop
dom = dom.offsetParent; dom = dom.offsetParent
} }
} }
return { return {
domX: x, domX: x,
domY: y, domY: y,
}; }
}, },
}, },
}; }
</script> </script>
<style scoped lang="stylus"> <style scoped lang="scss">
.wg-cap-wrap { .wg-cap-wrap {
background: var(--el-bg-color); background: var(--el-bg-color);
-webkit-border-radius: 10px; -webkit-border-radius: 10px;
-moz-border-radius: 10px; -moz-border-radius: 10px;
border-radius: 10px; border-radius: 10px;
-webkit-touch-callout: none; -webkit-touch-callout: none;
-webkit-user-select: none; -webkit-user-select: none;
-moz-user-select: none; -moz-user-select: none;
@@ -227,7 +236,6 @@ export default {
span { span {
padding-right: 5px; padding-right: 5px;
em { em {
padding: 0 3px; padding: 0 3px;
font-weight: bold; font-weight: bold;
@@ -255,7 +263,6 @@ export default {
.wg-cap-wrap__thumb.wg-cap-wrap__hidden { .wg-cap-wrap__thumb.wg-cap-wrap__hidden {
display: none; display: none;
} }
} }
.wg-cap-wrap__body { .wg-cap-wrap__body {
@@ -328,7 +335,6 @@ export default {
.wg-cap-wrap__ico { .wg-cap-wrap__ico {
flex: 1; flex: 1;
img { img {
width: 24px; width: 24px;
height: 24px; height: 24px;
@@ -339,9 +345,9 @@ export default {
} }
.wg-cap-wrap__btn { .wg-cap-wrap__btn {
display flex display: flex;
width: 120px; width: 120px;
justify-content right justify-content: right;
} }
} }
} }

View File

@@ -169,27 +169,27 @@ const isExternalImg = (link, files) => {
} }
</script> </script>
<style lang="stylus"> <style lang="scss">
@import '@/assets/css/markdown/vue.css'; @use '@/assets/css/markdown/vue.css' as *;
.chat-page, .chat-export { .chat-page,
.chat-export {
.chat-line-prompt-list { .chat-line-prompt-list {
background-color: var(--chat-content-bg-list); background-color: var(--chat-content-bg-list);
color: var(--theme-text-color-primary); color: var(--theme-text-color-primary);
justify-content: center; justify-content: center;
width 100% width: 100%;
padding-bottom: 1.5rem; padding-bottom: 1.5rem;
padding-top: 1.5rem; padding-top: 1.5rem;
// border-bottom: 0.5px solid var(--el-border-color); // border-bottom: 0.5px solid var(--el-border-color);
.chat-line-inner { .chat-line-inner {
display flex; display: flex;
width 100%; width: 100%;
max-width 900px; max-width: 900px;
padding-left 10px; padding-left: 10px;
.chat-icon { .chat-icon {
margin-right 20px; margin-right: 20px;
img { img {
width: 36px; width: 36px;
@@ -200,61 +200,61 @@ const isExternalImg = (link, files) => {
} }
.chat-item { .chat-item {
width 100% width: 100%;
padding: 0 5px 0 0; padding: 0 5px 0 0;
overflow: hidden; overflow: hidden;
.file-list-box { .file-list-box {
display flex display: flex;
flex-flow column flex-flow: column;
.image { .image {
display flex display: flex;
flex-flow row flex-flow: row;
margin-right 10px margin-right: 10px;
position relative position: relative;
.el-image { .el-image {
border 1px solid #e3e3e3 border: 1px solid #e3e3e3;
border-radius 10px border-radius: 10px;
margin-bottom 10px margin-bottom: 10px;
max-width 150px max-width: 150px;
max-height 150px max-height: 150px;
} }
} }
.item { .item {
display flex display: flex;
flex-flow row flex-flow: row;
border-radius 10px border-radius: 10px;
background-color: var(--chat-content-bg); background-color: var(--chat-content-bg);
border 1px solid #e3e3e3 border: 1px solid #e3e3e3;
color: var(--theme-text-color-primary); color: var(--theme-text-color-primary);
padding 6px padding: 6px;
margin-bottom 10px margin-bottom: 10px;
.icon { .icon {
.el-image { .el-image {
width 40px width: 40px;
height 40px height: 40px;
} }
} }
.body { .body {
margin-left 8px margin-left: 8px;
font-size 14px font-size: 14px;
.title { .title {
font-weight bold font-weight: bold;
line-height 24px line-height: 24px;
color #0D0D0D color: #0d0d0d;
} }
.info { .info {
color #B4B4B4 color: #b4b4b4;
span { span {
margin-right 10px margin-right: 10px;
} }
} }
} }
@@ -262,7 +262,7 @@ const isExternalImg = (link, files) => {
} }
.content { .content {
word-break break-word; word-break: break-word;
padding: 0; padding: 0;
color: var(--theme-text-color-primary); color: var(--theme-text-color-primary);
font-size: var(--content-font-size); font-size: var(--content-font-size);
@@ -272,59 +272,57 @@ const isExternalImg = (link, files) => {
img { img {
max-width: 600px; max-width: 600px;
border-radius: 10px; border-radius: 10px;
margin 10px 0 margin: 10px 0;
} }
p { p {
line-height 1.5 line-height: 1.5;
} }
p:last-child { p:last-child {
margin-bottom: 0 margin-bottom: 0;
} }
p:first-child { p:first-child {
margin-top 0 margin-top: 0;
} }
} }
.bar { .bar {
padding 10px 10px 10px 0; padding: 10px 10px 10px 0;
.bar-item { .bar-item {
// background-color #f7f7f8; // background-color #f7f7f8;
color #888 color: #888;
padding 3px 5px; padding: 3px 5px;
margin-right 10px; margin-right: 10px;
border-radius 5px; border-radius: 5px;
.el-icon { .el-icon {
position relative position: relative;
top 2px; top: 2px;
} }
} }
} }
} }
} }
} }
.chat-line-prompt-chat { .chat-line-prompt-chat {
background: var(--chat-bg); background: var(--chat-bg);
justify-content: center; justify-content: center;
width 100% width: 100%;
padding-bottom: 1.5rem; padding-bottom: 1.5rem;
padding-top: 1.5rem; padding-top: 1.5rem;
.chat-line-inner { .chat-line-inner {
display flex; display: flex;
width 100%; width: 100%;
padding 0 25px; padding: 0 25px;
flex-flow row-reverse flex-flow: row-reverse;
.chat-icon { .chat-icon {
margin-left 20px; margin-left: 20px;
img { img {
width: 36px; width: 36px;
@@ -337,74 +335,73 @@ const isExternalImg = (link, files) => {
.chat-item { .chat-item {
padding: 0; padding: 0;
overflow: hidden; overflow: hidden;
max-width calc(100% - 110px); max-width: calc(100% - 110px);
.file-list-box { .file-list-box {
display flex display: flex;
flex-flow column flex-flow: column;
.image { .image {
display flex display: flex;
flex-flow row flex-flow: row;
margin-right 10px margin-right: 10px;
position relative position: relative;
.el-image { .el-image {
border 1px solid #e3e3e3 border: 1px solid #e3e3e3;
border-radius 10px border-radius: 10px;
margin-bottom 10px margin-bottom: 10px;
max-width 150px max-width: 150px;
max-height 150px max-height: 150px;
} }
} }
.item { .item {
display flex display: flex;
flex-flow row flex-flow: row;
border-radius 10px border-radius: 10px;
background-color: var(--chat-content-bg); background-color: var(--chat-content-bg);
color: var(--theme-text-color-primary); color: var(--theme-text-color-primary);
border 1px solid #e3e3e3 border: 1px solid #e3e3e3;
padding 6px padding: 6px;
margin-bottom 10px margin-bottom: 10px;
.icon { .icon {
.el-image { .el-image {
width 40px width: 40px;
height 40px height: 40px;
} }
} }
.body { .body {
margin-left 8px margin-left: 8px;
font-size 14px font-size: 14px;
.title { .title {
font-weight bold font-weight: bold;
line-height 24px line-height: 24px;
color #0D0D0D color: #0d0d0d;
} }
.info { .info {
color #B4B4B4 color: #b4b4b4;
span { span {
margin-right 10px margin-right: 10px;
} }
} }
} }
} }
} }
.content-wrapper { .content-wrapper {
display flex display: flex;
flex-flow row-reverse flex-flow: row-reverse;
.content { .content {
word-break break-word; word-break: break-word;
padding: 1rem padding: 1rem;
color var(--theme-text-primary); color: var(--theme-text-primary);
font-size: var(--content-font-size); font-size: var(--content-font-size);
overflow: auto; overflow: auto;
background-color: var(--chat-user-content-bg); background-color: var(--chat-user-content-bg);
@@ -413,79 +410,40 @@ const isExternalImg = (link, files) => {
img { img {
max-width: 600px; max-width: 600px;
border-radius: 10px; border-radius: 10px;
margin 10px 0 margin: 10px 0;
} }
p { p {
line-height 1.5 line-height: 1.5;
} }
p:last-child { p:last-child {
margin-bottom: 0 margin-bottom: 0;
} }
p:first-child { p:first-child {
margin-top 0 margin-top: 0;
} }
} }
} }
.bar { .bar {
padding 10px 10px 10px 0; padding: 10px 10px 10px 0;
.bar-item { .bar-item {
color #888 color: #888;
padding 3px 5px; padding: 3px 5px;
margin-right 10px; margin-right: 10px;
border-radius 5px; border-radius: 5px;
.el-icon { .el-icon {
position relative
top 2px;
}
}
}
}
}
}
}
.operations
display none
position absolute
right 5px
top 5px
.text-box
&:hover
.operations
display flex
gap 5px
.op-edit
cursor pointer
color #409eff
font-size 16px
&:hover
color darken(#409eff, 10%)
.position-relative {
position: relative; position: relative;
} top: 2px;
}
.action-buttons { }
position: absolute; }
top: 10px; }
right: 10px; }
display: none; }
}
.content:hover .action-buttons {
display: block;
} }
</style> </style>

View File

@@ -311,11 +311,13 @@ const handleExpandClick = (e) => {
} }
</script> </script>
<style lang="stylus"> <style lang="scss">
@import '@/assets/css/markdown/vue.css'; @use '@/assets/css/markdown/vue.css' as *;
.chat-page,.chat-export { .chat-page,
--font-family: Menlo,"微软雅黑","Roboto Mono","Courier New",Courier,monospace,"Inter",sans-serif; .chat-export {
--font-family: Menlo, '微软雅黑', 'Roboto Mono', 'Courier New', Courier, monospace, 'Inter',
sans-serif;
font-family: var(--font-family); font-family: var(--font-family);
.chat-line { .chat-line {
@@ -332,118 +334,117 @@ const handleExpandClick = (e) => {
} }
p { p {
line-height 1.5 line-height: 1.5;
code { code {
color:var(--theme-text-color-primary); color: var(--theme-text-color-primary);
font-weight 600 font-weight: 600;
} }
} }
p:last-child { p:last-child {
margin-bottom: 0 margin-bottom: 0;
} }
p:first-child { p:first-child {
margin-top 0 margin-top: 0;
} }
.code-container { .code-container {
background-color #2b2b2b background-color: #2b2b2b;
border-radius 10px border-radius: 10px;
position relative position: relative;
.hljs { .hljs {
border-radius 10px border-radius: 10px;
width 100% width: 100%;
} }
.copy-code-btn { .copy-code-btn {
cursor pointer cursor: pointer;
font-size 12px font-size: 12px;
color #c1c1c1 color: #c1c1c1;
&:hover { &:hover {
color #20a0ff color: #20a0ff;
} }
} }
} }
// 添加代码块展开/收起样式 // 添加代码块展开/收起样式
.code-collapsed { .code-collapsed {
.hljs { .hljs {
max-height 200px max-height: 200px;
overflow hidden overflow: hidden;
position relative position: relative;
transition max-height 0.3s ease transition: max-height 0.3s ease;
&::after { &::after {
content '' content: '';
position absolute position: absolute;
bottom 0 bottom: 0;
left 0 left: 0;
right 0 right: 0;
height 30px height: 30px;
background linear-gradient(transparent, #2b2b2b) background: linear-gradient(transparent, #2b2b2b);
pointer-events none pointer-events: none;
} }
} }
} }
.code-expanded { .code-expanded {
.hljs { .hljs {
max-height none max-height: none;
overflow auto overflow: auto;
transition max-height 0.3s ease transition: max-height 0.3s ease;
&::after { &::after {
display none display: none;
} }
} }
} }
.expand-btn { .expand-btn {
transition color 0.2s ease transition: color 0.2s ease;
&:hover { &:hover {
color #20a0ff !important color: #20a0ff !important;
} }
} }
.lang-name { .lang-name {
color #00e0e0 color: #00e0e0;
} }
// 设置表格边框 // 设置表格边框
table { table {
width 100% width: 100%;
margin-bottom 1rem margin-bottom: 1rem;
border-collapse collapse; border-collapse: collapse;
border 1px solid #dee2e6; border: 1px solid #dee2e6;
background-color:var(--chat-content-bg); background-color: var(--chat-content-bg);
color:var(--theme-text-color-primary); color: var(--theme-text-color-primary);
thead { thead {
th { th {
border 1px solid #dee2e6 border: 1px solid #dee2e6;
vertical-align: bottom vertical-align: bottom;
border-bottom: 2px solid #dee2e6 border-bottom: 2px solid #dee2e6;
padding 10px padding: 10px;
} }
} }
td { td {
border 1px solid #dee2e6 border: 1px solid #dee2e6;
padding 10px padding: 10px;
} }
} }
// 代码快 // 代码快
blockquote { blockquote {
margin 0 0 0.8rem 0 margin: 0 0 0.8rem 0;
background-color: var(--quote-bg-color); background-color: var(--quote-bg-color);
padding: 0.8rem 1.5rem; padding: 0.8rem 1.5rem;
color: var(--quote-text-color); color: var(--quote-text-color);
@@ -458,21 +459,21 @@ const handleExpandClick = (e) => {
.chat-line-reply-list { .chat-line-reply-list {
justify-content: center; justify-content: center;
background-color: var(--chat-content-bg); background-color: var(--chat-content-bg);
color:var(--theme-text-color-primary); color: var(--theme-text-color-primary);
width 100% width: 100%;
padding-bottom: 1.5rem; padding-bottom: 1.5rem;
padding-top: 1.5rem; padding-top: 1.5rem;
border: 1px solid var(--el-border-color); border: 1px solid var(--el-border-color);
border-radius: 10px; border-radius: 10px;
.chat-line-inner { .chat-line-inner {
display flex; display: flex;
width 100%; width: 100%;
max-width 900px; max-width: 900px;
padding-left 10px; padding-left: 10px;
.chat-icon { .chat-icon {
margin-right 20px; margin-right: 20px;
img { img {
width: 36px; width: 36px;
@@ -483,82 +484,79 @@ const handleExpandClick = (e) => {
} }
.chat-item { .chat-item {
width 100% width: 100%;
position: relative; position: relative;
padding: 0; padding: 0;
overflow: hidden; overflow: hidden;
.content-wrapper { .content-wrapper {
min-height 20px; min-height: 20px;
word-break break-word; word-break: break-word;
padding: 0 padding: 0;
color:var(--theme-text-color-primary); color: var(--theme-text-color-primary);
font-size: var(--content-font-size); font-size: var(--content-font-size);
border-radius: 5px; border-radius: 5px;
overflow auto; overflow: auto;
} }
.bar { .bar {
padding 10px 10px 10px 0; padding: 10px 10px 10px 0;
.bar-item { .bar-item {
margin-right 10px; margin-right: 10px;
border-radius 5px; border-radius: 5px;
cursor pointer cursor: pointer;
display flex display: flex;
align-items center align-items: center;
justify-content center justify-content: center;
height 26px height: 26px;
.voice-icon { .voice-icon {
width 20px width: 20px;
height 20px height: 20px;
} }
.el-icon { .el-icon {
position relative position: relative;
top 2px; top: 2px;
cursor pointer cursor: pointer;
} }
} }
.el-button { .el-button {
height 20px height: 20px;
padding 5px 2px; padding: 5px 2px;
} }
} }
} }
.tool-box { .tool-box {
font-size 16px; font-size: 16px;
.el-button { .el-button {
height 20px height: 20px;
padding 5px 2px; padding: 5px 2px;
} }
} }
} }
} }
.chat-line-reply-chat { .chat-line-reply-chat {
justify-content: center; justify-content: center;
padding 1.5rem; padding: 1.5rem;
.chat-line-inner { .chat-line-inner {
display flex; display: flex;
width 100% width: 100%;
flex-flow row flex-flow: row;
.chat-icon { .chat-icon {
margin-right 20px; margin-right: 20px;
img { img {
width: 36px; width: 36px;
height: 36px; height: 36px;
border-radius: 50% border-radius: 50%;
padding: 1px; padding: 1px;
} }
} }
@@ -567,75 +565,71 @@ const handleExpandClick = (e) => {
position: relative; position: relative;
padding: 0; padding: 0;
overflow: hidden; overflow: hidden;
width 100% width: 100%;
max-width calc(100% - 110px) max-width: calc(100% - 110px);
.content-wrapper { .content-wrapper {
display flex display: flex;
.content { .content {
min-height 20px; min-height: 20px;
word-break break-word; word-break: break-word;
padding: 1rem padding: 1rem;
color var(--theme-text-primary); color: var(--theme-text-primary);
font-size: var(--content-font-size); font-size: var(--content-font-size);
overflow auto; overflow: auto;
// background-color #F5F5F5 // background-color #F5F5F5
background-color :var(--chat-content-bg); background-color: var(--chat-content-bg);
border-radius: 0 10px 10px 10px; border-radius: 0 10px 10px 10px;
width 100% width: 100%;
} }
} }
.bar { .bar {
padding 10px 10px 10px 0; padding: 10px 10px 10px 0;
display flex display: flex;
.bar-item { .bar-item {
margin-right 10px; margin-right: 10px;
border-radius 5px; border-radius: 5px;
display flex display: flex;
align-items center align-items: center;
justify-content center justify-content: center;
height 26px height: 26px;
.voice-icon { .voice-icon {
width 20px width: 20px;
height 20px height: 20px;
} }
.el-icon { .el-icon {
position relative position: relative;
top 2px; top: 2px;
cursor pointer cursor: pointer;
} }
} }
.bar-item.bg { .bar-item.bg {
// background-color var( --gray-btn-bg) // background-color var( --gray-btn-bg)
cursor pointer cursor: pointer;
} }
.el-button { .el-button {
height 20px height: 20px;
padding 5px 2px; padding: 5px 2px;
} }
} }
} }
.tool-box { .tool-box {
font-size 16px; font-size: 16px;
.el-button { .el-button {
height 20px height: 20px;
padding 5px 2px; padding: 5px 2px;
} }
} }
} }
} }
} }
</style> </style>

View File

@@ -45,9 +45,9 @@
</template> </template>
<script setup> <script setup>
import { computed, ref, onMounted } from 'vue'
import { useSharedStore } from '@/store/sharedata' import { useSharedStore } from '@/store/sharedata'
import { httpGet } from '@/utils/http' import { httpGet } from '@/utils/http'
import { computed, onMounted, ref } from 'vue'
const store = useSharedStore() const store = useSharedStore()
const data = ref({ const data = ref({
@@ -60,7 +60,7 @@ const props = defineProps({
show: Boolean, show: Boolean,
}) })
const showDialog = ref(props.show) const showDialog = computed(() => props.show)
const emits = defineEmits(['hide']) const emits = defineEmits(['hide'])
const close = function () { const close = function () {
emits('hide', false) emits('hide', false)
@@ -81,8 +81,4 @@ const changeTTSModel = (item) => {
} }
</script> </script>
<style lang="stylus" scoped> <style lang="scss" scoped></style>
.chat-setting {
}
</style>

View File

@@ -5,28 +5,30 @@
</div> </div>
</template> </template>
<script setup> <script setup>
import { onMounted, ref, watch } from 'vue'
import {onMounted, ref, watch} from "vue";
// eslint-disable-next-line no-undef // eslint-disable-next-line no-undef
const props = defineProps({ const props = defineProps({
second: Number, second: Number,
type: { type: {
type: String, type: String,
default: "" default: '',
} },
}); })
// eslint-disable-next-line no-undef // eslint-disable-next-line no-undef
const emits = defineEmits(['timeout']); const emits = defineEmits(['timeout'])
const counter = ref(props.second) const counter = ref(props.second)
const timerStr = ref("") const timerStr = ref('')
const handler = ref(null) const handler = ref(null)
watch(() => props.second, (newVal) => { watch(
() => props.second,
(newVal) => {
counter.value = newVal counter.value = newVal
resetTimer() resetTimer()
}); }
)
onMounted(() => { onMounted(() => {
resetTimer() resetTimer()
@@ -43,7 +45,7 @@ const resetTimer = () => {
formatTimer(counter.value) formatTimer(counter.value)
if (counter.value === 0) { if (counter.value === 0) {
clearInterval(handler.value) clearInterval(handler.value)
emits("timeout") emits('timeout')
} }
counter.value-- counter.value--
}, 1000) }, 1000)
@@ -56,45 +58,44 @@ const formatTimer = (secs) => {
if (secs > 3600) { if (secs > 3600) {
hour = Math.floor(secs / 3600) hour = Math.floor(secs / 3600)
if (hour < 10) { if (hour < 10) {
hour = "0" + hour hour = '0' + hour
} }
secs = secs % 3600 secs = secs % 3600
timer.push(hour + "") timer.push(hour + '')
} else { } else {
timer.push("00 时 ") timer.push('00 时 ')
} }
// 计算分钟 // 计算分钟
if (secs > 60) { if (secs > 60) {
min = Math.floor(secs / 60) min = Math.floor(secs / 60)
if (min < 10) { if (min < 10) {
min = "0" + min min = '0' + min
} }
secs = secs % 60 secs = secs % 60
timer.push(min + "") timer.push(min + '')
} else { } else {
timer.push("00 分 ") timer.push('00 分 ')
} }
// 计算秒数 // 计算秒数
if (secs < 10) { if (secs < 10) {
secs = "0" + secs secs = '0' + secs
} }
timer.push(secs + "") timer.push(secs + '')
timerStr.value = timer.join("") timerStr.value = timer.join('')
} }
// eslint-disable-next-line no-undef // eslint-disable-next-line no-undef
defineExpose({resetTimer}) defineExpose({ resetTimer })
</script> </script>
<style lang="stylus"> <style lang="scss">
.countdown { .countdown {
display flex display: flex;
.el-tag--large { .el-tag--large {
.el-tag__content { .el-tag__content {
font-size 14px font-size: 14px;
} }
} }
} }
</style> </style>

View File

@@ -13,7 +13,9 @@
</div> </div>
<div class="body"> <div class="body">
<div class="title"> <div class="title">
<el-link :href="file.url" target="_blank" style="--el-font-weight-primary: bold">{{ substr(file.name, 30) }}</el-link> <el-link :href="file.url" target="_blank" style="--el-font-weight-primary: bold">{{
substr(file.name, 30)
}}</el-link>
</div> </div>
<div class="info"> <div class="info">
<span>{{ GetFileType(file.ext) }}</span> <span>{{ GetFileType(file.ext) }}</span>
@@ -29,89 +31,94 @@
</template> </template>
<script setup> <script setup>
import { ref } from "vue"; import { FormatFileSize, GetFileIcon, GetFileType } from '@/store/system'
import { CircleCloseFilled } from "@element-plus/icons-vue"; import { isImage, removeArrayItem, substr } from '@/utils/libs'
import { isImage, removeArrayItem, substr } from "@/utils/libs"; import { CircleCloseFilled } from '@element-plus/icons-vue'
import { FormatFileSize, GetFileIcon, GetFileType } from "@/store/system"; import { ref } from 'vue'
const props = defineProps({ const props = defineProps({
files: { files: {
type: Array, type: Array,
default: [], default: [],
}, },
}); })
const emits = defineEmits(["removeFile"]); const emits = defineEmits(['removeFile'])
const fileList = ref(props.files); const fileList = ref(props.files)
const removeFile = (file) => { const removeFile = (file) => {
fileList.value = removeArrayItem(fileList.value, file, (v1, v2) => v1.url === v2.url); fileList.value = removeArrayItem(fileList.value, file, (v1, v2) => v1.url === v2.url)
emits("removeFile", file); emits('removeFile', file)
}; }
</script> </script>
<style scoped lang="stylus"> <style scoped lang="scss">
.chat-file-list { .chat-file-list {
display flex display: flex;
flex-flow row flex-flow: row;
.image { .image {
display flex display: flex;
flex-flow row flex-flow: row;
margin-right 10px margin-right: 10px;
max-width 600px max-width: 600px;
position relative position: relative;
.el-image { .el-image {
height 56px height: 56px;
width 56px width: 56px;
border 1px solid #e3e3e3 border: 1px solid #e3e3e3;
border-radius 10px border-radius: 10px;
} }
} }
.item { .item {
position relative position: relative;
display flex display: flex;
flex-flow row flex-flow: row;
border-radius 10px border-radius: 10px;
background-color:var(--chat-content-bg); background-color: var(--chat-content-bg);
color:var(--theme-text-color-primary); color: var(--theme-text-color-primary);
border 1px solid #e3e3e3 border: 1px solid #e3e3e3;
padding 6px padding: 6px;
margin-right 10px margin-right: 10px;
.icon { .icon {
.el-image { .el-image {
width 40px width: 40px;
height 40px height: 40px;
} }
} }
.body { .body {
margin-left 5px margin-left: 5px;
font-size 14px font-size: 14px;
.title { .title {
line-height 24px line-height: 24px;
color #0D0D0D color: #0d0d0d;
} }
.info { .info {
color #B4B4B4 color: #b4b4b4;
span { span {
margin-right 10px margin-right: 10px;
} }
} }
} }
} }
.action { .action {
position absolute position: absolute;
top -8px top: -8px;
right -8px right: -8px;
color #da0d54 color: #da0d54;
cursor pointer cursor: pointer;
font-size 20px font-size: 20px;
.el-icon { .el-icon {
background-color #fff background-color: #fff;
border-radius 50% border-radius: 50%;
} }
} }
} }

View File

@@ -3,7 +3,14 @@
<a class="file-upload-img" @click="fetchFiles(1)"> <a class="file-upload-img" @click="fetchFiles(1)">
<i class="iconfont icon-attachment-st"></i> <i class="iconfont icon-attachment-st"></i>
</a> </a>
<el-dialog class="file-list-dialog" v-model="show" :close-on-click-modal="true" :show-close="true" :width="800" title="文件管理"> <el-dialog
class="file-list-dialog"
v-model="show"
:close-on-click-modal="true"
:show-close="true"
:width="800"
title="文件管理"
>
<el-scrollbar ref="scrollbarRef" max-height="80vh" style="height: 100%" @scroll="onScroll"> <el-scrollbar ref="scrollbarRef" max-height="80vh" style="height: 100%" @scroll="onScroll">
<div class="file-list"> <div class="file-list">
<el-row :gutter="20"> <el-row :gutter="20">
@@ -25,12 +32,28 @@
<el-col :span="3" v-for="file in fileData.items" :key="file.url"> <el-col :span="3" v-for="file in fileData.items" :key="file.url">
<div class="grid-content"> <div class="grid-content">
<el-tooltip class="box-item" effect="dark" :content="file.name" placement="top"> <el-tooltip class="box-item" effect="dark" :content="file.name" placement="top">
<el-image :src="file.url" fit="cover" v-if="isImage(file.ext)" @click="insertURL(file)" /> <el-image
<el-image :src="GetFileIcon(file.ext)" fit="cover" v-else @click="insertURL(file)" /> :src="file.url"
fit="cover"
v-if="isImage(file.ext)"
@click="insertURL(file)"
/>
<el-image
:src="GetFileIcon(file.ext)"
fit="cover"
v-else
@click="insertURL(file)"
/>
</el-tooltip> </el-tooltip>
<div class="opt"> <div class="opt">
<el-button type="danger" size="small" :icon="Delete" @click="removeFile(file)" circle /> <el-button
type="danger"
size="small"
:icon="Delete"
@click="removeFile(file)"
circle
/>
</div> </div>
</div> </div>
</el-col> </el-col>
@@ -45,180 +68,176 @@
</template> </template>
<script setup> <script setup>
import {reactive, ref} from "vue"; import { checkSession } from '@/store/cache'
import {ElMessage} from "element-plus"; import { useSharedStore } from '@/store/sharedata'
import {httpGet, httpPost} from "@/utils/http"; import { GetFileIcon } from '@/store/system'
import {Delete, Plus} from "@element-plus/icons-vue"; import { closeLoading, showLoading } from '@/utils/dialog'
import {isImage, removeArrayItem} from "@/utils/libs"; import { httpGet, httpPost } from '@/utils/http'
import {GetFileIcon} from "@/store/system"; import { isImage, removeArrayItem } from '@/utils/libs'
import {checkSession} from "@/store/cache"; import { Delete, Plus } from '@element-plus/icons-vue'
import {useSharedStore} from "@/store/sharedata"; import { ElMessage } from 'element-plus'
import {closeLoading, showLoading} from "@/utils/dialog"; import { reactive, ref } from 'vue'
const props = defineProps({ const props = defineProps({
userId: Number, userId: Number,
}); })
const emits = defineEmits(["selected"]); const emits = defineEmits(['selected'])
const show = ref(false); const show = ref(false)
const scrollbarRef = ref(null); const scrollbarRef = ref(null)
const fileData = reactive({ const fileData = reactive({
items: [], items: [],
page: 1, page: 1,
isLastPage: true, isLastPage: true,
}); })
const store = useSharedStore(); const store = useSharedStore()
const fetchFiles = (pageNo) => { const fetchFiles = (pageNo) => {
checkSession() checkSession()
.then(() => { .then(() => {
show.value = true; show.value = true
httpPost("/api/upload/list", { page: pageNo || 1, page_size: 30 }) httpPost('/api/upload/list', { page: pageNo || 1, page_size: 30 })
.then((res) => { .then((res) => {
const { items, page, total_page } = res.data; const { items, page, total_page } = res.data
if (page === 1) { if (page === 1) {
fileData.items = items; fileData.items = items
} else { } else {
fileData.items = [...fileData.items, ...items]; fileData.items = [...fileData.items, ...items]
} }
fileData.isLastPage = page === total_page; fileData.isLastPage = page === total_page
if (!fileData.isLastPage) { if (!fileData.isLastPage) {
fileData.page = page + 1; fileData.page = page + 1
} }
}) })
.catch((e) => { .catch((e) => {
showMessageError("获取文件列表失败:" + e.message); showMessageError('获取文件列表失败:' + e.message)
}); })
}) })
.catch(() => { .catch(() => {
store.setShowLoginDialog(true); store.setShowLoginDialog(true)
}); })
}; }
// el-scrollbar 滚动回调 // el-scrollbar 滚动回调
const onScroll = (options) => { const onScroll = (options) => {
const wrapRef = scrollbarRef.value.wrapRef; const wrapRef = scrollbarRef.value.wrapRef
scrollbarRef.value.moveY = (wrapRef.scrollTop * 100) / wrapRef.clientHeight; scrollbarRef.value.moveY = (wrapRef.scrollTop * 100) / wrapRef.clientHeight
scrollbarRef.value.moveX = (wrapRef.scrollLeft * 100) / wrapRef.clientWidth; scrollbarRef.value.moveX = (wrapRef.scrollLeft * 100) / wrapRef.clientWidth
const poor = wrapRef.scrollHeight - wrapRef.clientHeight; const poor = wrapRef.scrollHeight - wrapRef.clientHeight
// 判断滚动到底部 自动加载数据 // 判断滚动到底部 自动加载数据
if (options.scrollTop + 2 >= poor && !fileData.isLastPage) { if (options.scrollTop + 2 >= poor && !fileData.isLastPage) {
fetchFiles(fileData.page); fetchFiles(fileData.page)
} }
}; }
const afterRead = (file) => { const afterRead = (file) => {
const formData = new FormData(); const formData = new FormData()
formData.append("file", file.file, file.name); formData.append('file', file.file, file.name)
showLoading("文件上传中..."); showLoading('文件上传中...')
// 执行上传操作 // 执行上传操作
httpPost("/api/upload", formData) httpPost('/api/upload', formData)
.then((res) => { .then((res) => {
fileData.items.unshift(res.data); fileData.items.unshift(res.data)
ElMessage.success({ message: "上传成功", duration: 500 }); ElMessage.success({ message: '上传成功', duration: 500 })
closeLoading() closeLoading()
}) })
.catch((e) => { .catch((e) => {
ElMessage.error("图片上传失败:" + e.message); ElMessage.error('图片上传失败:' + e.message)
closeLoading() closeLoading()
}); })
}; }
const removeFile = (file) => { const removeFile = (file) => {
httpGet("/api/upload/remove?id=" + file.id) httpGet('/api/upload/remove?id=' + file.id)
.then(() => { .then(() => {
fileData.items = removeArrayItem(fileData.items, file, (v1, v2) => { fileData.items = removeArrayItem(fileData.items, file, (v1, v2) => {
return v1.id === v2.id; return v1.id === v2.id
}); })
ElMessage.success("文件删除成功!"); ElMessage.success('文件删除成功!')
fetchFiles(1); fetchFiles(1)
}) })
.catch((e) => { .catch((e) => {
ElMessage.error("文件删除失败:" + e.message); ElMessage.error('文件删除失败:' + e.message)
}); })
}; }
const insertURL = (file) => { const insertURL = (file) => {
show.value = false; show.value = false
// 如果是相对路径,处理成绝对路径 // 如果是相对路径,处理成绝对路径
if (file.url.indexOf("http") === -1) { if (file.url.indexOf('http') === -1) {
file.url = location.protocol + "//" + location.host + file.url; file.url = location.protocol + '//' + location.host + file.url
} }
emits("selected", file); emits('selected', file)
}; }
</script> </script>
<style lang="stylus"> <style lang="scss">
.file-select-box { .file-select-box {
.file-upload-img { .file-upload-img {
.iconfont { .iconfont {
font-size: 19px; font-size: 19px;
cursor pointer; cursor: pointer;
} }
} }
.el-dialog { .el-dialog {
.el-dialog__body { .el-dialog__body {
//padding 0 //padding 0
overflow hidden overflow: hidden;
.file-list { .file-list {
margin-right 10px margin-right: 10px;
.grid-content { .grid-content {
margin-bottom 10px margin-bottom: 10px;
position relative position: relative;
.avatar-uploader { .avatar-uploader {
width 100% width: 100%;
display: flex; display: flex;
justify-content: center; justify-content: center;
align-items: center; align-items: center;
border 1px dashed #e1e1e1 border: 1px dashed #e1e1e1;
border-radius 6px border-radius: 6px;
.el-upload { .el-upload {
width 100% width: 100%;
height 80px height: 80px;
} }
} }
.el-image { .el-image {
width 100% width: 100%;
height 80px height: 80px;
border 1px solid #ffffff border: 1px solid #ffffff;
border-radius 6px border-radius: 6px;
cursor pointer cursor: pointer;
&:hover { &:hover {
border 1px solid #20a0ff border: 1px solid #20a0ff;
} }
} }
.iconfont { .iconfont {
color #20a0ff color: #20a0ff;
font-size 40px font-size: 40px;
} }
.opt { .opt {
display none display: none;
position absolute position: absolute;
top 5px top: 5px;
right 5px right: 5px;
} }
&:hover { &:hover {
.opt { .opt {
display block display: block;
} }
} }
} }
} }
} }
} }
} }

View File

@@ -58,33 +58,33 @@ getLicenseInfo()
}) })
</script> </script>
<style scoped lang="stylus"> <style scoped lang="scss">
.foot-container { .foot-container {
position: fixed; position: fixed;
left: 0; left: 0;
bottom: 0; bottom: 0;
width: 100%; width: 100%;
display flex; display: flex;
justify-content center justify-content: center;
background: var(--theme-bg); background: var(--theme-bg);
margin-top -4px margin-top: -4px;
.footer { .footer {
max-width 400px; max-width: 400px;
text-align center; text-align: center;
font-size 14px; font-size: 14px;
padding 20px; padding: 20px;
width 100% width: 100%;
a { a {
color:var(--text-color) color: var(--text-color);
&:hover { &:hover {
text-decoration underline text-decoration: underline;
} }
} }
span{ span {
color:var(--text-color) color: var(--text-color);
} }
} }
} }

View File

@@ -221,7 +221,7 @@ const removeImage = (index) => {
} }
</script> </script>
<style lang="stylus"> <style lang="scss">
.image-upload { .image-upload {
width: 100%; width: 100%;
} }
@@ -297,6 +297,7 @@ const removeImage = (index) => {
justify-content: center; justify-content: center;
} }
} }
.upload-placeholder { .upload-placeholder {
display: flex; display: flex;
flex-direction: column; flex-direction: column;
@@ -311,6 +312,7 @@ const removeImage = (index) => {
.el-upload-dragger { .el-upload-dragger {
width: 100%; width: 100%;
} }
.uploader { .uploader {
width: 100%; width: 100%;
} }

View File

@@ -1,19 +1,14 @@
<template> <template>
<div class="invite-list" v-loading="loading"> <div class="invite-list" v-loading="loading">
<el-row v-if="items.length > 0"> <el-row v-if="items.length > 0">
<el-table <el-table :data="items" :row-key="(row) => row.id" table-layout="auto" border>
:data="items"
:row-key="(row) => row.id"
table-layout="auto"
border
>
<el-table-column prop="username" label="用户" /> <el-table-column prop="username" label="用户" />
<el-table-column prop="invite_code" label="邀请码" /> <el-table-column prop="invite_code" label="邀请码" />
<el-table-column prop="remark" label="邀请奖励" /> <el-table-column prop="remark" label="邀请奖励" />
<el-table-column label="注册时间"> <el-table-column label="注册时间">
<template #default="scope"> <template #default="scope">
<span>{{ dateFormat(scope.row["created_at"]) }}</span> <span>{{ dateFormat(scope.row['created_at']) }}</span>
</template> </template>
</el-table-column> </el-table-column>
</el-table> </el-table>
@@ -36,51 +31,51 @@
</template> </template>
<script setup> <script setup>
import nodata from "@/assets/img/no-data.png"; import nodata from '@/assets/img/no-data.png'
import { onMounted, ref } from "vue"; import { httpGet } from '@/utils/http'
import { httpGet } from "@/utils/http"; import { dateFormat } from '@/utils/libs'
import { ElMessage } from "element-plus"; import Clipboard from 'clipboard'
import { dateFormat } from "@/utils/libs"; import { ElMessage } from 'element-plus'
import Clipboard from "clipboard"; import { onMounted, ref } from 'vue'
const items = ref([]); const items = ref([])
const total = ref(0); const total = ref(0)
const page = ref(1); const page = ref(1)
const pageSize = ref(10); const pageSize = ref(10)
const loading = ref(true); const loading = ref(true)
onMounted(() => { onMounted(() => {
fetchData(); fetchData()
const clipboard = new Clipboard(".copy-order-no"); const clipboard = new Clipboard('.copy-order-no')
clipboard.on("success", () => { clipboard.on('success', () => {
ElMessage.success("复制成功"); ElMessage.success('复制成功')
}); })
clipboard.on("error", () => { clipboard.on('error', () => {
ElMessage.error("复制失败"); ElMessage.error('复制失败')
}); })
}); })
// 获取数据 // 获取数据
const fetchData = () => { const fetchData = () => {
httpGet("/api/invite/list", { page: page.value, page_size: pageSize.value }) httpGet('/api/invite/list', { page: page.value, page_size: pageSize.value })
.then((res) => { .then((res) => {
if (res.data) { if (res.data) {
items.value = res.data.items; items.value = res.data.items
total.value = res.data.total; total.value = res.data.total
page.value = res.data.page; page.value = res.data.page
pageSize.value = res.data.page_size; pageSize.value = res.data.page_size
} }
loading.value = false; loading.value = false
}) })
.catch((e) => { .catch((e) => {
ElMessage.error("获取数据失败" + e.message); ElMessage.error('获取数据失败' + e.message)
}); })
}; }
</script> </script>
<style scoped lang="stylus"> <style scoped lang="scss">
.invite-list { .invite-list {
.pagination { .pagination {
margin: 20px 0 0 0; margin: 20px 0 0 0;
@@ -90,11 +85,11 @@ const fetchData = () => {
} }
.copy-order-no { .copy-order-no {
cursor pointer cursor: pointer;
position relative position: relative;
left 6px left: 6px;
top 2px top: 2px;
color #20a0ff color: #20a0ff;
} }
} }
</style> </style>

View File

@@ -1,7 +1,12 @@
<template> <template>
<div class="item__list-box" ref="containerRef"> <div class="item__list-box" ref="containerRef">
<el-row :gutter="gap"> <el-row :gutter="gap">
<el-col v-for="item in items" :key="item.id" :span="span" :style="{marginBottom:gap+'px'} "> <el-col
v-for="item in items"
:key="item.id"
:span="span"
:style="{ marginBottom: gap + 'px' }"
>
<slot :item="item"></slot> <slot :item="item"></slot>
</el-col> </el-col>
</el-row> </el-row>
@@ -10,23 +15,23 @@
<script setup> <script setup>
// 列表组件 // 列表组件
import {onMounted, ref} from "vue"; import { onMounted, ref } from 'vue'
// eslint-disable-next-line no-undef // eslint-disable-next-line no-undef
const props = defineProps({ const props = defineProps({
items: { items: {
type: Array, type: Array,
required: true required: true,
}, },
gap: { gap: {
type: Number, type: Number,
default: 10 default: 10,
}, },
width: { width: {
type: Number, type: Number,
default: 240 default: 240,
} },
}); })
const containerRef = ref(null) const containerRef = ref(null)
const span = ref(12) const span = ref(12)
@@ -54,10 +59,8 @@ const calcSpan = () => {
window.onresize = () => calcSpan() window.onresize = () => calcSpan()
</script> </script>
<style lang="stylus"> <style lang="scss">
.item__list-box { .item__list-box {
width 100% width: 100%;
} }
</style> </style>

View File

@@ -436,77 +436,75 @@ const doRegister = (verifyData) => {
} }
</script> </script>
<style lang="stylus"> <style lang="scss">
.login-dialog { .login-dialog {
border-radius 10px border-radius: 10px;
.el-tabs__nav { .el-tabs__nav {
display flex display: flex;
width 100% width: 100%;
justify-content space-between justify-content: space-between;
} }
.form { .form {
.block { .block {
margin-bottom 10px margin-bottom: 10px;
} }
.btn-row { .btn-row {
display flex display: flex;
.login-btn { .login-btn {
font-size 16px font-size: 16px;
width 100% width: 100%;
} }
.text { .text {
line-height 40px line-height: 40px;
.el-tag { .el-tag {
cursor pointer cursor: pointer;
} }
} }
.forget { .forget {
margin-left 10px margin-left: 10px;
} }
} }
.c-login { .c-login {
display flex display: flex;
.text { .text {
font-size 16px font-size: 16px;
color #a1a1a1 color: #a1a1a1;
display: flex; display: flex;
align-items: center; align-items: center;
} }
.login-type { .login-type {
display flex display: flex;
justify-content center justify-content: center;
.iconfont { .iconfont {
font-size 18px font-size: 18px;
background: #E9F1F6; background: #e9f1f6;
padding: 8px; padding: 8px;
border-radius: 50%; border-radius: 50%;
} }
.iconfont.icon-wechat { .iconfont.icon-wechat {
color #0bc15f color: #0bc15f;
} }
} }
} }
.text { .text {
color var(--el-text-color-primary) color: var(--el-text-color-primary);
} }
} }
.register-box { .register-box {
.wechat-card { .wechat-card {
text-align center text-align: center;
} }
} }
} }
</style> </style>

View File

@@ -5,11 +5,14 @@
<el-image :src="cover" fit="cover" /> <el-image :src="cover" fit="cover" />
</div> </div>
<div class="info"> <div class="info">
<div class="title">{{title}}</div> <div class="title">{{ title }}</div>
<div class="style"> <div class="style">
<span class="tags">{{ tags }}</span> <span class="tags">{{ tags }}</span>
<span class="text-lightGray"> | </span> <span class="text-lightGray"> | </span>
<span class="time">{{ formatTime(currentTime) }}<span class="split">/</span>{{ formatTime(duration) }}</span> <span class="time"
>{{ formatTime(currentTime) }}<span class="split">/</span
>{{ formatTime(duration) }}</span
>
</div> </div>
</div> </div>
@@ -33,231 +36,238 @@
</div> </div>
<audio ref="audio" @timeupdate="updateProgress" @ended="nextSong"></audio> <audio ref="audio" @timeupdate="updateProgress" @ended="nextSong"></audio>
<el-button v-if="showClose" class="close" type="info" :icon="Close" circle size="small" @click="emits('close')" /> <el-button
v-if="showClose"
class="close"
type="info"
:icon="Close"
circle
size="small"
@click="emits('close')"
/>
</div> </div>
</div> </div>
</template> </template>
<script setup> <script setup>
import {ref, onMounted, watch} from 'vue'; import { showMessageError } from '@/utils/dialog'
import {showMessageError} from "@/utils/dialog"; import { httpGet } from '@/utils/http'
import {Close} from "@element-plus/icons-vue"; import { formatTime } from '@/utils/libs'
import {formatTime} from "@/utils/libs"; import { Close } from '@element-plus/icons-vue'
import {httpGet} from "@/utils/http" import { onMounted, ref, watch } from 'vue'
const audio = ref(null); const audio = ref(null)
const isPlaying = ref(false); const isPlaying = ref(false)
const songIndex = ref(0); const songIndex = ref(0)
const currentTime = ref(0); const currentTime = ref(0)
const duration = ref(100); const duration = ref(100)
const progressPercent = ref(0); const progressPercent = ref(0)
const progressBarRef = ref(null) const progressBarRef = ref(null)
const title = ref("") const title = ref('')
const tags = ref("") const tags = ref('')
const cover = ref("") const cover = ref('')
// eslint-disable-next-line no-undef // eslint-disable-next-line no-undef
const props = defineProps({ const props = defineProps({
songs: { songs: {
type: Array, type: Array,
required: true, required: true,
default: () => [] default: () => [],
}, },
showClose: { showClose: {
type: Boolean, type: Boolean,
default: false default: false,
} },
}); })
// eslint-disable-next-line no-undef // eslint-disable-next-line no-undef
const emits = defineEmits(['close','play']); const emits = defineEmits(['close', 'play'])
watch(() => props.songs, (newVal) => {
loadSong(newVal[songIndex.value]);
});
watch(
() => props.songs,
(newVal) => {
loadSong(newVal[songIndex.value])
}
)
const loadSong = (song) => { const loadSong = (song) => {
if (!song) { if (!song) {
showMessageError("歌曲加载失败") showMessageError('歌曲加载失败')
return return
} }
title.value = song.title title.value = song.title
tags.value = song.tags tags.value = song.tags
cover.value = song.cover_url cover.value = song.cover_url
audio.value.src = song.audio_url; audio.value.src = song.audio_url
audio.value.load(); audio.value.load()
isPlaying.value = false isPlaying.value = false
audio.value.onloadedmetadata = () => { audio.value.onloadedmetadata = () => {
duration.value = audio.value.duration; duration.value = audio.value.duration
}; }
}; }
const togglePlay = () => { const togglePlay = () => {
if (isPlaying.value) { if (isPlaying.value) {
audio.value.pause(); audio.value.pause()
isPlaying.value = false isPlaying.value = false
} else { } else {
play() play()
} }
}; }
const play = () => { const play = () => {
if (isPlaying.value) { if (isPlaying.value) {
return return
} }
audio.value.play(); audio.value.play()
isPlaying.value = true isPlaying.value = true
if (audio.value.currentTime === 0) { if (audio.value.currentTime === 0) {
emits("play") emits('play')
// 增加播放数量 // 增加播放数量
httpGet("/api/suno/play",{song_id:props.songs[songIndex.value].song_id}).then().catch() httpGet('/api/suno/play', { song_id: props.songs[songIndex.value].song_id }).then().catch()
} }
} }
const prevSong = () => { const prevSong = () => {
songIndex.value = (songIndex.value - 1 + props.songs.length) % props.songs.length; songIndex.value = (songIndex.value - 1 + props.songs.length) % props.songs.length
loadSong(props.songs[songIndex.value]); loadSong(props.songs[songIndex.value])
audio.value.play(); audio.value.play()
isPlaying.value = true; isPlaying.value = true
}; }
const nextSong = () => { const nextSong = () => {
songIndex.value = (songIndex.value + 1) % props.songs.length; songIndex.value = (songIndex.value + 1) % props.songs.length
loadSong(props.songs[songIndex.value]); loadSong(props.songs[songIndex.value])
audio.value.play(); audio.value.play()
isPlaying.value = true; isPlaying.value = true
}; }
const updateProgress = () => { const updateProgress = () => {
try { try {
currentTime.value = audio.value.currentTime; currentTime.value = audio.value.currentTime
progressPercent.value = (currentTime.value / duration.value) * 100; progressPercent.value = (currentTime.value / duration.value) * 100
} catch (e) { } catch (e) {
console.error(e.message) console.error(e.message)
} }
}; }
const setProgress = (event) => { const setProgress = (event) => {
const totalWidth = progressBarRef.value.offsetWidth; const totalWidth = progressBarRef.value.offsetWidth
const clickX = event.offsetX; const clickX = event.offsetX
const audioDuration = audio.value.duration; const audioDuration = audio.value.duration
audio.value.currentTime = (clickX / totalWidth) * audioDuration; audio.value.currentTime = (clickX / totalWidth) * audioDuration
}; }
// eslint-disable-next-line no-undef // eslint-disable-next-line no-undef
defineExpose({ defineExpose({
play play,
}); })
onMounted(() => { onMounted(() => {
loadSong(props.songs[songIndex.value]); loadSong(props.songs[songIndex.value])
}); })
</script> </script>
<style lang="stylus" scoped> <style lang="scss" scoped>
.player { .player {
display flex display: flex;
justify-content center justify-content: center;
width 100% width: 100%;
.container { .container {
display flex display: flex;
background-color: #363030; background-color: #363030;
border-radius: 10px; border-radius: 10px;
border 1px solid #544F4F; border: 1px solid #544f4f;
padding: 5px; padding: 5px;
width: 80% width: 80%;
text-align: center; text-align: center;
position relative position: relative;
overflow hidden overflow: hidden;
.cover { .cover {
.el-image { .el-image {
border-radius: 50%; border-radius: 50%;
width 50px width: 50px;
} }
} }
.info { .info {
padding 0 10px padding: 0 10px;
min-width 300px min-width: 300px;
display flex display: flex;
justify-content center justify-content: center;
align-items flex-start align-items: flex-start;
flex-flow column flex-flow: column;
line-height 1.5 line-height: 1.5;
.title { .title {
font-weight 700 font-weight: 700;
font-size 16px font-size: 16px;
color #ffffff color: #ffffff;
} }
.style { .style {
font-size 14px font-size: 14px;
display flex display: flex;
color #e1e1e1 color: #e1e1e1;
.tags { .tags {
font-weight 600 font-weight: 600;
white-space: nowrap; /* 防止文本换行 */ white-space: nowrap;
overflow: hidden; /* 隐藏溢出的文本 */ overflow: hidden;
text-overflow: ellipsis; /* 使用省略号表示溢出的文本 */ text-overflow: ellipsis;
max-width 200px max-width: 200px;
} }
.text-lightGray { .text-lightGray {
color: rgb(114 110 108); color: rgb(114, 110, 108);
padding 0 3px padding: 0 3px;
} }
.time { .time {
font-family 'Input Sans' font-family: 'Input Sans';
font-weight 700 font-weight: 700;
.split { .split {
font-size 12px font-size: 12px;
position relative position: relative;
top -2px top: -2px;
margin 0 1px 0 3px margin: 0 1px 0 3px;
} }
} }
} }
} }
.controls-container { .controls-container {
width 100% width: 100%;
display flex display: flex;
flex-flow column flex-flow: column;
justify-content center justify-content: center;
.controls { .controls {
display: flex; display: flex;
justify-content: space-around; justify-content: space-around;
margin-bottom 10px margin-bottom: 10px;
.control-btn { .control-btn {
background: none; background: none;
border: none; border: none;
color: #fff; color: #fff;
cursor: pointer; cursor: pointer;
background-color #363030 background-color: #363030;
border-radius 5px border-radius: 5px;
padding 6px padding: 6px;
.iconfont { .iconfont {
font-size 20px font-size: 20px;
} }
&:hover { &:hover {
background-color #5F5958 background-color: #5f5958;
} }
} }
} }
} }
.progress-bar { .progress-bar {
position absolute position: absolute;
width 100% width: 100%;
left 0 left: 0;
bottom 0 bottom: 0;
height: 8px; height: 8px;
background-color: #555; background-color: #555;
cursor: pointer; cursor: pointer;
@@ -268,15 +278,13 @@ onMounted(() => {
border-radius: 5px; border-radius: 5px;
width: 0; width: 0;
} }
} }
.close { .close {
position absolute position: absolute;
right 10px right: 10px;
top 15px top: 15px;
} }
} }
} }
</style> </style>

View File

@@ -11,13 +11,13 @@
<div class="form" id="password-form"> <div class="form" id="password-form">
<el-form :model="form" label-width="120px"> <el-form :model="form" label-width="120px">
<el-form-item label="原始密码"> <el-form-item label="原始密码">
<el-input v-model="form['old_pass']" type="password"/> <el-input v-model="form['old_pass']" type="password" />
</el-form-item> </el-form-item>
<el-form-item label="新密码"> <el-form-item label="新密码">
<el-input v-model="form['password']" type="password"/> <el-input v-model="form['password']" type="password" />
</el-form-item> </el-form-item>
<el-form-item label="确认密码"> <el-form-item label="确认密码">
<el-input v-model="form['repass']" type="password"/> <el-input v-model="form['repass']" type="password" />
</el-form-item> </el-form-item>
</el-form> </el-form>
</div> </div>
@@ -25,64 +25,64 @@
<template #footer> <template #footer>
<span class="dialog-footer"> <span class="dialog-footer">
<el-button @click="close">关闭</el-button> <el-button @click="close">关闭</el-button>
<el-button type="primary" @click="save"> <el-button type="primary" @click="save"> 保存 </el-button>
保存
</el-button>
</span> </span>
</template> </template>
</el-dialog> </el-dialog>
</template> </template>
<script setup> <script setup>
import {computed, ref} from "vue" import { httpPost } from '@/utils/http'
import {httpPost} from "@/utils/http"; import { ElMessage } from 'element-plus'
import {ElMessage} from "element-plus"; import { computed, ref } from 'vue'
const props = defineProps({ const props = defineProps({
show: Boolean, show: Boolean,
}); })
const showDialog = computed(() => { const showDialog = computed(() => {
return props.show return props.show
}) })
const form = ref({}) const form = ref({})
const emits = defineEmits(['hide', 'logout']); const emits = defineEmits(['hide', 'logout'])
const save = function () { const save = function () {
if (!form.value['password'] || form.value['password'].length < 8) { if (!form.value['password'] || form.value['password'].length < 8) {
return ElMessage.error({message: "密码的长度为8-16个字符", appendTo: "#password-form"}); return ElMessage.error({ message: '密码的长度为8-16个字符', appendTo: '#password-form' })
} }
if (form.value['repass'] !== form.value['password']) { if (form.value['repass'] !== form.value['password']) {
return ElMessage.error({message: '两次输入密码不一致', appendTo: '#password-form'}); return ElMessage.error({ message: '两次输入密码不一致', appendTo: '#password-form' })
} }
httpPost('/api/user/password', form.value).then(() => { httpPost('/api/user/password', form.value)
.then(() => {
ElMessage.success({ ElMessage.success({
message: '更新成功', message: '更新成功',
appendTo: '#password-form', appendTo: '#password-form',
duration: 1000, duration: 1000,
onClose: () => emits('logout', false) onClose: () => emits('logout', false),
}) })
}).catch((e) => { })
.catch((e) => {
ElMessage.error({ ElMessage.error({
message: '更新失败,' + e.message, message: '更新失败,' + e.message,
appendTo: '#password-form' appendTo: '#password-form',
}) })
}) })
} }
const close = function () { const close = function () {
emits('hide', false); emits('hide', false)
} }
</script> </script>
<style lang="stylus"> <style lang="scss">
.password-dialog { .password-dialog {
.el-dialog { .el-dialog {
--el-dialog-width 90%; --el-dialog-width: 90%;
max-width 650px; max-width: 650px;
.el-dialog__body { .el-dialog__body {
overflow-y auto; overflow-y: auto;
.form { .form {
position relative; position: relative;
.el-message { .el-message {
position: absolute; position: absolute;

View File

@@ -324,6 +324,6 @@ const hangUp = async () => {
defineExpose({ connect, hangUp }) defineExpose({ connect, hangUp })
</script> </script>
<style lang="stylus" scoped> <style lang="scss" scoped>
@import "../assets/css/realtime.styl" @use '../assets/css/realtime.scss' as *;
</style> </style>

View File

@@ -9,30 +9,28 @@
<div class="form" id="bind-mobile-form"> <div class="form" id="bind-mobile-form">
<el-form :model="form"> <el-form :model="form">
<el-form-item> <el-form-item>
<el-input v-model="form.code"/> <el-input v-model="form.code" />
</el-form-item> </el-form-item>
</el-form> </el-form>
</div> </div>
<template #footer> <template #footer>
<span class="dialog-footer"> <span class="dialog-footer">
<el-button type="primary" @click="save"> <el-button type="primary" @click="save"> 立即兑换 </el-button>
立即兑换
</el-button>
</span> </span>
</template> </template>
</el-dialog> </el-dialog>
</template> </template>
<script setup> <script setup>
import {computed, ref} from "vue"; import { showMessageError, showMessageOK } from '@/utils/dialog'
import {ElMessage} from "element-plus"; import { httpPost } from '@/utils/http'
import {httpPost} from "@/utils/http"; import { ElMessage } from 'element-plus'
import {showMessageError, showMessageOK} from "@/utils/dialog"; import { computed, ref } from 'vue'
const props = defineProps({ const props = defineProps({
show: Boolean, show: Boolean,
}); })
const showDialog = computed(() => { const showDialog = computed(() => {
return props.show return props.show
@@ -43,26 +41,26 @@ const form = ref({
code: '', code: '',
}) })
const emits = defineEmits(['hide']); const emits = defineEmits(['hide'])
const save = () => { const save = () => {
if (form.value.code === '') { if (form.value.code === '') {
return ElMessage.error({message: "请输入兑换码"}); return ElMessage.error({ message: '请输入兑换码' })
} }
httpPost('/api/redeem/verify', form.value).then(() => { httpPost('/api/redeem/verify', form.value)
showMessageOK("兑换成功!") .then(() => {
showMessageOK('兑换成功!')
emits('hide', true) emits('hide', true)
}).catch(e => { })
showMessageError("兑换失败:" + e.message) .catch((e) => {
showMessageError('兑换失败:' + e.message)
}) })
} }
const close = function () { const close = function () {
emits('hide', false); emits('hide', false)
} }
</script> </script>
<style scoped> <style scoped lang="scss"></style>
</style>

View File

@@ -1,6 +1,13 @@
<template> <template>
<div class="reset-pass"> <div class="reset-pass">
<el-dialog v-model="showDialog" :close-on-click-modal="true" width="500px" :before-close="close" :title="title" class="reset-pass-dialog"> <el-dialog
v-model="showDialog"
:close-on-click-modal="true"
width="500px"
:before-close="close"
:title="title"
class="reset-pass-dialog"
>
<div class="form"> <div class="form">
<el-form :model="form" label-width="80px" label-position="left"> <el-form :model="form" label-width="80px" label-position="left">
<el-tabs v-model="form.type" class="demo-tabs"> <el-tabs v-model="form.type" class="demo-tabs">
@@ -47,82 +54,81 @@
</template> </template>
<script setup> <script setup>
import { computed, ref } from "vue"; import SendMsg from '@/components/SendMsg.vue'
import SendMsg from "@/components/SendMsg.vue"; import { httpPost } from '@/utils/http'
import { ElMessage } from "element-plus"; import { ElMessage } from 'element-plus'
import { httpPost } from "@/utils/http"; import { computed, ref } from 'vue'
import { validateEmail, validateMobile } from "@/utils/validate";
const props = defineProps({ const props = defineProps({
show: Boolean, show: Boolean,
mobile: String, mobile: String,
}); })
const showDialog = computed(() => { const showDialog = computed(() => {
return props.show; return props.show
}); })
const title = ref("重置密码"); const title = ref('重置密码')
const form = ref({ const form = ref({
mobile: "", mobile: '',
email: "", email: '',
type: "mobile", type: 'mobile',
code: "", code: '',
password: "", password: '',
repass: "", repass: '',
}); })
const emits = defineEmits(["hide"]); const emits = defineEmits(['hide'])
const save = () => { const save = () => {
if (form.value.code === "") { if (form.value.code === '') {
return ElMessage.error("请输入验证码"); return ElMessage.error('请输入验证码')
} }
if (form.value.password.length < 8) { if (form.value.password.length < 8) {
return ElMessage.error("密码长度必须大于8位"); return ElMessage.error('密码长度必须大于8位')
} }
if (form.value.repass !== form.value.password) { if (form.value.repass !== form.value.password) {
return ElMessage.error("两次输入密码不一致"); return ElMessage.error('两次输入密码不一致')
} }
httpPost("/api/user/resetPass", form.value) httpPost('/api/user/resetPass', form.value)
.then(() => { .then(() => {
ElMessage.success({ ElMessage.success({
message: "重置密码成功", message: '重置密码成功',
duration: 1000, duration: 1000,
onClose: () => emits("hide", false), onClose: () => emits('hide', false),
}); })
}) })
.catch((e) => { .catch((e) => {
ElMessage.error("重置密码失败:" + e.message); ElMessage.error('重置密码失败:' + e.message)
}); })
}; }
const close = function () { const close = function () {
emits("hide", false); emits('hide', false)
}; }
</script> </script>
<style lang="stylus"> <style lang="scss">
.reset-pass { .reset-pass {
.form { .form {
padding 0 20px padding: 0 20px;
} }
.code-row { .code-row {
width 100% width: 100%;
.send-button { .send-button {
padding-left 10px padding-left: 10px;
} }
} }
.reset-pass-dialog { .reset-pass-dialog {
.el-dialog__footer { .el-dialog__footer {
text-align center text-align: center;
padding-top 0 padding-top: 0;
} }
.el-dialog__body { .el-dialog__body {
padding 0 padding: 0;
} }
} }
} }

View File

@@ -1,5 +1,10 @@
<template> <template>
<el-dialog v-model="show" :fullscreen="true" @close="close" style="--el-dialog-border-radius: 0px"> <el-dialog
v-model="show"
:fullscreen="true"
@close="close"
style="--el-dialog-border-radius: 0px"
>
<template #header> <template #header>
<div class="header"> <div class="header">
<h3 style="color: var(--text-theme-color)">绘画任务详情</h3> <h3 style="color: var(--text-theme-color)">绘画任务详情</h3>
@@ -121,52 +126,52 @@
</template> </template>
<script setup> <script setup>
import { ref, watch, onMounted } from "vue"; import { showMessageError, showMessageOK } from '@/utils/dialog'
import Clipboard from "clipboard"; import Clipboard from 'clipboard'
import { showMessageOK, showMessageError } from "@/utils/dialog"; import { onMounted, ref, watch } from 'vue'
const props = defineProps({ const props = defineProps({
modelValue: Boolean, modelValue: Boolean,
data: Object, data: Object,
}); })
const item = ref(props.data); const item = ref(props.data)
const show = ref(props.modelValue); const show = ref(props.modelValue)
const emit = defineEmits(["drawSame", "close"]); const emit = defineEmits(['drawSame', 'close'])
const clipboard = ref(null); const clipboard = ref(null)
onMounted(() => { onMounted(() => {
clipboard.value = new Clipboard(".copy-prompt-wall"); clipboard.value = new Clipboard('.copy-prompt-wall')
clipboard.value.on("success", () => { clipboard.value.on('success', () => {
showMessageOK("复制成功!"); showMessageOK('复制成功!')
}); })
clipboard.value.on("error", () => { clipboard.value.on('error', () => {
showMessageError("复制失败!"); showMessageError('复制失败!')
}); })
}); })
watch( watch(
() => props.modelValue, () => props.modelValue,
(newValue) => { (newValue) => {
show.value = newValue; show.value = newValue
} }
); )
watch( watch(
() => props.data, () => props.data,
(newValue) => { (newValue) => {
item.value = newValue; item.value = newValue
} }
); )
const drawSame = (item) => { const drawSame = (item) => {
emit("drawSame", item); emit('drawSame', item)
}; }
const close = () => { const close = () => {
emit("close"); emit('close')
}; }
</script> </script>
<style lang="stylus" scoped></style> <style lang="scss" scoped></style>

View File

@@ -10,12 +10,12 @@
<script setup> <script setup>
// 发送短信验证码组件 // 发送短信验证码组件
import { ref } from "vue"; import Captcha from '@/components/Captcha.vue'
import { validateEmail, validateMobile } from "@/utils/validate"; import { getSystemInfo } from '@/store/cache'
import { httpPost } from "@/utils/http"; import { httpPost } from '@/utils/http'
import { ElMessage } from "element-plus"; import { validateEmail, validateMobile } from '@/utils/validate'
import Captcha from "@/components/Captcha.vue"; import { ElMessage } from 'element-plus'
import { getSystemInfo } from "@/store/cache"; import { ref } from 'vue'
// eslint-disable-next-line no-undef // eslint-disable-next-line no-undef
const props = defineProps({ const props = defineProps({
@@ -23,73 +23,72 @@ const props = defineProps({
size: String, size: String,
type: { type: {
type: String, type: String,
default: "mobile", default: 'mobile',
}, },
}); })
const btnText = ref("发送验证码"); const btnText = ref('发送验证码')
const canSend = ref(true); const canSend = ref(true)
const captchaRef = ref(null); const captchaRef = ref(null)
const enableVerify = ref(false); const enableVerify = ref(false)
getSystemInfo().then((res) => { getSystemInfo().then((res) => {
enableVerify.value = res.data["enabled_verify"]; enableVerify.value = res.data['enabled_verify']
}); })
const sendMsg = () => { const sendMsg = () => {
if (!validateMobile(props.receiver) && props.type === "mobile") { if (!validateMobile(props.receiver) && props.type === 'mobile') {
return ElMessage.error("请输入合法的手机号"); return ElMessage.error('请输入合法的手机号')
} }
if (!validateEmail(props.receiver) && props.type === "email") { if (!validateEmail(props.receiver) && props.type === 'email') {
return ElMessage.error("请输入合法的邮箱地址"); return ElMessage.error('请输入合法的邮箱地址')
} }
if (enableVerify.value) { if (enableVerify.value) {
captchaRef.value.loadCaptcha(); captchaRef.value.loadCaptcha()
} else { } else {
doSendMsg({}); doSendMsg({})
} }
}; }
const doSendMsg = (data) => { const doSendMsg = (data) => {
if (!canSend.value) { if (!canSend.value) {
return; return
} }
canSend.value = false; canSend.value = false
httpPost("/api/sms/code", { httpPost('/api/sms/code', {
receiver: props.receiver, receiver: props.receiver,
key: data.key, key: data.key,
dots: data.dots, dots: data.dots,
x: data.x, x: data.x,
}) })
.then(() => { .then(() => {
if (props.type === "mobile") { if (props.type === 'mobile') {
ElMessage.success("验证码发送成功"); ElMessage.success('验证码发送成功')
} else if (props.type === "email") { } else if (props.type === 'email') {
ElMessage.success("验证码已发送至邮箱,如果长时间未收到,请检查是否在垃圾邮件中!"); ElMessage.success('验证码已发送至邮箱,如果长时间未收到,请检查是否在垃圾邮件中!')
} }
let time = 60; let time = 60
btnText.value = time; btnText.value = time
const handler = setInterval(() => { const handler = setInterval(() => {
time = time - 1; time = time - 1
if (time <= 0) { if (time <= 0) {
clearInterval(handler); clearInterval(handler)
btnText.value = "重新发送"; btnText.value = '重新发送'
canSend.value = true; canSend.value = true
} else { } else {
btnText.value = time; btnText.value = time
} }
}, 1000); }, 1000)
}) })
.catch((e) => { .catch((e) => {
canSend.value = true; canSend.value = true
ElMessage.error("验证码发送失败:" + e.message); ElMessage.error('验证码发送失败:' + e.message)
}); })
}; }
</script> </script>
<style lang="stylus" scoped> <style lang="scss" scoped>
.send-verify-code { .send-verify-code {
.send-btn { .send-btn {
width: 100%; width: 100%;

View File

@@ -34,147 +34,152 @@
<script setup> <script setup>
// eslint-disable-next-line no-undef // eslint-disable-next-line no-undef
import { onMounted, ref, watch } from "vue"; import {
import { ArrowRightBold, CircleCheckFilled, CircleCloseFilled, Refresh } from "@element-plus/icons-vue"; ArrowRightBold,
CircleCheckFilled,
CircleCloseFilled,
Refresh,
} from '@element-plus/icons-vue'
import { onMounted, ref, watch } from 'vue'
// eslint-disable-next-line no-undef // eslint-disable-next-line no-undef
const props = defineProps({ const props = defineProps({
bgImg: String, bgImg: String,
bkImg: String, bkImg: String,
result: Number, result: Number,
}); })
const verifyText = ref("向右滑动完成验证"); const verifyText = ref('向右滑动完成验证')
const verifyMsg = ref(""); const verifyMsg = ref('')
const verifyMsgClass = ref("verify-text success"); const verifyMsgClass = ref('verify-text success')
const blockClass = ref("verify-move-block"); const blockClass = ref('verify-move-block')
const leftBarClass = ref("verify-left-bar"); const leftBarClass = ref('verify-left-bar')
const backgroundImg = ref(""); const backgroundImg = ref('')
const blockImg = ref(""); const blockImg = ref('')
const leftBarWidth = ref(0); const leftBarWidth = ref(0)
const blockLeft = ref(0); const blockLeft = ref(0)
const checked = ref(0); const checked = ref(0)
const time = ref(""); const time = ref('')
watch( watch(
() => props.bgImg, () => props.bgImg,
(newVal) => { (newVal) => {
backgroundImg.value = newVal; backgroundImg.value = newVal
} }
); )
watch( watch(
() => props.bkImg, () => props.bkImg,
(newVal) => { (newVal) => {
blockImg.value = newVal; blockImg.value = newVal
} }
); )
watch( watch(
() => props.result, () => props.result,
(newVal) => { (newVal) => {
checked.value = newVal; checked.value = newVal
if (newVal === 1) { if (newVal === 1) {
verifyMsgClass.value = "verify-text success"; verifyMsgClass.value = 'verify-text success'
blockClass.value = "verify-move-block success"; blockClass.value = 'verify-move-block success'
leftBarClass.value = "verify-left-bar success"; leftBarClass.value = 'verify-left-bar success'
verifyMsg.value = "验证成功"; verifyMsg.value = '验证成功'
setTimeout(() => emits("hide"), 1000); setTimeout(() => emits('hide'), 1000)
} else if (newVal === 2) { } else if (newVal === 2) {
verifyMsgClass.value = "verify-text error"; verifyMsgClass.value = 'verify-text error'
blockClass.value = "verify-move-block error"; blockClass.value = 'verify-move-block error'
leftBarClass.value = "verify-left-bar error"; leftBarClass.value = 'verify-left-bar error'
verifyMsg.value = "验证失败"; verifyMsg.value = '验证失败'
setTimeout(() => { setTimeout(() => {
reset(); reset()
emits("refresh"); emits('refresh')
}, 1000); }, 1000)
} else { } else {
reset(); reset()
} }
} }
); )
// eslint-disable-next-line no-undef // eslint-disable-next-line no-undef
const emits = defineEmits(["confirm", "refresh", "hide"]); const emits = defineEmits(['confirm', 'refresh', 'hide'])
let offsetX = 0, let offsetX = 0,
isDragging = false; isDragging = false
let start = 0; let start = 0
onMounted(() => { onMounted(() => {
const dragBlock = document.getElementById("dragBlock"); const dragBlock = document.getElementById('dragBlock')
dragBlock.addEventListener("mousedown", (evt) => { dragBlock.addEventListener('mousedown', (evt) => {
blockClass.value = "verify-move-block active"; blockClass.value = 'verify-move-block active'
leftBarClass.value = "verify-left-bar active"; leftBarClass.value = 'verify-left-bar active'
leftBarWidth.value = 32; leftBarWidth.value = 32
isDragging = true; isDragging = true
verifyText.value = ""; verifyText.value = ''
offsetX = evt.clientX; offsetX = evt.clientX
start = new Date().getTime(); start = new Date().getTime()
evt.preventDefault(); evt.preventDefault()
}); })
document.body.addEventListener("mousemove", (evt) => { document.body.addEventListener('mousemove', (evt) => {
if (!isDragging) { if (!isDragging) {
return; return
} }
const x = Math.max(evt.clientX - offsetX, 0); const x = Math.max(evt.clientX - offsetX, 0)
blockLeft.value = x; blockLeft.value = x
leftBarWidth.value = x + 32; leftBarWidth.value = x + 32
}); })
document.body.addEventListener("mouseup", () => { document.body.addEventListener('mouseup', () => {
if (!isDragging) { if (!isDragging) {
return; return
} }
time.value = ((new Date().getTime() - start) / 1000).toFixed(2); time.value = ((new Date().getTime() - start) / 1000).toFixed(2)
isDragging = false; isDragging = false
emits("confirm", Math.floor(blockLeft.value)); emits('confirm', Math.floor(blockLeft.value))
}); })
// 触摸事件 // 触摸事件
dragBlock.addEventListener("touchstart", function (e) { dragBlock.addEventListener('touchstart', function (e) {
isDragging = true; isDragging = true
blockClass.value = "verify-move-block active"; blockClass.value = 'verify-move-block active'
leftBarClass.value = "verify-left-bar active"; leftBarClass.value = 'verify-left-bar active'
leftBarWidth.value = 32; leftBarWidth.value = 32
isDragging = true; isDragging = true
verifyText.value = ""; verifyText.value = ''
offsetX = e.touches[0].clientX - dragBlock.getBoundingClientRect().left; offsetX = e.touches[0].clientX - dragBlock.getBoundingClientRect().left
start = new Date().getTime(); start = new Date().getTime()
e.preventDefault(); e.preventDefault()
}); })
document.addEventListener("touchmove", function (e) { document.addEventListener('touchmove', function (e) {
if (!isDragging) { if (!isDragging) {
return; return
} }
e.preventDefault(); e.preventDefault()
const x = Math.max(e.touches[0].clientX - offsetX, 0); const x = Math.max(e.touches[0].clientX - offsetX, 0)
blockLeft.value = x; blockLeft.value = x
leftBarWidth.value = x + 32; leftBarWidth.value = x + 32
}); })
document.addEventListener("touchend", function () { document.addEventListener('touchend', function () {
if (!isDragging) { if (!isDragging) {
return; return
} }
time.value = ((new Date().getTime() - start) / 1000).toFixed(2); time.value = ((new Date().getTime() - start) / 1000).toFixed(2)
isDragging = false; isDragging = false
emits("confirm", Math.floor(blockLeft.value)); emits('confirm', Math.floor(blockLeft.value))
}); })
}); })
// 重置验证码 // 重置验证码
const reset = () => { const reset = () => {
blockClass.value = "verify-move-block"; blockClass.value = 'verify-move-block'
leftBarClass.value = "verify-left-bar"; leftBarClass.value = 'verify-left-bar'
leftBarWidth.value = 0; leftBarWidth.value = 0
blockLeft.value = 0; blockLeft.value = 0
checked.value = 0; checked.value = 0
verifyText.value = "向右滑动完成验证"; verifyText.value = '向右滑动完成验证'
}; }
</script> </script>
<style scoped lang="stylus"> <style scoped lang="scss">
@keyframes expandUp { @keyframes expandUp {
0% { 0% {
transform: scaleY(0); transform: scaleY(0);
@@ -185,21 +190,21 @@ const reset = () => {
} }
.slide-captcha { .slide-captcha {
width 310px width: 310px;
* { * {
margin 0 margin: 0;
padding 0 padding: 0;
} }
.bg-img { .bg-img {
position relative position: relative;
width 310px width: 310px;
.verify-text { .verify-text {
position absolute position: absolute;
bottom 3px bottom: 3px;
padding 5px 10px padding: 5px 10px;
width 290px width: 290px;
color #ffffff color: #ffffff;
animation: expandUp 0.3s ease-in-out forwards; animation: expandUp 0.3s ease-in-out forwards;
transform-origin: bottom center; transform-origin: bottom center;
@@ -207,98 +212,96 @@ const reset = () => {
} }
.verify-text.success { .verify-text.success {
background-color rgba(92,184,92, 0.5) background-color: rgba(92, 184, 92, 0.5);
} }
.verify-text.error { .verify-text.error {
background-color rgba(184,92,92, 0.5) background-color: rgba(184, 92, 92, 0.5);
} }
.refresh { .refresh {
position absolute position: absolute;
right 5px right: 5px;
top 5px top: 5px;
font-size 20px font-size: 20px;
cursor pointer cursor: pointer;
color #ffffff color: #ffffff;
} }
.block { .block {
position absolute position: absolute;
top 0 top: 0;
left 0 left: 0;
} }
} }
.verify { .verify {
.verify-bar-area { .verify-bar-area {
position relative position: relative;
border: 1px solid #dddddd border: 1px solid #dddddd;
overflow hidden overflow: hidden;
height 34px height: 34px;
.verify-msg { .verify-msg {
display flex display: flex;
line-height 32px line-height: 32px;
width 100% width: 100%;
justify-content center justify-content: center;
} }
.verify-left-bar { .verify-left-bar {
position absolute position: absolute;
left 0 left: 0;
top 0 top: 0;
height 32px; height: 32px;
.verify-move-block { .verify-move-block {
position absolute position: absolute;
width: 32px; width: 32px;
height: 32px; height: 32px;
background-color: rgb(255, 255, 255); background-color: rgb(255, 255, 255);
border-top 1px solid #ffffff border-top: 1px solid #ffffff;
border-bottom 1px solid #ffffff border-bottom: 1px solid #ffffff;
border-right 1px solid #dddddd border-right: 1px solid #dddddd;
display flex display: flex;
justify-content center justify-content: center;
align-items center align-items: center;
.el-icon { .el-icon {
font-size 20px font-size: 20px;
cursor pointer cursor: pointer;
} }
} }
.verify-move-block.active { .verify-move-block.active {
background #409eff background: #409eff;
color #ffffff color: #ffffff;
border 1px solid #409eff border: 1px solid #409eff;
} }
.verify-move-block.success { .verify-move-block.success {
background #57AD57 background: #57ad57;
color #ffffff color: #ffffff;
border 1px solid #57AD57 border: 1px solid #57ad57;
} }
.verify-move-block.error { .verify-move-block.error {
background #D9534F background: #d9534f;
color #ffffff color: #ffffff;
border 1px solid #D9534F border: 1px solid #d9534f;
} }
} }
.verify-left-bar.active { .verify-left-bar.active {
background-color #F0FFF0 background-color: #f0fff0;
border 1px solid #409eff border: 1px solid #409eff;
} }
.verify-left-bar.success { .verify-left-bar.success {
background-color #F0FFF0 background-color: #f0fff0;
border 1px solid #57AD57 border: 1px solid #57ad57;
} }
.verify-left-bar.error { .verify-left-bar.error {
background-color #F0FFF0 background-color: #f0fff0;
border 1px solid #D9534F border: 1px solid #d9534f;
} }
} }
} }

View File

@@ -33,6 +33,6 @@ const props = defineProps({
}) })
</script> </script>
<style lang="stylus" scoped> <style lang="scss" scoped>
@import "../assets/css/running-job-list.styl" @use '../assets/css/running-job-list.scss' as *;
</style> </style>

View File

@@ -5,51 +5,53 @@
</template> </template>
<script setup> <script setup>
import { ref } from "vue"; import { useSharedStore } from '@/store/sharedata'
import { useSharedStore } from "@/store/sharedata"; import { ref } from 'vue'
const props = defineProps({ const props = defineProps({
size: { size: {
type: String, type: String,
default: "", default: '',
}, },
}); })
// 定义主题状态,初始值从 localStorage 获取 // 定义主题状态,初始值从 localStorage 获取
const store = useSharedStore(); const store = useSharedStore()
const themePage = ref(store.theme || "light"); const themePage = ref(store.theme || 'light')
// 切换主题函数 // 切换主题函数
const toggleTheme = () => { const toggleTheme = () => {
themePage.value = themePage.value === "light" ? "dark" : "light"; themePage.value = themePage.value === 'light' ? 'dark' : 'light'
store.setTheme(themePage.value); // 保存主题 store.setTheme(themePage.value) // 保存主题
}; }
</script> </script>
<style lang="stylus" scoped> <style lang="scss" scoped>
.theme-box{ .theme-box {
z-index :111 z-index: 111;
position: fixed; position: fixed;
right: 40px; right: 40px;
bottom: 150px; bottom: 150px;
cursor: pointer; cursor: pointer;
border: 1px solid #ccc; border: 1px solid #ccc;
border-radius: 50%; border-radius: 50%;
width 35px; width: 35px;
height: 35px; height: 35px;
line-height: 35px; line-height: 35px;
text-align: center; text-align: center;
// background-color: rgb(146, 147, 148); // background-color: rgb(146, 147, 148);
background: linear-gradient(135deg, rgba(134, 140, 255, 1) 0%, rgba(67, 24, 255, 1) 100%); background: linear-gradient(135deg, rgba(134, 140, 255, 1) 0%, rgba(67, 24, 255, 1) 100%);
transition: all 0.3s ease; transition: all 0.3s ease;
&:hover{
&:hover {
transform: scale(1.1); transform: scale(1.1);
} }
&:active{
&:active {
transform: scale(0.9); transform: scale(0.9);
} }
.iconfont{
.iconfont {
font-size: 20px; font-size: 20px;
color: yellow; color: yellow;
transition: transform 0.3s ease; transition: transform 0.3s ease;

View File

@@ -17,21 +17,20 @@
</template> </template>
<script setup> <script setup>
import {computed, ref, watch} from "vue"; import { checkSession } from '@/store/cache'
import {httpGet} from "@/utils/http"; import { showMessageError } from '@/utils/dialog'
import {checkSession} from "@/store/cache"; import { httpGet } from '@/utils/http'
import {showMessageError} from "@/utils/dialog"; import { computed, ref, watch } from 'vue'
const props = defineProps({ const props = defineProps({
show: Boolean, show: Boolean,
}); })
const emits = defineEmits(['hide']); const emits = defineEmits(['hide'])
const showDialog = computed(() => { const showDialog = computed(() => {
return props.show return props.show
}) })
const title = ref('绑定第三方登录') const title = ref('绑定第三方登录')
const openid = ref('') const openid = ref('')
const wechatBindURL = ref('') const wechatBindURL = ref('')
@@ -39,53 +38,55 @@ const loading = ref(true)
watch(showDialog, (val) => { watch(showDialog, (val) => {
if (val) { if (val) {
checkSession().then(user => { checkSession().then((user) => {
openid.value = user.openid openid.value = user.openid
}) })
const returnURL = `${location.protocol}//${location.host}/login/callback?action=bind` const returnURL = `${location.protocol}//${location.host}/login/callback?action=bind`
httpGet("/api/user/clogin?return_url="+returnURL).then(res => { httpGet('/api/user/clogin?return_url=' + returnURL)
.then((res) => {
wechatBindURL.value = res.data.url wechatBindURL.value = res.data.url
loading.value = false loading.value = false
}).catch(e => { })
.catch((e) => {
showMessageError(e.message) showMessageError(e.message)
}) })
} }
}) })
const close = function () { const close = function () {
emits('hide'); emits('hide')
} }
</script> </script>
<style lang="stylus" scoped> <style lang="scss" scoped>
.third-login { .third-login {
display flex display: flex;
justify-content center justify-content: center;
min-height 100px min-height: 100px;
.item { .item {
display flex display: flex;
flex-flow column flex-flow: column;
align-items center align-items: center;
.link { .link {
display flex display: flex;
.iconfont { .iconfont {
font-size 30px font-size: 30px;
cursor pointer cursor: pointer;
background #e9f1f6 background: #e9f1f6;
padding 10px padding: 10px;
border-radius 50% border-radius: 50%;
} }
margin-bottom 10px margin-bottom: 10px;
} }
.text { .text {
font-size 14px font-size: 14px;
} }
.icon-wechat,.ok { .icon-wechat,
.ok {
color: #0bc15f; color: #0bc15f;
} }
} }

View File

@@ -1,5 +1,12 @@
<template> <template>
<el-dialog class="config-dialog" v-model="showDialog" :close-on-click-modal="true" :before-close="close" style="max-width: 400px" title="账户信息"> <el-dialog
class="config-dialog"
v-model="showDialog"
:close-on-click-modal="true"
:before-close="close"
style="max-width: 400px"
title="账户信息"
>
<div class="flex-center-col pl-4 pr-4" id="user-info"> <div class="flex-center-col pl-4 pr-4" id="user-info">
<user-profile @hide="close" /> <user-profile @hide="close" />
</div> </div>
@@ -7,30 +14,30 @@
</template> </template>
<script setup> <script setup>
import { computed } from "vue"; import UserProfile from '@/components/UserProfile.vue'
import UserProfile from "@/components/UserProfile.vue"; import { computed } from 'vue'
// eslint-disable-next-line no-undef // eslint-disable-next-line no-undef
const props = defineProps({ const props = defineProps({
show: Boolean, show: Boolean,
}); })
const showDialog = computed(() => { const showDialog = computed(() => {
return props.show; return props.show
}); })
// eslint-disable-next-line no-undef // eslint-disable-next-line no-undef
const emits = defineEmits(["hide"]); const emits = defineEmits(['hide'])
const close = function () { const close = function () {
emits("hide", false); emits('hide', false)
}; }
</script> </script>
<style lang="stylus"> <style lang="scss">
.config-dialog { .config-dialog {
.el-dialog { .el-dialog {
--el-dialog-width 90%; --el-dialog-width: 90%;
max-width 800px; max-width: 800px;
} }
} }
</style> </style>

View File

@@ -21,7 +21,7 @@
<el-table-column prop="pay_name" label="支付名称" /> <el-table-column prop="pay_name" label="支付名称" />
<el-table-column label="支付时间"> <el-table-column label="支付时间">
<template #default="scope"> <template #default="scope">
<span v-if="scope.row['pay_time']">{{ dateFormat(scope.row["pay_time"]) }}</span> <span v-if="scope.row['pay_time']">{{ dateFormat(scope.row['pay_time']) }}</span>
<el-tag v-else>未支付</el-tag> <el-tag v-else>未支付</el-tag>
</template> </template>
</el-table-column> </el-table-column>
@@ -45,52 +45,52 @@
</template> </template>
<script setup> <script setup>
import nodata from "@/assets/img/no-data.png"; import nodata from '@/assets/img/no-data.png'
import { onMounted, ref } from "vue"; import { httpGet } from '@/utils/http'
import { httpGet } from "@/utils/http"; import { dateFormat } from '@/utils/libs'
import { ElMessage } from "element-plus"; import { DocumentCopy } from '@element-plus/icons-vue'
import { dateFormat } from "@/utils/libs"; import Clipboard from 'clipboard'
import { DocumentCopy } from "@element-plus/icons-vue"; import { ElMessage } from 'element-plus'
import Clipboard from "clipboard"; import { onMounted, ref } from 'vue'
const items = ref([]); const items = ref([])
const total = ref(0); const total = ref(0)
const page = ref(1); const page = ref(1)
const pageSize = ref(12); const pageSize = ref(12)
const loading = ref(true); const loading = ref(true)
onMounted(() => { onMounted(() => {
fetchData(); fetchData()
const clipboard = new Clipboard(".copy-order-no"); const clipboard = new Clipboard('.copy-order-no')
clipboard.on("success", () => { clipboard.on('success', () => {
ElMessage.success("复制成功"); ElMessage.success('复制成功')
}); })
clipboard.on("error", () => { clipboard.on('error', () => {
ElMessage.error("复制失败"); ElMessage.error('复制失败')
}); })
}); })
// 获取数据 // 获取数据
const fetchData = () => { const fetchData = () => {
httpGet("/api/order/list", { page: page.value, page_size: pageSize.value }) httpGet('/api/order/list', { page: page.value, page_size: pageSize.value })
.then((res) => { .then((res) => {
if (res.data) { if (res.data) {
items.value = res.data.items; items.value = res.data.items
total.value = res.data.total; total.value = res.data.total
page.value = res.data.page; page.value = res.data.page
pageSize.value = res.data.page_size; pageSize.value = res.data.page_size
} }
loading.value = false; loading.value = false
}) })
.catch((e) => { .catch((e) => {
ElMessage.error("获取数据失败" + e.message); ElMessage.error('获取数据失败' + e.message)
}); })
}; }
</script> </script>
<style scoped lang="stylus"> <style scoped lang="scss">
.user-bill { .user-bill {
background-color: var(--chat-bg); background-color: var(--chat-bg);
@@ -102,11 +102,11 @@ const fetchData = () => {
} }
.copy-order-no { .copy-order-no {
cursor pointer cursor: pointer;
position relative position: relative;
left 6px left: 6px;
top 2px top: 2px;
color #20a0ff color: #20a0ff;
} }
} }
</style> </style>

View File

@@ -2,7 +2,13 @@
<div class="user-info flex-center-col" id="user-info"> <div class="user-info flex-center-col" id="user-info">
<el-form :model="user" label-width="80px" label-position="left"> <el-form :model="user" label-width="80px" label-position="left">
<el-row> <el-row>
<el-upload class="avatar-uploader" :auto-upload="true" :show-file-list="false" :http-request="afterRead" accept=".png,.jpg,.jpeg,.bmp"> <el-upload
class="avatar-uploader"
:auto-upload="true"
:show-file-list="false"
:http-request="afterRead"
accept=".png,.jpg,.jpeg,.bmp"
>
<el-tooltip content="点击上传头像" placement="top" v-if="user.avatar"> <el-tooltip content="点击上传头像" placement="top" v-if="user.avatar">
<el-avatar :src="user.avatar" shape="circle" :size="100" /> <el-avatar :src="user.avatar" shape="circle" :size="100" />
</el-tooltip> </el-tooltip>
@@ -18,19 +24,27 @@
<div class="flex"> <div class="flex">
<span>{{ user.username }}</span> <span>{{ user.username }}</span>
<el-tooltip class="box-item" content="您已经是 VIP 会员" placement="right"> <el-tooltip class="box-item" content="您已经是 VIP 会员" placement="right">
<span class="vip-icon"><el-image v-if="user.vip" :src="vipImg" class="rounded-full ml-1 size-5" /></span> <span class="vip-icon"
><el-image v-if="user.vip" :src="vipImg" class="rounded-full ml-1 size-5"
/></span>
</el-tooltip> </el-tooltip>
</div> </div>
</el-form-item> </el-form-item>
<el-form-item label="剩余算力"> <el-form-item label="剩余算力">
<el-text type="warning">{{ user["power"] }}</el-text> <el-text type="warning">{{ user['power'] }}</el-text>
<el-tag type="info" size="small" class="ml-2 cursor-pointer" @click="gotoLog">算力日志</el-tag> <el-tag type="info" size="small" class="ml-2 cursor-pointer" @click="gotoLog"
<el-tooltip :content="`每日签到可获得 ${systemConfig.daily_power} 算力`" placement="top" v-if="systemConfig.daily_power > 0"> >算力日志</el-tag
>
<el-tooltip
:content="`每日签到可获得 ${systemConfig.daily_power} 算力`"
placement="top"
v-if="systemConfig.daily_power > 0"
>
<el-button type="primary" size="small" @click="signIn" class="ml-2">签到</el-button> <el-button type="primary" size="small" @click="signIn" class="ml-2">签到</el-button>
</el-tooltip> </el-tooltip>
</el-form-item> </el-form-item>
<el-form-item label="会员到期时间" v-if="user['expired_time'] > 0"> <el-form-item label="会员到期时间" v-if="user['expired_time'] > 0">
<el-tag type="danger">{{ dateFormat(user["expired_time"]) }}</el-tag> <el-tag type="danger">{{ dateFormat(user['expired_time']) }}</el-tag>
</el-form-item> </el-form-item>
<el-row class="opt-line"> <el-row class="opt-line">
@@ -41,116 +55,114 @@
</template> </template>
<script setup> <script setup>
import { onMounted, ref } from "vue"; import { checkSession, getSystemInfo } from '@/store/cache'
import { httpGet, httpPost } from "@/utils/http"; import { showMessageError, showMessageOK } from '@/utils/dialog'
import { ElMessage } from "element-plus"; import { httpGet, httpPost } from '@/utils/http'
import { Plus } from "@element-plus/icons-vue"; import { dateFormat } from '@/utils/libs'
import Compressor from "compressorjs"; import { Plus } from '@element-plus/icons-vue'
import { dateFormat } from "@/utils/libs"; import Compressor from 'compressorjs'
import { checkSession, getSystemInfo } from "@/store/cache"; import { ElMessage } from 'element-plus'
import { useRouter } from "vue-router"; import { onMounted, ref } from 'vue'
import { showMessageError, showMessageOK } from "@/utils/dialog"; import { useRouter } from 'vue-router'
const user = ref({ const user = ref({
vip: false, vip: false,
username: "演示数据", username: '演示数据',
nickname: "演示数据", nickname: '演示数据',
avatar: "/images/menu/member.png", avatar: '/images/menu/member.png',
mobile: "演示数据", mobile: '演示数据',
power: 99999, power: 99999,
}); })
const vipImg = ref("/images/menu/member.png"); const vipImg = ref('/images/menu/member.png')
const systemConfig = ref({}); const systemConfig = ref({})
const router = useRouter(); const router = useRouter()
const emits = defineEmits(["hide"]); const emits = defineEmits(['hide'])
onMounted(() => { onMounted(() => {
checkSession() checkSession()
.then(() => { .then(() => {
// 获取最新用户信息 // 获取最新用户信息
httpGet("/api/user/profile") httpGet('/api/user/profile')
.then((res) => { .then((res) => {
user.value = res.data; user.value = res.data
}) })
.catch((e) => { .catch((e) => {
ElMessage.error("获取用户信息失败:" + e.message); ElMessage.error('获取用户信息失败:' + e.message)
}); })
}) })
.catch((e) => { .catch((e) => {
console.log(e); console.log(e)
}); })
getSystemInfo().then((res) => { getSystemInfo().then((res) => {
systemConfig.value = res.data; systemConfig.value = res.data
}); })
}); })
const afterRead = (file) => { const afterRead = (file) => {
// 压缩图片并上传 // 压缩图片并上传
new Compressor(file.file, { new Compressor(file.file, {
quality: 0.6, quality: 0.6,
success(result) { success(result) {
const formData = new FormData(); const formData = new FormData()
formData.append("file", result, result.name); formData.append('file', result, result.name)
// 执行上传操作 // 执行上传操作
httpPost("/api/upload", formData) httpPost('/api/upload', formData)
.then((res) => { .then((res) => {
user.value.avatar = res.data.url; user.value.avatar = res.data.url
ElMessage.success({ message: "上传成功", duration: 500 }); ElMessage.success({ message: '上传成功', duration: 500 })
}) })
.catch((e) => { .catch((e) => {
ElMessage.error("图片上传失败:" + e.message); ElMessage.error('图片上传失败:' + e.message)
}); })
}, },
error(err) { error(err) {
console.log(err.message); console.log(err.message)
}, },
}); })
}; }
const save = () => { const save = () => {
httpPost("/api/user/profile/update", user.value) httpPost('/api/user/profile/update', user.value)
.then(() => { .then(() => {
ElMessage.success({ message: "更新成功", duration: 500 }); ElMessage.success({ message: '更新成功', duration: 500 })
}) })
.catch((e) => { .catch((e) => {
ElMessage.error("更新失败:" + e.message); ElMessage.error('更新失败:' + e.message)
}); })
}; }
const gotoLog = () => { const gotoLog = () => {
router.push("/powerLog"); router.push('/powerLog')
emits("hide", false); emits('hide', false)
}; }
const signIn = () => { const signIn = () => {
httpGet("/api/user/signin") httpGet('/api/user/signin')
.then(() => { .then(() => {
showMessageOK("签到成功"); showMessageOK('签到成功')
user.value.power += systemConfig.value.daily_power; user.value.power += systemConfig.value.daily_power
}) })
.catch((e) => { .catch((e) => {
showMessageError(e.message); showMessageError(e.message)
}); })
}; }
</script> </script>
<style lang="stylus" scoped> <style lang="scss" scoped>
.user-info { .user-info {
.el-row { .el-row {
justify-content center justify-content: center;
margin-bottom 10px margin-bottom: 10px;
} }
.vip-icon { .vip-icon {
position relative position: relative;
top 5px top: 5px;
} }
.opt-line { .opt-line {
.el-button { .el-button {
width 100% width: 100%;
} }
} }
} }

View File

@@ -116,54 +116,54 @@ const send = (text) => {
emits('send', text) emits('send', text)
} }
</script> </script>
<style scoped lang="stylus"> <style scoped lang="scss">
.welcome { .welcome {
text-align center text-align: center;
display flex display: flex;
justify-content center justify-content: center;
margin-top 8vh margin-top: 8vh;
.container { .container {
max-width 768px; max-width: 768px;
width 100% width: 100%;
.title { .title {
// font-size: 2.25rem // font-size: 2.25rem
line-height: 2.5rem line-height: 2.5rem;
font-weight 600 font-weight: 600;
margin-bottom: 4rem margin-bottom: 4rem;
color var(--text-color) color: var(--text-color);
} }
.grid-content { .grid-content {
.item-title { .item-title {
div { div {
padding 6px 10px; padding: 6px 10px;
.iconfont { .iconfont {
font-size 24px; font-size: 24px;
} }
} }
} }
.list-box { .list-box {
ul { ul {
padding 10px; padding: 10px;
li { li {
font-size 14px; font-size: 14px;
padding .75rem padding: 0.75rem;
border-radius 5px; border-radius: 5px;
background-color: var(--chat-wel-bg); background-color: var(--chat-wel-bg);
color:var( --theme-text-color-secondary); color: var(--theme-text-color-secondary);
line-height 1.5 line-height: 1.5;
a { a {
cursor pointer cursor: pointer;
display block display: block;
width 100% width: 100%;
} }
margin-top 10px; margin-top: 10px;
} }
} }
} }

View File

@@ -151,15 +151,15 @@ const logout = function () {
}) })
} }
</script> </script>
<style scoped lang="stylus"> <style scoped lang="scss">
.admin-header { .admin-header {
position: relative; position: relative;
box-sizing: border-box; box-sizing: border-box;
overflow hidden overflow: hidden;
height: 50px; height: 50px;
font-size: 22px; font-size: 22px;
background-color:var(--chat-content-bg); background-color: var(--chat-content-bg);
color:var(--theme-text-color-primary); color: var(--theme-text-color-primary);
.collapse-btn { .collapse-btn {
display: flex; display: flex;
@@ -171,15 +171,15 @@ const logout = function () {
cursor: pointer; cursor: pointer;
&:hover { &:hover {
background-color #eaecef background-color: #eaecef;
} }
} }
.breadcrumb { .breadcrumb {
float left float: left;
display flex display: flex;
align-items center align-items: center;
height 50px height: 50px;
} }
.header-right { .header-right {
@@ -226,7 +226,6 @@ const logout = function () {
} }
.user-avatar { .user-avatar {
} }
} }
} }
@@ -243,27 +242,26 @@ const logout = function () {
text-align: center; text-align: center;
.icon-reward { .icon-reward {
font-size 18px; font-size: 18px;
font-weight bold; font-weight: bold;
color #F56C6C color: #f56c6c;
} }
} }
</style> </style>
<style lang="stylus"> <style lang="scss">
.donate-dialog { .donate-dialog {
.el-dialog__body { .el-dialog__body {
text-align center; text-align: center;
.el-alert__description { .el-alert__description {
text-align left text-align: left;
font-size 14px; font-size: 14px;
line-height 1.5 line-height: 1.5;
} }
} }
} }
.admin-header { .admin-header {
} }
</style> </style>

View File

@@ -234,7 +234,7 @@ const sidebar = useSidebarStore()
setMenuItems(items) setMenuItems(items)
</script> </script>
<style scoped lang="stylus"> <style scoped lang="scss">
.sidebar { .sidebar {
display: block; display: block;
position: absolute; position: absolute;
@@ -244,24 +244,24 @@ setMenuItems(items)
overflow-y: scroll; overflow-y: scroll;
.logo { .logo {
display flex display: flex;
padding 6px 15px; padding: 6px 15px;
cursor pointer cursor: pointer;
background-color: #324157 background-color: #324157;
img { img {
height 36px; height: 36px;
padding-top 5px; padding-top: 5px;
border-radius 100% border-radius: 100%;
background #fff background: #fff;
border 2px solid #754ff6 border: 2px solid #754ff6;
padding 2px padding: 2px;
} }
.text { .text {
color #ffffff color: #ffffff;
font-weight bold font-weight: bold;
padding 12px 0 12px 10px; padding: 12px 0 12px 10px;
transition: width 2s ease; transition: width 2s ease;
} }
} }
@@ -269,15 +269,16 @@ setMenuItems(items)
ul { ul {
height: 100%; height: 100%;
.el-menu-item, .el-sub-menu { .el-menu-item,
.el-sub-menu {
.iconfont { .iconfont {
font-size 16px; font-size: 16px;
margin-right 5px; margin-right: 5px;
} }
} }
.el-menu-item.is-active { .el-menu-item.is-active {
background-color rgb(40, 52, 70) background-color: rgb(40, 52, 70);
} }
} }
@@ -291,26 +292,26 @@ setMenuItems(items)
} }
.sidebar.dark { .sidebar.dark {
border-right 1px solid var(--el-border-color-dark) border-right: 1px solid var(--el-border-color-dark);
.logo { .logo {
background var(--el-bg-color) background: var(--el-bg-color);
border-right 1px solid var(--el-border-color) border-right: 1px solid var(--el-border-color);
.text { .text {
color var(--el-text-color-regular) color: var(--el-text-color-regular);
} }
} }
ul { ul {
background var(--el-bg-color) background: var(--el-bg-color);
.el-menu-item.is-active { .el-menu-item.is-active {
background-color var(--el-menu-bg-color-dark) background-color: var(--el-menu-bg-color-dark);
} }
.el-menu-item:hover { .el-menu-item:hover {
background-color var(--el-menu-bg-color-darker) background-color: var(--el-menu-bg-color-darker);
} }
} }
@@ -319,7 +320,7 @@ setMenuItems(items)
} }
.el-menu { .el-menu {
border-color var(--el-border-color) border-color: var(--el-border-color);
} }
} }
</style> </style>

View File

@@ -1,5 +1,5 @@
<template> <template>
<div :class="'tags '+theme" v-if="tags.show"> <div :class="'tags ' + theme" v-if="tags.show">
<ul> <ul>
<li <li
class="tags-li" class="tags-li"
@@ -9,7 +9,7 @@
> >
<router-link :to="item.path" class="tags-li-title">{{ item.title }}</router-link> <router-link :to="item.path" class="tags-li-title">{{ item.title }}</router-link>
<el-icon @click="closeTags(index)"> <el-icon @click="closeTags(index)">
<Close/> <Close />
</el-icon> </el-icon>
</li> </li>
</ul> </ul>
@@ -18,7 +18,7 @@
<el-button size="small" type="info"> <el-button size="small" type="info">
标签选项 标签选项
<el-icon class="el-icon--right"> <el-icon class="el-icon--right">
<arrow-down/> <arrow-down />
</el-icon> </el-icon>
</el-button> </el-button>
<template #dropdown> <template #dropdown>
@@ -33,80 +33,83 @@
</template> </template>
<script setup> <script setup>
import {useTagsStore} from '@/store/tags'; import { checkAdminSession } from '@/store/cache'
import {onBeforeRouteUpdate, useRoute, useRouter} from 'vue-router'; import { useSharedStore } from '@/store/sharedata'
import {ArrowDown, Close} from "@element-plus/icons-vue"; import { useTagsStore } from '@/store/tags'
import {checkAdminSession} from "@/store/cache"; import { ArrowDown, Close } from '@element-plus/icons-vue'
import {ElMessageBox} from "element-plus"; import { ElMessageBox } from 'element-plus'
import {useSharedStore} from "@/store/sharedata"; import { ref, watch } from 'vue'
import {ref, watch} from "vue"; import { onBeforeRouteUpdate, useRoute, useRouter } from 'vue-router'
const store = useSharedStore() const store = useSharedStore()
const theme = ref(store.theme) const theme = ref(store.theme)
watch(() => store.theme, (val) => { watch(
() => store.theme,
(val) => {
theme.value = val theme.value = val
}) }
const router = useRouter(); )
const router = useRouter()
checkAdminSession().catch(() => { checkAdminSession().catch(() => {
ElMessageBox({ ElMessageBox({
title: '提示', title: '提示',
message: "当前会话已经失效,请重新登录", message: '当前会话已经失效,请重新登录',
confirmButtonText: 'OK', confirmButtonText: 'OK',
callback: () => router.replace('/admin/login') callback: () => router.replace('/admin/login'),
}); })
}) })
const isActive = (path) => { const isActive = (path) => {
return path === route.fullPath; return path === route.fullPath
}; }
const tags = useTagsStore(); const tags = useTagsStore()
const route = useRoute(); const route = useRoute()
// 关闭单个标签 // 关闭单个标签
const closeTags = (index) => { const closeTags = (index) => {
const delItem = tags.list[index]; const delItem = tags.list[index]
tags.delTagsItem(index); tags.delTagsItem(index)
const item = tags.list[index] ? tags.list[index] : tags.list[index - 1]; const item = tags.list[index] ? tags.list[index] : tags.list[index - 1]
if (item) { if (item) {
delItem.path === route.fullPath && router.push(item.path); delItem.path === route.fullPath && router.push(item.path)
} else { } else {
router.push('/admin'); router.push('/admin')
} }
}; }
// 设置标签 // 设置标签
const setTags = (route) => { const setTags = (route) => {
const isExist = tags.list.some(item => { const isExist = tags.list.some((item) => {
return item.path === route.fullPath; return item.path === route.fullPath
}); })
if (!isExist) { if (!isExist) {
if (tags.list.length >= 8) tags.delTagsItem(0); if (tags.list.length >= 8) tags.delTagsItem(0)
tags.setTagsItem({ tags.setTagsItem({
name: route.name, name: route.name,
title: route.meta.title, title: route.meta.title,
path: route.fullPath path: route.fullPath,
}); })
} }
}; }
setTags(route); setTags(route)
onBeforeRouteUpdate(to => { onBeforeRouteUpdate((to) => {
setTags(to); setTags(to)
}); })
// 关闭全部标签 // 关闭全部标签
const closeAll = () => { const closeAll = () => {
tags.clearTags(); tags.clearTags()
router.push('/admin'); router.push('/admin')
}; }
// 关闭其他标签 // 关闭其他标签
const closeOther = () => { const closeOther = () => {
const curItem = tags.list.filter(item => { const curItem = tags.list.filter((item) => {
return item.path === route.fullPath; return item.path === route.fullPath
}); })
tags.closeTagsOther(curItem); tags.closeTagsOther(curItem)
}; }
const handleTags = (command) => { const handleTags = (command) => {
command === 'other' ? closeOther() : closeAll(); command === 'other' ? closeOther() : closeAll()
}; }
// 关闭当前页面的标签页 // 关闭当前页面的标签页
// tags.closeCurrentTag({ // tags.closeCurrentTag({
@@ -115,15 +118,15 @@ const handleTags = (command) => {
// }); // });
</script> </script>
<style scoped lang="stylus"> <style scoped lang="scss">
.tags { .tags {
position: relative; position: relative;
height: 30px; height: 30px;
overflow: hidden; overflow: hidden;
background: #fff; background: #fff;
padding 5px 120px 5px 10px padding: 5px 120px 5px 10px;
-webkit-box-shadow: 0 1px 4px rgba(0, 21, 41, .08); -webkit-box-shadow: 0 1px 4px rgba(0, 21, 41, 0.08);
box-shadow: 0 1px 4px rgba(0, 21, 41, .08); box-shadow: 0 1px 4px rgba(0, 21, 41, 0.08);
ul { ul {
box-sizing: border-box; box-sizing: border-box;
@@ -164,7 +167,7 @@ const handleTags = (command) => {
} }
.tags-li.active .tags-li-title { .tags-li.active .tags-li-title {
color: var(--el-color-primary) color: var(--el-color-primary);
} }
} }
@@ -183,7 +186,6 @@ const handleTags = (command) => {
} }
.tags.dark { .tags.dark {
border-bottom 1px solid var(--el-border-color) border-bottom: 1px solid var(--el-border-color);
} }
</style> </style>

View File

@@ -24,7 +24,7 @@
class="image-slot" class="image-slot"
:style="{ :style="{
height: height + 'px', height: height + 'px',
lineHeight: height + 'px' lineHeight: height + 'px',
}" }"
> >
正在加载图片<span class="dot">...</span> 正在加载图片<span class="dot">...</span>
@@ -68,93 +68,92 @@
</template> </template>
<script setup> <script setup>
import { ref, watch } from "vue"; import { getSessionId } from '@/store/session'
import { Picture } from "@element-plus/icons-vue"; import { httpPost } from '@/utils/http'
import { httpPost } from "@/utils/http"; import { Picture } from '@element-plus/icons-vue'
import { getSessionId } from "@/store/session"; import { showNotify } from 'vant'
import { showNotify } from "vant"; import { ref, watch } from 'vue'
const props = defineProps({ const props = defineProps({
content: Object, content: Object,
icon: String, icon: String,
chatId: String, chatId: String,
roleId: Number, roleId: Number,
createdAt: String createdAt: String,
}); })
const data = ref(props.content); const data = ref(props.content)
const cacheKey = "img_placeholder_height"; const cacheKey = 'img_placeholder_height'
const item = localStorage.getItem(cacheKey); const item = localStorage.getItem(cacheKey)
const loading = ref(false); const loading = ref(false)
const height = ref(0); const height = ref(0)
if (item) { if (item) {
height.value = parseInt(item); height.value = parseInt(item)
} }
if (data.value["image"]?.width > 0) { if (data.value['image']?.width > 0) {
height.value = height.value = (350 * data.value['image']?.height) / data.value['image']?.width
(350 * data.value["image"]?.height) / data.value["image"]?.width; localStorage.setItem(cacheKey, height.value)
localStorage.setItem(cacheKey, height.value);
} }
data.value["showOpt"] = data.value["content"]?.indexOf("- Image #") === -1; data.value['showOpt'] = data.value['content']?.indexOf('- Image #') === -1
// console.log(data.value) // console.log(data.value)
watch( watch(
() => props.content, () => props.content,
(newVal) => { (newVal) => {
data.value = newVal; data.value = newVal
} }
); )
const emits = defineEmits(["disable-input", "disable-input"]); const emits = defineEmits(['disable-input', 'disable-input'])
const upscale = (index) => { const upscale = (index) => {
send("/api/mj/upscale", index); send('/api/mj/upscale', index)
}; }
const variation = (index) => { const variation = (index) => {
send("/api/mj/variation", index); send('/api/mj/variation', index)
}; }
const send = (url, index) => { const send = (url, index) => {
loading.value = true; loading.value = true
emits("disable-input"); emits('disable-input')
httpPost(url, { httpPost(url, {
index: index, index: index,
src: "chat", src: 'chat',
message_id: data.value?.["message_id"], message_id: data.value?.['message_id'],
message_hash: data.value?.["image"]?.hash, message_hash: data.value?.['image']?.hash,
session_id: getSessionId(), session_id: getSessionId(),
key: data.value?.["key"], key: data.value?.['key'],
prompt: data.value?.["prompt"], prompt: data.value?.['prompt'],
chat_id: props.chatId, chat_id: props.chatId,
role_id: props.roleId, role_id: props.roleId,
icon: props.icon icon: props.icon,
}) })
.then(() => { .then(() => {
showNotify({ showNotify({
type: "success", type: 'success',
message: "任务推送成功,请耐心等待任务执行..." message: '任务推送成功,请耐心等待任务执行...',
}); })
loading.value = false; loading.value = false
}) })
.catch((e) => { .catch((e) => {
showNotify({ type: "danger", message: "任务推送失败:" + e.message }); showNotify({ type: 'danger', message: '任务推送失败:' + e.message })
emits("disable-input"); emits('disable-input')
}); })
}; }
</script> </script>
<style lang="stylus"> <style lang="scss">
.mobile-message-mj { .mobile-message-mj {
display flex display: flex;
justify-content: flex-start; justify-content: flex-start;
.chat-icon { .chat-icon {
margin-right 5px margin-right: 5px;
.van-image { .van-image {
width 32px width: 32px;
img { img {
border-radius 5px border-radius: 5px;
} }
} }
} }
@@ -177,48 +176,47 @@ const send = (url, index) => {
} }
.content-box { .content-box {
display: flex;
display flex flex-direction: row;
flex-direction row
.content { .content {
text-align left text-align: left;
width 100% width: 100%;
overflow-x auto overflow-x: auto;
min-height 20px; min-height: 20px;
word-break break-word; word-break: break-word;
padding: 5px 10px; padding: 5px 10px;
color #444444 color: #444444;
background-color: #ffffff; background-color: #ffffff;
font-size: 16px font-size: 16px;
border-radius: 5px; border-radius: 5px;
.content-inner { .content-inner {
word-break break-word; word-break: break-word;
padding: 6px 10px; padding: 6px 10px;
color #374151; color: #374151;
font-size: var(--content-font-size); font-size: var(--content-font-size);
border-radius: 5px; border-radius: 5px;
overflow: auto; overflow: auto;
.text { .text {
p:first-child { p:first-child {
margin-top 0 margin-top: 0;
} }
} }
.images { .images {
max-width 350px; max-width: 350px;
.el-image { .el-image {
border-radius 10px; border-radius: 10px;
.image-slot { .image-slot {
color #c1c1c1 color: #c1c1c1;
width 350px width: 350px;
text-align center text-align: center;
border-radius 10px; border-radius: 10px;
border 1px solid #e1e1e1 border: 1px solid #e1e1e1;
} }
} }
} }
@@ -226,42 +224,39 @@ const send = (url, index) => {
.opt { .opt {
.opt-line { .opt-line {
margin 6px 0 margin: 6px 0;
ul { ul {
display flex display: flex;
flex-flow row flex-flow: row;
padding-left 10px padding-left: 10px;
li { li {
margin-right 10px margin-right: 10px;
a { a {
padding 3px 0 padding: 3px 0;
width 50px width: 50px;
text-align center text-align: center;
border-radius 5px border-radius: 5px;
display block display: block;
cursor pointer cursor: pointer;
background-color #4E5058 background-color: #4e5058;
color #ffffff color: #ffffff;
&:hover { &:hover {
background-color #6D6F78 background-color: #6d6f78;
} }
} }
} }
} }
} }
} }
} }
} }
} }
} }
.van-theme-dark { .van-theme-dark {
.mobile-message-reply { .mobile-message-reply {
.chat-item { .chat-item {
@@ -271,18 +266,16 @@ const send = (url, index) => {
.content-box { .content-box {
.content { .content {
color #c1c1c1 color: #c1c1c1;
background-color: #404042; background-color: #404042;
p > code { p > code {
color #c1c1c1 color: #c1c1c1;
background-color #2b2b2b background-color: #2b2b2b;
} }
} }
} }
} }
} }
} }
</style> </style>

View File

@@ -45,19 +45,19 @@ onMounted(() => {
}) })
</script> </script>
<style lang="stylus"> <style lang="scss">
.mobile-message-prompt { .mobile-message-prompt {
display flex display: flex;
justify-content: flex-end justify-content: flex-end;
.chat-icon { .chat-icon {
margin-left 5px margin-left: 5px;
.van-image { .van-image {
width 32px width: 32px;
img { img {
border-radius 5px border-radius: 5px;
} }
} }
} }
@@ -72,21 +72,21 @@ onMounted(() => {
height: 0; height: 0;
border-top: 5px solid transparent; border-top: 5px solid transparent;
border-bottom: 5px solid transparent; border-bottom: 5px solid transparent;
border-left: 5px solid #98E165; border-left: 5px solid #98e165;
position: absolute; position: absolute;
right: 0; right: 0;
top: 10px; top: 10px;
} }
.content { .content {
word-break break-word; word-break: break-word;
text-align left text-align: left;
padding: 5px 10px; padding: 5px 10px;
background-color: #98E165; background-color: #98e165;
color #444444 color: #444444;
font-size: 14px font-size: 14px;
border-radius: 5px border-radius: 5px;
line-height 1.5 line-height: 1.5;
} }
} }
} }
@@ -94,14 +94,13 @@ onMounted(() => {
.van-theme-dark { .van-theme-dark {
.mobile-message-prompt { .mobile-message-prompt {
.chat-item { .chat-item {
.triangle { .triangle {
border-left: 5px solid #223A34 border-left: 5px solid #223a34;
} }
.content { .content {
background-color: #223A34 background-color: #223a34;
color #c1c1c1 color: #c1c1c1;
} }
} }
} }

View File

@@ -62,19 +62,19 @@ onMounted(() => {
}) })
</script> </script>
<style lang="stylus"> <style lang="scss">
.mobile-message-reply { .mobile-message-reply {
display flex display: flex;
justify-content: flex-start; justify-content: flex-start;
.chat-icon { .chat-icon {
margin-right 5px margin-right: 5px;
.van-image { .van-image {
width 32px width: 32px;
img { img {
border-radius 5px border-radius: 5px;
} }
} }
} }
@@ -97,107 +97,102 @@ onMounted(() => {
} }
.content-box { .content-box {
display: flex;
display flex flex-direction: row;
flex-direction row
.content { .content {
text-align left text-align: left;
width 100% width: 100%;
overflow-x auto overflow-x: auto;
min-height 20px; min-height: 20px;
word-break break-word; word-break: break-word;
padding: 5px 10px; padding: 5px 10px;
color #444444 color: #444444;
background-color: #ffffff; background-color: #ffffff;
font-size: 14px font-size: 14px;
border-radius: 5px; border-radius: 5px;
p:last-child { p:last-child {
margin-bottom: 0 margin-bottom: 0;
} }
p:first-child { p:first-child {
margin-top 0 margin-top: 0;
} }
p { p {
code { code {
color #2b2b2b color: #2b2b2b;
background-color #c1c1c1 background-color: #c1c1c1;
padding 2px 5px padding: 2px 5px;
border-radius 5px border-radius: 5px;
} }
img { img {
max-width 100% max-width: 100%;
} }
} }
.code-container { .code-container {
position relative position: relative;
.hljs { .hljs {
border-radius 10px border-radius: 10px;
line-height 1.5 line-height: 1.5;
} }
.copy-code-mobile { .copy-code-mobile {
position: absolute; position: absolute;
right 10px right: 10px;
top 10px top: 10px;
cursor pointer cursor: pointer;
font-size 12px font-size: 12px;
color #c1c1c1 color: #c1c1c1;
&:hover { &:hover {
color #20a0ff color: #20a0ff;
} }
} }
} }
.lang-name { .lang-name {
display none display: none;
position absolute; position: absolute;
right 10px right: 10px;
bottom 50px bottom: 50px;
padding 2px 6px 4px 6px padding: 2px 6px 4px 6px;
background-color #444444 background-color: #444444;
border-radius 10px border-radius: 10px;
color #00e0e0 color: #00e0e0;
} }
// 设置表格边框 // 设置表格边框
table { table {
width 100% width: 100%;
margin-bottom 1rem margin-bottom: 1rem;
color #212529 color: #212529;
border-collapse collapse; border-collapse: collapse;
border 1px solid #dee2e6; border: 1px solid #dee2e6;
background-color #ffffff background-color: #ffffff;
thead { thead {
th { th {
border 1px solid #dee2e6 border: 1px solid #dee2e6;
vertical-align: bottom vertical-align: bottom;
border-bottom: 2px solid #dee2e6 border-bottom: 2px solid #dee2e6;
padding 10px padding: 10px;
} }
} }
td { td {
border 1px solid #dee2e6 border: 1px solid #dee2e6;
padding 10px padding: 10px;
} }
} }
// 代码快 // 代码快
blockquote { blockquote {
margin 0 margin: 0;
background-color: #ebfffe; background-color: #ebfffe;
padding: 0.8rem 1.5rem; padding: 0.8rem 1.5rem;
border-left: 0.5rem solid; border-left: 0.5rem solid;
@@ -206,11 +201,9 @@ onMounted(() => {
} }
} }
} }
} }
} }
.van-theme-dark { .van-theme-dark {
.mobile-message-reply { .mobile-message-reply {
.chat-item { .chat-item {
@@ -220,18 +213,16 @@ onMounted(() => {
.content-box { .content-box {
.content { .content {
color #c1c1c1 color: #c1c1c1;
background-color: #404042; background-color: #404042;
p > code { p > code {
color #c1c1c1 color: #c1c1c1;
background-color #2b2b2b background-color: #2b2b2b;
} }
} }
} }
} }
} }
} }
</style> </style>

View File

@@ -1,11 +1,6 @@
<template> <template>
<div class="black-dialog"> <div class="black-dialog">
<el-dialog <el-dialog v-model="showDialog" :title="title" :width="width" :before-close="cancel">
v-model="showDialog"
:title="title"
:width="width"
:before-close="cancel"
>
<div class="dialog-body"> <div class="dialog-body">
<slot></slot> <slot></slot>
</div> </div>
@@ -14,12 +9,9 @@
<el-button @click="cancel" style="--el-border-radius-base: 8px">{{ <el-button @click="cancel" style="--el-border-radius-base: 8px">{{
cancelText cancelText
}}</el-button> }}</el-button>
<el-button <el-button type="primary" @click="$emit('confirm')" v-if="!hideConfirm">{{
type="primary" confirmText
@click="$emit('confirm')" }}</el-button>
v-if="!hideConfirm"
>{{ confirmText }}</el-button
>
</div> </div>
</template> </template>
</el-dialog> </el-dialog>
@@ -27,81 +19,81 @@
</template> </template>
<script setup> <script setup>
import { ref, watch } from "vue"; import { ref, watch } from 'vue'
const props = defineProps({ const props = defineProps({
show: Boolean, show: Boolean,
title: { title: {
type: String, type: String,
default: "Tips" default: 'Tips',
}, },
width: { width: {
type: String, type: String,
default: "auto" default: 'auto',
}, },
hideFooter: { hideFooter: {
type: Boolean, type: Boolean,
default: false default: false,
}, },
hideConfirm: { hideConfirm: {
type: Boolean, type: Boolean,
default: false default: false,
}, },
confirmText: { confirmText: {
type: String, type: String,
default: "确定" default: '确定',
}, },
cancelText: { cancelText: {
type: String, type: String,
default: "取消" default: '取消',
} },
}); })
const emits = defineEmits(["confirm", "cancal"]); const emits = defineEmits(['confirm', 'cancal'])
const showDialog = ref(props.show); const showDialog = ref(props.show)
watch( watch(
() => props.show, () => props.show,
(newValue) => { (newValue) => {
showDialog.value = newValue; showDialog.value = newValue
} }
); )
const cancel = () => { const cancel = () => {
showDialog.value = false; showDialog.value = false
emits("cancal"); emits('cancal')
}; }
</script> </script>
<style lang="stylus"> <style lang="scss">
.black-dialog { .black-dialog {
.dialog-body { .dialog-body {
.form { .form {
.form-item { .form-item {
display flex display: flex;
flex-flow column flex-flow: column;
font-family: "Neue Montreal"; font-family: 'Neue Montreal';
padding 10px 0 padding: 10px 0;
.label { .label {
margin-bottom 0.6rem margin-bottom: 0.6rem;
margin-inline-end 0.75rem margin-inline-end: 0.75rem;
color #ffffff color: #ffffff;
font-size 1rem font-size: 1rem;
font-weight 500 font-weight: 500;
} }
.input { .input {
display flex display: flex;
padding 10px padding: 10px;
text-align left text-align: left;
font-size 1rem font-size: 1rem;
background none background: none;
border-radius 0.375rem border-radius: 0.375rem;
border 1px solid #8f8f8f border: 1px solid #8f8f8f;
outline: none; outline: none;
transition: border-color 0.5s ease, box-shadow 0.5s ease; transition: border-color 0.5s ease, box-shadow 0.5s ease;
&:focus { &:focus {
border-color: #0F7A71; border-color: #0f7a71;
box-shadow: 0 0 5px #0F7A71; box-shadow: 0 0 5px #0f7a71;
} }
} }
} }

View File

@@ -17,47 +17,47 @@
</template> </template>
<script setup> <script setup>
import { ref, watch } from "vue"; import { ref, watch } from 'vue'
const props = defineProps({ const props = defineProps({
value: { value: {
type: String, type: String,
default: "" default: '',
}, },
placeholder: { placeholder: {
type: String, type: String,
default: "" default: '',
}, },
type: { type: {
type: String, type: String,
default: "input" default: 'input',
}, },
rows: { rows: {
type: Number, type: Number,
default: 5 default: 5,
}, },
maxlength: { maxlength: {
type: Number, type: Number,
default: 1024 default: 1024,
} },
}); })
watch( watch(
() => props.value, () => props.value,
(newValue) => { (newValue) => {
model.value = newValue; model.value = newValue
} }
); )
const model = ref(props.value); const model = ref(props.value)
// eslint-disable-next-line no-undef // eslint-disable-next-line no-undef
const emits = defineEmits(["update:value"]); const emits = defineEmits(['update:value'])
const onInput = (value) => { const onInput = (value) => {
emits("update:value", value); emits('update:value', value)
}; }
</script> </script>
<style lang="stylus"> <style lang="scss">
.black-input-wrapper { .black-input-wrapper {
position relative position: relative;
.el-textarea__inner { .el-textarea__inner {
padding: 20px; padding: 20px;
@@ -66,15 +66,16 @@ const onInput = (value) => {
.word-stat { .word-stat {
position: absolute; position: absolute;
bottom 10px bottom: 10px;
right 10px right: 10px;
color rgb(209 203 199) color: rgb(209, 203, 199);
font-family: Neue Montreal, ui-sans-serif, system-ui, sans-serif, Apple Color Emoji, Segoe UI Emoji, Segoe UI Symbol, Noto Color Emoji; font-family: Neue Montreal, ui-sans-serif, system-ui, sans-serif, Apple Color Emoji,
font-size .875rem Segoe UI Emoji, Segoe UI Symbol, Noto Color Emoji;
line-height 1.25rem font-size: 0.875rem;
line-height: 1.25rem;
span { span {
margin 0 1px margin: 0 1px;
} }
} }
} }

View File

@@ -13,7 +13,7 @@
<div class="bar"></div> <div class="bar"></div>
</div> </div>
<div class="text"> <div class="text">
<slot>{{message}}</slot> <slot>{{ message }}</slot>
</div> </div>
</div> </div>
</template> </template>
@@ -25,13 +25,13 @@ defineProps({
type: String, type: String,
default: '任务正在执行', default: '任务正在执行',
}, },
}); })
</script> </script>
<style scoped lang="stylus"> <style scoped lang="scss">
.container { .container {
display: flex; display: flex;
flex-flow column flex-flow: column;
justify-content: center; justify-content: center;
align-items: center; align-items: center;
margin: 0; margin: 0;
@@ -43,7 +43,7 @@ defineProps({
justify-content: center; justify-content: center;
align-items: flex-end; align-items: flex-end;
height: 30px; height: 30px;
margin-bottom: 5px margin-bottom: 5px;
.bar { .bar {
width: 8px; width: 8px;
@@ -95,7 +95,8 @@ defineProps({
} }
@keyframes wave { @keyframes wave {
0%, 100% { 0%,
100% {
height: 10px; height: 10px;
} }
50% { 50% {

View File

@@ -19,31 +19,31 @@
@keyup.enter="handleInputConfirm" @keyup.enter="handleInputConfirm"
@blur="handleInputConfirm" @blur="handleInputConfirm"
/> />
<el-button v-else class="button-new-tag" size="small" @click="showInput"> <el-button v-else class="button-new-tag" size="small" @click="showInput"> + 新增 </el-button>
+ 新增
</el-button>
</div> </div>
</template> </template>
<script setup> <script setup>
import { nextTick, ref, watch } from 'vue'
import {nextTick, ref, watch} from "vue";
// eslint-disable-next-line no-undef // eslint-disable-next-line no-undef
const props = defineProps({ const props = defineProps({
value : { value: {
type: Array, type: Array,
default: () => [] default: () => [],
}, },
}); })
// eslint-disable-next-line no-undef // eslint-disable-next-line no-undef
const emits = defineEmits(['update:value']); const emits = defineEmits(['update:value'])
const tags = ref(props.value) const tags = ref(props.value)
const inputValue = ref('') const inputValue = ref('')
const inputVisible = ref(false) const inputVisible = ref(false)
const InputRef = ref(null) const InputRef = ref(null)
watch(() => props.value, (newValue) => { watch(
() => props.value,
(newValue) => {
tags.value = newValue tags.value = newValue
}) }
)
const handleClose = (tag) => { const handleClose = (tag) => {
tags.value.splice(tags.value.indexOf(tag), 1) tags.value.splice(tags.value.indexOf(tag), 1)
@@ -66,14 +66,13 @@ const handleInputConfirm = () => {
} }
</script> </script>
<style scoped lang="stylus"> <style scoped lang="scss">
.items-input-box { .items-input-box {
display flex display: flex;
.el-tag { .el-tag {
display flex display: flex;
margin-right 6px margin-right: 6px;
} }
} }
</style> </style>

View File

@@ -16,20 +16,20 @@
</template> </template>
<script setup> <script setup>
import { ref } from 'vue'; import { ref } from 'vue'
const ripples = ref([]); const ripples = ref([])
let rippleCount = 0; let rippleCount = 0
let animationId; let animationId
const startRipples = (event) => { const startRipples = (event) => {
const button = event.currentTarget; const button = event.currentTarget
const rect = button.getBoundingClientRect(); const rect = button.getBoundingClientRect()
const size = Math.max(rect.width, rect.height); const size = Math.max(rect.width, rect.height)
// const x = event.clientX - rect.left; // const x = event.clientX - rect.left;
// const y = event.clientY - rect.top; // const y = event.clientY - rect.top;
const x = rect.right - rect.left - size/2; const x = rect.right - rect.left - size / 2
const y = rect.bottom - rect.top - size/2; const y = rect.bottom - rect.top - size / 2
const createRipple = () => { const createRipple = () => {
ripples.value.push({ ripples.value.push({
@@ -37,59 +37,59 @@ const startRipples = (event) => {
x, x,
y, y,
size: 0, size: 0,
opacity: 0.5 opacity: 0.5,
}); })
if (ripples.value.length > 3) { if (ripples.value.length > 3) {
ripples.value.shift(); ripples.value.shift()
}
} }
};
const animate = () => { const animate = () => {
ripples.value.forEach(ripple => { ripples.value.forEach((ripple) => {
ripple.size += 2; ripple.size += 2
ripple.opacity -= 0.01; ripple.opacity -= 0.01
}); })
ripples.value = ripples.value.filter(ripple => ripple.opacity > 0); ripples.value = ripples.value.filter((ripple) => ripple.opacity > 0)
if (ripples.value.length < 3) { if (ripples.value.length < 3) {
createRipple(); createRipple()
} }
animationId = requestAnimationFrame(animate); animationId = requestAnimationFrame(animate)
}; }
createRipple(); createRipple()
animate(); animate()
}; }
const stopRipples = () => { const stopRipples = () => {
cancelAnimationFrame(animationId); cancelAnimationFrame(animationId)
ripples.value = []; ripples.value = []
}; }
const getRippleStyle = (ripple) => ({ const getRippleStyle = (ripple) => ({
left: `${ripple.x}px`, left: `${ripple.x}px`,
top: `${ripple.y}px`, top: `${ripple.y}px`,
width: `${ripple.size}px`, width: `${ripple.size}px`,
height: `${ripple.size}px`, height: `${ripple.size}px`,
opacity: ripple.opacity opacity: ripple.opacity,
}); })
</script> </script>
<style scoped lang="stylus"> <style scoped lang="scss">
.ripple-button { .ripple-button {
position: relative; position: relative;
overflow: hidden; overflow: hidden;
border: none; border: none;
background none; background: none;
color: white; color: white;
cursor: pointer; cursor: pointer;
border-radius: 50%; border-radius: 50%;
outline: none; outline: none;
margin 0 margin: 0;
padding 0 padding: 0;
} }
.ripple { .ripple {

View File

@@ -64,9 +64,9 @@ import {
Uploader, Uploader,
} from "vant"; } from "vant";
import { router } from "@/router"; import { router } from "@/router";
import "@/assets/css/theme-dark.styl"; import "@/assets/css/theme-dark.scss";
import "@/assets/css/theme-light.styl"; import "@/assets/css/theme-light.scss";
import "@/assets/css/common.styl"; import "@/assets/css/common.scss";
const pinia = createPinia(); const pinia = createPinia();
const themeStore = useThemeStore(pinia); // 使用 theme store const themeStore = useThemeStore(pinia); // 使用 theme store

View File

@@ -8,19 +8,19 @@
</template> </template>
<script setup> <script setup>
import {ref} from "vue" import { ref } from 'vue'
const winHeight = ref(window.innerHeight) const winHeight = ref(window.innerHeight)
</script> </script>
<style lang="stylus" scoped> <style lang="scss" scoped>
.page-404 { .page-404 {
display: flex; display: flex;
justify-content: center; justify-content: center;
background-color: #282c34; background-color: #282c34;
.inner { .inner {
text-align center text-align: center;
h1 { h1 {
color: #202020; color: #202020;
@@ -31,10 +31,9 @@ const winHeight = ref(window.innerHeight)
} }
h2 { h2 {
color #ffffff; color: #ffffff;
font-weight: bold; font-weight: bold;
} }
} }
} }
</style> </style>

View File

@@ -167,7 +167,7 @@ const useRole = (role) => {
} }
</script> </script>
<style lang="stylus" scoped> <style lang="scss" scoped>
@import "../assets/css/chat-app.styl" @use '../assets/css/chat-app.scss' as *;
@import "../assets/css/custom-scroll.styl" @use '../assets/css/custom-scroll.scss' as *;
</style> </style>

View File

@@ -7,93 +7,98 @@
<div v-for="item in chatData" :key="item.id"> <div v-for="item in chatData" :key="item.id">
<chat-prompt v-if="item.type === 'prompt'" :data="item" list-style="list" /> <chat-prompt v-if="item.type === 'prompt'" :data="item" list-style="list" />
<chat-reply v-else-if="item.type === 'reply'" :data="item" :read-only="true" list-style="list" /> <chat-reply
v-else-if="item.type === 'reply'"
:data="item"
:read-only="true"
list-style="list"
/>
</div> </div>
</div> </div>
<!-- end chat box --> <!-- end chat box -->
</div> </div>
</template> </template>
<script setup> <script setup>
import ChatReply from "@/components/ChatReply.vue"; import ChatPrompt from '@/components/ChatPrompt.vue'
import ChatPrompt from "@/components/ChatPrompt.vue"; import ChatReply from '@/components/ChatReply.vue'
import { nextTick, onMounted, ref } from "vue"; import { httpGet } from '@/utils/http'
import { useRouter } from "vue-router"; import Clipboard from 'clipboard'
import { httpGet } from "@/utils/http"; import { ElMessage } from 'element-plus'
import "highlight.js/styles/a11y-dark.css"; import hl from 'highlight.js'
import hl from "highlight.js"; import 'highlight.js/styles/a11y-dark.css'
import { ElMessage } from "element-plus"; import { nextTick, onMounted, ref } from 'vue'
import Clipboard from "clipboard"; import { useRouter } from 'vue-router'
const chatData = ref([]); const chatData = ref([])
const router = useRouter(); const router = useRouter()
const chatId = router.currentRoute.value.query["chat_id"]; const chatId = router.currentRoute.value.query['chat_id']
const loading = ref(true); const loading = ref(true)
const chatTitle = ref(""); const chatTitle = ref('')
httpGet("/api/chat/history?chat_id=" + chatId) httpGet('/api/chat/history?chat_id=' + chatId)
.then((res) => { .then((res) => {
const data = res.data; const data = res.data
if (!data) { if (!data) {
loading.value = false; loading.value = false
return; return
} }
for (let i = 0; i < data.length; i++) { for (let i = 0; i < data.length; i++) {
if (data[i].type === "prompt") { if (data[i].type === 'prompt') {
chatData.value.push(data[i]); chatData.value.push(data[i])
continue; continue
} else if (data[i].type === "mj") { } else if (data[i].type === 'mj') {
data[i].content = JSON.parse(data[i].content); data[i].content = JSON.parse(data[i].content)
data[i].content.content = data[i].content?.content; data[i].content.content = data[i].content?.content
chatData.value.push(data[i]); chatData.value.push(data[i])
continue; continue
} }
data[i].orgContent = data[i].content; data[i].orgContent = data[i].content
data[i].content = data[i].content; data[i].content = data[i].content
chatData.value.push(data[i]); chatData.value.push(data[i])
} }
nextTick(() => { nextTick(() => {
hl.configure({ ignoreUnescapedHTML: true }); hl.configure({ ignoreUnescapedHTML: true })
const blocks = document.querySelector("#chat-box").querySelectorAll("pre code"); const blocks = document.querySelector('#chat-box').querySelectorAll('pre code')
blocks.forEach((block) => { blocks.forEach((block) => {
hl.highlightElement(block); hl.highlightElement(block)
}); })
}); })
loading.value = false; loading.value = false
}) })
.catch((e) => { .catch((e) => {
ElMessage.error("加载聊天记录失败:" + e.message); ElMessage.error('加载聊天记录失败:' + e.message)
}); })
httpGet("/api/chat/detail?chat_id=" + chatId) httpGet('/api/chat/detail?chat_id=' + chatId)
.then((res) => { .then((res) => {
chatTitle.value = res.data.title; chatTitle.value = res.data.title
}) })
.catch((e) => { .catch((e) => {
ElMessage.error("加载会失败: " + e.message); ElMessage.error('加载会失败: ' + e.message)
}); })
onMounted(() => { onMounted(() => {
const clipboard = new Clipboard(".copy-reply"); const clipboard = new Clipboard('.copy-reply')
clipboard.on("success", () => { clipboard.on('success', () => {
ElMessage.success("复制成功!"); ElMessage.success('复制成功!')
}); })
clipboard.on("error", () => { clipboard.on('error', () => {
ElMessage.error("复制失败!"); ElMessage.error('复制失败!')
}); })
}); })
</script> </script>
<style lang="stylus"> <style lang="scss">
.chat-export { .chat-export {
display flex display: flex;
justify-content center justify-content: center;
padding 0 20px padding: 0 20px;
.chat-box { .chat-box {
width 100%; width: 100%;
// 变量定义 // 变量定义
--content-font-size: 16px; --content-font-size: 16px;
--content-color: #c1c1c1; --content-color: #c1c1c1;
@@ -102,7 +107,7 @@ onMounted(() => {
padding: 0 0 50px 0; padding: 0 0 50px 0;
.title { .title {
text-align center text-align: center;
} }
.chat-line { .chat-line {
@@ -111,7 +116,7 @@ onMounted(() => {
align-items: center; align-items: center;
.chat-line-inner { .chat-line-inner {
max-width 800px max-width: 800px;
} }
} }
} }

Some files were not shown because too many files have changed in this diff Show More