Soleilw 1 anno fa
parent
commit
a3ec287977

dist/assets/index-i0sh_yC6.js
File diff soppresso perché troppo grande
Vedi File


+ 1
- 1
dist/index.html Vedi File

@@ -5,7 +5,7 @@
<link rel="icon" type="image/svg+xml" href="/logo_1.jpg" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>菊城人才市场后台管理</title>
<script type="module" crossorigin src="/assets/index-zplygJt9.js"></script>
<script type="module" crossorigin src="/assets/index-i0sh_yC6.js"></script>
<link rel="stylesheet" crossorigin href="/assets/index-EE_SYqet.css">
</head>
<body>

+ 12
- 10
src/apis/models/index.ts Vedi File

@@ -3,6 +3,8 @@ import { url } from '../url'

export const Login = postModel(url.userLogin);
export const GetUserMenulist = getModel(url.UserMenulist);
export const PostSmsSend = postModel(url.SmsSend);
export const GetCaptcha = getModel(url.Captcha);

// 角色
export const PostRoleAdd = postModel(url.RoleAdd);
@@ -213,19 +215,19 @@ export const GetSysconfigList = getModel(url.SysconfigList); //
export const GetSysconfigDetail = getModel(url.SysconfigDetail);

// 反馈
export const PostFeedbackAdd = postModel(url.FeedbackAdd);
export const PostFeedbackDel = postModel(url.FeedbackDel);
export const PostFeedbackUpdate = postModel(url.FeedbackUpdate);
export const GetFeedbackList = getModel(url.FeedbackList);
export const GetFeedbackDetail = getModel(url.FeedbackDetail);
export const PostFeedbackAdd = postModel(url.FeedbackAdd);
export const PostFeedbackDel = postModel(url.FeedbackDel);
export const PostFeedbackUpdate = postModel(url.FeedbackUpdate);
export const GetFeedbackList = getModel(url.FeedbackList);
export const GetFeedbackDetail = getModel(url.FeedbackDetail);

// 反馈
export const PostCustomerAdd = postModel(url.CustomerAdd);
export const PostCustomerDel = postModel(url.CustomerDel);
export const GetCustomerUpdate = getModel(url.CustomerUpdate);
export const GetCustomerList = getModel(url.CustomerList);
export const PostCustomerAdd = postModel(url.CustomerAdd);
export const PostCustomerDel = postModel(url.CustomerDel);
export const GetCustomerUpdate = getModel(url.CustomerUpdate);
export const GetCustomerList = getModel(url.CustomerList);
export const GetCustomerDetail = getModel(url.CustomerDetail);

export const PostEsJobseeker = postModel(url.EsJobseeker);
export const PostTokenizerModify = postModel(url.TokenizerModify);
export const GetTokenizerGet = getModel(url.TokenizerGet);
export const GetTokenizerGet = getModel(url.TokenizerGet);

+ 25
- 23
src/apis/types/url.d.ts Vedi File

@@ -1,5 +1,7 @@
declare namespace urlType {
type url = {
Captcha : String,
SmsSend : String,
userLogin : String,
UserMenulist : String,
RoleAdd : String,
@@ -184,31 +186,31 @@ declare namespace urlType {
StatsPosition : String,
StatsTitleAndSkill : String,
StatsJobMajor : String,
'SysconfigAdd':String,
'SysconfigDel': String,
'SysconfigUpdate':String,
'SysconfigList': String,
'SysconfigDetail': String,
'SysconfigAdd' : String,
'SysconfigDel' : String,
'SysconfigUpdate' : String,
'SysconfigList' : String,
'SysconfigDetail' : String,
// 反馈
FeedbackAdd: String,
FeedbackDel: String,
FeedbackUpdate: String,
FeedbackList: String,
FeedbackDetail: String,
FeedbackAdd : String,
FeedbackDel : String,
FeedbackUpdate : String,
FeedbackList : String,
FeedbackDetail : String,
// 反馈
CustomerAdd: String,
CustomerDel: String,
CustomerUpdate: String,
CustomerList: String,
CustomerDetail:String,
DocUpload: String,
EsJobseeker: String,
TokenizerModify: String,
TokenizerGet:String,
CustomerAdd : String,
CustomerDel : String,
CustomerUpdate : String,
CustomerList : String,
CustomerDetail : String,
DocUpload : String,
EsJobseeker : String,
TokenizerModify : String,
TokenizerGet : String,

}
}

+ 3
- 0
src/apis/url.ts Vedi File

@@ -4,6 +4,9 @@ let common : string = '/common';
export const url : urlType.url = {
userLogin: admin + '/user/login',
UserMenulist: admin + '/user/menulist',

SmsSend: common + '/sms/send', // 短信验证码
Captcha: common + '/captcha', // 获取验证码
// 角色
RoleAdd: admin + '/role/add',
RoleList: admin + '/role/list',

+ 68
- 0
src/components/form/image-container.vue Vedi File

@@ -0,0 +1,68 @@
<template>
<div v-if="needPre">
<img :src="imgObj.src" alt=""
:style="{width: imgObj.width,height: imgObj.height,'object-fit': imgObj.mode, 'border-radius': 0} "
@click="preImage(imgObj.src)">
<a-modal v-model:open="imageBigOpen" width="50%" centered :footer="null" @cancel="close">
<div style="padding: 30px;">
<img :src="imgObj.src" style="width: 100%; height: 100%;">
</div>
</a-modal>
</div>
<div v-else>
<img :src="imgObj.src" alt=""
:style="{width: imgObj.width,height: imgObj.height,'object-fit': imgObj.mode, 'border-radius': 0} ">
</div>

</template>

<script lang="ts" setup>
import { ref, onMounted, defineProps, watch, computed } from 'vue';

const props = defineProps({
imgObj: {
type: Object,
default: {}
},
need: {
type: Boolean,
default: false
}
});

let needPre = ref<Boolean>(props.need)
let imageBigOpen = ref<Boolean>(false)
interface imgType {
src ?: String,
width ?: Number,
height ?: Number,
mode ?: String,
}
const imgObj = ref<imgType>({
src: '',
width: 0,
height: 0,
mode: '',
})

// 预览
const preImage = (src) => {
imageBigOpen.value = true
}

const close = (src) => {
imageBigOpen.value = false
}



watch(() => [props.imgObj], (newVal : any) => {
if (newVal[0]) {
imgObj.value = newVal[0]
}
}, { immediate: true })
</script>

<style>
</style>

+ 2
- 1
src/main.ts Vedi File

@@ -21,6 +21,7 @@ import ACSelect from '@/components/cSelect/select.vue';
import ACSelectCommon from '@/components/cSelect/common.vue';
import UploadOne from '@/components/upload/one.vue';
import UploadFile from '@/components/upload/file.vue';
import ImageContainer from '@/components/form/image-container.vue';
import { Model } from 'node_modules/echarts/index';

// router.beforeEach(async (to, from, next) => {
@@ -76,7 +77,7 @@ app.component('a-c-select', ACSelect);
app.component('a-xuanze', AXuanze);
app.component('a-shujilian', AShujilian);
app.component('search-select', SearchSelect);
app.component('image-container', ImageContainer)
app.component('a-c-select-common', ACSelectCommon);
app.component('QuillEditor', QuillEditor)
app.component('upload-one', UploadOne)

+ 3
- 3
src/views/information/article/add/add.vue Vedi File

@@ -17,8 +17,8 @@
<a-col span="24">
<a-form-item label="上传文件,可将链接放入文章内容">
<upload-file @uploadSuccess="uploadDocSuccess"></upload-file>
<a-typography-paragraph v-if="createForm.doc" :copyable="{ text: imageprefix+createForm.doc}">
{{imageprefix+createForm.doc}}
<a-typography-paragraph v-if="createForm.doc_url" :copyable="{ text: imageprefix+createForm.doc_url}">
{{imageprefix+createForm.doc_url}}
</a-typography-paragraph>
</a-form-item>
</a-col>
@@ -92,7 +92,7 @@
// 上传文件
const uploadDocSuccess = (data : Object) => {
createForm.value.doc = data
createForm.value.doc_url = data
}

// 选择栏目/频道

+ 2
- 2
src/views/information/article/add/data.ts Vedi File

@@ -1,7 +1,7 @@
export let dataForm = {
title: '',
cover_img: '',
doc: '',
doc_url: '',
section_id: 0,
content: '',
stick_top: 0,
@@ -18,7 +18,7 @@ export const reset = () => {
dataForm = {
title: '',
cover_img: '',
doc: '',
doc_url: '',
section_id: 0,
content: '',
stick_top: 0,

+ 131
- 62
src/views/login/login.vue Vedi File

@@ -4,80 +4,136 @@
<h2 class="title">菊城人才市场招聘后台管理系统</h2>
<div class="sub-title">欢迎使用</div>
<a-form>
<a-row>
<a-col :span="24"><a-form-item>
<a-input placeholder="账号" v-model:value="createForm.mobile">
<template #prefix>
<user-outlined type="user" />
</template>
</a-input>
</a-form-item>
</a-col>
</a-row>
<a-row>
<a-col :span="24">
<a-form-item>
<a-input type="password" placeholder="密码" v-model:value="createForm.password">
<template #prefix>
<LockOutlined />
</template>
<template #suffix>
<a-tooltip title="Extra information">
<EyeInvisibleOutlined style="color: rgba(0, 0, 0, 0.25)" />
</a-tooltip>
</template>
</a-input>
</a-form-item>
</a-col>
</a-row>
<a-row :gutter="10">
<a-col :span="16">
<a-form-item>
<a-input type="password" placeholder="验证码">
<template #prefix>
<LockOutlined />
</template>
<template #suffix>
<a-tooltip title="Extra information">
<EyeInvisibleOutlined style="color: rgba(0, 0, 0, 0.25)" />
</a-tooltip>
</template>
</a-input>
</a-form-item>
</a-col>
<a-col :span="8">
<a-button style="width: 100%;">验证码</a-button>
</a-col>
</a-row>
<a-row type="flex" justify="end">
<a-col :span="6">
<a-form-item>
<div>忘记密码?</div>
</a-form-item>
</a-col>
</a-row>
<a-row>
<a-col :span="24">
<a-button @click="toLogin" style="width: 100%;" type="primary">登录</a-button>
</a-col>
</a-row>
<a-space direction="vertical">
<a-row :gutter="10">
<a-col :span="24">
<a-form-item>
<a-input size="large" placeholder="账号" v-model:value="createForm.mobile">
<template #prefix>
<user-outlined type="user" />
</template>
</a-input>
</a-form-item>
</a-col>
</a-row>
<a-row :gutter="10">
<a-col :span="24">
<a-form-item>
<a-input size="large" type="password" placeholder="密码"
v-model:value="createForm.password">
<template #prefix>
<LockOutlined />
</template>
<template #suffix>
<a-tooltip title="Extra information">
<EyeInvisibleOutlined style="color: rgba(0, 0, 0, 0.25)" />
</a-tooltip>
</template>
</a-input>
</a-form-item>
</a-col>
</a-row>
<a-row :gutter="10">
<a-col span="12">
<a-form-item>
<a-input v-model:value="createForm.captcha" placeholder="图形验证码" size="large" />
</a-form-item>
</a-col>
<a-col span="12">
<a-form-item>
<image-container :imgObj="{src: codeImage,width: '100%',height: '40px', mode: 'fill'}"
@click="getCaptcha"></image-container>
</a-form-item>
</a-col>
</a-row>
<a-row :gutter="10">
<a-col span="16">
<a-form-item>
<a-input v-model:value="createForm.sms_code" placeholder="短信验证码" size="large" />
</a-form-item>
</a-col>
<a-col span="8">
<a-form-item>
<a-button type="primary" block size="large" @click="sendCode"
:disabled="state.disabled">
{{ state.codeTxt }}</a-button>
</a-form-item>
</a-col>
</a-row>
<!-- <a-row type="flex" justify="end">
<a-col :span="6">
<a-form-item>
<div>忘记密码?</div>
</a-form-item>
</a-col>
</a-row> -->
<a-row>
<a-col :span="24">
<a-button @click="toLogin" style="width: 100%;" type="primary">登录</a-button>
</a-col>
</a-row>
</a-space>

</a-form>
</div>
</div>
</template>

<script lang="ts" setup>
import { ref } from 'vue';
import { Login } from '@/apis/models';
import { ref, onMounted, onBeforeUnmount } from 'vue';
import { Login, PostSmsSend, GetCaptcha } from '@/apis/models';
import { useAsRouter } from '@/hooks/useAsRouter'
import { UserOutlined, InfoCircleOutlined, LockOutlined, EyeInvisibleOutlined } from '@ant-design/icons-vue';
import { useCommon } from '@/hooks/useCommon';
let { message } = useCommon();
const { routerTo } = useAsRouter();
let capt_id = ref<String>('')
let codeImage = ref<String>('')


const createForm = ref<Object>({
mobile: '',
password: ''
password: '',
// captcha: '',
// sms_code: ''
})

interface State {
count : number;
sending : boolean;
disabled : boolean;
}
const state = ref<State>({
count: 60,
codeTxt: '获取验证码',
disabled: false,
});

let timer = ref<any>(null)
const sendCode = () => {
if (!createForm.value.mobile) {
message.danger('请输入手机号')
return false;
}
PostSmsSend({ mobile: createForm.mobile, captcha: '', capt_id: capt_id.value }).then(res => {
message.success('发送验证码成功,验证码有效期为一分钟');
timer.value = setInterval(function () {
if (state.value.count > 1) {
state.value.count = state.value.count - 1;
state.value.codeTxt = '剩余' + (state.value.count - 1) + '秒';
state.value.disabled = true
} else {
clearInterval(timer.value);
state.value.count = 60;
state.value.codeTxt = '获取验证码';
state.value.disabled = false
};
}, 1000)
})
};

onBeforeUnmount(() => {
clearInterval(timer.value);
})
const toLogin = () => {
if (!createForm.value.mobile) {
@@ -87,7 +143,7 @@
if (!createForm.value.password) {
message.warning('请输入密码');
return false;
}
}
Login(createForm.value).then(res => {
sessionStorage.setItem('token', res.data.jwttoken.accesstoken);
routerTo('/home');
@@ -99,6 +155,19 @@
// sessionStorage.setItem('token', '1321');
// routerTo('/home');
}


const getCaptcha = () => {
capt_id.value = ''
GetCaptcha().then(res => {
capt_id.value = res.data.capt_id;
codeImage.value = res.data.img;
})
}

onMounted(() => {
getCaptcha()
})
</script>

<style lang="less">

Loading…
Annulla
Salva