Browse Source

完善功能

old
wangqing 5 years ago
parent
commit
9a9a5fcfff
  1. 6
      src/api/index.js
  2. 27
      src/store/modules/global.js
  3. 3
      src/utils/defaultValue.js
  4. 4
      src/utils/index.js
  5. 13
      src/views/404.vue
  6. 50
      src/views/account/login.vue
  7. 154
      src/views/form/setting.vue
  8. 7
      src/views/form/write.vue
  9. 2
      src/views/home/index.vue
  10. 2
      vue.config.js
  11. 5
      yarn.lock

6
src/api/index.js

@ -85,6 +85,10 @@ api.interceptors.response.use(
duration: 5 * 1000
})
} else if (res.code === 401) {
// 有一个接口进入该方法 其他接口则不在进入
let reLogin = store.getters['global/isReLogin']
if (!reLogin) {
store.dispatch('global/loginExpired', true).then(() => {
// to re-login
MessageBox.confirm('登录状态已过期,您可以继续留在该页面,或者重新登录', '系统提示', {
confirmButtonText: '重新登录',
@ -93,6 +97,8 @@ api.interceptors.response.use(
}).then(() => {
toLogin()
})
})
}
}
return Promise.reject(res)
},

27
src/store/modules/global.js

@ -2,13 +2,32 @@
* 存放全局公用状态
*/
const state = {}
const state = {
reLogin: false
}
const getters = {}
const getters = {
isReLogin: state => {
return state.reLogin
}
}
const actions = {}
const actions = {
loginExpired(context, status) {
return new Promise(resolve => {
context.commit('setReLogin', {
status: status
})
resolve()
})
}
}
const mutations = {}
const mutations = {
setReLogin(state, data) {
state.reLogin = data.status
}
}
export default {
namespaced: true,

3
src/utils/defaultValue.js

@ -1,5 +1,6 @@
export default {
projectShareTitle: '填鸭表单',
projectShareDesc: '快来填写吧',
projectShareImg: 'https://qiniu.smileyi.top/c4ca4238a0b923820dcc509a6f75849b/4b2c7071f3f543549907b9e3b41df1ed.png'
projectShareImg: 'https://qiniu.smileyi.top/c4ca4238a0b923820dcc509a6f75849b/4b2c7071f3f543549907b9e3b41df1ed.png',
projectSubmitPromptText: '您已完成本次填写,感谢您的帮助与支持'
}

4
src/utils/index.js

@ -176,3 +176,7 @@ export function getQueryString(name) {
r = null
return context == null || context == '' || context == 'undefined' ? '' : context
}
export function getCurrentDomain() {
return window.location.protocol + '//' + window.location.host
}

13
src/views/404.vue

@ -1,6 +1,8 @@
<template>
<div>
我真的尽力了但还是找不到页面
<div class=""
style="display: flex; height: 100vh; align-items: center; justify-content: center; justify-items: center;"
>
<p class="title"> 404联系一下开发者 </p>
</div>
</template>
<script>
@ -15,3 +17,10 @@ export default {
methods: {}
}
</script>
<style>
.title {
color: rgba(32, 91, 181, 100);
font-size: 84px;
text-align: left;
}
</style>

50
src/views/account/login.vue

@ -11,7 +11,15 @@
<el-tab-pane label="微信扫码登录" name="wx">
<div class="wx-login">
<div style="text-align: center;">
<img class="wx-login-qrcode" :src="wxLoginQrCode">
<el-image
v-loading="wxQrCodeLoading"
class="wx-login-qrcode"
:src="wxLoginQrCode"
fit="fill"
@load="(e)=>{
this.wxQrCodeLoading=false
}"
/>
</div>
<div style="text-align: center;">
<el-link icon="el-icon-refresh-left"
@ -33,7 +41,9 @@
</el-col>
<el-col :span="9" :offset="3">
<div class="other-login">
<span @click="redirectUrl(qqLoginAuthorizeUrl)">
<svg-icon name="loginQQ" class="other-login-icon" />
</span>
<svg-icon name="loginWx" class="other-login-icon" />
</div>
</el-col>
@ -99,7 +109,9 @@
<el-row>
<el-col :offset="8">
<div class="other-login">
<span @click="redirectUrl(qqLoginAuthorizeUrl)">
<svg-icon name="loginQQ" class="other-login-icon" />
</span>
<svg-icon name="loginWx" class="other-login-icon" />
</div>
</el-col>
@ -175,6 +187,9 @@
</div>
</template>
<script>
import {getCurrentDomain} from '@/utils'
export default {
name: 'Login',
data() {
@ -223,10 +238,12 @@ export default {
email: '',
password: ''
},
wxQrCodeLoading: true,
wxLoginQrCode: '',
wxLoginId: '',
refreshWxQrcodeTimer: null,
wxQrcodeResultTimer: null
wxQrcodeResultTimer: null,
qqLoginAuthorizeUrl: ''
}
},
created() {
@ -237,6 +254,7 @@ export default {
this.wxQrcodeResultTimer = setInterval(() => {
this.getLoginWxQrCodeResult()
}, 5 * 1000)
this.getQQLoginAuthorizeUrl()
},
destroyed() {
clearInterval(this.refreshWxQrcodeTimer)
@ -247,12 +265,25 @@ export default {
},
registerHandleClick() {
},
//
getLoginWxQrCode() {
this.wxQrCodeLoading = true
this.$api.get('/login/wx/qrcode').then(res => {
this.wxLoginQrCode = res.data.qrCodeUrl
this.wxLoginId = res.data.loginId
})
},
// qq
getQQLoginAuthorizeUrl() {
let reUrl = getCurrentDomain() + '/redirect'
this.$api.get('/login/qq/authorize/url', {params: {redirectUri: reUrl}}).then(res => {
this.qqLoginAuthorizeUrl = res.data
})
},
redirectUrl(url) {
console.log(url)
location.href = url
},
getLoginWxQrCodeResult() {
this.$api.get('/login/wx/qrcode/result', {params: {loginId: this.wxLoginId}}).then(res => {
if (res.data) {
@ -298,8 +329,10 @@ export default {
loginSuccessHandle(data) {
this.msgSuccess('登录成功')
this.$store.dispatch('user/login', data).then(() => {
//
this.$store.dispatch('global/loginExpired', false).then(() => {
})
//
// eslint-disable-next-line no-debugger
if (this.$route.query.redirect) {
this.$router.replace({
path: this.$route.query.redirect
@ -327,7 +360,7 @@ export default {
}
}
</script>
<style scoped>
<style lang="scss" scoped>
.login-body {
font-familyly: "Helvetica Neue", helvetica, "PingFang SC", "Hiragino Sans GB", "Microsoft YaHei", "微软雅黑", arial, sans-serif;
@ -341,21 +374,14 @@ export default {
margin-left: 100px;
height: 500px;
width: 520px;
.wx-login {
display: flex;
align-content: center;
align-items: center;
justify-content: center;
flex-direction: column;
}
}
.wx-login-qrcode {
margin: 20px;
width: 194px;
height: 194px;
}
.other-login .other-login-icon {
margin-left: 10px;
cursor: pointer;
}
.login-tip {
color: rgba(16, 16, 16, 1);

154
src/views/form/setting.vue

@ -1,5 +1,5 @@
<template>
<el-form ref="setting" :model="userProjectSettingData">
<el-form ref="setting" :model="userProjectSettingData" :rules="settingRules">
<el-row class="project-setting-container" type="flex" justify="center" align="top">
<el-col :span="5" :offset="3" class="project-setting-view">
<p class="project-setting-title">
@ -54,7 +54,7 @@
<el-col :span="20" class="setting-input">
<el-input v-model="userProjectSettingData.submitPromptText"
:show-word-limit="true"
:maxlength="100"
:maxlength="50"
@change="saveUserProjectSetting"/>
</el-col>
</el-row>
@ -75,7 +75,7 @@
<el-col :span="20" class="setting-input">
<el-input
:show-word-limit="true"
:maxlength="100"
:maxlength="50"
@change="saveUserProjectSetting"
v-model="userProjectSettingData.submitJumpUrl"/>
</el-col>
@ -148,7 +148,7 @@
<el-col :span="15">
<el-input class="setting-input" style="width: 80%"
:show-word-limit="true"
:maxlength="100"
:maxlength="50"
@change="saveUserProjectSetting"
v-model="userProjectSettingData.timedNotEnabledPromptText"/>
</el-col>
@ -160,7 +160,7 @@
<el-col :span="15">
<el-input class="setting-input" style="width: 80%"
:show-word-limit="true"
:maxlength="100"
:maxlength="50"
@change="saveUserProjectSetting"
v-model="userProjectSettingData.timedDeactivatePromptText"/>
</el-col>
@ -220,7 +220,7 @@
<el-input class="setting-input" style="width: 80%"
@change="saveUserProjectSetting"
:show-word-limit="true"
:maxlength="100"
:maxlength="50"
v-model="userProjectSettingData.timedNotEnabledPromptText"/>
</el-col>
</el-row>
@ -232,7 +232,7 @@
<el-input class="setting-input" style="width: 80%"
@change="saveUserProjectSetting"
:show-word-limit="true"
:maxlength="100"
:maxlength="50"
v-model="userProjectSettingData.timedDeactivatePromptText"/>
</el-col>
</el-row>
@ -257,7 +257,7 @@
<el-input class="setting-input" style="width: 80%"
@change="saveUserProjectSetting"
:show-word-limit="true"
:maxlength="100"
:maxlength="50"
v-model="userProjectSettingData.timedEndPromptText"/>
</el-col>
</el-row>
@ -274,7 +274,7 @@
</el-row>
<el-row type="flex" align="middle">
<el-col :span="12">
<p class="project-setting-label">每人限制填写1次</p>
<p class="project-setting-label">每人每天限制填写1次</p>
</el-col>
<el-col :span="12">
<el-switch
@ -291,7 +291,7 @@
<el-input class="setting-input" style="width: 80%"
@change="saveUserProjectSetting"
:show-word-limit="true"
:maxlength="100"
:maxlength="50"
v-model="userProjectSettingData.writeOncePromptText"/>
</el-col>
</el-row>
@ -322,9 +322,12 @@
<p class="project-setting-sub-label">请填写邮箱</p>
</el-col>
<el-col :span="12">
<el-form-item prop="newWriteNotifyEmail">
<el-input class="setting-input" style="width: 80%"
@change="saveUserProjectSetting"
placeholder="多个邮箱用 ; 隔开"
v-model="userProjectSettingData.newWriteNotifyEmail"/>
</el-form-item>
</el-col>
</el-row>
<el-row type="flex" align="middle">
@ -342,7 +345,7 @@
<el-col :span="10">
<p class="project-setting-sub-label">
需要关注公众号
<el-link>TDUCK</el-link>
<el-link type="primary" @click="openSubNotifyWxDialogHandle">TDUCK</el-link>
</p>
</el-col>
</el-row>
@ -351,10 +354,21 @@
<p class="project-setting-sub-label">提醒人</p>
</el-col>
<el-col :span="12">
<img style="width: 24px;height: 24px;" src=""/>
<span class="sub-user-view" v-for="(user,i) in subNotifyWxUserList">
<i class="el-icon-close sub-user-delete" @click="deleteSubNotifyUserHandle(i)"/>
<el-avatar :src="user.headImgUrl"></el-avatar>
</span>
</el-col>
</el-row>
</div>
<el-dialog title="微信扫描二维码订阅"
width="400px"
:visible.sync="dialogSubNotifyVisible">
<el-image
style="width: 150px; height: 150px"
:src="subNotifyWxQrCode"
fit="fill"></el-image>
</el-dialog>
<el-row type="flex" align="middle">
<el-col :span="12">
<p class="project-setting-label">记录微信用户个人信息</p>
@ -435,7 +449,7 @@
<el-input
@change="saveUserProjectSetting"
:show-word-limit="true"
:maxlength="100"
:maxlength="50"
class="setting-input" style="width: 80%" v-model="userProjectSettingData.shareTitle"/>
</el-col>
</el-row>
@ -456,7 +470,7 @@
<el-input
@change="saveUserProjectSetting"
:show-word-limit="true"
:maxlength="100"
:maxlength="50"
class="setting-input" style="width: 80%" v-model="userProjectSettingData.shareDesc"/>
</el-col>
</el-row>
@ -473,6 +487,15 @@ export default {
},
data() {
return {
settingRules: {
newWriteNotifyEmail: [
{
trigger: 'blur',
pattern: /^((([a-z0-9_\.-]+)@([\da-z\.-]+)\.([a-z\.]{2,6}\;))*(([a-z0-9_\.-]+)@([\da-z\.-]+)\.([a-z\.]{2,6})))$/,
message: '请输入正确发送的邮箱'
}
]
},
projectSetting: {
showPromptImg: false,
showPromptText: true,
@ -491,8 +514,8 @@ export default {
submitPromptText: '提交成功 !',
submitJumpUrl: '',
wxWrite: false,
timedNotEnabledPromptText: '',
timedDeactivatePromptText: '',
timedNotEnabledPromptText: '填写尚未启用',
timedDeactivatePromptText: '填写尚已经停用',
timedQuantitativeQuantity: null,
timedEndPromptText: '',
everyoneWriteOnce: false,
@ -506,7 +529,11 @@ export default {
shareImg: '',
shareTitle: '',
shareDesc: ''
}
},
dialogSubNotifyVisible: false,
subNotifyWxQrCode: '',
subNotifyWxUserList: [],
subNotifyUserTimer: null
}
},
computed: {
@ -519,6 +546,10 @@ export default {
mounted() {
this.projectKey = this.$route.query.key
this.queryUserProjectSetting()
this.getSubNotifyWxQrCode()
},
destroyed() {
clearInterval(this.subNotifyUserTimer)
},
methods: {
uploadSubmitPromptHandle(response, file, fileList) {
@ -539,13 +570,16 @@ export default {
timedQuantitativeQuantity, newWriteNotifyEmail, newWriteNotifyWx,
shareImg, shareTitle, shareDesc
} = res.data
if (newWriteNotifyWx) {
this.querySubNotifyWxUser(newWriteNotifyWx)
}
this.projectSetting = {
showPromptImg: !!submitPromptImg,
showPromptText: !!submitPromptText,
showSubmitJumpUrl: !!submitJumpUrl,
timingCollectForm: timedCollectionBeginTime & !timedQuantitativeQuantity,
timingCollectForm: !!timedCollectionBeginTime && !!timedQuantitativeQuantity,
timingCollectTimeRange: !!timedQuantitativeQuantity,
newFeedbackRemind: newWriteNotifyEmail | newWriteNotifyWx,
newFeedbackRemind: !!newWriteNotifyEmail || !!newWriteNotifyWx,
newFeedbackRemindEmail: !!newWriteNotifyEmail,
newFeedbackRemindWx: !!newWriteNotifyWx,
customizeShareIcon: !!shareImg,
@ -560,6 +594,46 @@ export default {
this.$api.post('/user/project/setting/save', this.userProjectSettingData).then(res => {
})
},
openSubNotifyWxDialogHandle() {
this.dialogSubNotifyVisible = true
this.projectSetting.newFeedbackRemindWx = true
this.subNotifyUserTimer = setInterval(() => {
this.querySubNotifyWxUser()
}, 5 * 1000)
},
querySubNotifyWxUser(openIdStr) {
this.$api.get('/user/project/wx/notify/user', {
params: {
key: this.projectKey,
openIdStr: openIdStr
}
}).then(res => {
this.subNotifyWxUserList = res.data
if (this.subNotifyWxUserList) {
let changeNewWriteNotifyWx = this.subNotifyWxUserList.map(item => item.openId).join(';')
if (!openIdStr && changeNewWriteNotifyWx != this.userProjectSettingData.newWriteNotifyWx) {
this.userProjectSettingData.newWriteNotifyWx = changeNewWriteNotifyWx
this.saveUserProjectSetting()
}
}
})
},
getSubNotifyWxQrCode() {
this.$api.get('/user/project/wx/notify/qrcode', {params: {key: this.projectKey}}).then(res => {
this.subNotifyWxQrCode = res.data
})
},
deleteSubNotifyUserHandle(i) {
if (this.subNotifyWxUserList) {
let openId = this.subNotifyWxUserList[i].openId
let key = this.projectKey
this.$api.post(`/user/project/wx/notify/user/delete/${key}/${openId}`).then(res => {
this.subNotifyWxUserList.splice(i)
this.userProjectSettingData.newWriteNotifyWx = this.subNotifyWxUserList.map(item => item.openId).join(';')
this.saveUserProjectSetting()
})
}
},
clearFieldHandle(fields) {
fields.forEach((field) => {
this.$set(this.userProjectSettingData, field, '')
@ -627,12 +701,29 @@ export default {
justify-content: center;
}
/deep/ .setting-input input {
border: none;
border-bottom: 1px solid rgba(187, 187, 187, 100);
border-radius: 0;
line-height: 20px;
height: 20px;
.sub-user-view {
position: relative;
width: 60px;
cursor: pointer;
}
.sub-user-view:hover .sub-user-delete {
display: block;
}
.sub-user-delete {
position: absolute;
right: -6px;
background-color: red;
color: white;
border-radius: 50px;
padding: 2px;
font-size: 12px;
height: 16px;
width: 16px;
font-weight: 500;
line-height: 18px;
display: none;
}
.share-img {
@ -645,9 +736,22 @@ export default {
justify-content: center;
}
/deep/ .setting-input input {
border: none;
border-bottom: 1px solid rgba(187, 187, 187, 100);
border-radius: 0;
line-height: 20px;
height: 20px;
}
/deep/ .collection-date-picker input {
border: none;
border-bottom: 1px solid rgba(187, 187, 187, 100);
border-radius: 0;
}
/deep/ .el-form-item--mini.el-form-item, .el-form-item--small.el-form-item {
margin: 0;
}
</style>

7
src/views/form/write.vue

@ -19,9 +19,10 @@
:src="userProjectSetting.submitPromptImg"
fit="cover"></el-image>
</div>
<p style="text-align: center" v-if="userProjectSetting.submitPromptText">
<p style="text-align: center">
<i class="el-icon-check"/>
<span v-if="userProjectSetting.submitPromptText">{{ userProjectSetting.submitPromptText }}</span>
<span v-else>{{globalDefaultValue.projectSubmitPromptText}}</span>
</p>
</div>
</div>
@ -50,6 +51,7 @@ export default {
userProjectSetting: {
submitPromptText: ''
},
globalDefaultValue: defaultValue,
//
wxAuthorizationUrl: '',
wxAuthorizationCode: '',
@ -64,7 +66,6 @@ export default {
let key = this.$route.query.key
this.projectConfig.projectKey = key
let wxCode = getQueryString('code')
alert(wxCode)
if (wxCode) {
alert(wxCode)
this.wxAuthorizationCode = wxCode
@ -206,7 +207,7 @@ export default {
'projectKey': this.projectConfig.projectKey,
'collectData': data
}).then(res => {
this.formState = true
this.writeStatus = 2
})
}
}

2
src/views/home/index.vue

@ -58,7 +58,7 @@ export default {
menuRouters: [
{
routerPath: '/proposal',
title: '提出建议'
title: '免费模板'
},
{
routerPath: '/sources',

2
vue.config.js

@ -59,7 +59,7 @@ module.exports = {
// 开发环境默认开启反向代理,如果不需要请自行注释
proxy: {
'/tduck-api': {
target: 'http://localhost:8999/',
target: 'http://smalljop.test.utools.club',
changeOrigin: true
}
}

5
yarn.lock

@ -8701,11 +8701,6 @@ q@^1.1.2:
resolved "https://registry.npm.taobao.org/q/download/q-1.5.1.tgz#7e32f75b41381291d04611f1bf14109ac00651d7"
integrity sha1-fjL3W0E4EpHQRhHxvxQQmsAGUdc=
qrcodejs2@^0.0.2:
version "0.0.2"
resolved "https://registry.yarnpkg.com/qrcodejs2/-/qrcodejs2-0.0.2.tgz#465afe5e39f19facecb932c11f7a186109146ae1"
integrity sha1-Rlr+Xjnxn6zsuTLBH3oYYQkUauE=
qs@6.7.0:
version "6.7.0"
resolved "https://registry.npm.taobao.org/qs/download/qs-6.7.0.tgz#41dc1a015e3d581f1621776be31afb2876a9b1bc"

Loading…
Cancel
Save