初始化项目
This commit is contained in:
@@ -1,124 +0,0 @@
|
||||
<template>
|
||||
<div class="tinymce-container editor-container">
|
||||
<textarea ref="text" :id="tinymceId" class="tinymce-textarea"/>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import plugins from './plugins'
|
||||
import toolbar from './toolbar'
|
||||
import {putFileFun} from '../../api/resource/oss.js'
|
||||
|
||||
let id = 0
|
||||
|
||||
function getid() {
|
||||
return `tinymce${id++}`
|
||||
}
|
||||
|
||||
export default {
|
||||
name: 'Tinymce',
|
||||
props: {
|
||||
height: {
|
||||
type: Number,
|
||||
required: false,
|
||||
default: 360
|
||||
},
|
||||
value:{type:String,default:""}
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
ed:null,
|
||||
hasInit:false,
|
||||
tinymceId: getid(),
|
||||
}
|
||||
},
|
||||
mounted() {
|
||||
this.initTinymce()
|
||||
},
|
||||
deactivated() {
|
||||
this.destroyTinymce()
|
||||
},
|
||||
destroyed() {
|
||||
this.ed.off('blur')
|
||||
this.destroyTinymce()
|
||||
},
|
||||
methods: {
|
||||
initTinymce() {
|
||||
window.tinymce.init({
|
||||
selector: `#${this.tinymceId}`,
|
||||
language:'zh_CN',
|
||||
plugins: plugins,
|
||||
toolbar: toolbar,
|
||||
height: this.height, //编辑器高度
|
||||
min_height: 400,
|
||||
fontsize_formats: '12px 14px 16px 18px 24px 36px 48px 56px 72px',
|
||||
font_formats: '微软雅黑=Microsoft YaHei,Helvetica Neue,PingFang SC,sans-serif;苹果苹方=PingFang SC,Microsoft YaHei,sans-serif;宋体=simsun,serif;仿宋体=FangSong,serif;黑体=SimHei,sans-serif;Arial=arial,helvetica,sans-serif;Arial Black=arial black,avant garde;Book Antiqua=book antiqua,palatino;Comic Sans MS=comic sans ms,sans-serif;Courier New=courier new,courier;Georgia=georgia,palatino;Helvetica=helvetica;Impact=impact,chicago;Symbol=symbol;Tahoma=tahoma,arial,helvetica,sans-serif;Terminal=terminal,monaco;Times New Roman=times new roman,times;Verdana=verdana,geneva;Webdings=webdings;Wingdings=wingdings,zapf dingbats;知乎配置=BlinkMacSystemFont, Helvetica Neue, PingFang SC, Microsoft YaHei, Source Han Sans SC, Noto Sans CJK SC, WenQuanYi Micro Hei, sans-serif;小米配置=Helvetica Neue,Helvetica,Arial,Microsoft Yahei,Hiragino Sans GB,Heiti SC,WenQuanYi Micro Hei,sans-serif',
|
||||
extended_valid_elements:'script[src]',
|
||||
template_cdate_format: '[CDATE: %m/%d/%Y : %H:%M:%S]',
|
||||
template_mdate_format: '[MDATE: %m/%d/%Y : %H:%M:%S]',
|
||||
autosave_ask_before_unload: false,
|
||||
toolbar_mode : 'wrap',
|
||||
images_upload_base_path: '',
|
||||
images_upload_handler: function (blobInfo, succFun) {
|
||||
var file = blobInfo.file ? blobInfo.file : blobInfo.blob()
|
||||
putFileFun(file).then(e => {
|
||||
succFun(e.data.data.link)
|
||||
})
|
||||
},
|
||||
setup:(ed) => {
|
||||
this.ed = ed
|
||||
ed.on("blur", () => {
|
||||
this.$emit('input',this.getContent())
|
||||
})
|
||||
}
|
||||
}).then(()=>{
|
||||
this.hasInit = true
|
||||
this.setContent(this.value)
|
||||
});
|
||||
},
|
||||
destroyTinymce() {
|
||||
if (window.tinymce.get(this.tinymceId)) {
|
||||
window.tinymce.get(this.tinymceId).destroy()
|
||||
}
|
||||
},
|
||||
setContent(value) {
|
||||
if (this.hasInit)
|
||||
{window.tinyMCE.get(this.tinymceId).setContent(value)}
|
||||
},
|
||||
getContent() {
|
||||
return window.tinymce.get(this.tinymceId).getContent()
|
||||
},
|
||||
},
|
||||
watch:{
|
||||
value(val){
|
||||
this.setContent(val)
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
.tinymce-container {
|
||||
position: relative;
|
||||
}
|
||||
.tinymce-container>>>.mce-fullscreen {
|
||||
z-index: 10000;
|
||||
}
|
||||
.tinymce-textarea {
|
||||
visibility: hidden;
|
||||
z-index: -1;
|
||||
}
|
||||
.editor-custom-btn-container {
|
||||
position: absolute;
|
||||
right: 4px;
|
||||
top: 4px;
|
||||
z-index: 2005;
|
||||
}
|
||||
.fullscreen .editor-custom-btn-container {
|
||||
z-index: 10000;
|
||||
position: fixed;
|
||||
}
|
||||
.editor-upload-btn {
|
||||
display: inline-block;
|
||||
}
|
||||
</style>
|
||||
@@ -1,5 +0,0 @@
|
||||
|
||||
const plugins = 'print preview searchreplace autolink directionality visualblocks visualchars fullscreen image link media template code codesample table charmap hr pagebreak nonbreaking anchor insertdatetime advlist lists wordcount imagetools textpattern help emoticons autosave indent2em autoresize axupimgs'
|
||||
|
||||
|
||||
export default plugins
|
||||
@@ -1,6 +0,0 @@
|
||||
|
||||
const toolbar = 'code undo redo restoredraft | cut copy paste pastetext | forecolor backcolor bold italic underline strikethrough link anchor | alignleft aligncenter alignright alignjustify outdent indent | \
|
||||
styleselect formatselect fontselect fontsizeselect | bullist numlist | blockquote subscript superscript removeformat | \
|
||||
table image media charmap emoticons hr pagebreak insertdatetime print preview | fullscreen | indent2em axupimgs'
|
||||
|
||||
export default toolbar
|
||||
@@ -1,126 +0,0 @@
|
||||
<template>
|
||||
<div class="basic-block"
|
||||
:style="styleName">
|
||||
<div class="box"
|
||||
:style="boxStyleName">
|
||||
<router-link :to="to">
|
||||
<span v-text="text"></span>
|
||||
<p v-text="dept"></p>
|
||||
<i :class="icon"></i>
|
||||
</router-link>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
name: 'basicBlock',
|
||||
props: {
|
||||
icon: {
|
||||
type: String,
|
||||
},
|
||||
background: {
|
||||
type: String,
|
||||
},
|
||||
to: {
|
||||
type: Object,
|
||||
default: () => {
|
||||
return {}
|
||||
}
|
||||
},
|
||||
text: {
|
||||
type: String,
|
||||
},
|
||||
dept: {
|
||||
type: String,
|
||||
},
|
||||
time: {
|
||||
type: [Number, String]
|
||||
},
|
||||
gutter: {
|
||||
type: [Number, String],
|
||||
default: 5,
|
||||
},
|
||||
color: {
|
||||
type: String,
|
||||
},
|
||||
width: {
|
||||
type: [Number, String]
|
||||
},
|
||||
height: {
|
||||
type: [Number, String]
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
styleName () {
|
||||
return {
|
||||
animationDelay: `${this.time / 25}s`,
|
||||
width: this.setPx(this.width),
|
||||
height: this.setPx(this.height),
|
||||
margin: this.setPx(this.gutter)
|
||||
}
|
||||
},
|
||||
boxStyleName () {
|
||||
return {
|
||||
backgroundColor: this.color,
|
||||
backgroundImage: `url('${this.background}')`,
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss">
|
||||
.basic-block {
|
||||
opacity: 0;
|
||||
|
||||
box-sizing: border-box;
|
||||
color: #fff;
|
||||
animation: mymove 1s;
|
||||
animation-fill-mode: forwards;
|
||||
.box {
|
||||
position: relative;
|
||||
box-sizing: border-box;
|
||||
padding: 15px;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
transition: all 1s;
|
||||
background-size: cover;
|
||||
&:hover {
|
||||
transform: rotateY(360deg);
|
||||
}
|
||||
}
|
||||
|
||||
a {
|
||||
color: #fff;
|
||||
}
|
||||
span {
|
||||
display: block;
|
||||
font-size: 16px;
|
||||
}
|
||||
p {
|
||||
width: 80%;
|
||||
font-size: 10px;
|
||||
color: #eee;
|
||||
line-height: 22px;
|
||||
}
|
||||
i {
|
||||
position: absolute;
|
||||
bottom: 15px;
|
||||
right: 15px;
|
||||
font-size: 50px !important ;
|
||||
}
|
||||
@keyframes mymove {
|
||||
from {
|
||||
opacity: 0;
|
||||
transform: scale(0);
|
||||
}
|
||||
to {
|
||||
opacity: 1;
|
||||
transform: scale(1);
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
@@ -1,54 +0,0 @@
|
||||
<template>
|
||||
<div class="basic-container"
|
||||
:class="{'basic-container--block':block}">
|
||||
<el-card>
|
||||
<slot></slot>
|
||||
</el-card>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
name: "basicContainer",
|
||||
props: {
|
||||
radius: {
|
||||
type: [String, Number],
|
||||
default: 10
|
||||
},
|
||||
background: {
|
||||
type: String
|
||||
},
|
||||
block: {
|
||||
type: Boolean,
|
||||
default: false
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
styleName () {
|
||||
return {
|
||||
borderRadius: this.setPx(this.radius),
|
||||
background: this.background,
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
</script>
|
||||
|
||||
<style lang="scss">
|
||||
.basic-container {
|
||||
padding: 10px 6px;
|
||||
box-sizing: border-box;
|
||||
&--block {
|
||||
height: 100%;
|
||||
.el-card {
|
||||
height: 100%;
|
||||
}
|
||||
}
|
||||
.el-card {
|
||||
width: 100%;
|
||||
}
|
||||
&:first-child {
|
||||
padding-top: 0;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
@@ -1,85 +0,0 @@
|
||||
<template>
|
||||
<el-cascader
|
||||
:options="area.data"
|
||||
:show-all-levels="showAllLevels"
|
||||
v-model="model"
|
||||
:filterable="filterable"
|
||||
:placeholder="placeholder"
|
||||
:disabled="disabled"
|
||||
:clearable="clearable"
|
||||
></el-cascader>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { mapGetters } from "vuex";
|
||||
|
||||
function getProv(code) {
|
||||
return code.substring(0, 2) + "0000";
|
||||
}
|
||||
function getCity(code) {
|
||||
return code.substring(0, 4) + "00";
|
||||
}
|
||||
|
||||
export default {
|
||||
props: {
|
||||
value: String,
|
||||
filterable: Boolean,
|
||||
placeholder: String,
|
||||
showAllLevels: { type: Boolean, default: true },
|
||||
disabled: Boolean,
|
||||
clearable: Boolean,
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
options: [],
|
||||
};
|
||||
},
|
||||
created() {
|
||||
this.$store.dispatch("InitArea");
|
||||
},
|
||||
watch: {},
|
||||
computed: {
|
||||
...mapGetters(["area"]),
|
||||
prov() {
|
||||
if (this.county) {
|
||||
return getProv(this.county);
|
||||
} else {
|
||||
return "";
|
||||
}
|
||||
},
|
||||
city() {
|
||||
if (this.county) {
|
||||
return getCity(this.county);
|
||||
} else {
|
||||
return "";
|
||||
}
|
||||
},
|
||||
county: {
|
||||
get() {
|
||||
return this.value;
|
||||
},
|
||||
set(val) {
|
||||
this.$emit("input", val);
|
||||
},
|
||||
},
|
||||
model: {
|
||||
set(val) {
|
||||
if (val.length > 2) {
|
||||
this.county = val[2];
|
||||
} else {
|
||||
this.county = undefined;
|
||||
}
|
||||
},
|
||||
get() {
|
||||
if (this.county) {
|
||||
return [this.prov, this.city, this.county];
|
||||
}
|
||||
return null;
|
||||
},
|
||||
},
|
||||
},
|
||||
};
|
||||
</script>
|
||||
|
||||
<style>
|
||||
</style>
|
||||
@@ -1,24 +0,0 @@
|
||||
<template>
|
||||
<div class="error-page">
|
||||
<div class="img"
|
||||
style=" background-image: url('./img/bg/403.svg');"></div>
|
||||
<div class="content">
|
||||
<h1>403</h1>
|
||||
<div class="desc">抱歉,你无权访问该页面</div>
|
||||
<div class="actions">
|
||||
<router-link :to="{path:'/'}">
|
||||
<el-button type="primary">返回首页</el-button>
|
||||
</router-link>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
name: "error-403"
|
||||
};
|
||||
</script>
|
||||
<style lang="scss" scoped>
|
||||
@import "./style.scss";
|
||||
</style>
|
||||
@@ -1,24 +0,0 @@
|
||||
<template>
|
||||
<div class="error-page">
|
||||
<div class="img"
|
||||
style=" background-image: url('./img/bg/404.svg');"></div>
|
||||
<div class="content">
|
||||
<h1>404</h1>
|
||||
<div class="desc">抱歉,你访问的页面不存在</div>
|
||||
<div class="actions">
|
||||
<router-link :to="{path:'/'}">
|
||||
<el-button type="primary">返回首页</el-button>
|
||||
</router-link>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
name: "error-404"
|
||||
};
|
||||
</script>
|
||||
<style lang="scss" scoped>
|
||||
@import "./style.scss";
|
||||
</style>
|
||||
@@ -1,24 +0,0 @@
|
||||
<template>
|
||||
<div class="error-page">
|
||||
<div class="img"
|
||||
style=" background-image: url('./img/bg/500.svg');"></div>
|
||||
<div class="content">
|
||||
<h1>500</h1>
|
||||
<div class="desc">抱歉,服务器出错了</div>
|
||||
<div class="actions">
|
||||
<router-link :to="{path:'/'}">
|
||||
<el-button type="primary">返回首页</el-button>
|
||||
</router-link>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
name: "error-500"
|
||||
};
|
||||
</script>
|
||||
<style lang="scss" scoped>
|
||||
@import "./style.scss";
|
||||
</style>
|
||||
@@ -1,32 +0,0 @@
|
||||
.error-page {
|
||||
background: #f0f2f5;
|
||||
margin-top: -30px;
|
||||
height: 100%;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
.img {
|
||||
margin-right: 80px;
|
||||
height: 360px;
|
||||
width: 100%;
|
||||
max-width: 430px;
|
||||
background-repeat: no-repeat;
|
||||
background-position: 50% 50%;
|
||||
background-size: contain;
|
||||
}
|
||||
.content {
|
||||
h1 {
|
||||
color: #434e59;
|
||||
font-size: 72px;
|
||||
font-weight: 600;
|
||||
line-height: 72px;
|
||||
margin-bottom: 24px;
|
||||
}
|
||||
.desc {
|
||||
color: rgba(0, 0, 0, 0.45);
|
||||
font-size: 20px;
|
||||
line-height: 28px;
|
||||
margin-bottom: 16px;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,65 +0,0 @@
|
||||
<template>
|
||||
<el-upload action="#" class="upload" drag :before-upload="beforeUpload">
|
||||
<i class="el-icon-upload"></i>
|
||||
<div class="el-upload__text">
|
||||
将文件拖到此处,或
|
||||
<em>点击上传</em>
|
||||
</div>
|
||||
<div class="el-upload__tip" slot="tip">
|
||||
<span>请上传 .xls,.xlsx 标准格式文件 </span>
|
||||
<span class="redFont"> 最多可上传1000条Excel数据</span>
|
||||
</div>
|
||||
</el-upload>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { isExcel } from "@/util/validate";
|
||||
import XLSX from "xlsx";
|
||||
|
||||
function fixdata(data) {
|
||||
let o = "";
|
||||
let l = 0;
|
||||
let w = 10240;
|
||||
for (; l < data.byteLength / w; ++l) {
|
||||
o += String.fromCharCode.apply(
|
||||
null,
|
||||
new Uint8Array(data.slice(l * w, l * w + w))
|
||||
);
|
||||
}
|
||||
o += String.fromCharCode.apply(null, new Uint8Array(data.slice(l * w)));
|
||||
return o;
|
||||
}
|
||||
|
||||
export default {
|
||||
props: { success: Function },
|
||||
methods: {
|
||||
beforeUpload(file) {
|
||||
if (!isExcel(file)) {
|
||||
this.$message.error("上传参保信息只能是 .xls,.xlsx 标准格式文件!");
|
||||
return;
|
||||
}
|
||||
let reader = new FileReader();
|
||||
let self = this;
|
||||
reader.onload = function(e) {
|
||||
var data = e.target.result;
|
||||
var wb = XLSX.read(btoa(fixdata(data)), {
|
||||
type: "base64"
|
||||
});
|
||||
var questions = XLSX.utils.sheet_to_json(wb.Sheets[wb.SheetNames[0]]);
|
||||
self.success(questions);
|
||||
};
|
||||
reader.readAsArrayBuffer(file);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
};
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
.upload {
|
||||
display: inline-block;
|
||||
}
|
||||
.redFont{
|
||||
color:#ff0000;
|
||||
}
|
||||
</style>
|
||||
@@ -1,21 +0,0 @@
|
||||
<template>
|
||||
<div style="text-align: right;margin: 0 0 5px 0">
|
||||
<el-button icon="el-icon-close" circle @click="goBack" size="small"></el-button>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
data() {
|
||||
return {};
|
||||
},
|
||||
methods: {
|
||||
goBack() {
|
||||
this.$router.go(-1);
|
||||
}
|
||||
}
|
||||
};
|
||||
</script>
|
||||
|
||||
<style>
|
||||
</style>
|
||||
@@ -1,129 +0,0 @@
|
||||
<template>
|
||||
<basic-container>
|
||||
<iframe :src="src"
|
||||
class="iframe"
|
||||
ref="iframe"></iframe>
|
||||
</basic-container>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import {mapGetters} from "vuex";
|
||||
import NProgress from "nprogress"; // progress bar
|
||||
import "nprogress/nprogress.css"; // progress bar style
|
||||
export default {
|
||||
name: "AvueIframe",
|
||||
data() {
|
||||
return {
|
||||
urlPath: this.getUrlPath() //iframe src 路径
|
||||
};
|
||||
},
|
||||
created() {
|
||||
NProgress.configure({showSpinner: false});
|
||||
},
|
||||
mounted() {
|
||||
this.load();
|
||||
this.resize();
|
||||
},
|
||||
props: ["routerPath"],
|
||||
watch: {
|
||||
$route: function () {
|
||||
this.load();
|
||||
},
|
||||
routerPath: function () {
|
||||
// 监听routerPath变化,改变src路径
|
||||
this.urlPath = this.getUrlPath();
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
...mapGetters(["screen"]),
|
||||
src() {
|
||||
return this.$route.query.src
|
||||
? this.$route.query.src.replace("$", "#")
|
||||
: this.urlPath;
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
// 显示等待框
|
||||
show() {
|
||||
NProgress.start();
|
||||
},
|
||||
// 隐藏等待狂
|
||||
hide() {
|
||||
NProgress.done();
|
||||
},
|
||||
// 加载浏览器窗口变化自适应
|
||||
resize() {
|
||||
window.onresize = () => {
|
||||
this.iframeInit();
|
||||
};
|
||||
},
|
||||
// 加载组件
|
||||
load() {
|
||||
this.show();
|
||||
var flag = true; //URL是否包含问号
|
||||
if (this.$route.query.src !== undefined && this.$route.query.src.indexOf("?") === -1) {
|
||||
flag = false;
|
||||
}
|
||||
var list = [];
|
||||
for (var key in this.$route.query) {
|
||||
if (key !== "src" && key !== "name" && key !== "i18n") {
|
||||
list.push(`${key}= this.$route.query[key]`);
|
||||
}
|
||||
}
|
||||
list = list.join("&").toString();
|
||||
if (flag) {
|
||||
this.$route.query.src = `${this.$route.query.src}${
|
||||
list.length > 0 ? `&list` : ""
|
||||
}`;
|
||||
} else {
|
||||
this.$route.query.src = `${this.$route.query.src}${
|
||||
list.length > 0 ? `?list` : ""
|
||||
}`;
|
||||
}
|
||||
//超时3s自动隐藏等待狂,加强用户体验
|
||||
let time = 3;
|
||||
const timeFunc = setInterval(() => {
|
||||
time--;
|
||||
if (time === 0) {
|
||||
this.hide();
|
||||
clearInterval(timeFunc);
|
||||
}
|
||||
}, 1000);
|
||||
this.iframeInit();
|
||||
},
|
||||
//iframe窗口初始化
|
||||
iframeInit() {
|
||||
const iframe = this.$refs.iframe;
|
||||
const clientHeight =
|
||||
document.documentElement.clientHeight - (screen > 1 ? 200 : 130);
|
||||
if (!iframe) return;
|
||||
iframe.style.height = `${clientHeight}px`;
|
||||
if (iframe.attachEvent) {
|
||||
iframe.attachEvent("onload", () => {
|
||||
this.hide();
|
||||
});
|
||||
} else {
|
||||
iframe.onload = () => {
|
||||
this.hide();
|
||||
};
|
||||
}
|
||||
},
|
||||
getUrlPath: function () {
|
||||
//获取 iframe src 路径
|
||||
let url = window.location.href;
|
||||
url = url.replace("/myiframe", "");
|
||||
return url;
|
||||
}
|
||||
}
|
||||
};
|
||||
</script>
|
||||
|
||||
<style lang="scss">
|
||||
.iframe {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
border: 0;
|
||||
overflow: hidden;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
</style>
|
||||
@@ -1,320 +0,0 @@
|
||||
<template>
|
||||
<!-- <div v-if="jlHelpShow" class="jl-help" :style="{'height': height, 'width': width +'px'}">-->
|
||||
<div class="jl-help avue-right-sidebar" :class="{'jl-help-active': jlHelpShow}">
|
||||
<div v-if="jlHelpShow">
|
||||
<div class="jl-switch">
|
||||
{{helpSwitch}}
|
||||
<el-switch
|
||||
v-model="switchValue"
|
||||
@change="switchHelp"
|
||||
active-text="默认弹出此侧边栏">
|
||||
</el-switch>
|
||||
</div>
|
||||
<!--政策法规 isShowPolicy -->
|
||||
<div v-if="helpList.isShowPolicy === 1">
|
||||
<div>
|
||||
<div class="big-blank"></div>
|
||||
<p class="jl-help-title">政策法规</p>
|
||||
<div class="medium-blank"></div>
|
||||
<div v-if="policyList.length === 0">
|
||||
暂无内容
|
||||
</div>
|
||||
<div class="jl-small-title" v-for="(item, index) in policyList" :key="index" @click="lookNews(item)">
|
||||
<span>[{{item.secondName}}]</span>
|
||||
<p>{{item.title}}</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="small-blank"></div>
|
||||
<div class="jl-hr"></div>
|
||||
</div>
|
||||
|
||||
<!--常见问题 isShowQuestion -->
|
||||
<div v-if="helpList.isShowQuestion === 1">
|
||||
<div>
|
||||
<div class="big-blank"></div>
|
||||
<p class="jl-help-title">常见问题</p>
|
||||
<div class="medium-blank"></div>
|
||||
<div v-if="questionList.length === 0">
|
||||
暂无内容
|
||||
</div>
|
||||
<div class="jl-small-title" v-for="(item, index) in questionList" :key="index" @click="lookNews(item)">
|
||||
<span>[{{item.secondName}}]</span>
|
||||
<p>{{item.title}}</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="small-blank"></div>
|
||||
<div class="jl-hr"></div>
|
||||
</div>
|
||||
|
||||
<!-- 广告位 isShowCarousel -->
|
||||
<div class="jl-advertisement" v-if="helpList.isShowCarousel === 1">
|
||||
<div class="big-blank"></div>
|
||||
<div>
|
||||
<img
|
||||
v-for="(item, index) in carouselVoList"
|
||||
:key="index"
|
||||
:src="item.image"
|
||||
class="img"
|
||||
alt="">
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 客服 isShowCustservice -->
|
||||
<div v-if="helpList.isShowCustservice === 1">
|
||||
<div class="big-blank"></div>
|
||||
<div class="jl-user">
|
||||
<div class="jl-head-portrait">
|
||||
<img src="../../../public/img/help/portrait.png" height="42" width="42"/>
|
||||
</div>
|
||||
<div class="jl-userInfo">
|
||||
<p class="name">您好,我是小助手</p>
|
||||
<p class="tip">您的专属客服顾问</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="jl-help-code">
|
||||
<div class="img"></div>
|
||||
<div class="jl-help-code-tips">
|
||||
扫码添加您的专属顾问
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="big-blank"></div>
|
||||
<div class="jl-hr"></div>
|
||||
</div>
|
||||
|
||||
<!--服务热线-->
|
||||
<div>
|
||||
<div class="big-blank"></div>
|
||||
<p class="jl-help-title">服务热线</p>
|
||||
<div class="medium-blank"></div>
|
||||
<div class="jl-help-phone">
|
||||
<img src="../../../public/img/help/phone.png" height="20" width="20"/>
|
||||
<p>185-0020-6848</p>
|
||||
</div>
|
||||
<div class="jl-help-time">
|
||||
<p>服务时间:周一至周六08:30-18:00</p>
|
||||
</div>
|
||||
</div>
|
||||
<div style="height: 120px;"></div>
|
||||
|
||||
</div>
|
||||
<el-drawer
|
||||
title="查看"
|
||||
:with-header="false"
|
||||
:visible.sync="drawer"
|
||||
:direction="direction"
|
||||
:size="drawerSize">
|
||||
<div v-html="content">
|
||||
</div>
|
||||
</el-drawer>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import {mapState, mapGetters} from "vuex";
|
||||
import {
|
||||
getStore,
|
||||
} from '@/util/store'
|
||||
export default {
|
||||
name: "index",
|
||||
props: {
|
||||
helpShow: {
|
||||
default: true,
|
||||
type: Boolean
|
||||
}
|
||||
},
|
||||
data () {
|
||||
return {
|
||||
switchValue: true,
|
||||
drawer: false,
|
||||
direction: 'rtl',
|
||||
drawerSize: '1000px',
|
||||
content: '',
|
||||
height: 0,
|
||||
}
|
||||
},
|
||||
watch: {},
|
||||
methods: {
|
||||
// 每次点击时进行切换;修改状态在整个系统生效;
|
||||
switchHelp (v) {
|
||||
var helpSwitch = v ? 1 : 2
|
||||
this.$store.dispatch('jlHelpSwitch', helpSwitch)
|
||||
},
|
||||
lookNews(item){
|
||||
this.drawer = true
|
||||
this.content = item.content
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
...mapState({
|
||||
helpTag: state => state.common.helpTag,
|
||||
helpList: state => state.common.helpList,
|
||||
}),
|
||||
jlHelpShow () {
|
||||
return this.helpTag
|
||||
},
|
||||
helpSwitch () {
|
||||
var helpSwitch = this.$store.state.common.helpSwitch
|
||||
var status = helpSwitch === 1 ? true : false;
|
||||
this.switchValue = status
|
||||
return ''
|
||||
},
|
||||
policyList () {
|
||||
return this.helpList.contentListPolicy
|
||||
},
|
||||
questionList () {
|
||||
return this.helpList.contentListQuestion
|
||||
},
|
||||
carouselVoList () {
|
||||
return this.helpList.carouselVoList
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
p {
|
||||
margin: 0!important;
|
||||
}
|
||||
.big-blank{
|
||||
height:24px;
|
||||
}
|
||||
.medium-blank{
|
||||
height:16px;
|
||||
}
|
||||
.small-blank{
|
||||
height:12px;
|
||||
}
|
||||
.jl-switch{
|
||||
height: 40px;border-bottom:1px solid #f6f6f6;
|
||||
margin-left: -20px;margin-right: -20px;line-height: 40px;padding-left:20px;
|
||||
}
|
||||
.jl-hr{
|
||||
width: 198px;
|
||||
height: 1px;
|
||||
background-color: rgba(0, 0, 0, 0.08);
|
||||
}
|
||||
.jl-help-active{
|
||||
border-top:1px solid #f6f6f6;
|
||||
border-left:1px solid #f6f6f6;
|
||||
box-shadow: 0 1px 2px 0 rgba(0, 0, 0, 0.15);
|
||||
width: 240px !important;
|
||||
overflow: auto;min-height: 500px;
|
||||
height: calc(100% - 64px);
|
||||
background-color: #FFFFFF;
|
||||
padding: 0 20px 20px 20px;
|
||||
}
|
||||
.jl-help{
|
||||
width: 0;
|
||||
}
|
||||
|
||||
.jl-help-title{
|
||||
font-weight: bold;
|
||||
|
||||
height: 19px;
|
||||
font-size: 14px;
|
||||
color: rgba(0, 0, 0, 0.8);
|
||||
line-height: 19px;
|
||||
}
|
||||
|
||||
.jl-small-title:hover p{
|
||||
color: rgba(0, 0, 0, 1) !important;
|
||||
}
|
||||
.jl-small-title:hover span{
|
||||
color: rgba(0, 0, 0, 1) !important;
|
||||
}
|
||||
.jl-small-title{
|
||||
display: flex;
|
||||
font-size: 12px;
|
||||
margin-bottom: 12px;
|
||||
cursor: pointer;
|
||||
}
|
||||
.jl-small-title span{
|
||||
color: rgba(0, 0, 0, 0.4);
|
||||
margin-right:12px;
|
||||
}
|
||||
.jl-small-title p{
|
||||
color: rgba(0, 0, 0, 0.7);
|
||||
flex: 1;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
.jl-advertisement .img{
|
||||
width: 198px;
|
||||
height: 120px;
|
||||
background-color: #e3e3e3;
|
||||
border-radius: 4px;
|
||||
}
|
||||
|
||||
.jl-user{
|
||||
display: flex;
|
||||
align-items: center;
|
||||
font-size: 12px;
|
||||
}
|
||||
.jl-user .jl-head-portrait{
|
||||
width: 56px;
|
||||
height: 56px;
|
||||
border-radius: 50%;
|
||||
border: 1px solid #fdfef8;
|
||||
text-align: center;
|
||||
line-height: 44px;
|
||||
background-color: #fdfef8;
|
||||
margin-right: 8px;
|
||||
}
|
||||
.jl-userInfo{
|
||||
font-size: 15px;
|
||||
line-height: 20px;
|
||||
}
|
||||
.jl-userInfo .name{
|
||||
color: rgba(0, 0, 0, 0.7);
|
||||
}
|
||||
.jl-userInfo .tip{
|
||||
color: #419EFF;
|
||||
}
|
||||
|
||||
.jl-help-code{
|
||||
display: flex;
|
||||
align-items: center;
|
||||
flex-flow: column;
|
||||
}
|
||||
.jl-help-code .img{
|
||||
background: url("/manage/img/kefu.jpg") no-repeat;
|
||||
background-size: 126px 126px;
|
||||
width: 126px;
|
||||
height: 126px;
|
||||
}
|
||||
.jl-help-code-tips{
|
||||
width: 120px;
|
||||
height: 17px;
|
||||
font-size: 12px;
|
||||
font-weight: 400;
|
||||
color: rgba(0, 0, 0, 0.4);
|
||||
line-height: 17px;
|
||||
/*margin-bottom: 20px;*/
|
||||
margin-top: 16px;
|
||||
}
|
||||
|
||||
.jl-help-phone{
|
||||
display: flex;
|
||||
align-items: center;
|
||||
font-size: 20px;
|
||||
font-weight: 600;
|
||||
color: rgba(0, 0, 0, 0.8);
|
||||
}
|
||||
.jl-help-phone img{
|
||||
margin-right: 14px;
|
||||
}
|
||||
|
||||
.jl-help-time{
|
||||
font-size: 12px;
|
||||
color: rgba(0, 0, 0, 0.4);
|
||||
line-height: 16px;
|
||||
margin-top: 9px;
|
||||
}
|
||||
|
||||
</style>
|
||||
@@ -1,151 +0,0 @@
|
||||
<template>
|
||||
<div>
|
||||
<div class="jl-tabs" ref="body">
|
||||
<span
|
||||
v-for="(value, index) in data"
|
||||
ref="tab"
|
||||
:key="index"
|
||||
:class="{ 'jl-tab': true, active: active === index }"
|
||||
@click="change(index, $event)"
|
||||
>{{ value }}</span
|
||||
>
|
||||
<div :class="lineClass" :style="lineStyle"></div>
|
||||
</div>
|
||||
<div class="jl-tabs float" v-show="fixedShow">
|
||||
<span
|
||||
v-for="(value, index) in data"
|
||||
:key="index"
|
||||
class="jl-tab"
|
||||
:class="{ 'jl-tab': true, active: active === index }"
|
||||
@click="change(index, $event)"
|
||||
ref="tab"
|
||||
>{{ value }}</span
|
||||
>
|
||||
<div :class="lineClass" :style="lineStyle"></div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
props: {
|
||||
fixedShow: {
|
||||
type: Boolean,
|
||||
default: false,
|
||||
},
|
||||
maxFixed: { type: Number },
|
||||
data: {
|
||||
type: Array,
|
||||
default() {
|
||||
return [];
|
||||
},
|
||||
},
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
active: 0,
|
||||
lineWidth: 0,
|
||||
lineLeft: 0,
|
||||
mounted: false,
|
||||
activeStatus: false
|
||||
};
|
||||
},
|
||||
mounted() {
|
||||
this.initLine();
|
||||
},
|
||||
computed: {
|
||||
lineStyle() {
|
||||
return { width: `${this.lineWidth}px`, left: `${this.lineLeft}px` };
|
||||
},
|
||||
lineClass() {
|
||||
return {
|
||||
line: true,
|
||||
mounted: this.mounted,
|
||||
};
|
||||
},
|
||||
},
|
||||
methods: {
|
||||
initLine() {
|
||||
if (this.data.length > 0) {
|
||||
this.$nextTick(() => {
|
||||
this.lineWidth = this.$refs.tab[0].clientWidth;
|
||||
this.lineLeft = this.$refs.tab[0].offsetLeft;
|
||||
setTimeout(() => {
|
||||
this.mounted = true;
|
||||
}, 20);
|
||||
});
|
||||
}
|
||||
},
|
||||
change(val) {
|
||||
if (val === this.active) {
|
||||
return;
|
||||
}
|
||||
this.active = val;
|
||||
this.activeStatus = true
|
||||
setTimeout(() => {
|
||||
this.activeStatus = false
|
||||
}, 500)
|
||||
this.$emit("change", this.data[val]);
|
||||
if (this.fixed && this.fixedShow) {
|
||||
this.$refs.body.scrollIntoView(true);
|
||||
}
|
||||
},
|
||||
tabNum(index){
|
||||
if(this.active === index)return
|
||||
this.active = index;
|
||||
}
|
||||
},
|
||||
watch: {
|
||||
data() {
|
||||
this.initLine();
|
||||
},
|
||||
active(val){
|
||||
const tab = this.$refs.tab[val]
|
||||
this.lineWidth = tab.clientWidth;
|
||||
this.lineLeft = tab.offsetLeft;
|
||||
}
|
||||
},
|
||||
};
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
.jl-tabs {
|
||||
width: 1000px;
|
||||
background-color: #fff;
|
||||
text-align: center;
|
||||
margin-bottom: 20px;
|
||||
position: relative;
|
||||
}
|
||||
.jl-tab {
|
||||
padding: 20px 21px 18px 21px;
|
||||
display: inline-block;
|
||||
font-size: 18px;
|
||||
letter-spacing: 0;
|
||||
text-align: center;
|
||||
color: #333333;
|
||||
margin-right: 45px;
|
||||
cursor: pointer;
|
||||
}
|
||||
.jl-tab.active {
|
||||
color: #5aa0fa;
|
||||
}
|
||||
.jl-tabs .jl-tab:last-of-type {
|
||||
margin-right: 0px;
|
||||
}
|
||||
.jl-tabs .line {
|
||||
height: 4px;
|
||||
background: #5aa0fa;
|
||||
position: absolute;
|
||||
bottom: 0;
|
||||
}
|
||||
.jl-tabs .line.mounted {
|
||||
transition: left 0.5s;
|
||||
}
|
||||
.jl-tabs.float {
|
||||
position: fixed;
|
||||
top: 0;
|
||||
z-index: 2000;
|
||||
background: #ffffff;
|
||||
box-shadow: 0 0 10px 0 rgba(0, 0, 0, 0.15);
|
||||
}
|
||||
</style>
|
||||
@@ -1,220 +0,0 @@
|
||||
<template>
|
||||
<div class="app-container">
|
||||
<el-autocomplete
|
||||
v-model="addressLocation"
|
||||
style="width:100%;"
|
||||
popper-class="autoAddressClass"
|
||||
:fetch-suggestions="querySearchAsync"
|
||||
:trigger-on-focus="false"
|
||||
placeholder="详细地址"
|
||||
clearable="false"
|
||||
@select="handleSelect"
|
||||
:disabled="!isCanEdit"
|
||||
v-show="type!=='view'"
|
||||
@input="addressChangeHandle"
|
||||
>
|
||||
<template slot-scope="{ item }">
|
||||
<div style="overflow:hidden;">
|
||||
<div class="title">{{ item.title }}</div>
|
||||
<span class="address ellipsis">{{ item.address }}</span>
|
||||
</div>
|
||||
</template>
|
||||
</el-autocomplete>
|
||||
|
||||
<div ref="mapContainer" style="width:100%;height:300px;" v-if="isCanEdit" />
|
||||
<div ref="viewMap" style="width:100%;height:300px;" v-else />
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
/* eslint-disable */
|
||||
import { getcoder, querySearch } from "@/api/tenant/map";
|
||||
export default {
|
||||
props: {
|
||||
lat: {
|
||||
type: "string",
|
||||
default: 23.1315381,
|
||||
},
|
||||
lng: {
|
||||
type: "string",
|
||||
default: 113.3324436,
|
||||
},
|
||||
address: String,
|
||||
isCanEdit: Boolean,
|
||||
type: {
|
||||
type: "string",
|
||||
default: "",
|
||||
},
|
||||
},
|
||||
data () {
|
||||
return {
|
||||
map: "", // 地图实例
|
||||
mk: "", // Marker实例
|
||||
map2: "", // 地图实例
|
||||
mk2: "", // Marker实例,
|
||||
addressLocation: this.address,
|
||||
key: "FW3BZ-6JTK6-GCUS5-MZCRR-3GPR5-HJFEI",
|
||||
addressTip: [],
|
||||
};
|
||||
},
|
||||
mounted () {
|
||||
this.initMap();
|
||||
},
|
||||
watch: {},
|
||||
methods: {
|
||||
addressChangeHandle(val){
|
||||
if(val == ""){
|
||||
this.$emit('addressDel',"删除了地址数据")
|
||||
}
|
||||
|
||||
},
|
||||
// 初始化地图
|
||||
initMap () {
|
||||
var that = this;
|
||||
|
||||
if (this.isCanEdit) {
|
||||
var point = new qq.maps.LatLng(this.lat, this.lng);
|
||||
// 1、挂载第一张地图
|
||||
this.map = new qq.maps.Map(this.$refs.mapContainer, {
|
||||
center: point,
|
||||
zoom: 19,
|
||||
//启用缩放控件
|
||||
zoomControl: true,
|
||||
//地图缩放控件参数
|
||||
zoomControlOptions: {
|
||||
position: qq.maps.ControlPosition.TOP_LEFT,
|
||||
},
|
||||
//地图比例尺控件,若为false则不显示比例尺控件
|
||||
scaleControl: false,
|
||||
});
|
||||
|
||||
// 3、设置图像标注并绑定拖拽标注结束后事件
|
||||
this.mk = new qq.maps.Marker({
|
||||
position: point,
|
||||
draggable: true,
|
||||
map: that.map,
|
||||
});
|
||||
// 绑定拖拽标注结束后事件
|
||||
qq.maps.event.addListener(this.mk, "dragend", function (e) {
|
||||
that.getAddrByPoint(e.latLng);
|
||||
});
|
||||
//6、浏览器定位
|
||||
if (this.type === "add") {
|
||||
this.geolocation();
|
||||
}
|
||||
// 7、绑定点击地图任意点事件
|
||||
qq.maps.event.addListener(this.map, "click", function (e) {
|
||||
that.getAddrByPoint(e.latLng);
|
||||
});
|
||||
} else {
|
||||
var point2 = new qq.maps.LatLng(this.lat, this.lng);
|
||||
// 1、挂载第二张地图
|
||||
this.map2 = new qq.maps.Map(this.$refs.viewMap, {
|
||||
center: point2,
|
||||
zoom: 19,
|
||||
//地图缩放控件参数
|
||||
zoomControlOptions: {
|
||||
position: qq.maps.ControlPosition.TOP_LEFT,
|
||||
},
|
||||
//地图比例尺控件,若为false则不显示比例尺控件
|
||||
scaleControl: false,
|
||||
});
|
||||
// 2、设置图像标注并绑定拖拽标注结束后事件
|
||||
this.mk2 = new qq.maps.Marker({
|
||||
position: point2,
|
||||
draggable: false,
|
||||
map: that.map2,
|
||||
});
|
||||
}
|
||||
},
|
||||
// 浏览器定位函数
|
||||
geolocation () {
|
||||
var that = this;
|
||||
var geolocation = new qq.maps.Geolocation(
|
||||
"FW3BZ-6JTK6-GCUS5-MZCRR-3GPR5-HJFEI",
|
||||
"jobslink 企业"
|
||||
);
|
||||
geolocation.getLocation(this.showPosition, this.showErr, {
|
||||
timeout: 20000,
|
||||
failTipFlag: true,
|
||||
});
|
||||
},
|
||||
showPosition (position) {
|
||||
this.getAddrByPoint({
|
||||
lat: position.lat,
|
||||
lng: position.lng,
|
||||
});
|
||||
},
|
||||
showErr () {
|
||||
console.log("定位失败!");
|
||||
},
|
||||
// // 2、逆地址解析函数
|
||||
getAddrByPoint (point) {
|
||||
var currentPoint = new qq.maps.LatLng(point.lat, point.lng);
|
||||
var that = this;
|
||||
var location = point.lat + "," + point.lng;
|
||||
getcoder(location, encodeURI(this.key), 0).then((res) => {
|
||||
that.mk.setPosition(currentPoint);
|
||||
that.map.panTo(currentPoint);
|
||||
let obj = {
|
||||
address: res.data.result.address,
|
||||
lng: point.lng,
|
||||
lat: point.lat,
|
||||
};
|
||||
that.addressLocation = obj.address
|
||||
that.$emit("addAddress", obj);
|
||||
});
|
||||
},
|
||||
async querySearchAsync (queryString, cb) {
|
||||
await querySearch(queryString, encodeURI(this.key)).then((res) => {
|
||||
if (res.data.status === 0) {
|
||||
this.addressTip = res.data.data;
|
||||
}
|
||||
});
|
||||
var results = this.addressTip;
|
||||
|
||||
clearTimeout(this.timeout);
|
||||
this.timeout = setTimeout(() => {
|
||||
cb(results);
|
||||
}, 1000 * Math.random());
|
||||
},
|
||||
// 8-2、选择地址
|
||||
handleSelect (item) {
|
||||
this.addressLocation = item.address;
|
||||
var point = new qq.maps.LatLng(item.location.lat, item.location.lng);
|
||||
this.mk.setPosition(point);
|
||||
this.map.panTo(point);
|
||||
let obj = {
|
||||
title: item.title,
|
||||
address: item.address,
|
||||
lng: item.location.lng,
|
||||
lat: item.location.lat,
|
||||
};
|
||||
this.$emit("addAddress", obj);
|
||||
},
|
||||
},
|
||||
};
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.autoAddressClass {
|
||||
li {
|
||||
i.el-icon-search {
|
||||
margin-top: 11px;
|
||||
}
|
||||
.mgr10 {
|
||||
margin-right: 10px;
|
||||
}
|
||||
.title {
|
||||
text-overflow: ellipsis;
|
||||
overflow: hidden;
|
||||
}
|
||||
.address {
|
||||
line-height: 1;
|
||||
font-size: 12px;
|
||||
color: #b4b4b4;
|
||||
margin-bottom: 5px;
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
@@ -1,29 +0,0 @@
|
||||
<template>
|
||||
<el-dialog append-to-body title="提示" :visible.sync="dialogVisible" width="30%" :before-close="handleClose">
|
||||
<span class="noSignText">您还未开通电子签章功能,请前往“农民工用工管理”的“电子签章管理”中申请开通电子签章功能</span>
|
||||
<span slot="footer" class="dialog-footer">
|
||||
<el-button type="primary" @click="dialogVisible = false">确 定</el-button>
|
||||
</span>
|
||||
</el-dialog>
|
||||
</template>
|
||||
<script>
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
dialogVisible: false,
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
open() {
|
||||
this.dialogVisible = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
<style>
|
||||
.noSignText {
|
||||
text-align: center;
|
||||
font-size: 15px;
|
||||
font-weight: 500;
|
||||
}
|
||||
</style>
|
||||
@@ -1,147 +0,0 @@
|
||||
<template>
|
||||
<basic-container>
|
||||
<el-drawer title="个人简历" append-to-body :visible.sync="drawer" size="60%">
|
||||
<div class="page" v-loading="loading">
|
||||
<div class="title">
|
||||
<b style="font-size:16px;">基础信息</b>
|
||||
</div>
|
||||
|
||||
<div class="basic-info">
|
||||
<div class="avatar">
|
||||
<img src="/manage/svg/avatar.svg" style="display:inline-block;width:100%;height:auto;" />
|
||||
<i
|
||||
class="iconfont iconnan"
|
||||
style="position:absolute;top:5px;right:5px;"
|
||||
v-if="data.age===1"
|
||||
></i>
|
||||
<i class="iconfont iconnv" style="position:absolute;top:5px;right:5px;" v-else></i>
|
||||
</div>
|
||||
|
||||
<table>
|
||||
<tr>
|
||||
<td>{{data.realName}}</td>
|
||||
<td>{{data.age}}岁</td>
|
||||
<td style="padding-left:120px">身份</td>
|
||||
<td>灵活用工</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>联系方式</td>
|
||||
<td>{{data.telphone}}</td>
|
||||
<td style="padding-left:120px">期望地点</td>
|
||||
<td>{{getCity(data.cityId)}}</td>
|
||||
</tr>
|
||||
</table>
|
||||
</div>
|
||||
|
||||
<div class="title">
|
||||
<b>期望行业</b>
|
||||
</div>
|
||||
<div class="content">
|
||||
<el-tag v-for="(item,index) in data.list" :key="index">{{item.trade}}</el-tag>
|
||||
</div>
|
||||
|
||||
<div class="title">
|
||||
<b>具备技能</b>
|
||||
</div>
|
||||
<div class="content">
|
||||
<el-tag type="success" v-for="(item,index) in data.list" :key="index">{{item.worktypes}}</el-tag>
|
||||
</div>
|
||||
|
||||
<div class="title">
|
||||
<b>技能水平</b>
|
||||
</div>
|
||||
<div class="content">
|
||||
<el-tag type="danger" v-for="(item,index) in data.list" :key="index">{{item.skills}}</el-tag>
|
||||
</div>
|
||||
</div>
|
||||
</el-drawer>
|
||||
</basic-container>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
|
||||
import { getDetail } from "@/api/tenant/resume";
|
||||
// import {mapGetters} from "vuex";
|
||||
|
||||
export default {
|
||||
comments: {
|
||||
|
||||
},
|
||||
components: {
|
||||
},
|
||||
data () {
|
||||
return {
|
||||
userId: '',
|
||||
loading: false,
|
||||
drawer: false,
|
||||
data: {}
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
},
|
||||
watch: {
|
||||
|
||||
},
|
||||
methods: {
|
||||
getCity (val) {
|
||||
if (val) {
|
||||
return this.$store.getters.getAreaParents(val)[0].label + this.$store.getters.getAreaParents(val)[1].label
|
||||
}
|
||||
},
|
||||
/*打开drawer*/
|
||||
openDialog (row) {
|
||||
this.userId = row.userId;
|
||||
this.drawer = true;
|
||||
this.getDetail();
|
||||
},
|
||||
/*加载数据*/
|
||||
getDetail () {
|
||||
this.loading = true;
|
||||
getDetail(this.userId).then(res => {
|
||||
const data = res.data.data;
|
||||
this.data = data;
|
||||
this.loading = false;
|
||||
});
|
||||
}
|
||||
|
||||
}
|
||||
};
|
||||
</script>
|
||||
<style scoped>
|
||||
.page {
|
||||
/* padding: 0 30px; */
|
||||
}
|
||||
.page .title {
|
||||
margin-bottom: 20px;
|
||||
font-size: 16px;
|
||||
}
|
||||
|
||||
.page .basic-info {
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
justify-content: flex-start;
|
||||
align-items: center;
|
||||
flex-wrap: wrap;
|
||||
margin-bottom: 30px;
|
||||
}
|
||||
|
||||
.page .basic-info .avatar {
|
||||
position: relative;
|
||||
width: 120px;
|
||||
margin-right: 100px;
|
||||
}
|
||||
.page .basic-info table {
|
||||
border-collapse: separate;
|
||||
border-spacing: 0px 20px;
|
||||
}
|
||||
.page .basic-info table tr td {
|
||||
min-width: 100px;
|
||||
}
|
||||
|
||||
.page .content {
|
||||
margin-bottom: 30px;
|
||||
}
|
||||
.el-tag {
|
||||
margin-right: 10px;
|
||||
}
|
||||
</style>
|
||||
@@ -1,178 +0,0 @@
|
||||
<template>
|
||||
<div>
|
||||
<el-tag
|
||||
class="tag-select-tag"
|
||||
:key="index"
|
||||
v-for="(tag,index) in value"
|
||||
:disable-transitions="true"
|
||||
closable
|
||||
@close="removeSkill(tag[prop.value], true)"
|
||||
size="medium"
|
||||
>{{ tag[prop.label] }}</el-tag
|
||||
>
|
||||
<slot name="dialog-btn" v-if="canSelect">
|
||||
<el-button class="button-new-tag" size="small" @click="showSelect(true)"
|
||||
>+ 选择{{ name }}</el-button
|
||||
>
|
||||
</slot>
|
||||
<el-dialog
|
||||
:title="name"
|
||||
:visible.sync="dialogVisible"
|
||||
width="30%"
|
||||
:close-on-click-modal="false"
|
||||
:close-on-press-escape="false"
|
||||
:append-to-body="true"
|
||||
v-loading="loading"
|
||||
>
|
||||
<div>
|
||||
<el-tag
|
||||
class="tag-select-tag"
|
||||
:key="key"
|
||||
v-for="(value, key) in selected"
|
||||
closable
|
||||
type="primary"
|
||||
:disable-transitions="true"
|
||||
@close="removeSkill(key)"
|
||||
size="medium"
|
||||
>{{ value }}</el-tag
|
||||
>
|
||||
</div>
|
||||
<div class="tag-select-tip">请选择您所需的{{ name }}</div>
|
||||
<div class="tag-select-searchinp">
|
||||
<el-input
|
||||
v-model="search"
|
||||
placeholder="搜索您想要的标签"
|
||||
clearable=""
|
||||
></el-input>
|
||||
</div>
|
||||
<div>
|
||||
<el-tag
|
||||
class="tag-select-tag"
|
||||
type="info"
|
||||
:disable-transitions="true"
|
||||
size="medium"
|
||||
effect="plain"
|
||||
v-for="(tag,index) in noSelect"
|
||||
:key="index"
|
||||
@click="editSkill(tag)"
|
||||
>{{ tag[prop.label] }}</el-tag
|
||||
>
|
||||
</div>
|
||||
<span slot="footer" class="dialog-footer">
|
||||
<el-button
|
||||
icon="el-icon-circle-plus-outline"
|
||||
type="primary"
|
||||
@click="submit"
|
||||
>保 存</el-button
|
||||
>
|
||||
<el-button icon="el-icon-circle-close" @click="dialogVisible = false"
|
||||
>取 消</el-button
|
||||
>
|
||||
</span>
|
||||
</el-dialog>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import _ from "lodash";
|
||||
|
||||
export default {
|
||||
name: "tagSelect",
|
||||
props: {
|
||||
value: {
|
||||
type: Array,
|
||||
default() {
|
||||
return [];
|
||||
},
|
||||
},
|
||||
name: String,
|
||||
data: {
|
||||
type: Array,
|
||||
default() {
|
||||
return [];
|
||||
},
|
||||
},
|
||||
canSelect: { type: Boolean, default: true },
|
||||
loading: Boolean,
|
||||
prop: {
|
||||
type: Object,
|
||||
default() {
|
||||
return {
|
||||
label: "label",
|
||||
value: "value",
|
||||
};
|
||||
},
|
||||
},
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
search: "",
|
||||
dialogVisible: false,
|
||||
selected: {},
|
||||
};
|
||||
},
|
||||
computed: {
|
||||
noSelect() {
|
||||
let data = this.data.filter((item) => {
|
||||
return !this.selected.hasOwnProperty(item[this.prop.value]);
|
||||
});
|
||||
if (this.search) {
|
||||
data = this.data.filter((item) => {
|
||||
return (
|
||||
item[this.prop.label]
|
||||
.toLowerCase()
|
||||
.indexOf(this.search.toLowerCase()) > -1
|
||||
);
|
||||
});
|
||||
}
|
||||
return data;
|
||||
},
|
||||
},
|
||||
watch: {},
|
||||
methods: {
|
||||
/*技能*/
|
||||
editSkill(tag) {
|
||||
this.$set(this.selected, tag[this.prop.value], tag[this.prop.label]);
|
||||
},
|
||||
removeSkill(key, save) {
|
||||
this.$delete(this.selected, key);
|
||||
if (save) {
|
||||
this.submit();
|
||||
}
|
||||
},
|
||||
submit() {
|
||||
const res = [];
|
||||
for (const key in this.selected) {
|
||||
const item = {};
|
||||
item[this.prop.label] = this.selected[key];
|
||||
item[this.prop.value] = key;
|
||||
res.push(item);
|
||||
}
|
||||
this.$emit("input", res);
|
||||
this.dialogVisible = false;
|
||||
},
|
||||
showSelect(flag) {
|
||||
const value = _.cloneDeep(this.value || []);
|
||||
let selected = {};
|
||||
value.forEach((element) => {
|
||||
selected[element[this.prop.value]] = element[this.prop.label];
|
||||
});
|
||||
this.selected = selected;
|
||||
this.dialogVisible = flag;
|
||||
},
|
||||
},
|
||||
created(){
|
||||
this.showSelect();
|
||||
},
|
||||
};
|
||||
</script>
|
||||
<style>
|
||||
.tag-select-tag {
|
||||
margin: 0 5px 5px 0;
|
||||
cursor: pointer;
|
||||
}
|
||||
.tag-select-tip,
|
||||
.tag-select-searchinp {
|
||||
margin-bottom: 5px;
|
||||
}
|
||||
</style>
|
||||
@@ -1,25 +0,0 @@
|
||||
<template>
|
||||
<el-tooltip effect="dark" placement="right">
|
||||
<div slot="content">
|
||||
1.选择相应的搜索时间类型
|
||||
<br/>
|
||||
2.选择相应的搜索时间范围
|
||||
<br>
|
||||
3.点击“搜索”按钮查看详情
|
||||
</div>
|
||||
<img src="./tip.png" height="26" width="26" class="toolTipImg"/>
|
||||
</el-tooltip>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
name: "index"
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
.toolTipImg{
|
||||
margin-bottom: -5px;
|
||||
margin-right: 10px;
|
||||
}
|
||||
</style>
|
||||
Binary file not shown.
|
Before Width: | Height: | Size: 2.7 KiB |
File diff suppressed because one or more lines are too long
@@ -1,252 +0,0 @@
|
||||
<template>
|
||||
<div style="position: relative">
|
||||
<div class="verify-img-out">
|
||||
<div
|
||||
class="verify-img-panel"
|
||||
:style="{'width': setSize.imgWidth,
|
||||
'height': setSize.imgHeight,
|
||||
'background-size' : setSize.imgWidth + ' '+ setSize.imgHeight,
|
||||
'margin-bottom': vSpace + 'px'}"
|
||||
>
|
||||
<div class="verify-refresh" style="z-index:3" @click="refresh" v-show="showRefresh">
|
||||
<i class="iconfont icon-refresh"></i>
|
||||
</div>
|
||||
<img
|
||||
:src="'data:image/png;base64,'+pointBackImgBase"
|
||||
ref="canvas"
|
||||
alt
|
||||
style="width:100%;height:100%;display:block"
|
||||
@click="bindingClick?canvasClick($event):undefined"
|
||||
/>
|
||||
|
||||
<div
|
||||
v-for="(tempPoint, index) in tempPoints"
|
||||
:key="index"
|
||||
class="point-area"
|
||||
:style="{
|
||||
'background-color':'#1abd6c',
|
||||
color:'#fff',
|
||||
'z-index':9999,
|
||||
width:'20px',
|
||||
height:'20px',
|
||||
'text-align':'center',
|
||||
'line-height':'20px',
|
||||
'border-radius': '50%',
|
||||
position:'absolute',
|
||||
top:parseInt(tempPoint.y-10) + 'px',
|
||||
left:parseInt(tempPoint.x-10) + 'px'
|
||||
}"
|
||||
>{{index + 1}}</div>
|
||||
</div>
|
||||
</div>
|
||||
<!-- 'height': this.barSize.height, -->
|
||||
<div
|
||||
class="verify-bar-area"
|
||||
:style="{'width': setSize.imgWidth,
|
||||
'color': this.barAreaColor,
|
||||
'border-color': this.barAreaBorderColor,
|
||||
'line-height':this.barSize.height}"
|
||||
>
|
||||
<span class="verify-msg">{{text}}</span>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
<script type="text/babel">
|
||||
/**
|
||||
* VerifyPoints
|
||||
* @description 点选
|
||||
* */
|
||||
import { resetSize } from './../utils/util'
|
||||
import { aesEncrypt } from "./../utils/ase"
|
||||
import { reqGet, reqCheck } from "./../api/index"
|
||||
|
||||
export default {
|
||||
name: 'VerifyPoints',
|
||||
props: {
|
||||
//弹出式pop,固定fixed
|
||||
mode: {
|
||||
type: String,
|
||||
default: 'fixed'
|
||||
},
|
||||
captchaType: {
|
||||
type: String,
|
||||
},
|
||||
//间隔
|
||||
vSpace: {
|
||||
type: Number,
|
||||
default: 5
|
||||
},
|
||||
imgSize: {
|
||||
type: Object,
|
||||
default () {
|
||||
return {
|
||||
width: '310px',
|
||||
height: '155px'
|
||||
}
|
||||
}
|
||||
},
|
||||
barSize: {
|
||||
type: Object,
|
||||
default () {
|
||||
return {
|
||||
width: '310px',
|
||||
height: '40px'
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
data () {
|
||||
return {
|
||||
secretKey: '', //后端返回的ase加密秘钥
|
||||
checkNum: 3, //默认需要点击的字数
|
||||
fontPos: [], //选中的坐标信息
|
||||
checkPosArr: [], //用户点击的坐标
|
||||
num: 1, //点击的记数
|
||||
pointBackImgBase: '', //后端获取到的背景图片
|
||||
poinTextList: [], //后端返回的点击字体顺序
|
||||
backToken: '', //后端返回的token值
|
||||
setSize: {
|
||||
imgHeight: 0,
|
||||
imgWidth: 0,
|
||||
barHeight: 0,
|
||||
barWidth: 0
|
||||
},
|
||||
tempPoints: [],
|
||||
text: '',
|
||||
barAreaColor: undefined,
|
||||
barAreaBorderColor: undefined,
|
||||
showRefresh: true,
|
||||
bindingClick: true
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
resetSize () {
|
||||
return resetSize
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
init () {
|
||||
//加载页面
|
||||
this.fontPos.splice(0, this.fontPos.length)
|
||||
this.checkPosArr.splice(0, this.checkPosArr.length)
|
||||
this.num = 1
|
||||
this.getPictrue();
|
||||
this.$nextTick(() => {
|
||||
this.setSize = this.resetSize(this) //重新设置宽度高度
|
||||
this.$parent.$emit('ready', this)
|
||||
})
|
||||
},
|
||||
canvasClick (e) {
|
||||
this.checkPosArr.push(this.getMousePos(this.$refs.canvas, e));
|
||||
if (this.num == this.checkNum) {
|
||||
this.num = this.createPoint(this.getMousePos(this.$refs.canvas, e));
|
||||
//按比例转换坐标值
|
||||
this.checkPosArr = this.pointTransfrom(this.checkPosArr, this.setSize);
|
||||
//等创建坐标执行完
|
||||
setTimeout(() => {
|
||||
// var flag = this.comparePos(this.fontPos, this.checkPosArr);
|
||||
//发送后端请求
|
||||
var captchaVerification = this.secretKey ? aesEncrypt(this.backToken + '---' + JSON.stringify(this.checkPosArr), this.secretKey) : this.backToken + '---' + JSON.stringify(this.checkPosArr)
|
||||
let data = {
|
||||
captchaType: this.captchaType,
|
||||
"pointJson": this.secretKey ? aesEncrypt(JSON.stringify(this.checkPosArr), this.secretKey) : JSON.stringify(this.checkPosArr),
|
||||
"token": this.backToken
|
||||
}
|
||||
reqCheck(data).then(res => {
|
||||
if (res.repCode == "0000") {
|
||||
this.barAreaColor = '#4cae4c'
|
||||
this.barAreaBorderColor = '#5cb85c'
|
||||
this.text = '验证成功'
|
||||
this.bindingClick = false
|
||||
if (this.mode == 'pop') {
|
||||
setTimeout(() => {
|
||||
this.$parent.clickShow = false;
|
||||
this.refresh();
|
||||
}, 1500)
|
||||
}
|
||||
this.$parent.$emit('success', { captchaVerification })
|
||||
} else {
|
||||
this.$parent.$emit('error', this)
|
||||
this.barAreaColor = '#d9534f'
|
||||
this.barAreaBorderColor = '#d9534f'
|
||||
this.text = '验证失败'
|
||||
setTimeout(() => {
|
||||
this.refresh();
|
||||
}, 700);
|
||||
}
|
||||
})
|
||||
}, 400);
|
||||
}
|
||||
if (this.num < this.checkNum) {
|
||||
this.num = this.createPoint(this.getMousePos(this.$refs.canvas, e));
|
||||
}
|
||||
},
|
||||
|
||||
//获取坐标
|
||||
getMousePos: function (obj, e) {
|
||||
var x = e.offsetX
|
||||
var y = e.offsetY
|
||||
return { x, y }
|
||||
},
|
||||
//创建坐标点
|
||||
createPoint: function (pos) {
|
||||
this.tempPoints.push(Object.assign({}, pos))
|
||||
return ++this.num;
|
||||
},
|
||||
refresh: function () {
|
||||
this.tempPoints.splice(0, this.tempPoints.length)
|
||||
this.barAreaColor = '#000'
|
||||
this.barAreaBorderColor = '#ddd'
|
||||
this.bindingClick = true
|
||||
this.fontPos.splice(0, this.fontPos.length)
|
||||
this.checkPosArr.splice(0, this.checkPosArr.length)
|
||||
this.num = 1
|
||||
this.getPictrue();
|
||||
this.text = '验证失败'
|
||||
this.showRefresh = true
|
||||
},
|
||||
|
||||
// 请求背景图片和验证图片
|
||||
getPictrue () {
|
||||
let data = {
|
||||
captchaType: this.captchaType
|
||||
}
|
||||
reqGet(data).then(res => {
|
||||
if (res.repCode == "0000") {
|
||||
this.pointBackImgBase = res.repData.originalImageBase64
|
||||
this.backToken = res.repData.token
|
||||
this.secretKey = res.repData.secretKey
|
||||
this.poinTextList = res.repData.wordList
|
||||
this.text = '请依次点击【' + this.poinTextList.join(",") + '】'
|
||||
} else {
|
||||
this.text = res.repMsg;
|
||||
}
|
||||
})
|
||||
},
|
||||
//坐标转换函数
|
||||
pointTransfrom (pointArr, imgSize) {
|
||||
var newPointArr = pointArr.map(p => {
|
||||
let x = Math.round(310 * p.x / parseInt(imgSize.imgWidth))
|
||||
let y = Math.round(155 * p.y / parseInt(imgSize.imgHeight))
|
||||
return { x, y }
|
||||
})
|
||||
return newPointArr
|
||||
}
|
||||
},
|
||||
watch: {
|
||||
// type变化则全面刷新
|
||||
type: {
|
||||
immediate: true,
|
||||
handler () {
|
||||
this.init()
|
||||
}
|
||||
}
|
||||
},
|
||||
mounted () {
|
||||
// 禁止拖拽
|
||||
this.$el.onselectstart = function () {
|
||||
return false
|
||||
}
|
||||
},
|
||||
}
|
||||
</script>
|
||||
@@ -1,375 +0,0 @@
|
||||
<template>
|
||||
<div style="position: relative;">
|
||||
<div
|
||||
v-if="type === '2'"
|
||||
class="verify-img-out"
|
||||
:style="{height: (parseInt(setSize.imgHeight) + vSpace) + 'px'}"
|
||||
>
|
||||
<div
|
||||
class="verify-img-panel"
|
||||
:style="{width: setSize.imgWidth,
|
||||
height: setSize.imgHeight,}"
|
||||
>
|
||||
<img
|
||||
:src="'data:image/png;base64,'+backImgBase"
|
||||
alt
|
||||
style="width:100%;height:100%;display:block"
|
||||
/>
|
||||
<div class="verify-refresh" @click="refresh" v-show="showRefresh">
|
||||
<i class="iconfont icon-refresh"></i>
|
||||
</div>
|
||||
<transition name="tips">
|
||||
<span
|
||||
class="verify-tips"
|
||||
v-if="tipWords"
|
||||
:class="passFlag ?'suc-bg':'err-bg'"
|
||||
>{{tipWords}}</span>
|
||||
</transition>
|
||||
</div>
|
||||
</div>
|
||||
<!-- 公共部分 -->
|
||||
<div
|
||||
class="verify-bar-area"
|
||||
:style="{width: setSize.imgWidth,
|
||||
height: barSize.height,
|
||||
'line-height':barSize.height}"
|
||||
>
|
||||
<span class="verify-msg" v-text="text"></span>
|
||||
<div
|
||||
class="verify-left-bar"
|
||||
:style="{width: (leftBarWidth!==undefined)?leftBarWidth: barSize.height, height: barSize.height, 'border-color': leftBarBorderColor, transaction: transitionWidth}"
|
||||
>
|
||||
<span class="verify-msg" v-text="finishText"></span>
|
||||
<div
|
||||
class="verify-move-block"
|
||||
@touchstart="start"
|
||||
@mousedown="start"
|
||||
:style="{width: barSize.height, height: barSize.height, 'background-color': moveBlockBackgroundColor, left: moveBlockLeft, transition: transitionLeft}"
|
||||
>
|
||||
<i :class="['verify-icon iconfont', iconClass]" :style="{color: iconColor}"></i>
|
||||
<div
|
||||
v-if="type === '2'"
|
||||
class="verify-sub-block"
|
||||
:style="{'width':Math.floor(parseInt(setSize.imgWidth)*47/310)+ 'px',
|
||||
'height': setSize.imgHeight,
|
||||
'top':'-' + (parseInt(setSize.imgHeight) + vSpace) + 'px',
|
||||
'background-size': setSize.imgWidth + ' ' + setSize.imgHeight,
|
||||
}"
|
||||
>
|
||||
<img
|
||||
:src="'data:image/png;base64,'+blockBackImgBase"
|
||||
alt
|
||||
style="width:100%;height:100%;display:block"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
<script type="text/babel">
|
||||
/**
|
||||
* VerifySlide
|
||||
* @description 滑块
|
||||
* */
|
||||
import { aesEncrypt } from "../utils/ase"
|
||||
import { resetSize } from '../utils/util'
|
||||
import { reqGet, reqCheck } from "../api/index"
|
||||
|
||||
// "captchaType":"blockPuzzle",
|
||||
/* eslint-disable */
|
||||
export default {
|
||||
name: 'VerifySlide',
|
||||
props: {
|
||||
captchaType: {
|
||||
type: String,
|
||||
},
|
||||
type: {
|
||||
type: String,
|
||||
default: '1'
|
||||
},
|
||||
//弹出式pop,固定fixed
|
||||
mode: {
|
||||
type: String,
|
||||
default: 'fixed'
|
||||
},
|
||||
vSpace: {
|
||||
type: Number,
|
||||
default: 5
|
||||
},
|
||||
explain: {
|
||||
type: String,
|
||||
default: '向右滑动完成验证'
|
||||
},
|
||||
imgSize: {
|
||||
type: Object,
|
||||
default () {
|
||||
return {
|
||||
width: '310px',
|
||||
height: '155px'
|
||||
}
|
||||
}
|
||||
},
|
||||
blockSize: {
|
||||
type: Object,
|
||||
default () {
|
||||
return {
|
||||
width: '50px',
|
||||
height: '50px'
|
||||
}
|
||||
}
|
||||
},
|
||||
barSize: {
|
||||
type: Object,
|
||||
default () {
|
||||
return {
|
||||
width: '310px',
|
||||
height: '40px'
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
data () {
|
||||
return {
|
||||
secretKey: '', //后端返回的加密秘钥 字段
|
||||
passFlag: '', //是否通过的标识
|
||||
backImgBase: '', //验证码背景图片
|
||||
blockBackImgBase: '', //验证滑块的背景图片
|
||||
backToken: "", //后端返回的唯一token值
|
||||
startMoveTime: "", //移动开始的时间
|
||||
endMovetime: '', //移动结束的时间
|
||||
tipsBackColor: '', //提示词的背景颜色
|
||||
tipWords: '',
|
||||
text: '',
|
||||
finishText: '',
|
||||
setSize: {
|
||||
imgHeight: 0,
|
||||
imgWidth: 0,
|
||||
barHeight: 0,
|
||||
barWidth: 0
|
||||
},
|
||||
top: 0,
|
||||
left: 0,
|
||||
moveBlockLeft: undefined,
|
||||
leftBarWidth: undefined,
|
||||
// 移动中样式
|
||||
moveBlockBackgroundColor: undefined,
|
||||
leftBarBorderColor: '#ddd',
|
||||
iconColor: undefined,
|
||||
iconClass: 'icon-right',
|
||||
status: false, //鼠标状态
|
||||
isEnd: false, //是够验证完成
|
||||
showRefresh: true,
|
||||
transitionLeft: '',
|
||||
transitionWidth: ''
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
barArea () {
|
||||
return this.$el.querySelector('.verify-bar-area')
|
||||
},
|
||||
resetSize () {
|
||||
return resetSize
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
init () {
|
||||
this.text = this.explain
|
||||
this.getPictrue();
|
||||
this.$nextTick(() => {
|
||||
let setSize = this.resetSize(this) //重新设置宽度高度
|
||||
for (let key in setSize) {
|
||||
this.$set(this.setSize, key, setSize[key])
|
||||
}
|
||||
this.$parent.$emit('ready', this)
|
||||
})
|
||||
|
||||
var _this = this
|
||||
|
||||
window.removeEventListener("touchmove", function (e) {
|
||||
_this.move(e);
|
||||
});
|
||||
window.removeEventListener("mousemove", function (e) {
|
||||
_this.move(e);
|
||||
});
|
||||
|
||||
//鼠标松开
|
||||
window.removeEventListener("touchend", function () {
|
||||
_this.end();
|
||||
});
|
||||
window.removeEventListener("mouseup", function () {
|
||||
_this.end();
|
||||
});
|
||||
|
||||
window.addEventListener("touchmove", function (e) {
|
||||
_this.move(e);
|
||||
});
|
||||
window.addEventListener("mousemove", function (e) {
|
||||
_this.move(e);
|
||||
});
|
||||
|
||||
//鼠标松开
|
||||
window.addEventListener("touchend", function () {
|
||||
_this.end();
|
||||
});
|
||||
window.addEventListener("mouseup", function () {
|
||||
_this.end();
|
||||
});
|
||||
},
|
||||
|
||||
//鼠标按下
|
||||
start: function (e) {
|
||||
e = e || window.event
|
||||
if (!e.touches) { //兼容PC端
|
||||
var x = e.clientX;
|
||||
} else { //兼容移动端
|
||||
var x = e.touches[0].pageX;
|
||||
}
|
||||
this.startLeft = Math.floor(x - this.barArea.getBoundingClientRect().left);
|
||||
this.startMoveTime = +new Date(); //开始滑动的时间
|
||||
if (this.isEnd == false) {
|
||||
this.text = ''
|
||||
this.moveBlockBackgroundColor = '#337ab7'
|
||||
this.leftBarBorderColor = '#337AB7'
|
||||
this.iconColor = '#fff'
|
||||
e.stopPropagation();
|
||||
this.status = true;
|
||||
}
|
||||
},
|
||||
//鼠标移动
|
||||
move: function (e) {
|
||||
e = e || window.event
|
||||
if (this.status && this.isEnd == false) {
|
||||
if (!e.touches) { //兼容PC端
|
||||
var x = e.clientX;
|
||||
} else { //兼容移动端
|
||||
var x = e.touches[0].pageX;
|
||||
}
|
||||
var bar_area_left = this.barArea.getBoundingClientRect().left;
|
||||
var move_block_left = x - bar_area_left //小方块相对于父元素的left值
|
||||
if (move_block_left >= this.barArea.offsetWidth - parseInt(parseInt(this.blockSize.width) / 2) - 2) {
|
||||
move_block_left = this.barArea.offsetWidth - parseInt(parseInt(this.blockSize.width) / 2) - 2;
|
||||
}
|
||||
if (move_block_left <= 0) {
|
||||
move_block_left = parseInt(parseInt(this.blockSize.width) / 2);
|
||||
}
|
||||
//拖动后小方块的left值
|
||||
this.moveBlockLeft = (move_block_left - this.startLeft) + "px"
|
||||
this.leftBarWidth = (move_block_left - this.startLeft) + "px"
|
||||
}
|
||||
},
|
||||
|
||||
//鼠标松开
|
||||
end: function () {
|
||||
this.endMovetime = +new Date();
|
||||
var _this = this;
|
||||
//判断是否重合
|
||||
if (this.status && this.isEnd == false) {
|
||||
var moveLeftDistance = parseInt((this.moveBlockLeft || '').replace('px', ''));
|
||||
moveLeftDistance = moveLeftDistance * 310 / parseInt(this.setSize.imgWidth)
|
||||
let data = {
|
||||
captchaType: this.captchaType,
|
||||
"pointJson": this.secretKey ? aesEncrypt(JSON.stringify({ x: moveLeftDistance, y: 5.0 }), this.secretKey) : JSON.stringify({ x: moveLeftDistance, y: 5.0 }),
|
||||
"token": this.backToken
|
||||
}
|
||||
reqCheck(data).then(res => {
|
||||
if (res.repCode == "0000") {
|
||||
this.moveBlockBackgroundColor = '#5cb85c'
|
||||
this.leftBarBorderColor = '#5cb85c'
|
||||
this.iconColor = '#fff'
|
||||
this.iconClass = 'icon-check'
|
||||
this.showRefresh = false
|
||||
this.isEnd = true;
|
||||
if (this.mode == 'pop') {
|
||||
setTimeout(() => {
|
||||
this.$parent.clickShow = false;
|
||||
this.refresh();
|
||||
}, 1500)
|
||||
}
|
||||
this.passFlag = true
|
||||
this.tipWords = `${((this.endMovetime - this.startMoveTime) / 1000).toFixed(2)}s验证成功`
|
||||
var captchaVerification = this.secretKey ? aesEncrypt(this.backToken + '---' + JSON.stringify({ x: moveLeftDistance, y: 5.0 }), this.secretKey) : this.backToken + '---' + JSON.stringify({ x: moveLeftDistance, y: 5.0 })
|
||||
setTimeout(() => {
|
||||
this.tipWords = ""
|
||||
this.$parent.closeBox();
|
||||
this.$parent.$emit('success', { captchaVerification })
|
||||
}, 1000)
|
||||
} else {
|
||||
this.moveBlockBackgroundColor = '#d9534f'
|
||||
this.leftBarBorderColor = '#d9534f'
|
||||
this.iconColor = '#fff'
|
||||
this.iconClass = 'icon-close'
|
||||
this.passFlag = false
|
||||
setTimeout(function () {
|
||||
_this.refresh();
|
||||
}, 1000);
|
||||
this.$parent.$emit('error', this)
|
||||
this.tipWords = "验证失败"
|
||||
setTimeout(() => {
|
||||
this.tipWords = ""
|
||||
}, 1000)
|
||||
}
|
||||
})
|
||||
this.status = false;
|
||||
}
|
||||
},
|
||||
|
||||
refresh: function () {
|
||||
this.showRefresh = true
|
||||
this.finishText = ''
|
||||
|
||||
this.transitionLeft = 'left .3s'
|
||||
this.moveBlockLeft = 0
|
||||
|
||||
this.leftBarWidth = undefined
|
||||
this.transitionWidth = 'width .3s'
|
||||
|
||||
this.leftBarBorderColor = '#ddd'
|
||||
this.moveBlockBackgroundColor = '#fff'
|
||||
this.iconColor = '#000'
|
||||
this.iconClass = 'icon-right'
|
||||
this.isEnd = false
|
||||
|
||||
this.getPictrue()
|
||||
setTimeout(() => {
|
||||
this.transitionWidth = ''
|
||||
this.transitionLeft = ''
|
||||
this.text = this.explain
|
||||
}, 300)
|
||||
},
|
||||
|
||||
// 请求背景图片和验证图片
|
||||
getPictrue () {
|
||||
let data = {
|
||||
captchaType: this.captchaType
|
||||
}
|
||||
reqGet(data).then(res => {
|
||||
if (res.repCode == "0000") {
|
||||
this.backImgBase = res.repData.originalImageBase64
|
||||
this.blockBackImgBase = res.repData.jigsawImageBase64
|
||||
this.backToken = res.repData.token
|
||||
this.secretKey = res.repData.secretKey
|
||||
} else {
|
||||
this.tipWords = res.repMsg;
|
||||
}
|
||||
})
|
||||
},
|
||||
},
|
||||
watch: {
|
||||
// type变化则全面刷新
|
||||
type: {
|
||||
immediate: true,
|
||||
handler () {
|
||||
this.init()
|
||||
}
|
||||
}
|
||||
},
|
||||
mounted () {
|
||||
// 禁止拖拽
|
||||
this.$el.onselectstart = function () {
|
||||
return false
|
||||
}
|
||||
},
|
||||
}
|
||||
</script>
|
||||
|
||||
@@ -1,27 +0,0 @@
|
||||
/**
|
||||
* 此处可直接引用自己项目封装好的 axios 配合后端联调
|
||||
*/
|
||||
|
||||
|
||||
import request from '@/router/axios';
|
||||
// import request from "@/api/axios.js" //调用项目封装的axios
|
||||
|
||||
//获取验证图片 以及token
|
||||
export function reqGet (data) {
|
||||
return request({
|
||||
url: '/captcha/get',
|
||||
method: 'post',
|
||||
data
|
||||
})
|
||||
}
|
||||
|
||||
//滑动或者点选验证
|
||||
export function reqCheck (data) {
|
||||
return request({
|
||||
url: '/captcha/check',
|
||||
method: 'post',
|
||||
data
|
||||
})
|
||||
}
|
||||
|
||||
|
||||
@@ -1,11 +0,0 @@
|
||||
import CryptoJS from 'crypto-js'
|
||||
/**
|
||||
* @word 要加密的内容
|
||||
* @keyWord String 服务器随机返回的关键字
|
||||
* */
|
||||
export function aesEncrypt (word, keyWord = "XwKsGlMcdPMEhR1B") {
|
||||
var key = CryptoJS.enc.Utf8.parse(keyWord);
|
||||
var srcs = CryptoJS.enc.Utf8.parse(word);
|
||||
var encrypted = CryptoJS.AES.encrypt(srcs, key, { mode: CryptoJS.mode.ECB, padding: CryptoJS.pad.Pkcs7 });
|
||||
return encrypted.toString();
|
||||
}
|
||||
@@ -1,36 +0,0 @@
|
||||
export function resetSize(vm) {
|
||||
var img_width, img_height, bar_width, bar_height; //图片的宽度、高度,移动条的宽度、高度
|
||||
|
||||
var parentWidth = vm.$el.parentNode.offsetWidth || window.offsetWidth
|
||||
var parentHeight = vm.$el.parentNode.offsetHeight || window.offsetHeight
|
||||
|
||||
if (vm.imgSize.width.indexOf('%') != -1) {
|
||||
img_width = parseInt(this.imgSize.width) / 100 * parentWidth + 'px'
|
||||
} else {
|
||||
img_width = this.imgSize.width;
|
||||
}
|
||||
|
||||
if (vm.imgSize.height.indexOf('%') != -1) {
|
||||
img_height = parseInt(this.imgSize.height) / 100 * parentHeight + 'px'
|
||||
} else {
|
||||
img_height = this.imgSize.height
|
||||
}
|
||||
|
||||
if (vm.barSize.width.indexOf('%') != -1) {
|
||||
bar_width = parseInt(this.barSize.width) / 100 * parentWidth + 'px'
|
||||
} else {
|
||||
bar_width = this.barSize.width
|
||||
}
|
||||
|
||||
if (vm.barSize.height.indexOf('%') != -1) {
|
||||
bar_height = parseInt(this.barSize.height) / 100 * parentHeight + 'px'
|
||||
} else {
|
||||
bar_height = this.barSize.height
|
||||
}
|
||||
|
||||
return {imgWidth: img_width, imgHeight: img_height, barWidth: bar_width, barHeight: bar_height}
|
||||
}
|
||||
|
||||
export const _code_chars = [1, 2, 3, 4, 5, 6, 7, 8, 9, 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z', 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z']
|
||||
export const _code_color1 = ['#fffff0', '#f0ffff', '#f0fff0', '#fff0f0']
|
||||
export const _code_color2 = ['#FF0033', '#006699', '#993366', '#FF9900', '#66CC66', '#FF33CC']
|
||||
Reference in New Issue
Block a user