Skip to content
项目
群组
代码片段
帮助
正在加载...
帮助
提交反馈
为 GitLab 提交贡献
登录
切换导航
功
功能演示系统
项目
项目
详情
动态
版本
周期分析
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
统计图
议题
0
议题
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
CI / CD
CI / CD
流水线
作业
计划
统计图
Wiki
Wiki
代码片段
代码片段
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
统计图
创建新议题
作业
提交
议题看板
打开侧边栏
示例
功能演示系统
提交
0dc2f7ca
提交
0dc2f7ca
编写于
2年前
作者:
ibizdev
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
ShineKOT 发布系统代码 [后台服务,演示应用]
上级
30265302
变更
30
隐藏空白字符变更
内嵌
并排
正在显示
30 个修改的文件
包含
1922 行增加
和
4 行删除
+1922
-4
dingding.svg
app_Web/public/assets/img/dingding.svg
+1
-0
qiyeweixin.svg
app_Web/public/assets/img/qiyeweixin.svg
+1
-0
app-register.ts
app_Web/src/app-register.ts
+20
-0
dingding.svg
app_Web/src/assets/img/dingding.svg
+1
-0
qiyeweixin.svg
app_Web/src/assets/img/qiyeweixin.svg
+1
-0
app-login-button.less
...yout-element/login/app-login-button/app-login-button.less
+3
-0
app-login-button.vue
...ayout-element/login/app-login-button/app-login-button.vue
+26
-0
app-login-captcha.vue
...out-element/login/app-login-captcha/app-login-captcha.vue
+61
-0
reset.png
...element/login/app-login-captcha/vue-puzzle-code/reset.png
+0
-0
vue-puzzle-code.less
...in/app-login-captcha/vue-puzzle-code/vue-puzzle-code.less
+239
-0
vue-puzzle-code.vue
...gin/app-login-captcha/vue-puzzle-code/vue-puzzle-code.vue
+578
-0
app-login-input.vue
.../layout-element/login/app-login-input/app-login-input.vue
+32
-0
app-login-message.less
...ut-element/login/app-login-message/app-login-message.less
+15
-0
app-login-message.vue
...out-element/login/app-login-message/app-login-message.vue
+26
-0
app-login-note-verify.less
...nt/login/app-login-note-verify/app-login-note-verify.less
+21
-0
app-login-note-verify.vue
...ent/login/app-login-note-verify/app-login-note-verify.vue
+153
-0
app-login-org.less
...nts/layout-element/login/app-login-org/app-login-org.less
+34
-0
app-login-org.vue
...ents/layout-element/login/app-login-org/app-login-org.vue
+129
-0
app-login-third.less
...layout-element/login/app-login-third/app-login-third.less
+11
-0
app-login-third.vue
.../layout-element/login/app-login-third/app-login-third.vue
+310
-0
app-preset-caption.less
...t-element/text/app-preset-caption/app-preset-caption.less
+9
-0
app-preset-caption.vue
...ut-element/text/app-preset-caption/app-preset-caption.vue
+16
-0
app-preset-text.less
.../layout-element/text/app-preset-text/app-preset-text.less
+4
-0
app-preset-text.vue
...s/layout-element/text/app-preset-text/app-preset-text.vue
+172
-0
app-preset-title.less
...ayout-element/text/app-preset-title/app-preset-title.less
+5
-0
app-preset-title.vue
...layout-element/text/app-preset-title/app-preset-title.vue
+32
-0
components_en_US_base.ts
...Web/src/locale/lanres/components/components_en_US_base.ts
+9
-0
components_zh_CN_base.ts
...Web/src/locale/lanres/components/components_zh_CN_base.ts
+9
-0
default-searchform-base.vue
...s/ibizbook/default-searchform/default-searchform-base.vue
+2
-2
quicksearchform-searchform-base.vue
...searchform-searchform/quicksearchform-searchform-base.vue
+2
-2
未找到文件。
app_Web/public/assets/img/dingding.svg
0 → 100644
浏览文件 @
0dc2f7ca
<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
<svg
t=
"1616652640756"
class=
"icon"
viewBox=
"0 0 1024 1024"
version=
"1.1"
xmlns=
"http://www.w3.org/2000/svg"
p-id=
"651"
width=
"48"
height=
"48"
xmlns:xlink=
"http://www.w3.org/1999/xlink"
><defs><style
type=
"text/css"
></style></defs><path
d=
"M512 2C230.2 2 2 230.2 2 512s228.2 510 510 510 510-228.2 510-510S793.3 2 512 2z m235.9 442c-1 4.6-3.6 10.8-7.2 19.1l-0.5 0.5c-21.6 45.8-77.3 135.5-77.3 135.5l-0.5-0.5-16.5 28.3h78.8L574.3 826.8l34-136h-61.8l21.6-90.2c-17.5 4.1-38.1 9.8-62.3 18 0 0-33 19.1-94.8-37.1 0 0-41.7-37.1-17.5-45.8 10.3-4.1 50-8.8 81.4-12.9 42.2-5.7 68.5-8.8 68.5-8.8s-130.3 2.1-161.2-3.1c-30.9-4.6-70.1-56.7-78.3-102 0 0-12.9-24.7 27.8-12.9 40.2 11.8 209.2 45.8 209.2 45.8S321.4 375 307 358.5c-14.4-16.5-42.8-89.6-39.2-134.5 0 0 1.5-11.3 12.9-8.2 0 0 161.8 74.2 272.5 114.4C664.5 371.4 760.8 392 747.9 444z"
fill=
"#3296FA"
p-id=
"652"
></path></svg>
\ No newline at end of file
This diff is collapsed.
Click to expand it.
app_Web/public/assets/img/qiyeweixin.svg
0 → 100644
浏览文件 @
0dc2f7ca
<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
<svg
t=
"1616652700601"
class=
"icon"
viewBox=
"0 0 1024 1024"
version=
"1.1"
xmlns=
"http://www.w3.org/2000/svg"
p-id=
"973"
xmlns:xlink=
"http://www.w3.org/1999/xlink"
width=
"48"
height=
"48"
><defs><style
type=
"text/css"
></style></defs><path
d=
"M512 2c281.7 0 510 228.3 510 510s-228.3 510-510 510S2 793.7 2 512 230.3 2 512 2z m159.8 680.3c-4 3.9-4 10.2-0.2 14.1 0.4 0.5 0.9 0.9 1.5 1.2 22.1 20.4 36.4 47.9 40.4 77.7 6.2 22.4 29.7 35.7 52.4 29.5 22.5-5.9 35.9-28.9 30-51.3 0-0.1-0.1-0.2-0.1-0.4-4.7-16.8-19.3-29.1-36.7-30.8-28-5.1-53.5-19.2-72.8-40.1-4.1-3.8-10.5-3.8-14.5 0.1z m-225.7-483c-76.4 8.3-145.8 40.6-195.6 91-19.4 19.4-35.5 41.8-47.8 66.3-37.7 74.9-31.4 164.4 16.5 233.2 13.5 20.2 35.8 45.4 56.1 63.3l-9.2 71.3-1 3c-0.3 0.9-0.3 1.9-0.4 2.8l-0.2 2.3 0.2 2.3c1.2 12.7 12.5 22 25.2 20.9 3.5-0.3 6.8-1.4 9.8-3.1h0.4l1.4-1 22-10.8 65.5-32.5c31.1 8.8 63.4 13.2 95.8 13 40 0.1 79.8-6.7 117.5-20.2-18.8-6-30.9-24.3-29-44-39 12.4-80.2 16.4-120.8 11.9l-6.5-0.9c-14.7-1.9-29.2-4.9-43.4-8.9-7.8-2.4-16.1-1.5-23.3 2.4l-1.8 0.9-53.9 31.3-2.3 1.4c-1.3 0.7-1.9 1-2.6 1-2-0.1-3.5-1.8-3.4-3.8l2-8.2 2.4-8.9 3.9-14.7 4.5-16.4c3-9.2-0.3-19.2-8.2-24.8-21.1-15.5-39.5-34.4-54.4-56-37.9-54.2-43-124.8-13.3-183.8 9.9-19.5 22.9-37.4 38.4-52.9 40.9-41.6 98.3-68.1 161.9-74.9 22-2.4 44.2-2.4 66.2 0 63.2 7.2 120.4 34 161.1 75.4 15.4 15.7 28.2 33.6 37.9 53.2 12.5 24.8 19 52.3 19.1 80.1 0 2.9-0.3 5.8-0.4 8.6 16.8-10.2 38.4-7.7 52.4 6.1l1.9 2.3c3.3-41.2-4.8-82.5-23.3-119.5-12.1-24.5-28.1-46.8-47.3-66.3-52.5-52-121.4-84.3-194.9-91.7-26.4-3.4-52.9-3.5-79.1-0.7z m418.2 405.4c-7.2 1.9-13.8 5.7-19.2 11h-0.1c-6.9 6.8-11.2 15.7-12.2 25.3-5.2 27.8-19.5 53.1-40.5 72-4 3.8-4.1 10.1-0.3 14.1l0.1 0.1c4 4 10.5 4.1 14.6 0.1 0.5-0.5 0.9-0.9 1.2-1.5 20.9-21.9 48.7-36 78.7-39.8 22.8-6.1 36.2-29.2 30.1-51.6-6.2-22.5-29.6-35.8-52.4-29.7z m-160.4-42l-0.7 0.7c-20.9 22.7-49.2 37.3-79.9 41.2-22.6 5.9-36.2 28.7-30.2 51.1 1.9 7.3 5.9 14 11.3 19.3 16.7 16.4 43.7 16.4 60.4-0.1 6.8-6.8 11.1-15.7 12.2-25.2 5.3-27.8 19.6-53.1 40.7-72 4.1-3.7 4.5-10 0.9-14.1l-0.1-0.1c-4-4.2-10.4-4.5-14.6-0.8z m39.6-76.6c-7.1 1.9-13.6 5.7-18.7 10.8-16.4 16.2-16.6 42.6-0.4 59l0.5 0.5c6.9 6.8 15.9 11 25.5 12.1 28 5.1 53.6 19.1 72.9 39.9 4 4 10.4 4 14.4 0.1 4-3.8 4.1-10.1 0.3-14.1-0.5-0.5-1.1-1-1.7-1.4-22.1-20.4-36.4-47.8-40.4-77.6-6.1-22.4-29.6-35.5-52.4-29.3z"
fill=
"#0082EF"
p-id=
"974"
></path></svg>
\ No newline at end of file
This diff is collapsed.
Click to expand it.
app_Web/src/app-register.ts
浏览文件 @
0dc2f7ca
...
...
@@ -115,6 +115,16 @@ import AppStandardContainer from './components/layout-element/container/app-stan
import
AppTabPanel
from
'./components/layout-element/container/app-tab-panel/app-tab-panel.vue'
;
import
AppTabPage
from
'./components/layout-element/container/app-tab-page/app-tab-page.vue'
;
import
AppNavPos
from
'./components/layout-element/container/app-nav-pos/app-nav-pos.vue'
;
import
AppPreSetText
from
'./components/layout-element/text/app-preset-text/app-preset-text.vue'
;
import
AppPreSetCaption
from
'./components/layout-element/text/app-preset-caption/app-preset-caption.vue'
;
import
AppPreSetTitle
from
'./components/layout-element/text/app-preset-title/app-preset-title.vue'
;
import
AppLoginInput
from
'./components/layout-element/login/app-login-input/app-login-input.vue'
;
import
AppLoginButton
from
'./components/layout-element/login/app-login-button/app-login-button.vue'
;
import
AppLoginOrg
from
'./components/layout-element/login/app-login-org/app-login-org.vue'
;
import
AppLoginMessage
from
'./components/layout-element/login/app-login-message/app-login-message.vue'
;
import
AppLoginThird
from
'./components/layout-element/login/app-login-third/app-login-third.vue'
;
import
AppLoginCaptcha
from
'./components/layout-element/login/app-login-captcha/app-login-captcha.vue'
;
import
AppLoginNoteVerify
from
'./components/layout-element/login/app-login-note-verify/app-login-note-verify.vue'
;
// 全局挂载UI实体服务注册中心
window
[
'uiServiceRegister'
]
=
uiServiceRegister
;
// 全局挂载实体权限服务注册中心
...
...
@@ -244,5 +254,15 @@ export const AppComponents = {
v
.
component
(
'app-tab-panel'
,
AppTabPanel
);
v
.
component
(
'app-tab-page'
,
AppTabPage
);
v
.
component
(
'app-nav-pos'
,
AppNavPos
);
v
.
component
(
'app-preset-text'
,
AppPreSetText
);
v
.
component
(
'app-preset-caption'
,
AppPreSetCaption
);
v
.
component
(
'app-preset-title'
,
AppPreSetTitle
);
v
.
component
(
'app-login-input'
,
AppLoginInput
);
v
.
component
(
'app-login-button'
,
AppLoginButton
);
v
.
component
(
'app-login-org'
,
AppLoginOrg
);
v
.
component
(
'app-login-message'
,
AppLoginMessage
);
v
.
component
(
'app-login-third'
,
AppLoginThird
);
v
.
component
(
'app-login-captcha'
,
AppLoginCaptcha
);
v
.
component
(
'app-login-note-verify'
,
AppLoginNoteVerify
);
},
};
\ No newline at end of file
This diff is collapsed.
Click to expand it.
app_Web/src/assets/img/dingding.svg
0 → 100644
浏览文件 @
0dc2f7ca
<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
<svg
t=
"1616652640756"
class=
"icon"
viewBox=
"0 0 1024 1024"
version=
"1.1"
xmlns=
"http://www.w3.org/2000/svg"
p-id=
"651"
width=
"48"
height=
"48"
xmlns:xlink=
"http://www.w3.org/1999/xlink"
><defs><style
type=
"text/css"
></style></defs><path
d=
"M512 2C230.2 2 2 230.2 2 512s228.2 510 510 510 510-228.2 510-510S793.3 2 512 2z m235.9 442c-1 4.6-3.6 10.8-7.2 19.1l-0.5 0.5c-21.6 45.8-77.3 135.5-77.3 135.5l-0.5-0.5-16.5 28.3h78.8L574.3 826.8l34-136h-61.8l21.6-90.2c-17.5 4.1-38.1 9.8-62.3 18 0 0-33 19.1-94.8-37.1 0 0-41.7-37.1-17.5-45.8 10.3-4.1 50-8.8 81.4-12.9 42.2-5.7 68.5-8.8 68.5-8.8s-130.3 2.1-161.2-3.1c-30.9-4.6-70.1-56.7-78.3-102 0 0-12.9-24.7 27.8-12.9 40.2 11.8 209.2 45.8 209.2 45.8S321.4 375 307 358.5c-14.4-16.5-42.8-89.6-39.2-134.5 0 0 1.5-11.3 12.9-8.2 0 0 161.8 74.2 272.5 114.4C664.5 371.4 760.8 392 747.9 444z"
fill=
"#3296FA"
p-id=
"652"
></path></svg>
\ No newline at end of file
This diff is collapsed.
Click to expand it.
app_Web/src/assets/img/qiyeweixin.svg
0 → 100644
浏览文件 @
0dc2f7ca
<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
<svg
t=
"1616652700601"
class=
"icon"
viewBox=
"0 0 1024 1024"
version=
"1.1"
xmlns=
"http://www.w3.org/2000/svg"
p-id=
"973"
xmlns:xlink=
"http://www.w3.org/1999/xlink"
width=
"48"
height=
"48"
><defs><style
type=
"text/css"
></style></defs><path
d=
"M512 2c281.7 0 510 228.3 510 510s-228.3 510-510 510S2 793.7 2 512 230.3 2 512 2z m159.8 680.3c-4 3.9-4 10.2-0.2 14.1 0.4 0.5 0.9 0.9 1.5 1.2 22.1 20.4 36.4 47.9 40.4 77.7 6.2 22.4 29.7 35.7 52.4 29.5 22.5-5.9 35.9-28.9 30-51.3 0-0.1-0.1-0.2-0.1-0.4-4.7-16.8-19.3-29.1-36.7-30.8-28-5.1-53.5-19.2-72.8-40.1-4.1-3.8-10.5-3.8-14.5 0.1z m-225.7-483c-76.4 8.3-145.8 40.6-195.6 91-19.4 19.4-35.5 41.8-47.8 66.3-37.7 74.9-31.4 164.4 16.5 233.2 13.5 20.2 35.8 45.4 56.1 63.3l-9.2 71.3-1 3c-0.3 0.9-0.3 1.9-0.4 2.8l-0.2 2.3 0.2 2.3c1.2 12.7 12.5 22 25.2 20.9 3.5-0.3 6.8-1.4 9.8-3.1h0.4l1.4-1 22-10.8 65.5-32.5c31.1 8.8 63.4 13.2 95.8 13 40 0.1 79.8-6.7 117.5-20.2-18.8-6-30.9-24.3-29-44-39 12.4-80.2 16.4-120.8 11.9l-6.5-0.9c-14.7-1.9-29.2-4.9-43.4-8.9-7.8-2.4-16.1-1.5-23.3 2.4l-1.8 0.9-53.9 31.3-2.3 1.4c-1.3 0.7-1.9 1-2.6 1-2-0.1-3.5-1.8-3.4-3.8l2-8.2 2.4-8.9 3.9-14.7 4.5-16.4c3-9.2-0.3-19.2-8.2-24.8-21.1-15.5-39.5-34.4-54.4-56-37.9-54.2-43-124.8-13.3-183.8 9.9-19.5 22.9-37.4 38.4-52.9 40.9-41.6 98.3-68.1 161.9-74.9 22-2.4 44.2-2.4 66.2 0 63.2 7.2 120.4 34 161.1 75.4 15.4 15.7 28.2 33.6 37.9 53.2 12.5 24.8 19 52.3 19.1 80.1 0 2.9-0.3 5.8-0.4 8.6 16.8-10.2 38.4-7.7 52.4 6.1l1.9 2.3c3.3-41.2-4.8-82.5-23.3-119.5-12.1-24.5-28.1-46.8-47.3-66.3-52.5-52-121.4-84.3-194.9-91.7-26.4-3.4-52.9-3.5-79.1-0.7z m418.2 405.4c-7.2 1.9-13.8 5.7-19.2 11h-0.1c-6.9 6.8-11.2 15.7-12.2 25.3-5.2 27.8-19.5 53.1-40.5 72-4 3.8-4.1 10.1-0.3 14.1l0.1 0.1c4 4 10.5 4.1 14.6 0.1 0.5-0.5 0.9-0.9 1.2-1.5 20.9-21.9 48.7-36 78.7-39.8 22.8-6.1 36.2-29.2 30.1-51.6-6.2-22.5-29.6-35.8-52.4-29.7z m-160.4-42l-0.7 0.7c-20.9 22.7-49.2 37.3-79.9 41.2-22.6 5.9-36.2 28.7-30.2 51.1 1.9 7.3 5.9 14 11.3 19.3 16.7 16.4 43.7 16.4 60.4-0.1 6.8-6.8 11.1-15.7 12.2-25.2 5.3-27.8 19.6-53.1 40.7-72 4.1-3.7 4.5-10 0.9-14.1l-0.1-0.1c-4-4.2-10.4-4.5-14.6-0.8z m39.6-76.6c-7.1 1.9-13.6 5.7-18.7 10.8-16.4 16.2-16.6 42.6-0.4 59l0.5 0.5c6.9 6.8 15.9 11 25.5 12.1 28 5.1 53.6 19.1 72.9 39.9 4 4 10.4 4 14.4 0.1 4-3.8 4.1-10.1 0.3-14.1-0.5-0.5-1.1-1-1.7-1.4-22.1-20.4-36.4-47.8-40.4-77.6-6.1-22.4-29.6-35.5-52.4-29.3z"
fill=
"#0082EF"
p-id=
"974"
></path></svg>
\ No newline at end of file
This diff is collapsed.
Click to expand it.
app_Web/src/components/layout-element/login/app-login-button/app-login-button.less
0 → 100644
浏览文件 @
0dc2f7ca
.app-user-button {
width: 100%;
}
\ No newline at end of file
This diff is collapsed.
Click to expand it.
app_Web/src/components/layout-element/login/app-login-button/app-login-button.vue
0 → 100644
浏览文件 @
0dc2f7ca
<
template
>
<div
class=
"app-user-button"
>
<i-button
@
click=
"handleSubmit"
:type=
"type"
>
{{
caption
}}
</i-button>
</div>
</
template
>
<
script
lang=
"ts"
>
import
{
Vue
,
Component
,
Watch
,
Prop
,
Model
}
from
"vue-property-decorator"
;
@
Component
({})
export
default
class
AppUserId
extends
Vue
{
@
Prop
()
public
predefinedType
!
:
string
;
@
Prop
()
public
type
?:
string
;
@
Prop
()
public
caption
!
:
string
;
public
handleSubmit
()
{
this
.
$emit
(
'itemClick'
,
this
.
predefinedType
);
}
}
</
script
>
<
style
lang=
"less"
>
@import './app-login-button.less';
</
style
>
\ No newline at end of file
This diff is collapsed.
Click to expand it.
app_Web/src/components/layout-element/login/app-login-captcha/app-login-captcha.vue
0 → 100644
浏览文件 @
0dc2f7ca
<
template
>
<div
class=
"app-preset-auth"
>
<auth-puzzle-vcode
:show=
"show"
@
success=
"onSuccess"
@
fail=
"onFail"
/>
<i-button
ghost
@
click=
"executeOpen"
long
class=
"app-preset-auth-button"
>
验证
</i-button
>
</div>
</
template
>
<
script
lang=
"ts"
>
import
{
Vue
,
Component
,
Prop
,
Model
}
from
"vue-property-decorator"
;
import
AuthPuzzleVcode
from
"./vue-puzzle-code/vue-puzzle-code.vue"
;
@
Component
({
components
:
{
"auth-puzzle-vcode"
:
AuthPuzzleVcode
,
},
})
export
default
class
AppPreSetAuth
extends
Vue
{
/**
* 是否显示
*/
public
show
:
boolean
=
false
;
/**
* 打开
*/
public
executeOpen
()
{
this
.
show
=
true
;
}
/**
* 成功
*/
public
onSuccess
()
{
this
.
show
=
false
;
this
.
$emit
(
"success"
);
}
/**
* 失败
*/
public
onFail
()
{
this
.
$emit
(
"fail"
);
}
}
</
script
>
<
style
lang=
'less'
>
.app-preset-auth {
.app-preset-auth-button {
border: 1px solid #dcdee2;
border-radius: 4px;
color: #515a6e;
&:hover{
border: 1px solid #dcdee2;
color: #515a6e;
}
}
}
</
style
>
\ No newline at end of file
This diff is collapsed.
Click to expand it.
app_Web/src/components/layout-element/login/app-login-captcha/vue-puzzle-code/reset.png
0 → 100644
浏览文件 @
0dc2f7ca
1.1 KB
This diff is collapsed.
Click to expand it.
app_Web/src/components/layout-element/login/app-login-captcha/vue-puzzle-code/vue-puzzle-code.less
0 → 100644
浏览文件 @
0dc2f7ca
.vue-puzzle-vcode {
position: fixed;
top: 0;
left: 0;
bottom: 0;
right: 0;
background-color: rgba(0, 0, 0, 0.3);
z-index: 999;
opacity: 0;
pointer-events: none;
transition: opacity 200ms;
&.show_ {
opacity: 1;
pointer-events: auto;
}
}
.vue-auth-box_ {
position: absolute;
top: 40%;
left: 50%;
transform: translate(-50%, -50%);
padding: 20px;
background: #fff;
user-select: none;
border-radius: 3px;
box-shadow: 0 1px 3px rgba(0, 0, 0, 0.3);
.auth-body_ {
position: relative;
overflow: hidden;
border-radius: 3px;
.loading-box_ {
position: absolute;
top: 0;
left: 0;
bottom: 0;
right: 0;
background-color: rgba(0, 0, 0, 0.8);
z-index: 20;
opacity: 1;
transition: opacity 200ms;
display: flex;
align-items: center;
justify-content: center;
&.hide_ {
opacity: 0;
pointer-events: none;
.loading-gif_ {
span {
animation-play-state: paused;
}
}
}
.loading-gif_ {
flex: none;
height: 5px;
line-height: 0;
@keyframes load {
0% {
opacity: 1;
transform: scale(1.3);
}
100% {
opacity: 0.2;
transform: scale(0.3);
}
}
span {
display: inline-block;
width: 5px;
height: 100%;
margin-left: 2px;
border-radius: 50%;
background-color: #888;
animation: load 1.04s ease infinite;
&:nth-child(1) {
margin-left: 0;
}
&:nth-child(2) {
animation-delay: 0.13s;
}
&:nth-child(3) {
animation-delay: 0.26s;
}
&:nth-child(4) {
animation-delay: 0.39s;
}
&:nth-child(5) {
animation-delay: 0.52s;
}
}
}
}
.info-box_ {
position: absolute;
bottom: 0;
left: 0;
width: 100%;
height: 24px;
line-height: 24px;
text-align: center;
overflow: hidden;
font-size: 13px;
background-color: #83ce3f;
opacity: 0;
transform: translateY(24px);
transition: all 200ms;
color: #fff;
z-index: 10;
&.show {
opacity: 0.95;
transform: translateY(0);
}
&.fail {
background-color: #ce594b;
}
}
.auth-canvas2_ {
position: absolute;
top: 0;
left: 0;
width: 60px;
height: 100%;
z-index: 2;
}
.auth-canvas3_ {
position: absolute;
top: 0;
left: 0;
opacity: 0;
transition: opacity 600ms;
z-index: 3;
&.show {
opacity: 1;
}
}
.flash_ {
position: absolute;
top: 0;
left: 0;
width: 30px;
height: 100%;
background-color: rgba(255, 255, 255, 0.1);
z-index: 3;
&.show {
transition: transform 600ms;
}
}
.reset_ {
position: absolute;
top: 2px;
right: 2px;
width: 35px;
height: auto;
z-index: 12;
cursor: pointer;
transition: transform 200ms;
transform: rotate(0deg);
&:hover {
transform: rotate(-90deg);
}
}
}
.auth-control_ {
.range-box {
position: relative;
width: 100%;
background-color: #eef1f8;
margin-top: 20px;
border-radius: 3px;
box-shadow: 0 0 8px rgba(240, 240, 240, 0.6) inset;
.range-text {
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
font-size: 14px;
color: #b7bcd1;
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
text-align: center;
width: 100%;
}
.range-slider {
position: absolute;
height: 100%;
width: 50px;
background-color: rgba(106, 160, 255, 0.8);
border-radius: 3px;
.range-btn {
position: absolute;
display: flex;
align-items: center;
justify-content: center;
right: 0;
width: 50px;
height: 100%;
background-color: #fff;
border-radius: 3px;
box-shadow: 0 0 4px #ccc;
cursor: pointer;
& > div {
width: 0;
height: 40%;
transition: all 200ms;
&:nth-child(2) {
margin: 0 4px;
}
border: solid 1px #6aa0ff;
}
&:hover,
&.isDown {
& > div:first-child {
border: solid 4px transparent;
height: 0;
border-right-color: #6aa0ff;
}
& > div:nth-child(2) {
border-width: 3px;
height: 0;
border-radius: 3px;
margin: 0 6px;
border-right-color: #6aa0ff;
}
& > div:nth-child(3) {
border: solid 4px transparent;
height: 0;
border-left-color: #6aa0ff;
}
}
}
}
}
}
}
.vue-puzzle-overflow {
overflow: hidden !important;
}
\ No newline at end of file
This diff is collapsed.
Click to expand it.
app_Web/src/components/layout-element/login/app-login-captcha/vue-puzzle-code/vue-puzzle-code.vue
0 → 100644
浏览文件 @
0dc2f7ca
<
template
>
<!-- 本体部分 -->
<div
:id=
"id"
:class=
"['vue-puzzle-vcode',
{ show_: show }]"
@mousedown="onCloseMouseDown"
@mouseup="onCloseMouseUp"
@touchstart="onCloseMouseDown"
@touchend="onCloseMouseUp">
<div
class=
"vue-auth-box_"
@
mousedown
.
stop
@
touchstart
.
stop
>
<div
class=
"auth-body_"
:style=
"`height: $
{canvasHeight}px`">
<!-- 主图,有缺口 -->
<canvas
ref=
"canvas1"
:width=
"canvasWidth"
:height=
"canvasHeight"
:style=
"`width:$
{canvasWidth}px;height:${canvasHeight}px`" />
<!-- 成功后显示的完整图 -->
<canvas
ref=
"canvas3"
:class=
"['auth-canvas3_',
{ show: isSuccess }]"
:width="canvasWidth"
:height="canvasHeight"
:style="`width:${canvasWidth}px;height:${canvasHeight}px`" />
<!-- 小图 -->
<canvas
:width=
"puzzleBaseSize"
class=
"auth-canvas2_"
:height=
"canvasHeight"
ref=
"canvas2"
:style=
"
`width:$
{puzzleBaseSize}px;height:${canvasHeight}px;transform:translateX(${styleWidth -
sliderBaseSize -
(puzzleBaseSize - sliderBaseSize) *
((styleWidth - sliderBaseSize) /
(canvasWidth - sliderBaseSize))}px)`
" />
<div
:class=
"['loading-box_',
{ hide_: !loading }]">
<div
class=
"loading-gif_"
>
<span></span>
<span></span>
<span></span>
<span></span>
<span></span>
</div>
</div>
<div
:class=
"['info-box_',
{ show: infoBoxShow }, { fail: infoBoxFail }]">
{{
infoText
}}
</div>
<div
:class=
"['flash_',
{ show: isSuccess }]"
:style="
`transform: translateX(${
isSuccess
? `${canvasWidth + canvasHeight * 0.578}px`
: `-${canvasHeight * 0.578}px`
}) skew(-30deg, 0);`
">
</div>
<img
class=
"reset_"
@
click=
"reset"
:src=
"resetSvg"
/>
</div>
<div
class=
"auth-control_"
>
<div
class=
"range-box"
:style=
"`height:$
{sliderBaseSize}px`">
<div
class=
"range-text"
>
{{
sliderText
}}
</div>
<div
class=
"range-slider"
ref=
"range-slider"
:style=
"`width:$
{styleWidth}px`">
<div
:class=
"['range-btn',
{ isDown: mouseDown }]"
:style="`width:${sliderBaseSize}px`"
@mousedown="onRangeMouseDown($event)"
@touchstart="onRangeMouseDown($event)">
<div></div>
<div></div>
<div></div>
</div>
</div>
</div>
</div>
</div>
</div>
</
template
>
<
script
>
import
resetSvg
from
"./reset.png"
;
export
default
{
/** 私有数据 **/
data
()
{
return
{
mouseDown
:
false
,
// 鼠标是否在按钮上按下
startWidth
:
50
,
// 鼠标点下去时父级的width
startX
:
0
,
// 鼠标按下时的X
newX
:
0
,
// 鼠标当前的偏移X
pinX
:
0
,
// 拼图的起始X
pinY
:
0
,
// 拼图的起始Y
loading
:
true
,
// 是否正在加在中,主要是等图片onload
isCanSlide
:
false
,
// 是否可以拉动滑动条
error
:
false
,
// 图片加在失败会出现这个,提示用户手动刷新
infoBoxShow
:
false
,
// 提示信息是否出现
infoText
:
""
,
// 提示等信息
infoBoxFail
:
false
,
// 是否验证失败
timer1
:
null
,
// setTimout1
closeDown
:
false
,
// 为了解决Mac上的click BUG
isSuccess
:
false
,
// 验证成功
resetSvg
,
imgIndex
:
-
1
// 用于自定义图片时不会随机到重复的图片
};
},
/** 父级参数 **/
props
:
{
id
:
{
type
:
String
},
canvasWidth
:
{
type
:
Number
,
default
:
310
},
// 主canvas的宽
canvasHeight
:
{
type
:
Number
,
default
:
160
},
// 主canvas的高
// 是否出现,由父级控制
show
:
{
type
:
Boolean
,
default
:
false
},
puzzleScale
:
{
type
:
Number
,
default
:
1
},
// 拼图块的大小缩放比例
sliderSize
:
{
type
:
Number
,
default
:
50
},
// 滑块的大小
range
:
{
type
:
Number
,
default
:
10
},
// 允许的偏差值
// 所有的背景图片
imgs
:
{
type
:
Array
},
successText
:
{
type
:
String
,
default
:
"验证通过!"
},
failText
:
{
type
:
String
,
default
:
"验证失败,请重试"
},
sliderText
:
{
type
:
String
,
default
:
"拖动滑块完成拼图"
}
},
/** 生命周期 **/
mounted
()
{
document
.
body
.
appendChild
(
this
.
$el
);
document
.
addEventListener
(
"mousemove"
,
this
.
onRangeMouseMove
,
false
);
document
.
addEventListener
(
"mouseup"
,
this
.
onRangeMouseUp
,
false
);
document
.
addEventListener
(
"touchmove"
,
this
.
onRangeMouseMove
,
{
passive
:
false
});
document
.
addEventListener
(
"touchend"
,
this
.
onRangeMouseUp
,
false
);
if
(
this
.
show
)
{
document
.
body
.
classList
.
add
(
"vue-puzzle-overflow"
);
}
this
.
reset
();
},
beforeDestroy
()
{
clearTimeout
(
this
.
timer1
);
document
.
body
.
removeChild
(
this
.
$el
);
document
.
removeEventListener
(
"mousemove"
,
this
.
onRangeMouseMove
,
false
);
document
.
removeEventListener
(
"mouseup"
,
this
.
onRangeMouseUp
,
false
);
document
.
removeEventListener
(
"touchmove"
,
this
.
onRangeMouseMove
,
{
passive
:
false
});
document
.
removeEventListener
(
"touchend"
,
this
.
onRangeMouseUp
,
false
);
},
/** 监听 **/
watch
:
{
show
(
newV
)
{
// 每次出现都应该重新初始化
if
(
newV
)
{
document
.
body
.
classList
.
add
(
"vue-puzzle-overflow"
);
this
.
reset
();
}
else
{
document
.
body
.
classList
.
remove
(
"vue-puzzle-overflow"
);
}
}
},
/** 计算属性 **/
computed
:
{
// styleWidth是底部用户操作的滑块的父级,就是轨道在鼠标的作用下应该具有的宽度
styleWidth
()
{
const
w
=
this
.
startWidth
+
this
.
newX
-
this
.
startX
;
return
w
<
this
.
sliderBaseSize
?
this
.
sliderBaseSize
:
w
>
this
.
canvasWidth
?
this
.
canvasWidth
:
w
;
},
// 图中拼图块的60 * 用户设定的缩放比例计算之后的值 0.2~2
puzzleBaseSize
()
{
return
Math
.
round
(
Math
.
max
(
Math
.
min
(
this
.
puzzleScale
,
2
),
0.2
)
*
52.5
+
6
);
},
// 处理一下sliderSize,弄成整数,以免计算有偏差
sliderBaseSize
()
{
return
Math
.
max
(
Math
.
min
(
Math
.
round
(
this
.
sliderSize
),
Math
.
round
(
this
.
canvasWidth
*
0.5
)
),
10
);
}
},
/** 方法 **/
methods
:
{
// 关闭
onClose
()
{
if
(
!
this
.
mouseDown
)
{
clearTimeout
(
this
.
timer1
);
this
.
$emit
(
"close"
);
}
},
onCloseMouseDown
()
{
this
.
closeDown
=
true
;
},
onCloseMouseUp
()
{
if
(
this
.
closeDown
)
{
this
.
onClose
();
}
this
.
closeDown
=
false
;
},
// 鼠标按下准备拖动
onRangeMouseDown
(
e
)
{
if
(
this
.
isCanSlide
)
{
this
.
mouseDown
=
true
;
this
.
startWidth
=
this
.
$refs
[
"range-slider"
].
clientWidth
;
this
.
newX
=
e
.
clientX
||
e
.
changedTouches
[
0
].
clientX
;
this
.
startX
=
e
.
clientX
||
e
.
changedTouches
[
0
].
clientX
;
}
},
// 鼠标移动
onRangeMouseMove
(
e
)
{
if
(
this
.
mouseDown
)
{
e
.
preventDefault
();
this
.
newX
=
e
.
clientX
||
e
.
changedTouches
[
0
].
clientX
;
}
},
// 鼠标抬起
onRangeMouseUp
()
{
if
(
this
.
mouseDown
)
{
this
.
mouseDown
=
false
;
this
.
submit
();
}
},
/**
* 开始进行
* @param withCanvas 是否强制使用canvas随机作图
*/
init
(
withCanvas
)
{
this
.
loading
=
true
;
this
.
isCanSlide
=
false
;
const
c
=
this
.
$refs
.
canvas1
;
const
c2
=
this
.
$refs
.
canvas2
;
const
c3
=
this
.
$refs
.
canvas3
;
const
ctx
=
c
.
getContext
(
"2d"
);
const
ctx2
=
c2
.
getContext
(
"2d"
);
const
ctx3
=
c3
.
getContext
(
"2d"
);
const
img
=
document
.
createElement
(
"img"
);
ctx
.
clearRect
(
0
,
0
,
this
.
canvasWidth
,
this
.
canvasHeight
);
ctx2
.
clearRect
(
0
,
0
,
this
.
canvasWidth
,
this
.
canvasHeight
);
// 取一个随机坐标,作为拼图块的位置
this
.
pinX
=
this
.
getRandom
(
this
.
puzzleBaseSize
,
this
.
canvasWidth
-
this
.
puzzleBaseSize
-
20
);
// 留20的边距
this
.
pinY
=
this
.
getRandom
(
20
,
this
.
canvasHeight
-
this
.
puzzleBaseSize
-
20
);
// 主图高度 - 拼图块自身高度 - 20边距
img
.
crossOrigin
=
"anonymous"
;
// 匿名,想要获取跨域的图片
img
.
onload
=
()
=>
{
const
[
x
,
y
,
w
,
h
]
=
this
.
makeImgSize
(
img
);
ctx
.
save
();
// 先画小图
this
.
paintBrick
(
ctx
);
ctx
.
closePath
();
if
(
!
(
navigator
.
userAgent
.
indexOf
(
"Firefox"
)
>=
0
&&
navigator
.
userAgent
.
indexOf
(
"Windows"
)
>=
0
)
)
{
// 非火狐,在此画外阴影
ctx
.
shadowOffsetX
=
0
;
ctx
.
shadowOffsetY
=
0
;
ctx
.
shadowColor
=
"#000"
;
ctx
.
shadowBlur
=
3
;
ctx
.
fill
();
}
ctx
.
clip
();
// 按照外阴影区域切割
ctx
.
save
();
// 小图外阴影
ctx
.
shadowOffsetX
=
0
;
ctx
.
shadowOffsetY
=
0
;
ctx
.
shadowColor
=
"#000"
;
ctx
.
shadowBlur
=
2
;
ctx
.
fill
();
ctx
.
restore
();
ctx
.
drawImage
(
img
,
x
,
y
,
w
,
h
);
ctx3
.
drawImage
(
img
,
x
,
y
,
w
,
h
);
// 设置小图的内阴影
ctx
.
globalCompositeOperation
=
"source-atop"
;
this
.
paintBrick
(
ctx
);
ctx
.
arc
(
this
.
pinX
+
Math
.
ceil
(
this
.
puzzleBaseSize
/
2
),
this
.
pinY
+
Math
.
ceil
(
this
.
puzzleBaseSize
/
2
),
this
.
puzzleBaseSize
*
1.2
,
0
,
Math
.
PI
*
2
,
true
);
ctx
.
closePath
();
ctx
.
shadowColor
=
"rgba(255, 255, 255, .8)"
;
ctx
.
shadowOffsetX
=
-
1
;
ctx
.
shadowOffsetY
=
-
1
;
ctx
.
shadowBlur
=
Math
.
min
(
Math
.
ceil
(
8
*
this
.
puzzleScale
),
12
);
ctx
.
fillStyle
=
"#ffffaa"
;
ctx
.
fill
();
// 将小图赋值给ctx2
const
imgData
=
ctx
.
getImageData
(
this
.
pinX
-
3
,
// 为了阴影 是从-3px开始截取,判定的时候要+3px
this
.
pinY
-
20
,
this
.
pinX
+
this
.
puzzleBaseSize
+
5
,
this
.
pinY
+
this
.
puzzleBaseSize
+
5
);
ctx2
.
putImageData
(
imgData
,
0
,
this
.
pinY
-
20
);
// 清理
ctx
.
restore
();
ctx
.
clearRect
(
0
,
0
,
this
.
canvasWidth
,
this
.
canvasHeight
);
// 画缺口
ctx
.
save
();
this
.
paintBrick
(
ctx
);
ctx
.
globalAlpha
=
0.8
;
ctx
.
fillStyle
=
"#ffffff"
;
ctx
.
fill
();
ctx
.
restore
();
// 画缺口的内阴影
ctx
.
save
();
ctx
.
globalCompositeOperation
=
"source-atop"
;
this
.
paintBrick
(
ctx
);
ctx
.
arc
(
this
.
pinX
+
Math
.
ceil
(
this
.
puzzleBaseSize
/
2
),
this
.
pinY
+
Math
.
ceil
(
this
.
puzzleBaseSize
/
2
),
this
.
puzzleBaseSize
*
1.2
,
0
,
Math
.
PI
*
2
,
true
);
ctx
.
shadowColor
=
"#000"
;
ctx
.
shadowOffsetX
=
2
;
ctx
.
shadowOffsetY
=
2
;
ctx
.
shadowBlur
=
16
;
ctx
.
fill
();
ctx
.
restore
();
// 画整体背景图
ctx
.
save
();
ctx
.
globalCompositeOperation
=
"destination-over"
;
ctx
.
drawImage
(
img
,
x
,
y
,
w
,
h
);
ctx
.
restore
();
this
.
loading
=
false
;
this
.
isCanSlide
=
true
;
};
img
.
onerror
=
()
=>
{
this
.
init
(
true
);
// 如果图片加载错误就重新来,并强制用canvas随机作图
};
if
(
!
withCanvas
&&
this
.
imgs
&&
this
.
imgs
.
length
)
{
let
randomNum
=
this
.
getRandom
(
0
,
this
.
imgs
.
length
-
1
);
if
(
randomNum
===
this
.
imgIndex
)
{
if
(
randomNum
===
this
.
imgs
.
length
-
1
)
{
randomNum
=
0
;
}
else
{
randomNum
++
;
}
}
this
.
imgIndex
=
randomNum
;
img
.
src
=
this
.
imgs
[
randomNum
];
}
else
{
img
.
src
=
this
.
makeImgWithCanvas
();
}
},
// 工具 - 范围随机数
getRandom
(
min
,
max
)
{
return
Math
.
ceil
(
Math
.
random
()
*
(
max
-
min
)
+
min
);
},
// 工具 - 设置图片尺寸cover方式贴合canvas尺寸 w/h
makeImgSize
(
img
)
{
const
imgScale
=
img
.
width
/
img
.
height
;
const
canvasScale
=
this
.
canvasWidth
/
this
.
canvasHeight
;
let
x
=
0
,
y
=
0
,
w
=
0
,
h
=
0
;
if
(
imgScale
>
canvasScale
)
{
h
=
this
.
canvasHeight
;
w
=
imgScale
*
h
;
y
=
0
;
x
=
(
this
.
canvasWidth
-
w
)
/
2
;
}
else
{
w
=
this
.
canvasWidth
;
h
=
w
/
imgScale
;
x
=
0
;
y
=
(
this
.
canvasHeight
-
h
)
/
2
;
}
return
[
x
,
y
,
w
,
h
];
},
// 绘制拼图块的路径
paintBrick
(
ctx
)
{
const
moveL
=
Math
.
ceil
(
15
*
this
.
puzzleScale
);
// 直线移动的基础距离
ctx
.
beginPath
();
ctx
.
moveTo
(
this
.
pinX
,
this
.
pinY
);
ctx
.
lineTo
(
this
.
pinX
+
moveL
,
this
.
pinY
);
ctx
.
arcTo
(
this
.
pinX
+
moveL
,
this
.
pinY
-
moveL
/
2
,
this
.
pinX
+
moveL
+
moveL
/
2
,
this
.
pinY
-
moveL
/
2
,
moveL
/
2
);
ctx
.
arcTo
(
this
.
pinX
+
moveL
+
moveL
,
this
.
pinY
-
moveL
/
2
,
this
.
pinX
+
moveL
+
moveL
,
this
.
pinY
,
moveL
/
2
);
ctx
.
lineTo
(
this
.
pinX
+
moveL
+
moveL
+
moveL
,
this
.
pinY
);
ctx
.
lineTo
(
this
.
pinX
+
moveL
+
moveL
+
moveL
,
this
.
pinY
+
moveL
);
ctx
.
arcTo
(
this
.
pinX
+
moveL
+
moveL
+
moveL
+
moveL
/
2
,
this
.
pinY
+
moveL
,
this
.
pinX
+
moveL
+
moveL
+
moveL
+
moveL
/
2
,
this
.
pinY
+
moveL
+
moveL
/
2
,
moveL
/
2
);
ctx
.
arcTo
(
this
.
pinX
+
moveL
+
moveL
+
moveL
+
moveL
/
2
,
this
.
pinY
+
moveL
+
moveL
,
this
.
pinX
+
moveL
+
moveL
+
moveL
,
this
.
pinY
+
moveL
+
moveL
,
moveL
/
2
);
ctx
.
lineTo
(
this
.
pinX
+
moveL
+
moveL
+
moveL
,
this
.
pinY
+
moveL
+
moveL
+
moveL
);
ctx
.
lineTo
(
this
.
pinX
,
this
.
pinY
+
moveL
+
moveL
+
moveL
);
ctx
.
lineTo
(
this
.
pinX
,
this
.
pinY
+
moveL
+
moveL
);
ctx
.
arcTo
(
this
.
pinX
+
moveL
/
2
,
this
.
pinY
+
moveL
+
moveL
,
this
.
pinX
+
moveL
/
2
,
this
.
pinY
+
moveL
+
moveL
/
2
,
moveL
/
2
);
ctx
.
arcTo
(
this
.
pinX
+
moveL
/
2
,
this
.
pinY
+
moveL
,
this
.
pinX
,
this
.
pinY
+
moveL
,
moveL
/
2
);
ctx
.
lineTo
(
this
.
pinX
,
this
.
pinY
);
},
// 用canvas随机生成图片
makeImgWithCanvas
()
{
const
canvas
=
document
.
createElement
(
"canvas"
);
const
ctx
=
canvas
.
getContext
(
"2d"
);
canvas
.
width
=
this
.
canvasWidth
;
canvas
.
height
=
this
.
canvasHeight
;
ctx
.
fillStyle
=
`rgb(
${
this
.
getRandom
(
100
,
255
)}
,
${
this
.
getRandom
(
100
,
255
)}
,
${
this
.
getRandom
(
100
,
255
)}
)`
;
ctx
.
fillRect
(
0
,
0
,
this
.
canvasWidth
,
this
.
canvasHeight
);
// 随机画10个图形
for
(
let
i
=
0
;
i
<
12
;
i
++
)
{
ctx
.
fillStyle
=
`rgb(
${
this
.
getRandom
(
100
,
255
)}
,
${
this
.
getRandom
(
100
,
255
)}
,
${
this
.
getRandom
(
100
,
255
)}
)`
;
ctx
.
strokeStyle
=
`rgb(
${
this
.
getRandom
(
100
,
255
)}
,
${
this
.
getRandom
(
100
,
255
)}
,
${
this
.
getRandom
(
100
,
255
)}
)`
;
if
(
this
.
getRandom
(
0
,
2
)
>
1
)
{
// 矩形
ctx
.
save
();
ctx
.
rotate
((
this
.
getRandom
(
-
90
,
90
)
*
Math
.
PI
)
/
180
);
ctx
.
fillRect
(
this
.
getRandom
(
-
20
,
canvas
.
width
-
20
),
this
.
getRandom
(
-
20
,
canvas
.
height
-
20
),
this
.
getRandom
(
10
,
canvas
.
width
/
2
+
10
),
this
.
getRandom
(
10
,
canvas
.
height
/
2
+
10
)
);
ctx
.
restore
();
}
else
{
// 圆
ctx
.
beginPath
();
const
ran
=
this
.
getRandom
(
-
Math
.
PI
,
Math
.
PI
);
ctx
.
arc
(
this
.
getRandom
(
0
,
canvas
.
width
),
this
.
getRandom
(
0
,
canvas
.
height
),
this
.
getRandom
(
10
,
canvas
.
height
/
2
+
10
),
ran
,
ran
+
Math
.
PI
*
1.5
);
ctx
.
closePath
();
ctx
.
fill
();
}
}
return
canvas
.
toDataURL
(
"image/png"
);
},
// 开始判定
submit
()
{
// 偏差 x = puzzle的起始X - (用户真滑动的距离) + (puzzle的宽度 - 滑块的宽度) * (用户真滑动的距离/canvas总宽度)
// 最后+ 的是补上slider和滑块宽度不一致造成的缝隙
const
x
=
Math
.
abs
(
this
.
pinX
-
(
this
.
styleWidth
-
this
.
sliderBaseSize
)
+
(
this
.
puzzleBaseSize
-
this
.
sliderBaseSize
)
*
((
this
.
styleWidth
-
this
.
sliderBaseSize
)
/
(
this
.
canvasWidth
-
this
.
sliderBaseSize
))
-
3
);
if
(
x
<
this
.
range
)
{
// 成功
this
.
infoText
=
this
.
successText
;
this
.
infoBoxFail
=
false
;
this
.
infoBoxShow
=
true
;
this
.
isCanSlide
=
false
;
this
.
isSuccess
=
true
;
// 成功后准备关闭
clearTimeout
(
this
.
timer1
);
this
.
timer1
=
setTimeout
(()
=>
{
// 成功的回调
this
.
$emit
(
"success"
,
x
);
},
800
);
}
else
{
// 失败
this
.
infoText
=
this
.
failText
;
this
.
infoBoxFail
=
true
;
this
.
infoBoxShow
=
true
;
this
.
isCanSlide
=
false
;
// 失败的回调
this
.
$emit
(
"fail"
,
x
);
// 800ms后重置
clearTimeout
(
this
.
timer1
);
this
.
timer1
=
setTimeout
(()
=>
{
this
.
reset
();
},
800
);
}
},
// 重置
reset
()
{
this
.
infoBoxFail
=
false
;
this
.
infoBoxShow
=
false
;
this
.
isCanSlide
=
true
;
this
.
isSuccess
=
false
;
this
.
startWidth
=
this
.
sliderBaseSize
;
// 鼠标点下去时父级的width
this
.
startX
=
0
;
// 鼠标按下时的X
this
.
newX
=
0
;
// 鼠标当前的偏移X
this
.
init
();
}
}
};
</
script
>
<
style
lang=
"less"
>
@import './vue-puzzle-code.less';
</
style
>
This diff is collapsed.
Click to expand it.
app_Web/src/components/layout-element/login/app-login-input/app-login-input.vue
0 → 100644
浏览文件 @
0dc2f7ca
<
template
>
<div
class=
"app-user-input"
>
<i-input
size=
'large'
:prefix=
'icon'
v-model=
"value"
:placeholder=
"placeholder"
>
</i-input>
</div>
</
template
>
<
script
lang=
"ts"
>
import
{
Vue
,
Component
,
Watch
,
Prop
,
Model
}
from
'vue-property-decorator'
;
@
Component
({
})
export
default
class
AppUserId
extends
Vue
{
/**
* 登录名称
*
* @type {string}
* @memberof AppUserId
*/
@
Prop
({
default
:
''
})
public
value
!
:
string
;
@
Prop
()
public
icon
?:
string
;
@
Prop
()
public
placeholder
?:
string
;
}
</
script
>
This diff is collapsed.
Click to expand it.
app_Web/src/components/layout-element/login/app-login-message/app-login-message.less
0 → 100644
浏览文件 @
0dc2f7ca
.app-login-message{
.ivu-alert{
display: flex;
align-items: center;
background-color: rgb(255, 225, 225);
.ivu-alert-icon{
position: unset;
margin-right: 5px;
}
}
.ivu-alert-error,
.ivu-alert-with-icon{
padding-left: 10px;
}
}
\ No newline at end of file
This diff is collapsed.
Click to expand it.
app_Web/src/components/layout-element/login/app-login-message/app-login-message.vue
0 → 100644
浏览文件 @
0dc2f7ca
<
template
>
<div
class=
"app-login-message"
>
<alert
v-show=
"value"
type=
"error"
show-icon
>
{{
value
}}
</alert>
</div>
</
template
>
<
script
lang=
'ts'
>
import
{
Component
,
Vue
,
Prop
}
from
"vue-property-decorator"
;
@
Component
({})
export
default
class
AppPreSetLoginMessage
extends
Vue
{
/**
* 内容
*
* @type {string}
* @memberof AppPreSetLoginMessage
*/
@
Prop
()
public
value
?:
string
;
}
</
script
>
<
style
lang=
'less'
>
@import "./app-login-message.less";
</
style
>
\ No newline at end of file
This diff is collapsed.
Click to expand it.
app_Web/src/components/layout-element/login/app-login-note-verify/app-login-note-verify.less
0 → 100644
浏览文件 @
0dc2f7ca
.app-preset-smsverification{
.content {
display: flex;
margin: 5px 0;
.el-button {
border: 1px solid #dcdee2;
margin-left: 10px;
color: #606266;
background-color: #fff;
&:hover {
border: 1px solid #dcdee2;
}
}
}
.code{
padding-top: 8px;
}
.error {
color: red;
}
}
\ No newline at end of file
This diff is collapsed.
Click to expand it.
app_Web/src/components/layout-element/login/app-login-note-verify/app-login-note-verify.vue
0 → 100644
浏览文件 @
0dc2f7ca
<
template
>
<div
class=
"app-preset-smsverification"
>
<div
class=
"content"
>
<i-input
size=
"default"
type=
"text"
v-model=
"phoneNumber"
:placeholder=
"$t('components.login.phoneplaceholder')"
@
on-blur=
"veriPhoneNumber"
></i-input>
<el-button
:disabled=
"disabled"
size=
"mini"
type=
"primary"
@
click=
"getVeriCode()"
>
{{
disabled
?
`${countDown
}
s ${$t('components.login.getcodeafter')
}
`
:
`${$t('components.login.getcode')
}
`
}}
<
/el-butto
n
>
<
/div
>
<
div
class
=
"code"
>
<
i
-
input
size
=
"default"
type
=
"text"
:
value
=
"currentValue"
@
input
=
"codeChange"
:
placeholder
=
"$t('components.login.codeplaceholder')"
><
/i-input
>
<
/div
>
<
/div
>
<
/template
>
<
script
lang
=
'ts'
>
import
{
Vue
,
Component
,
Prop
}
from
"vue-property-decorator"
;
@
Component
({
}
)
export
default
class
AppPresetSmsVerification
extends
Vue
{
/**
*验证码值
*
* @type {string
}
* @memberof AppPresetSmsVerification
*/
@
Prop
()
public
value
!
:
string
;
/**
*验证码当前值
*
* @type {string
}
* @memberof AppPresetSmsVerification
*/
get
currentValue
():
string
{
return
this
.
value
;
}
/**
* 手机号
*
* @type {*
}
* @memberof AppPresetSmsVerification
*/
public
phoneNumber
:
string
=
''
;
/**
* 倒计时
*
* @type {*
}
* @memberof AppPresetSmsVerification
*/
public
countDown
:
number
=
60
;
/**
* 错误提示
* @type {*
}
* @memberof AppPresetSmsVerification
*/
public
phoneError
=
false
;
/**
* 是否禁用获取验证码按钮
*
* @type {*
}
* @memberof AppPresetSmsVerification
*/
public
disabled
:
boolean
=
false
;
/**
* 定时器
*
* @type {*
}
* @memberof AppPresetSmsVerification
*/
public
timer
:
any
;
/**
* @description 设置倒计时
* @memberof AppPresetSmsVerification
*/
public
setCountDown
()
{
if
(
this
.
countDown
>
0
)
{
this
.
countDown
--
;
}
else
{
this
.
countDown
=
60
;
this
.
disabled
=
false
;
clearInterval
(
this
.
timer
);
}
this
.
$forceUpdate
();
}
/**
* @description 验证码输入变化
* @memberof AppPresetSmsVerification
*/
public
codeChange
(
value
:
string
)
{
this
.
$emit
(
"change"
,
value
);
}
/**
* @description 校验手机号
* @memberof AppPresetSmsVerification
*/
public
veriPhoneNumber
():
boolean
{
this
.
phoneError
=
!
/^1
[
3-9
]\d
{9
}
$/
.
test
(
this
.
phoneNumber
);
if
(
this
.
phoneError
)
{
this
.
$emit
(
"error"
,
this
.
$t
(
'components.login.phonefailed'
));
}
else
{
this
.
$emit
(
"error"
,
''
);
}
return
this
.
phoneError
;
}
/**
* @description 获取验证码
* @memberof AppPresetSmsVerification
*/
public
getVeriCode
()
{
if
(
this
.
phoneError
)
return
;
// todo
this
.
$http
.
post
(
``
,
{
}
).
then
((
response
:
any
)
=>
{
if
(
response
.
status
==
200
)
{
this
.
disabled
=
true
;
this
.
timer
=
setInterval
(()
=>
{
this
.
setCountDown
();
}
,
1000
);
}
}
);
}
}
<
/script
>
<
style
lang
=
'less'
>
@
import
"./app-login-note-verify.less"
;
<
/style>
\ No newline at end of file
This diff is collapsed.
Click to expand it.
app_Web/src/components/layout-element/login/app-login-org/app-login-org.less
0 → 100644
浏览文件 @
0dc2f7ca
.app-auth-org-picker {
height: 36px;
width: 100%;
.app-org-sector-remote {
width: 100%;
.org-sector-choice{
background-color: #e6f7ff;
}
}
.ivu-dropdown{
width: inherit;
position: relative;
.ivu-select-dropdown{
width: 100%;
}
}
.auth-org-picker-dropdown{
width: inherit;
position: relative;
border-radius: 5px;
border: 1px solid gray;
.ivu-select-dropdown{
width: 100%;
}
}
.menu-item-no-data{
width: 100%;
font-size: 16px;
text-align: center;
color: #dbdbdb;
padding: 5px 0;
}
}
\ No newline at end of file
This diff is collapsed.
Click to expand it.
app_Web/src/components/layout-element/login/app-login-org/app-login-org.vue
0 → 100644
浏览文件 @
0dc2f7ca
<
template
>
<div
class=
"app-org-picker"
>
<div
class=
"app-org-sector-remote"
>
<dropdown
@
on-click=
"orgSelect"
@
on-visible-change=
"visibleChange"
>
<div
class=
"org-sector"
>
<Input
:value=
"getSelectedOrgName"
placeholder=
"请选择部门"
readonly
:icon=
"iconClass"
/>
</div>
<dropdown-menu
slot=
"list"
>
<dropdown-item
:class=
"
{ 'org-sector-choice': Object.is(item.srforgsectorid, getSelectedOrgName) }"
:name="item.srforgsectorid"
v-for="(item, index) in selectedOrgArray"
:key="index"
>
{{
item
.
srforgsectorname
}}
</dropdown-item>
<div
class=
"menu-item-no-data"
v-show=
"!selectedOrgArray.length"
>
暂无数据
</div>
</dropdown-menu>
</dropdown>
</div>
</div>
</
template
>
<
script
lang=
'ts'
>
import
{
Vue
,
Component
,
Inject
,
Prop
}
from
'vue-property-decorator'
;
@
Component
({})
export
default
class
AppAuthOrgPicker
extends
Vue
{
/**
* 输入值
*
* @type {*}
* @memberof AppAuthOrgPicker
*/
@
Prop
()
public
value
!
:
string
;
/**
* 默认数据来源模式
*
* @type {string}
* @memberof AppAuthOrgPicker
*
*/
public
selectMode
:
'REMOTE'
|
'LOCAL'
=
'LOCAL'
;
/**
* 选中组织部门id
*
* @type {string}
* @memberof AppAuthOrgPicker
*/
public
selectedOrgId
:
string
=
''
;
/**
* 图标名称
*
* @type {boolean}
* @memberof AppAuthOrgPicker
*/
public
iconClass
:
string
=
'ios-arrow-down'
;
/**
* 选中组织部门名称
*
* @type {string}
* @memberof AppAuthOrgPicker
*/
get
getSelectedOrgName
()
{
if
(
this
.
value
)
{
const
selectedValue
=
this
.
selectedOrgArray
.
find
((
item
:
any
)
=>
{
return
item
.
srforgsectorid
==
this
.
value
;
});
return
selectedValue
?.
srforgsectorname
;
}
}
/**
* 组织部门名称数组
*
* @type {Array<any>}
* @memberof AppAuthOrgPicker
*/
public
selectedOrgArray
:
Array
<
any
>
=
[];
/**
* 组件初始化数据,vue生命周期
*
* @memberof AppAuthOrgPicker
*/
public
created
()
{
this
.
getOrgData
();
}
/**
* 选择组织部门回调
*
* @memberof AppAuthOrgPicker
*/
public
orgSelect
(
data
:
string
)
{
if
(
Object
.
is
(
data
,
this
.
selectedOrgId
))
{
return
;
}
let
item
:
any
=
this
.
selectedOrgArray
.
find
((
_item
:
any
)
=>
Object
.
is
(
_item
.
srforgsectorid
,
data
));
this
.
$emit
(
'valueChange'
,
{
value
:
item
.
srforgsectorid
});
}
/**
* 下拉框打开或收起回调
*
* @memberof AppAuthOrgPicker
*/
visibleChange
(
data
:
boolean
)
{
this
.
iconClass
=
data
?
'ios-arrow-up'
:
'ios-arrow-down'
;
}
/**
* 获取数据
*
* @memberof AppAuthOrgPicker
*/
public
async
getOrgData
()
{
// todo
console
.
log
(
'获取数据暂未实现'
);
}
}
</
script
>
<
style
lang=
"less"
>
@import './app-login-org.less';
</
style
>
\ No newline at end of file
This diff is collapsed.
Click to expand it.
app_Web/src/components/layout-element/login/app-login-third/app-login-third.less
0 → 100644
浏览文件 @
0dc2f7ca
.app-login-third {
text-align: center;
.app-login-third-imgrwap {
.sign-btn {
.third-svg-container {
margin: 0px;
padding: 0px;
}
}
}
}
\ No newline at end of file
This diff is collapsed.
Click to expand it.
app_Web/src/components/layout-element/login/app-login-third/app-login-third.vue
0 → 100644
浏览文件 @
0dc2f7ca
<
template
>
<div
class=
"app-login-third"
>
<span
class=
"title"
>
{{
$t
(
"components.login.other"
)
}}
</span>
<div
class=
"app-login-third-imgrwap"
>
<div
class=
"sign-btn"
@
click=
"handleThirdLogin('DINGDING')"
>
<img
class=
"third-svg-container"
src=
"@/assets/img/dingding.svg"
/>
</div>
<div
class=
"sign-btn"
@
click=
"handleThirdLogin('WXWORK')"
>
<img
class=
"third-svg-container"
src=
"@/assets/img/qiyeweixin.svg"
/>
</div>
</div>
</div>
</
template
>
<
script
lang=
"ts"
>
import
{
Component
,
Vue
}
from
"vue-property-decorator"
;
import
qs
from
"qs"
;
import
*
as
dd
from
"dingtalk-jsapi"
;
import
axios
from
"axios"
;
import
{
Util
}
from
"@/utils"
;
@
Component
({})
export
default
class
AppThirdLogin
extends
Vue
{
/**
* 处理第三方登录
*
* @param type 登录类型
* @memberof AppThirdLogin
*/
handleThirdLogin
(
type
:
string
)
{
switch
(
type
)
{
case
"DINGDING"
:
this
.
dingTalkHandleClick
();
break
;
case
"WXWORK"
:
this
.
wxWorkHandleClick
();
break
;
default
:
console
.
warn
(
`暂不支持
${
type
}
登录`
);
break
;
}
}
/**
* 钉钉登录
*
* @memberof AppThirdLogin
*/
async
dingTalkHandleClick
()
{
let
result
:
any
=
await
this
.
dingtalkLogin
();
if
(
result
)
{
if
(
result
.
state
&&
Object
.
is
(
result
.
state
,
"SUCCESS"
))
{
const
data
=
result
.
data
;
// 截取地址,拼接需要部分组成新地址
const
baseUrl
=
this
.
getNeedLocation
();
// 1.钉钉开放平台提供的appId
const
appId
=
data
.
appid
;
// 2.钉钉扫码后回调地址,需要UrlEncode转码
const
redirect_uri
=
baseUrl
+
"assets/third/dingdingRedirect.html?id="
+
data
.
appid
;
const
redirect_uri_encode
=
encodeURIComponent
(
redirect_uri
);
// 3.钉钉扫码url
const
url
=
"https://oapi.dingtalk.com/connect/qrconnect?response_type=code"
+
"&appid="
+
appId
+
"&redirect_uri="
+
redirect_uri_encode
+
"&scope=snsapi_login"
+
"&state=STATE"
;
// 4.跳转钉钉扫码
window
.
location
.
href
=
url
;
}
else
if
(
result
.
message
)
{
throw
new
Error
(
result
.
message
);
}
}
}
/**
* 微信登录
*
* @memberof AppThirdLogin
*/
async
wxWorkHandleClick
()
{
let
result
:
any
=
await
this
.
wxWorkLogin
();
if
(
result
)
{
if
(
result
.
state
&&
Object
.
is
(
result
.
state
,
"SUCCESS"
))
{
const
data
=
result
.
data
;
// 截取地址,拼接需要部分组成新地址
const
baseUrl
=
this
.
getNeedLocation
();
// 1.微信平台提供的appId
const
appId
=
data
.
corp_id
;
const
agentId
=
data
.
agentid
;
// 2.微信扫码后回调地址,需要UrlEncode转码
const
redirect_uri
=
baseUrl
+
"assets/third/wxWorkRedirect.html?id="
+
data
.
appid
;
const
redirect_uri_encode
=
encodeURIComponent
(
redirect_uri
);
// 3.微信扫码url
const
url
=
"https://open.work.weixin.qq.com/wwopen/sso/qrConnect?state=STATE"
+
"&appid="
+
appId
+
"&agentid="
+
agentId
+
"&redirect_uri="
+
redirect_uri_encode
;
// 4.跳转微信扫码
window
.
location
.
href
=
url
;
}
else
if
(
result
.
message
)
{
throw
new
Error
(
result
.
message
);
}
}
}
/**
* 截取地址
*
* @memberof AppThirdLogin
*/
private
getNeedLocation
()
{
// 截取地址,拼接需要部分组成新地址
const
scheme
=
window
.
location
.
protocol
;
const
host
=
window
.
location
.
host
;
let
baseUrl
:
any
=
scheme
+
"//"
+
host
;
const
port
=
window
.
location
.
port
;
if
(
port
)
{
if
(
port
==
"80"
||
port
==
"443"
)
{
baseUrl
+=
"/"
;
}
else
{
baseUrl
+=
":"
+
port
+
"/"
;
}
}
else
{
baseUrl
+=
"/"
;
}
return
baseUrl
;
}
/**
* 钉钉授权登录
*
* @memberof AppThirdService
*/
public
dingtalkLogin
():
Promise
<
any
>
{
return
new
Promise
((
resolve
)
=>
{
// 请求头
const
headers
=
{};
const
tempViewParam
=
Util
.
getDcSystemIdViewParam
();
if
(
tempViewParam
&&
tempViewParam
.
srfdcsystem
)
{
Object
.
assign
(
headers
,
{
srfdcsystem
:
tempViewParam
.
srfdcsystem
});
}
const
get
:
Promise
<
any
>
=
this
.
getData
(
"/uaa/open/dingtalk/appid"
,
{},
false
,
headers
);
get
.
then
((
response
:
any
)
=>
{
if
(
response
&&
response
.
status
===
200
)
{
const
data
=
response
.
data
;
if
(
data
&&
data
.
appid
)
{
resolve
({
state
:
"SUCCESS"
,
data
:
data
});
}
else
{
resolve
({
state
:
"ERROR"
,
message
:
`获取网站应用appid失败,
${
data
.
detail
}
`
,
});
}
}
}).
catch
((
error
:
any
)
=>
{
const
data
=
error
.
data
;
if
(
data
&&
data
.
detail
)
{
resolve
({
state
:
"ERROR"
,
message
:
`获取网站应用appid失败,
${
data
.
detail
}
`
,
});
}
else
{
resolve
({
state
:
"ERROR"
,
message
:
`获取网站应用appid失败`
});
}
});
});
}
/**
* 企业微信授权登录
*
* @memberof AppThirdService
*/
public
wxWorkLogin
():
Promise
<
any
>
{
return
new
Promise
((
resolve
)
=>
{
// 请求头
const
headers
=
{};
const
tempViewParam
=
Util
.
getDcSystemIdViewParam
();
if
(
tempViewParam
&&
tempViewParam
.
srfdcsystem
)
{
Object
.
assign
(
headers
,
{
srfdcsystem
:
tempViewParam
.
srfdcsystem
});
}
const
get
:
Promise
<
any
>
=
this
.
getData
(
"/uaa/open/wxwork/appid"
,
{},
false
,
headers
);
get
.
then
((
response
:
any
)
=>
{
if
(
response
&&
response
.
status
===
200
)
{
const
data
=
response
.
data
;
if
(
data
&&
(
data
.
corp_id
||
data
.
appid
))
{
resolve
({
state
:
"SUCCESS"
,
data
:
data
});
}
else
{
resolve
({
state
:
"ERROR"
,
message
:
`获取网站应用appid失败,
${
data
.
detail
}
`
,
});
}
}
}).
catch
((
error
:
any
)
=>
{
const
data
=
error
.
data
;
if
(
data
&&
data
.
detail
)
{
resolve
({
state
:
"ERROR"
,
message
:
`获取网站应用appid失败,
${
data
.
detail
}
`
,
});
}
else
{
resolve
({
state
:
"ERROR"
,
message
:
`获取网站应用appid失败`
});
}
});
});
}
/**
* 钉钉内部免登
*
* @memberof AppThirdService
*/
public
embedDingTalkLogin
(
Environment
:
any
):
Promise
<
any
>
{
return
new
Promise
((
resolve
)
=>
{
// 请求头
const
headers
=
{};
const
tempViewParam
=
Util
.
getDcSystemIdViewParam
();
if
(
tempViewParam
&&
tempViewParam
.
srfdcsystem
)
{
Object
.
assign
(
headers
,
{
srfdcsystem
:
tempViewParam
.
srfdcsystem
});
}
const
param
=
Util
.
handleViewParam
(
window
.
location
.
href
);
if
(
param
.
corpId
)
{
let
corpId
:
string
=
param
.
corpId
;
if
(
corpId
.
indexOf
(
"#"
)
>
-
1
)
{
corpId
=
corpId
.
split
(
"#"
)[
0
];
}
dd
.
runtime
.
permission
.
requestAuthCode
({
corpId
})
.
then
((
res
:
any
)
=>
{
if
(
res
&&
res
.
code
)
{
this
.
getData
(
`/uaa/open/dingtalk/auth/
${
res
.
code
}
`
,
{},
false
,
headers
).
then
((
res
:
any
)
=>
{
if
(
res
.
status
==
200
&&
(
res
.
data
.
token
||
res
.
data
.
user
))
{
resolve
({
state
:
"SUCCESS"
,
data
:
res
.
data
});
}
else
{
resolve
({
state
:
"ERROR"
,
message
:
`
${
res
.
data
.
message
}
`
});
}
});
}
else
{
resolve
({
state
:
"ERROR"
,
message
:
`钉钉用户信息获取失败`
});
}
})
.
catch
((
error
:
any
)
=>
{
resolve
({
state
:
"ERROR"
,
message
:
`钉钉用户信息获取失败`
});
});
}
else
{
resolve
({
state
:
"ERROR"
,
message
:
`获取企业ID失败`
});
}
});
}
/**
* 获取数据
*
* @memberof AppThirdService
*/
public
getData
(
url
:
string
,
params
:
any
=
{},
isloading
?:
boolean
,
headers
:
any
=
{})
{
params
=
this
.
handleRequestData
(
params
);
if
(
params
.
srfparentdata
)
{
Object
.
assign
(
params
,
params
.
srfparentdata
);
delete
params
.
srfparentdata
;
}
if
(
Object
.
keys
(
params
).
length
>
0
)
{
let
tempParam
:
any
=
{};
Object
.
keys
(
params
).
forEach
((
item
:
any
)
=>
{
if
(
params
[
item
]
||
Object
.
is
(
params
[
item
],
0
))
{
tempParam
[
item
]
=
params
[
item
];
}
});
if
(
Object
.
keys
(
tempParam
).
length
>
0
)
{
url
+=
`?
${
qs
.
stringify
(
tempParam
)}
`
;
}
}
return
new
Promise
((
resolve
:
any
,
reject
:
any
)
=>
{
axios
.
get
(
url
,
{
headers
:
headers
}).
then
((
response
:
any
)
=>
{
resolve
(
response
);
});
});
}
/**
* 处理请求数据
*
* @memberof AppThirdService
*/
public
handleRequestData
(
data
:
any
)
{
if
(
data
?.
srfsessionkey
)
{
delete
data
.
srfsessionkey
;
}
if
(
data
?.
srfsessionid
)
{
delete
data
.
srfsessionid
;
}
if
(
data
?.
srfparentdemapname
)
{
delete
data
.
srfparentdemapname
;
}
return
data
;
}
}
</
script
>
<
style
lang=
"less"
>
@import "./app-login-third.less";
</
style
>
This diff is collapsed.
Click to expand it.
app_Web/src/components/layout-element/text/app-preset-caption/app-preset-caption.less
0 → 100644
浏览文件 @
0dc2f7ca
.app-preset-caption {
padding: 8px;
.caption-info {
font-weight: 600;
font-family: "Microsoft YaHei";
font-size: 14px;
}
}
\ No newline at end of file
This diff is collapsed.
Click to expand it.
app_Web/src/components/layout-element/text/app-preset-caption/app-preset-caption.vue
0 → 100644
浏览文件 @
0dc2f7ca
<
template
>
<div
class=
"app-preset-caption"
>
<slot></slot>
</div>
</
template
>
<
script
lang=
"ts"
>
import
{
Vue
,
Component
}
from
"vue-property-decorator"
;
@
Component
({})
export
default
class
AppPreSetCaption
extends
Vue
{}
</
script
>
<
style
lang=
'less'
>
@import "./app-preset-caption.less";
</
style
>
\ No newline at end of file
This diff is collapsed.
Click to expand it.
app_Web/src/components/layout-element/text/app-preset-text/app-preset-text.less
0 → 100644
浏览文件 @
0dc2f7ca
.app-preset-text {
width: 100%;
height: 100%;
}
\ No newline at end of file
This diff is collapsed.
Click to expand it.
app_Web/src/components/layout-element/text/app-preset-text/app-preset-text.vue
0 → 100644
浏览文件 @
0dc2f7ca
<
template
>
<div
:class=
"['app-preset-text', `app-preset-text--$
{contentType.toLowerCase()}`]">
<!-- 直接内容类型 -->
<template
v-if=
"Object.is(contentType, 'RAW')"
>
<template
v-if=
"Object.is(renderMode, 'TEXT')"
>
<span
:style=
"cssStyle"
>
{{
value
}}
</span>
</
template
>
<
template
v-else-if=
"Object.is(renderMode, 'HEADING1')"
>
<h1
:style=
"cssStyle"
>
{{
value
}}
</h1>
</
template
>
<
template
v-else-if=
"Object.is(renderMode, 'HEADING2')"
>
<h2
:style=
"cssStyle"
>
{{
value
}}
</h2>
</
template
>
<
template
v-else-if=
"Object.is(renderMode, 'HEADING3')"
>
<h3
:style=
"cssStyle"
>
{{
value
}}
</h3>
</
template
>
<
template
v-else-if=
"Object.is(renderMode, 'HEADING4')"
>
<h4
:style=
"cssStyle"
>
{{
value
}}
</h4>
</
template
>
<
template
v-else-if=
"Object.is(renderMode, 'HEADING5')"
>
<h5
:style=
"cssStyle"
>
{{
value
}}
</h5>
</
template
>
<
template
v-else-if=
"Object.is(renderMode, 'HEADING6')"
>
<h6
:style=
"cssStyle"
>
{{
value
}}
</h6>
</
template
>
<
template
v-else-if=
"Object.is(renderMode, 'PARAGRAPH')"
>
<p
:style=
"cssStyle"
>
{{
value
}}
</p>
</
template
>
</template>
<!-- 图片类型 -->
<
template
v-else-if=
"Object.is(contentType, 'IMAGE')"
>
<img
:style=
"cssStyle"
v-if=
"imgUrl"
:src=
"imgUrl"
/>
<i
:style=
"cssStyle"
v-else
:class=
"imageClass ? imageClass : ''"
></i>
</
template
>
<!-- HTML类型 -->
<
template
v-else-if=
"Object.is(contentType, 'HTML')"
>
<div
:style=
"cssStyle"
v-html=
"value"
/>
</
template
>
<!-- MARKDOWN类型 -->
<
template
v-else-if=
"Object.is(contentType, 'MARKDOWN')"
>
MARKDOWN暂未支持
<!--
<app-markdown-editor
:style=
"cssStyle"
mode=
"PREVIEWONLY"
:itemValue=
"value"
></app-markdown-editor>
-->
</
template
>
</div>
</template>
<
script
lang=
"ts"
>
import
{
Vue
,
Component
,
Prop
}
from
'vue-property-decorator'
;
@
Component
({})
export
default
class
AppPreSetText
extends
Vue
{
/**
* 输入值
*
* @type {*}
* @memberof AppPreSetText
*/
@
Prop
()
public
value
!
:
any
;
/**
* 内容类型
*
* @type {string}
* @memberof AppPreSetText
*/
@
Prop
({
default
:
'RAW'
})
public
contentType
!
:
'RAW'
|
'HTML'
|
'IMAGE'
|
'MARKDOWN'
;
/**
* 绘制模式
*
* @type {string}
* @memberof AppPreSetText
*/
@
Prop
({
default
:
'TEXT'
})
public
renderMode
!
:
'TEXT'
|
'HEADING1'
|
'HEADING2'
|
'HEADING3'
|
'HEADING4'
|
'HEADING5'
|
'HEADING6'
|
'PARAGRAPH'
;
/**
* 内容样式
*
* @type {string}
* @memberof AppPreSetText
*/
@
Prop
()
public
contentStyle
?:
string
;
/**
* 预置类型
*
* @type {string}
* @memberof AppPreSetText
*/
@
Prop
({
default
:
'STATIC_TEXT'
})
public
predefinedType
!
:
'FIELD_TEXT_DYNAMIC'
|
'STATIC_LABEL'
|
'STATIC_TEXT'
;
/**
* 图标
*
* @memberof AppPreSetText
*/
@
Prop
()
public
imageClass
?:
string
;
/**
* 动态图片路径
*
* @memberof AppPreSetText
*/
protected
dynaImgUrl
:
string
=
''
;
/**
* 样式
*
* @memberof AppPreSetText
*/
protected
cssStyle
:
string
=
''
;
/**
* 图片路径
*
* @memberof AppPreSetText
*/
get
imgUrl
():
string
{
return
this
.
dynaImgUrl
;
}
/**
* Vue生命周期 --- Created
*
* @memberof AppPreSetText
*/
created
()
{
this
.
handleText
();
this
.
handleDynaImg
();
}
/**
* 处理文本
*
* @memberof AppPreSetText
*/
protected
handleText
()
{
if
(
this
.
predefinedType
===
'STATIC_LABEL'
)
{
this
.
cssStyle
+=
"white-space: nowrap;overflow: hidden;text-overflow: ellipsis;"
;
}
}
/**
* 处理动态图片
*
* @memberof AppPreSetText
*/
protected
handleDynaImg
()
{
// TODO 动态图片
// if (this.value && typeof this.value == 'string') {
// // 默认识别文件对象形式,识别失败则为全路径模式
// try {
// const _files = JSON.parse(this.value);
// const file = _files instanceof Array ? _files[0] : null;
// const url = file && file.id ? `${this.downloadUrl}/${file.id}` : '';
// ImgurlBase64.getInstance()
// .getImgURLOfBase64(url)
// .then((res: any) => {
// this.dynaImgUrl = res;
// });
// } catch (error) {
// this.dynaImgUrl = this.value;
// }
// }
}
}
</
script
>
<
style
lang=
"less"
>
@import './app-preset-text.less';
</
style
>
\ No newline at end of file
This diff is collapsed.
Click to expand it.
app_Web/src/components/layout-element/text/app-preset-title/app-preset-title.less
0 → 100644
浏览文件 @
0dc2f7ca
.app-preset-title {
padding: 16px;
font-weight: 600;
font-size: 24px;
}
\ No newline at end of file
This diff is collapsed.
Click to expand it.
app_Web/src/components/layout-element/text/app-preset-title/app-preset-title.vue
0 → 100644
浏览文件 @
0dc2f7ca
<
template
>
<h1
class=
"app-preset-title"
>
{{
curValue
}}
</h1>
</
template
>
<
script
lang=
"ts"
>
import
{
Environment
}
from
"@/environments/environment"
;
import
{
Vue
,
Component
}
from
'vue-property-decorator'
;
@
Component
({})
export
default
class
AppPreSetTitle
extends
Vue
{
/**
* 当前值
*
* @memberof AppPreSetTitle
*/
public
curValue
:
string
=
''
;
/**
* 初始化
*
* @memberof AppPreSetTitle
*/
public
created
()
{
this
.
curValue
=
Environment
.
AppTitle
;
}
}
</
script
>
<
style
lang=
'less'
>
@import './app-preset-title.less';
</
style
>
\ No newline at end of file
This diff is collapsed.
Click to expand it.
app_Web/src/locale/lanres/components/components_en_US_base.ts
浏览文件 @
0dc2f7ca
...
...
@@ -158,6 +158,8 @@ function getLocaleResourceBase(){
placeholder2
:
'Password'
,
name
:
'Login'
,
reset
:
'Reset'
,
register
:
'Register'
,
logout
:
'Logout'
,
other
:
'Other login methods'
,
tip
:
'Enter username and password'
,
warning1
:
'QQ authorization login not supported'
,
...
...
@@ -171,6 +173,13 @@ function getLocaleResourceBase(){
message
:
'The password cannot be empty'
,
},
loginfailed
:
'Login failed'
,
authfailed
:
'Authentication failed'
,
phoneplaceholder
:
'Please enter your mobile phone number'
,
phonefailed
:
'The phone number is incorrect'
,
codeplaceholder
:
'Please enter the verification code'
,
getcode
:
'Get verification code'
,
getcodeafter
:
'Get verification code after'
,
entervercode
:
'Please enter the verification code'
,
},
appUser
:
{
name
:
'System'
,
...
...
This diff is collapsed.
Click to expand it.
app_Web/src/locale/lanres/components/components_zh_CN_base.ts
浏览文件 @
0dc2f7ca
...
...
@@ -159,6 +159,8 @@ function getLocaleResourceBase(){
placeholder2
:
'密码'
,
name
:
'登录'
,
reset
:
'重置'
,
register
:
'注册'
,
logout
:
'登出'
,
other
:
'其他登录方式'
,
tip
:
'输入用户名和密码'
,
warning1
:
'qq授权登录暂未支持'
,
...
...
@@ -172,6 +174,13 @@ function getLocaleResourceBase(){
message
:
'密码不能为空'
,
},
loginfailed
:
'登录失败'
,
authfailed
:
'验证失败'
,
phoneplaceholder
:
'请输入手机号'
,
phonefailed
:
'手机号不正确'
,
codeplaceholder
:
'请输入验证码'
,
getcode
:
'获取验证码'
,
getcodeafter
:
'后获取验证码'
,
entervercode
:
'请输入验证码'
,
},
appUser
:
{
name
:
'系统管理员'
,
...
...
This diff is collapsed.
Click to expand it.
app_Web/src/widgets/ibizbook/default-searchform/default-searchform-base.vue
浏览文件 @
0dc2f7ca
...
...
@@ -663,7 +663,7 @@ export default class DefaultBase extends Vue implements ControlInterface {
*/
public
load
(
opt
:
any
=
{}):
void
{
if
(
!
this
.
loadAction
){
this
.
$Notice
.
error
({
title
:
(
this
.
$t
(
'app.commonWords.wrong'
)
as
string
),
desc
:
'IBIZBOOKUsr
3
GridView'
+
(
this
.
$t
(
'app.searchForm.notConfig.loadAction'
)
as
string
)
});
this
.
$Notice
.
error
({
title
:
(
this
.
$t
(
'app.commonWords.wrong'
)
as
string
),
desc
:
'IBIZBOOKUsr
9
GridView'
+
(
this
.
$t
(
'app.searchForm.notConfig.loadAction'
)
as
string
)
});
return
;
}
const
arg
:
any
=
{
...
opt
};
...
...
@@ -699,7 +699,7 @@ export default class DefaultBase extends Vue implements ControlInterface {
*/
public
loadDraft
(
opt
:
any
=
{},
mode
?:
string
):
void
{
if
(
!
this
.
loaddraftAction
){
this
.
$Notice
.
error
({
title
:
(
this
.
$t
(
'app.commonWords.wrong'
)
as
string
),
desc
:
'IBIZBOOKUsr
3
GridView'
+
(
this
.
$t
(
'app.searchForm.notConfig.loaddraftAction'
)
as
string
)
});
this
.
$Notice
.
error
({
title
:
(
this
.
$t
(
'app.commonWords.wrong'
)
as
string
),
desc
:
'IBIZBOOKUsr
9
GridView'
+
(
this
.
$t
(
'app.searchForm.notConfig.loaddraftAction'
)
as
string
)
});
return
;
}
const
arg
:
any
=
{
...
opt
}
;
...
...
This diff is collapsed.
Click to expand it.
app_Web/src/widgets/ibizbook/quicksearchform-searchform/quicksearchform-searchform-base.vue
浏览文件 @
0dc2f7ca
...
...
@@ -621,7 +621,7 @@ export default class QUICKSEARCHFORMBase extends Vue implements ControlInterface
*/
public
load
(
opt
:
any
=
{}):
void
{
if
(
!
this
.
loadAction
){
this
.
$Notice
.
error
({
title
:
(
this
.
$t
(
'app.commonWords.wrong'
)
as
string
),
desc
:
'IBIZBOOK
List
View'
+
(
this
.
$t
(
'app.searchForm.notConfig.loadAction'
)
as
string
)
});
this
.
$Notice
.
error
({
title
:
(
this
.
$t
(
'app.commonWords.wrong'
)
as
string
),
desc
:
'IBIZBOOK
Calendar
View'
+
(
this
.
$t
(
'app.searchForm.notConfig.loadAction'
)
as
string
)
});
return
;
}
const
arg
:
any
=
{
...
opt
};
...
...
@@ -657,7 +657,7 @@ export default class QUICKSEARCHFORMBase extends Vue implements ControlInterface
*/
public
loadDraft
(
opt
:
any
=
{},
mode
?:
string
):
void
{
if
(
!
this
.
loaddraftAction
){
this
.
$Notice
.
error
({
title
:
(
this
.
$t
(
'app.commonWords.wrong'
)
as
string
),
desc
:
'IBIZBOOK
List
View'
+
(
this
.
$t
(
'app.searchForm.notConfig.loaddraftAction'
)
as
string
)
});
this
.
$Notice
.
error
({
title
:
(
this
.
$t
(
'app.commonWords.wrong'
)
as
string
),
desc
:
'IBIZBOOK
Calendar
View'
+
(
this
.
$t
(
'app.searchForm.notConfig.loaddraftAction'
)
as
string
)
});
return
;
}
const
arg
:
any
=
{
...
opt
}
;
...
...
This diff is collapsed.
Click to expand it.
编辑
预览
Markdown
格式
0%
请重试
or
添加新附件
添加附件
取消
您添加了
0
人
到此讨论。请谨慎行事。
先完成此消息的编辑!
取消
想要评论请
注册
或
登录