Compare commits
8 Commits
07d53c7a68
...
75475b3854
| Author | SHA1 | Date | |
|---|---|---|---|
| 75475b3854 | |||
|
|
c4e45597a4 | ||
|
|
19ba9aac26 | ||
| 22204bedec | |||
| f31a47f56c | |||
| 89fed5a6ea | |||
| feee90ffbd | |||
| c84cf055ef |
@ -153,6 +153,10 @@ async def loginUser(ns):
|
|||||||
if type1 == 1:
|
if type1 == 1:
|
||||||
# 手机号验证码登录
|
# 手机号验证码登录
|
||||||
userreacs = await sor.R('users', {'mobile': ns.get('username')})
|
userreacs = await sor.R('users', {'mobile': ns.get('username')})
|
||||||
|
|
||||||
|
if not userreacs:
|
||||||
|
userreacs = await sor.R('users', {'username': ns.get('username')})
|
||||||
|
|
||||||
# 如果是微信扫码后绑定已有账号
|
# 如果是微信扫码后绑定已有账号
|
||||||
if ns.get('wechat_openid'):
|
if ns.get('wechat_openid'):
|
||||||
if userreacs:
|
if userreacs:
|
||||||
|
|||||||
@ -43,57 +43,101 @@ async def logintype(ns):
|
|||||||
|
|
||||||
db = DBPools()
|
db = DBPools()
|
||||||
async with db.sqlorContext('kboss') as sor:
|
async with db.sqlorContext('kboss') as sor:
|
||||||
type = 0
|
|
||||||
if ns.get('codeid'):
|
domain_name = ns.get('domain_name')
|
||||||
type += 1
|
if domain_name in ['www.opencomputing.cn', 'dev.opencomputing.cn', 'localhost:9527'] and ns.get('username') != '开元云(北京)科技有限公司':
|
||||||
|
if not ns.get('mobile'):
|
||||||
|
return {
|
||||||
|
'status': False,
|
||||||
|
'msg': '请输入手机号'
|
||||||
|
}
|
||||||
|
real_mobile_li = await sor.R('users', {'username': ns['username']})
|
||||||
|
if not real_mobile_li:
|
||||||
|
return {
|
||||||
|
'status': False,
|
||||||
|
'msg': '用户名有误'
|
||||||
|
}
|
||||||
|
real_mobile = real_mobile_li[0]['mobile'] if real_mobile_li else None
|
||||||
|
if not real_mobile:
|
||||||
|
return {
|
||||||
|
'status': False,
|
||||||
|
'msg': '未查询到匹配得手机号码'
|
||||||
|
}
|
||||||
|
|
||||||
|
if real_mobile and ns['mobile'] != real_mobile:
|
||||||
|
return {
|
||||||
|
'status': False,
|
||||||
|
'msg': '您的手机号与用户名不匹配'
|
||||||
|
}
|
||||||
|
|
||||||
|
if not ns.get('codeid'):
|
||||||
|
return {
|
||||||
|
'status': False,
|
||||||
|
'msg': 'codeid不存在, 请输入验证码'
|
||||||
|
}
|
||||||
code = await sor.R('validatecode', {'id': ns.get('codeid'), 'vcode': ns.get('vcode')})
|
code = await sor.R('validatecode', {'id': ns.get('codeid'), 'vcode': ns.get('vcode')})
|
||||||
if len(code) < 1:
|
if len(code) < 1:
|
||||||
return {'status': False, 'msg': '验证码不正确'}
|
return {'status': False, 'msg': '验证码不正确'}
|
||||||
if type == 1:
|
|
||||||
# 手机号登录
|
|
||||||
users = await sor.R('users', {'mobile': ns.get('username')})
|
|
||||||
else:
|
|
||||||
password = password_encode(ns['password'])
|
password = password_encode(ns['password'])
|
||||||
users = await sor.R('users', {'username': ns.get('username'), 'password': password})
|
users = await sor.R('users', {'username': ns.get('username'), 'password': password})
|
||||||
if len(users) < 1:
|
if len(users) < 1:
|
||||||
return {"status": False,'msg':'用户名或密码错误'}
|
return {"status": False,'msg':'用户名或密码错误'}
|
||||||
elif ns.get('username') == "admin":
|
|
||||||
return {'status': True}
|
return {'status': True}
|
||||||
|
|
||||||
else:
|
else:
|
||||||
reseller = await sor.R('reseller', {'domain_name': ns.get('domain_name')})
|
type = 0
|
||||||
# 查到用户的所在机构
|
if ns.get('codeid'):
|
||||||
user_org = await sor.R('organization', {'id': users[0]['orgid']})
|
type += 1
|
||||||
#0代表用户为主 1代表用户为子
|
code = await sor.R('validatecode', {'id': ns.get('codeid'), 'vcode': ns.get('vcode')})
|
||||||
user_type = 0
|
if len(code) < 1:
|
||||||
# 子页面判断用户
|
return {'status': False, 'msg': '验证码不正确'}
|
||||||
if len(reseller) >= 1:
|
if type == 1:
|
||||||
if reseller[0]['orgid'] == user_org[0]['parentid']:
|
# 手机号登录
|
||||||
user_type += 1
|
users = await sor.R('users', {'mobile': ns.get('username')})
|
||||||
if reseller[0]['orgid'] == users[0]['orgid']:
|
|
||||||
user_type += 1
|
|
||||||
# 主页面判断用户
|
|
||||||
else:
|
else:
|
||||||
resellers = await sor.R('reseller', {'orgid': user_org[0]['parentid']})
|
password = password_encode(ns['password'])
|
||||||
if len(resellers) >= 1:
|
users = await sor.R('users', {'username': ns.get('username'), 'password': password})
|
||||||
user_type += 1
|
if len(users) < 1:
|
||||||
if users[0]['user_reseller'] == '1':
|
return {"status": False,'msg':'用户名或密码错误'}
|
||||||
user_type += 1
|
elif ns.get('username') == "admin":
|
||||||
# 证明是主级页面
|
return {'status': True}
|
||||||
if len(reseller) < 1:
|
else:
|
||||||
# 用户为主
|
reseller = await sor.R('reseller', {'domain_name': ns.get('domain_name')})
|
||||||
if user_type == 0:
|
# 查到用户的所在机构
|
||||||
return {'status': True}
|
user_org = await sor.R('organization', {'id': users[0]['orgid']})
|
||||||
|
#0代表用户为主 1代表用户为子
|
||||||
|
user_type = 0
|
||||||
|
# 子页面判断用户
|
||||||
|
if len(reseller) >= 1:
|
||||||
|
if reseller[0]['orgid'] == user_org[0]['parentid']:
|
||||||
|
user_type += 1
|
||||||
|
if reseller[0]['orgid'] == users[0]['orgid']:
|
||||||
|
user_type += 1
|
||||||
|
# 主页面判断用户
|
||||||
else:
|
else:
|
||||||
|
resellers = await sor.R('reseller', {'orgid': user_org[0]['parentid']})
|
||||||
|
if len(resellers) >= 1:
|
||||||
|
user_type += 1
|
||||||
|
if users[0]['user_reseller'] == '1':
|
||||||
|
user_type += 1
|
||||||
|
# 证明是主级页面
|
||||||
|
if len(reseller) < 1:
|
||||||
|
# 用户为主
|
||||||
|
if user_type == 0:
|
||||||
|
return {'status': True}
|
||||||
|
else:
|
||||||
|
# 用户为子
|
||||||
|
return {'status': False,'msg':'用户名或密码错误'}
|
||||||
|
# 子级页面
|
||||||
|
else:
|
||||||
|
# 用户为主
|
||||||
|
if user_type == 0:
|
||||||
|
return {'status': False,'msg':'用户名或密码错误'}
|
||||||
# 用户为子
|
# 用户为子
|
||||||
return {'status': False,'msg':'用户名或密码错误'}
|
else:
|
||||||
# 子级页面
|
return {'status': True}
|
||||||
else:
|
|
||||||
# 用户为主
|
|
||||||
if user_type == 0:
|
|
||||||
return {'status': False,'msg':'用户名或密码错误'}
|
|
||||||
# 用户为子
|
|
||||||
else:
|
|
||||||
return {'status': True}
|
|
||||||
|
|
||||||
ret = await logintype(params_kw)
|
ret = await logintype(params_kw)
|
||||||
return ret
|
return ret
|
||||||
@ -160,8 +160,13 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div v-show="aiDialogVisible" class="ai-chat-panel">
|
<div
|
||||||
<div class="ai-chat-panel__header">
|
v-show="aiDialogVisible"
|
||||||
|
ref="aiChatPanel"
|
||||||
|
class="ai-chat-panel"
|
||||||
|
:style="aiPanelStyle"
|
||||||
|
>
|
||||||
|
<div class="ai-chat-panel__header" @mousedown="startAIPanelDrag">
|
||||||
<div class="ai-chat-panel__title">
|
<div class="ai-chat-panel__title">
|
||||||
<span class="ai-chat-panel__logo">AI</span>
|
<span class="ai-chat-panel__logo">AI</span>
|
||||||
<span>有问题,找开元</span>
|
<span>有问题,找开元</span>
|
||||||
@ -260,6 +265,15 @@ export default Vue.extend({
|
|||||||
aiInput: '',
|
aiInput: '',
|
||||||
aiLoading: false,
|
aiLoading: false,
|
||||||
aiMessages: [],
|
aiMessages: [],
|
||||||
|
aiPanelPosition: {
|
||||||
|
left: null,
|
||||||
|
top: null
|
||||||
|
},
|
||||||
|
aiPanelDragging: false,
|
||||||
|
aiPanelDragOffset: {
|
||||||
|
x: 0,
|
||||||
|
y: 0
|
||||||
|
},
|
||||||
aiQuickQuestions: [
|
aiQuickQuestions: [
|
||||||
'推荐适合训练大模型的 GPU 服务器',
|
'推荐适合训练大模型的 GPU 服务器',
|
||||||
'4090 和 A100 怎么选',
|
'4090 和 A100 怎么选',
|
||||||
@ -308,6 +322,9 @@ export default Vue.extend({
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
beforeDestroy() {
|
||||||
|
this.stopAIPanelDrag()
|
||||||
|
},
|
||||||
computed: {
|
computed: {
|
||||||
...mapGetters(["sidebar", "avatar", "device"]),
|
...mapGetters(["sidebar", "avatar", "device"]),
|
||||||
...mapState({
|
...mapState({
|
||||||
@ -342,6 +359,18 @@ export default Vue.extend({
|
|||||||
} else {
|
} else {
|
||||||
return this.$route.path.includes('/homePage/index');
|
return this.$route.path.includes('/homePage/index');
|
||||||
}
|
}
|
||||||
|
},
|
||||||
|
aiPanelStyle() {
|
||||||
|
if (this.aiPanelPosition.left === null || this.aiPanelPosition.top === null) {
|
||||||
|
return {}
|
||||||
|
}
|
||||||
|
|
||||||
|
return {
|
||||||
|
left: `${this.aiPanelPosition.left}px`,
|
||||||
|
top: `${this.aiPanelPosition.top}px`,
|
||||||
|
right: 'auto',
|
||||||
|
bottom: 'auto'
|
||||||
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
@ -350,12 +379,14 @@ export default Vue.extend({
|
|||||||
handleAIClick() {
|
handleAIClick() {
|
||||||
this.aiDialogVisible = true
|
this.aiDialogVisible = true
|
||||||
this.$nextTick(() => {
|
this.$nextTick(() => {
|
||||||
|
this.initAIPanelPosition()
|
||||||
this.scrollAIChatToBottom()
|
this.scrollAIChatToBottom()
|
||||||
})
|
})
|
||||||
},
|
},
|
||||||
|
|
||||||
closeAIPanel() {
|
closeAIPanel() {
|
||||||
this.aiDialogVisible = false
|
this.aiDialogVisible = false
|
||||||
|
this.stopAIPanelDrag()
|
||||||
},
|
},
|
||||||
|
|
||||||
resetAIChat() {
|
resetAIChat() {
|
||||||
@ -367,6 +398,73 @@ export default Vue.extend({
|
|||||||
this.sendAIMessage(question)
|
this.sendAIMessage(question)
|
||||||
},
|
},
|
||||||
|
|
||||||
|
initAIPanelPosition() {
|
||||||
|
if (this.aiPanelPosition.left !== null && this.aiPanelPosition.top !== null) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
const panel = this.$refs.aiChatPanel
|
||||||
|
if (!panel) return
|
||||||
|
|
||||||
|
const panelWidth = panel.offsetWidth || 380
|
||||||
|
const panelHeight = panel.offsetHeight || 620
|
||||||
|
|
||||||
|
this.aiPanelPosition = {
|
||||||
|
left: Math.max(window.innerWidth - panelWidth - 24, 16),
|
||||||
|
top: Math.max(window.innerHeight - panelHeight - 24, 16)
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
startAIPanelDrag(event) {
|
||||||
|
if (event.button !== 0) return
|
||||||
|
if (event.target && event.target.closest('.ai-chat-panel__close')) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
const panel = this.$refs.aiChatPanel
|
||||||
|
if (!panel) return
|
||||||
|
|
||||||
|
const rect = panel.getBoundingClientRect()
|
||||||
|
this.aiPanelDragging = true
|
||||||
|
this.aiPanelDragOffset = {
|
||||||
|
x: event.clientX - rect.left,
|
||||||
|
y: event.clientY - rect.top
|
||||||
|
}
|
||||||
|
|
||||||
|
window.addEventListener('mousemove', this.handleAIPanelDrag)
|
||||||
|
window.addEventListener('mouseup', this.stopAIPanelDrag)
|
||||||
|
document.body.style.userSelect = 'none'
|
||||||
|
},
|
||||||
|
|
||||||
|
handleAIPanelDrag(event) {
|
||||||
|
if (!this.aiPanelDragging) return
|
||||||
|
|
||||||
|
const panel = this.$refs.aiChatPanel
|
||||||
|
if (!panel) return
|
||||||
|
|
||||||
|
const panelWidth = panel.offsetWidth || 380
|
||||||
|
const panelHeight = panel.offsetHeight || 620
|
||||||
|
const minLeft = 0
|
||||||
|
const minTop = 0
|
||||||
|
const maxLeft = Math.max(window.innerWidth - panelWidth, 0)
|
||||||
|
const maxTop = Math.max(window.innerHeight - panelHeight, 0)
|
||||||
|
|
||||||
|
const nextLeft = event.clientX - this.aiPanelDragOffset.x
|
||||||
|
const nextTop = event.clientY - this.aiPanelDragOffset.y
|
||||||
|
|
||||||
|
this.aiPanelPosition = {
|
||||||
|
left: Math.min(Math.max(nextLeft, minLeft), maxLeft),
|
||||||
|
top: Math.min(Math.max(nextTop, minTop), maxTop)
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
stopAIPanelDrag() {
|
||||||
|
this.aiPanelDragging = false
|
||||||
|
window.removeEventListener('mousemove', this.handleAIPanelDrag)
|
||||||
|
window.removeEventListener('mouseup', this.stopAIPanelDrag)
|
||||||
|
document.body.style.userSelect = ''
|
||||||
|
},
|
||||||
|
|
||||||
handleAIKeydown(event) {
|
handleAIKeydown(event) {
|
||||||
if (event.key === 'Enter' && !event.shiftKey) {
|
if (event.key === 'Enter' && !event.shiftKey) {
|
||||||
event.preventDefault()
|
event.preventDefault()
|
||||||
@ -1251,6 +1349,7 @@ export default Vue.extend({
|
|||||||
justify-content: space-between;
|
justify-content: space-between;
|
||||||
border-bottom: 1px solid #f0f0f0;
|
border-bottom: 1px solid #f0f0f0;
|
||||||
background: #fff;
|
background: #fff;
|
||||||
|
cursor: move;
|
||||||
}
|
}
|
||||||
|
|
||||||
&__title {
|
&__title {
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
Loading…
x
Reference in New Issue
Block a user