Browse Source

完善功能·

old
wangqing 5 years ago
parent
commit
87dad0b20e
  1. 3
      .env.development
  2. 2
      package.json
  3. 1
      public/MP_verify_ADM9iUdaNzf3LpYF.txt
  4. 2
      src/api/index.js
  5. BIN
      src/assets/logo.png
  6. 3
      src/main.js
  7. 1
      src/router/index.js
  8. 2
      src/router/modules/root.js
  9. 5
      src/utils/defaultValue.js
  10. 45
      src/utils/index.js
  11. 26
      src/utils/loadWxSdk.js
  12. 91
      src/views/account/login.vue
  13. 2
      src/views/form/PreView.vue
  14. 40
      src/views/form/ProjectForm.vue
  15. 11
      src/views/form/index.vue
  16. 162
      src/views/form/publish.vue
  17. 2
      src/views/form/setting.vue
  18. 170
      src/views/form/write.vue
  19. 54
      src/views/home/index.vue
  20. 6
      vue.config.js
  21. 48
      yarn.lock

3
.env.development

@ -1,9 +1,10 @@
# 页面标题
VUE_APP_TITLE = 填鸭测试环境
# 接口请求地址,会设置到 axios 的 baseURL 参数上
VUE_APP_API_ROOT = http://localhost:8999/tduck-api
VUE_APP_API_ROOT = /tduck-api
# 是否开启 CDN 支持,开启设置 ON,关闭设置 OFF
# 详情介绍请阅读 http://eoner.gitee.io/vue-automation/#/cdn
VUE_APP_CDN = OFF
# 调试工具,可设置 eruda 或 vconsole,如果不需要开启则留空
VUE_APP_DEBUG_TOOL =

2
package.json

@ -21,7 +21,9 @@
"js-md5": "^0.7.3",
"nprogress": "^0.2.0",
"vue": "^2.6.12",
"vue-clipboard2": "^0.3.1",
"vue-meta": "^2.4.0",
"vue-qr": "^2.3.0",
"vue-router": "^3.4.8",
"vuedraggable": "^2.24.3",
"vuex": "^3.5.1"

1
public/MP_verify_ADM9iUdaNzf3LpYF.txt

@ -0,0 +1 @@
ADM9iUdaNzf3LpYF

2
src/api/index.js

@ -15,7 +15,7 @@ const toLogin = () => {
}
const api = axios.create({
baseURL: process.env.NODE_ENV !== 'development' && process.env.VUE_APP_API_ROOT,
baseURL: process.env.VUE_APP_API_ROOT,
timeout: 10000,
responseType: 'json',
withCredentials: false,

BIN
src/assets/logo.png

Binary file not shown.

Before

Width:  |  Height:  |  Size: 8.4 KiB

3
src/main.js

@ -11,7 +11,7 @@ import api from './api'
import store from './store/index'
// 全局组件自动注册
import '@/components/autoRegister'
import VueClipboard from 'vue-clipboard2'
Vue.prototype.$api = api
Vue.prototype.$dayjs = dayjs
Vue.prototype.$store = store
@ -29,6 +29,7 @@ Vue.prototype.msgInfo = function(msg) {
this.$message.info(msg)
}
Vue.use(VueClipboard)
Vue.use(meta)
Vue.use(Element, {size: 'small', zIndex: 3000})

1
src/router/index.js

@ -30,6 +30,7 @@ routes.push({
})
const router = new Router({
mode: 'history',
routes: routes.flat()
})

2
src/router/modules/root.js

@ -70,7 +70,7 @@ export default [
path: '/project/view',
meta: {requireLogin: false},
component: () => import(/* webpackChunkName: 'root' */ '@/views/form/ProjectForm.vue')
`` },
},
{
path: '/project/write',
meta: {requireLogin: false},

5
src/utils/defaultValue.js

@ -0,0 +1,5 @@
export default {
projectShareTitle: '填鸭表单',
projectShareDesc: '快来填写吧',
projectShareImg: 'https://qiniu.smileyi.top/c4ca4238a0b923820dcc509a6f75849b/4b2c7071f3f543549907b9e3b41df1ed.png'
}

45
src/utils/index.js

@ -1,5 +1,6 @@
/* eslint-disable no-nested-ternary */
/* eslint-disable no-restricted-syntax */
/* eslint-disable guard-for-in */
/**
* num 小于0左缩进num*2个空格 大于0右缩进num*2个空格
@ -9,7 +10,10 @@
*/
export function indent(str, num, len = 2) {
if (num === 0) return str
const isLeft = num < 0; const result = []; let reg; let
const isLeft = num < 0
const result = []
let reg
let
spaces = ''
if (isLeft) {
num *= -1
@ -126,9 +130,15 @@ export function deepClone(obj) {
// RegExp
if (_toString.call(obj) === '[object RegExp]') {
const flags = []
if (obj.global) { flags.push('g') }
if (obj.multiline) { flags.push('m') }
if (obj.ignoreCase) { flags.push('i') }
if (obj.global) {
flags.push('g')
}
if (obj.multiline) {
flags.push('m')
}
if (obj.ignoreCase) {
flags.push('i')
}
return new RegExp(obj.source, flags.join(''))
}
@ -143,15 +153,26 @@ export function deepClone(obj) {
}
export function uuid() {
let s = [];
let hexDigits = "0123456789abcdef";
let s = []
let hexDigits = '0123456789abcdef'
for (var i = 0; i < 36; i++) {
s[i] = hexDigits.substr(Math.floor(Math.random() * 0x10), 1);
s[i] = hexDigits.substr(Math.floor(Math.random() * 0x10), 1)
}
s[14] = "4"; // bits 12-15 of the time_hi_and_version field to 0010
s[19] = hexDigits.substr((s[19] & 0x3) | 0x8, 1); // bits 6-7 of the clock_seq_hi_and_reserved to 01
s[8] = s[13] = s[18] = s[23] = "-";
s[14] = '4' // bits 12-15 of the time_hi_and_version field to 0010
s[19] = hexDigits.substr((s[19] & 0x3) | 0x8, 1) // bits 6-7 of the clock_seq_hi_and_reserved to 01
s[8] = s[13] = s[18] = s[23] = '-'
let uuid = s.join('')
return uuid
}
let uuid = s.join("");
return uuid;
export function getQueryString(name) {
let reg = new RegExp('(^|&)' + name + '=([^&]*)(&|$)', 'i')
let r = window.location.search.substr(1).match(reg) //获取url中"?"符后的字符串并正则匹配
let context = ''
if (r != null)
context = r[2]
reg = null
r = null
return context == null || context == '' || context == 'undefined' ? '' : context
}

26
src/utils/loadWxSdk.js

@ -0,0 +1,26 @@
import loadScript from './loadScript'
import ELEMENT from 'element-ui'
let wxObj
export default function loadWXJs(cb) {
if (wxObj) {
cb(wxObj)
return
}
const loading = ELEMENT.Loading.service({
fullscreen: true,
lock: true,
text: 'wxsdk资源加载中...',
spinner: 'el-icon-loading',
background: 'rgba(255, 255, 255, 0.5)'
})
loadScript('http://res.wx.qq.com/open/js/jweixin-1.6.0.js', () => {
loading.close()
// eslint-disable-next-line no-undef
wxObj = wx
cb(wxObj)
})
}

91
src/views/account/login.vue

@ -11,10 +11,15 @@
<el-tab-pane label="微信扫码登录" name="wx">
<div class="wx-login">
<div style="text-align: center;">
<img class="qrcode" :src="wxLoginQrCode">
<img class="wx-login-qrcode" :src="wxLoginQrCode">
</div>
<div style="text-align: center;">
<el-link icon="el-icon-refresh-left" :underline="false">刷新二维码</el-link>
<el-link icon="el-icon-refresh-left"
:underline="false"
@click="getLoginWxQrCode"
>
刷新二维码
</el-link>
</div>
<el-divider style="width: 100px;" />
<el-row>
@ -218,19 +223,48 @@ export default {
email: '',
password: ''
},
wxLoginQrCode: 'http://qiniu.smileyi.top/20191213/9f217b754ad44f0caaa83040ce62fe93.png'
wxLoginQrCode: '',
wxLoginId: '',
refreshWxQrcodeTimer: null,
wxQrcodeResultTimer: null
}
},
created() {
this.getLoginWxQrCode()
this.refreshWxQrcodeTimer = setInterval(() => {
this.getLoginWxQrCode()
}, 5 * 60 * 1000)
this.wxQrcodeResultTimer = setInterval(() => {
this.getLoginWxQrCodeResult()
}, 5 * 1000)
},
destroyed() {
clearInterval(this.refreshWxQrcodeTimer)
clearInterval(this.wxQrcodeResultTimer)
},
methods: {
loginTypeHandleClick() {
},
registerHandleClick() {
},
getLoginWxQrCode() {
this.$api.get('/login/wx/qrcode').then(res => {
this.wxLoginQrCode = res.data.qrCodeUrl
this.wxLoginId = res.data.loginId
})
},
getLoginWxQrCodeResult() {
this.$api.get('/login/wx/qrcode/result', {params: {loginId: this.wxLoginId}}).then(res => {
if (res.data) {
this.loginSuccessHandle(res.data)
}
})
},
sendEmailCodeHandle() {
this.$refs['emailRegForm'].validateField('email', err => {
if (!err) {
this.validateCodeBtn = true
this.$api.get(`/user/send-email-code?email=${this.accountForm.email}`).then(() => {
this.$api.get(`/register/email/code?email=${this.accountForm.email}`).then(() => {
this.msgSuccess('验证码发送成功,5分钟内有效')
this.validateCodeBtn = true
let count = 60
@ -249,7 +283,7 @@ export default {
emailRegHandle() {
this.$refs['emailRegForm'].validate(valid => {
if (valid) {
this.$api.post('/user/email-register', this.accountForm).then(() => {
this.$api.post('/register/email', this.accountForm).then(() => {
this.msgSuccess('注册成功,快去登录吧')
setTimeout(() => {
this.formType = 'login'
@ -261,26 +295,29 @@ export default {
}
})
},
loginSuccessHandle(data) {
this.msgSuccess('登录成功')
this.$store.dispatch('user/login', data).then(() => {
//
// eslint-disable-next-line no-debugger
if (this.$route.query.redirect) {
this.$router.replace({
path: this.$route.query.redirect
})
} else {
if (window.history.length <= 1) {
this.$router.push({path: '/home'})
} else {
this.$router.push({path: '/home'})
}
}
})
},
loginHandle() {
this.$refs['accountLoginForm'].validate(valid => {
if (valid) {
this.$api.post('/user/account-login', this.accountForm).then(res => {
this.msgSuccess('登录成功')
this.$store.dispatch('user/login', res.data).then(() => {
//
// eslint-disable-next-line no-debugger
if (this.$route.query.redirect) {
this.$router.replace({
path: this.$route.query.redirect
})
} else {
if (window.history.length <= 1) {
this.$router.push({path: '/home'})
} else {
this.$router.push({path: '/home'})
}
}
})
this.$api.post('/login/account', this.accountForm).then(res => {
this.loginSuccessHandle(res.data)
})
} else {
return false
@ -293,7 +330,7 @@ export default {
<style scoped>
.login-body {
font-family: "Helvetica Neue", Helvetica, "PingFang SC", "Hiragino Sans GB", "Microsoft YaHei", "微软雅黑", Arial, sans-serif;
font-familyly: "Helvetica Neue", helvetica, "PingFang SC", "Hiragino Sans GB", "Microsoft YaHei", "微软雅黑", arial, sans-serif;
margin: 90px 0 0 0;
}
.login-img {
@ -310,11 +347,13 @@ export default {
align-items: center;
justify-content: center;
flex-direction: column;
.qrcode {
margin: 20px;
}
}
}
.wx-login-qrcode {
margin: 20px;
width: 194px;
height: 194px;
}
.other-login .other-login-icon {
margin-left: 10px;
}

2
src/views/form/PreView.vue

@ -49,7 +49,7 @@ export default {
},
mounted() {
let url = window.location.protocol + '//' + window.location.host
this.mobilePreviewUrl = `${url}/#/project/view?key=${this.projectKey}`
this.mobilePreviewUrl = `${url}/project/view?key=${this.projectKey}`
this.$set(this.projectConfig, 'projectKey', this.projectKey)
},
components: {

40
src/views/form/ProjectForm.vue

@ -14,13 +14,13 @@
<el-row v-if="projectTheme.showTitle" type="flex" justify="center" align="middle">
<el-col :sm="{span:20}" :xs="{span:24,offset:0}" style="text-align: center">
<h4 class="form-name-text">
{{formConf.title}}</h4>
{{ formConf.title }}</h4>
</el-col>
</el-row>
<el-row v-if="projectTheme.showDescribe" type="flex" justify="center" align="middle">
<el-col :sm="{span:20}" :xs="{span:24,offset:0}" style="text-align: center">
<p class="form-name-text">
{{formConf.description}}
{{ formConf.description }}
</p>
</el-col>
</el-row>
@ -35,7 +35,6 @@
import Parser from '@/components/parser/Parser'
import {dbDataConvertForItemJson} from '@/utils/convert'
window.onload = function() {
document.addEventListener('touchstart', function(event) {
if (event.touches.length > 1) {
@ -114,23 +113,24 @@ export default {
this.formConf.description = res.data.project.describe
if (res.data.userProjectTheme) {
this.projectTheme = res.data.userProjectTheme
}
let {submitBtnText, showNumber,btnsColor} = res.data.userProjectTheme
if (submitBtnText) {
this.formConf.submitBtnText = submitBtnText
}
if (showNumber) {
this.formConf.showNumber = showNumber
}
if(btnsColor){
this.formConf.submitBtnColor = btnsColor
}
let {submitBtnText, showNumber, btnsColor} = res.data.userProjectTheme
if (submitBtnText) {
this.formConf.submitBtnText = submitBtnText
}
if (showNumber) {
this.formConf.showNumber = showNumber
}
if (btnsColor) {
this.formConf.submitBtnColor = btnsColor
}
}
}
})
},
methods: {
submitForm(data) {
this.$emit('submit',data)
this.$emit('submit', data)
}
}
}
@ -163,10 +163,12 @@ export default {
.logo-img {
max-height: 120px;
}
.submit-btn-form-item{
.submit-btn-form-item {
text-align: left;
}
.submit-btn-form-item button{
.submit-btn-form-item button {
width: 20%;
}
@ -184,10 +186,10 @@ export default {
.logo-img {
max-height: 2.94rem;
}
.submit-btn-form-item{
.submit-btn-form-item {
text-align: center;
}
.submit-btn-form-item button{
.submit-btn-form-item button {
width: 80%;
}
}

11
src/views/form/index.vue

@ -6,10 +6,6 @@
<i class="el-icon-arrow-left"/>
返回
</el-button>
<el-button size="mini" round>
<router-link target="_blank" :to="{path:'/project/write',query:{key:this.projectKey}}">发布预览
</router-link>
</el-button>
</el-col>
<el-col :span="10" :offset="3">
<el-menu :default-active="activeIndex" @select="handleSelect" style="background-color: transparent"
@ -25,6 +21,7 @@
<editor :projectKey="projectKey" v-if="activeIndex==1&&projectKey"/>
<theme :projectKey="projectKey" v-if="activeIndex==2"/>
<setting :projectKey="projectKey" v-if="activeIndex==3"/>
<publish :projectKey="projectKey" v-if="activeIndex==4"/>
</div>
</template>
@ -32,16 +29,18 @@
import editor from './editor'
import theme from './theme'
import setting from './setting'
import publish from './publish'
export default {
components: {
editor,
theme,
setting
setting,
publish
},
data() {
return {
activeIndex: '2',
activeIndex: '4',
projectKey: ''
}
},

162
src/views/form/publish.vue

@ -0,0 +1,162 @@
<template>
<div class="publish-container">
<div>
<div class="publish-btn-view" v-if="!publishStatus">
<el-button
@click="publishProject"
size="medium"
class="publish-btn"
type="primary"><i class="el-icon-document-checked el-icon--right">开始发布</i></el-button>
</div>
<div class="publish-finish-view" v-if="publishStatus">
<el-row type="flex" align="middle">
<el-col :span="20" style="">
<div style="display: flex;justify-content: center">
<div class="icon-view">
<i class="el-icon-check success-icon"/>
</div>
</div>
<div>
<p class="success-title">恭喜您发布成功</p>
</div>
<div>
<p class="link-text"> {{ writeLink }}</p>
</div>
<el-row>
<el-col :span="6" :offset="6">
<el-button v-clipboard:copy="writeLink"
v-clipboard:success="()=>{this.msgSuccess('复制成功')}"
v-clipboard:error="()=>{this.msgError('复制失败')}" type="primary">复制链接
</el-button>
</el-col>
<el-col :span="6">
<el-button type="warning">查看反馈</el-button>
</el-col>
</el-row>
</el-col>
<el-col :span="6">
<div>
<vue-qr v-if="writeLink" :callback="qrCodeGenSuccess" :text="writeLink"
:size="194"></vue-qr>
</div>
<div style="text-align: center">
<el-link type="primary" @click="()=>{
this.downloadFile('qrcode.png',this.qrCodeUrl)
}">下载分享二维码</el-link>
</div>
</el-col>
</el-row>
</div>
</div>
</div>
</template>
<script>
import VueQr from 'vue-qr'
export default {
name: 'projectPublish',
components: {
VueQr
},
props: {
projectKey: ''
},
mounted() {
let url = window.location.protocol + '//' + window.location.host
this.writeLink = `${url}/project/write?key=${this.projectKey}`
},
data() {
return {
publishStatus: false,
writeLink: '',
qrCodeUrl: ''
}
}, methods: {
publishProject() {
this.$api.post(`/user/project/publish/${this.projectKey}`).then(res => {
this.publishStatus = true
this.msgSuccess('发布成功')
})
},
qrCodeGenSuccess(dataUrl, id) {
this.qrCodeUrl = dataUrl
},
downloadFile(fileName, content) {
let aLink = document.createElement('a');
let blob = this.base64ToBlob(content); //new Blob([content]);
let evt = document.createEvent("HTMLEvents");
evt.initEvent("click", true, true);//initEvent FF
aLink.download = fileName;
aLink.href = URL.createObjectURL(blob);
// aLink.dispatchEvent(evt);
aLink.click()
},
//base64blob
base64ToBlob(code) {
let parts = code.split(';base64,')
let contentType = parts[0].split(':')[1]
let raw = window.atob(parts[1])
let rawLength = raw.length
let uInt8Array = new Uint8Array(rawLength)
for (let i = 0; i < rawLength; ++i) {
uInt8Array[i] = raw.charCodeAt(i)
}
return new Blob([uInt8Array], {type: contentType})
}
}
}
</script>
<style lang="scss" scoped>
.publish-container {
width: 100%;
height: 100%;
padding: 0px;
margin: 0;
background-color: #F7F7F7;
font-family: "Helvetica Neue", Helvetica, "PingFang SC", "Hiragino Sans GB", "Microsoft YaHei", "微软雅黑", Arial, sans-serif;
min-height: 84vh;
display: flex;
align-items: center;
justify-content: center;
}
.publish-finish-view {
width: 500px;
height: 200px;
text-align: center;
.icon-view {
width: 59px;
height: 59px;
border-radius: 100px;
background-color: #0076FF;
display: flex;
align-items: center;
align-content: center;
justify-items: center;
justify-content: center;
}
.success-icon {
text-align: center;
color: white;
font-size: 30px;
}
.success-title {
color: rgba(16, 16, 16, 100);
font-size: 28px;
}
.link-text {
color: rgba(16, 16, 16, 100);
font-size: 14px;
}
}
</style>

2
src/views/form/setting.vue

@ -532,8 +532,8 @@ export default {
queryUserProjectSetting() {
this.userProjectSettingData.projectKey = this.projectKey
this.$api.get(`/user/project/setting/query/${this.projectKey}`).then(res => {
this.userProjectSettingData = res.data
if (res.data) {
this.userProjectSettingData = res.data
let {
submitPromptImg, submitPromptText, submitJumpUrl, timedCollectionBeginTime,
timedQuantitativeQuantity, newWriteNotifyEmail, newWriteNotifyWx,

170
src/views/form/write.vue

@ -1,12 +1,18 @@
<template>
<div class="write-container">
<div v-if="!writeFinish">
<div v-if="writeStatus==0">
<p style="text-align: center" v-if="writeNotStartPrompt">
<i class="el-icon-check"/>
<span v-if="writeNotStartPrompt">{{ writeNotStartPrompt }}</span>
</p>
</div>
<div v-if="writeStatus==1">
<project-form
@submit="submitForm"
:projectConfig="projectConfig"
v-if="projectConfig.projectKey"/>
</div>
<div v-if="writeFinish">
<div v-if="writeStatus==2">
<div style="text-align: center">
<el-image
v-if="userProjectSetting.submitPromptImg"
@ -15,7 +21,7 @@
</div>
<p style="text-align: center" v-if="userProjectSetting.submitPromptText">
<i class="el-icon-check"/>
{{userProjectSetting.submitPromptText}}
<span v-if="userProjectSetting.submitPromptText">{{ userProjectSetting.submitPromptText }}</span>
</p>
</div>
</div>
@ -23,6 +29,11 @@
<script>
import ProjectForm from './ProjectForm'
import loadWXJs from '@/utils/loadWxSdk'
import defaultValue from '@/utils/defaultValue'
import {getQueryString} from '@/utils'
let wx
export default {
name: 'WriteView',
@ -34,33 +45,162 @@ export default {
preview: false,
showBtns: true
},
writeFinish: false,
userProjectSetting: {}
writeStatus: 1,
writeNotStartPrompt: '',
userProjectSetting: {
submitPromptText: ''
},
//
wxAuthorizationUrl: '',
wxAuthorizationCode: '',
wxUserInfo: {},
wxSignature: {}
}
},
mounted() {
beforeCreate() {
},
created() {
let key = this.$route.query.key
this.projectConfig.projectKey = key
let wxCode = getQueryString('code')
alert(wxCode)
if (wxCode) {
alert(wxCode)
this.wxAuthorizationCode = wxCode
this.getWxAuthorizationUserInfo()
}
this.getWxAuthorizationUrl()
this.queryProjectSettingStatus()
this.queryProjectSetting()
//
let url = window.location.href.split(('#'))[0]
this.$api.get('/wx/jsapi/signature', {params: {url: url}}).then(res => {
this.wxSignature = res.data
this.setWxConfig()
})
},
mounted() {
},
components: {
ProjectForm
}, methods: {
queryProjectSettingStatus() {
//
this.$api.get(`/user/project/setting/status/${this.projectConfig.projectKey}`).then(res => {
if (res.msg) {
this.writeNotStartPrompt = res.msg
this.writeStatus = 0
}
})
},
getWxAuthorizationUserInfo() {
let wxAuthorizationCode = this.wxAuthorizationCode
//code
this.$api.get(`/authorization/user/info`, {
params: {
code: wxAuthorizationCode
}
}).then(res => {
if (res.data) {
this.wxUserInfo = res.data
alert(res.data)
}
})
},
getWxAuthorizationUrl() {
//url
this.$api.get(`/wx/jsapi/authorization/url`, {params: {url: window.location.href}}).then(res => {
if (res.data) {
this.wxAuthorizationUrl = res.data
}
})
},
setWxConfig() {
let signature = this.wxSignature
loadWXJs(val => {
wx = val
wx.config({
debug: false, // ,apialertpclogpc
appId: signature.appId, //
timestamp: signature.timestamp, //
nonceStr: signature.nonceStr, //
signature: signature.signature,//
jsApiList: [
'updateAppMessageShareData',
'updateTimelineShareData',
'showMenuItems',
'hideMenuItems',
'chooseWXPay'
] // 使JS
})
this.setWxProjectShare()
})
},
/**
* 微信分享
*/
setWxProjectShare() {
let {shareImg, shareTitle, shareDesc} = this.userProjectSetting
console.log(wx)
wx.ready(function() { //
console.log('ready')
wx.updateAppMessageShareData({
title: shareTitle ? shareTitle : defaultValue.projectShareTitle, //
desc: shareDesc ? shareDesc : defaultValue.projectShareDesc, //
link: window.location.href, // JS
imgUrl: shareImg ? shareImg : defaultValue.projectShareImg, //
success: function() {
//
console.log('succcess')
},
fail: function() {
console.log('fail')
}
})
wx.updateTimelineShareData({
title: shareTitle ? shareTitle : defaultValue.projectShareTitle, //
desc: shareDesc ? shareDesc : defaultValue.projectShareDesc, //
link: window.location.href, // JS
imgUrl: shareImg ? shareImg : defaultValue.projectShareImg, //
success: function() {
//
console.log('succcess')
},
fail: function() {
console.log('fail')
}
})
})
},
queryProjectSetting() {
this.$api.get(`/user/project/setting/query/${this.projectConfig.projectKey}`).then(res => {
this.userProjectSetting = res.data
if(res.data.wxWrite){
let ua = navigator.userAgent.toLowerCase()
let isWeixin = ua.indexOf('micromessenger') != -1
let isAndroid = ua.indexOf('android') != -1
let isIos = (ua.indexOf('iphone') != -1) || (ua.indexOf('ipad') != -1)
if (!isWeixin) {
document.head.innerHTML = '<title>抱歉,出错了</title><meta charset="utf-8"><meta name="viewport" content="width=device-width, initial-scale=1, user-scalable=0"><link rel="stylesheet" type="text/css" href="https://res.wx.qq.com/open/libs/weui/0.4.1/weui.css">'
document.body.innerHTML = '<div class="weui_msg"><div class="weui_icon_area"><i class="weui_icon_info weui_icon_msg"></i></div><div class="weui_text_area"><h4 class="weui_msg_title">请在微信客户端打开链接</h4></div></div>'
if (res.data) {
this.userProjectSetting = res.data
//
if (res.data && res.data.wxWrite) {
//
if (res.data.recordWxUser && !this.wxAuthorizationCode) {
console.log(this.wxAuthorizationUrl)
location.href = this.wxAuthorizationUrl
} else {
this.onlyWxOpenHandle()
}
}
}
})
},
onlyWxOpenHandle() {
let ua = navigator.userAgent.toLowerCase()
let isWeixin = ua.indexOf('micromessenger') != -1
let isAndroid = ua.indexOf('android') != -1
let isIos = (ua.indexOf('iphone') != -1) || (ua.indexOf('ipad') != -1)
if (!isWeixin) {
document.head.innerHTML = '<title>抱歉,出错了</title><meta charset="utf-8"><meta name="viewport" content="width=device-width, initial-scale=1, user-scalable=0"><link rel="stylesheet" type="text/css" href="https://res.wx.qq.com/open/libs/weui/0.4.1/weui.css">'
document.body.innerHTML = '<div class="weui_msg"><div class="weui_icon_area"><i class="weui_icon_info weui_icon_msg"></i></div><div class="weui_text_area"><h4 class="weui_msg_title">请在微信客户端打开链接</h4></div></div>'
}
},
submitForm(data) {
this.$api.post('/user/project/result/create', {
'projectKey': this.projectConfig.projectKey,

54
src/views/home/index.vue

@ -1,34 +1,44 @@
<template>
<el-container>
<el-header height="80px" class="homeHeaderView">
<el-header height="80" class="home-header-view">
<el-row type="flex" align="middle">
<el-col :span="4" :offset="1">
<img src="@/assets/images/indexLogo.png" class="headerLogoImg"
<img src="@/assets/images/indexLogo.png" class="header-logo-img"
@click="$router.push({path:'/project/create'})"
>
</el-col>
<el-col :span="6">
<el-col :span="10">
<el-menu :default-active="menuIndex" mode="horizontal" :router="true" text-color="#205BB5"
active-text-color="#205BB5"
>
<el-menu-item v-for="(item, index) in menuRouters" :key="index" :index="item.routerPath"
:route="item.routerPath" class="menuItem"
:route="item.routerPath" class="menu-item"
>
{{ item.title }}
</el-menu-item>
</el-menu>
<!-- <span v-for="(item, index) in menuRouters" :key="index"-->
<!-- class="menu-item"-->
<!-- @click="activeMenuHandle(item.routerPath)"-->
<!-- >-->
<!-- {{ item.title }}-->
<!-- </span>-->
</el-col>
<el-col :offset="8" :span="1">
<el-col :span="1">
<el-button round>升级</el-button>
</el-col>
<el-col :span="1">
<svg-icon name="loginWx" style="width: 24px; height: 24px;" />
<div style="display: flex; align-items: center; justify-content: center;">
<svg-icon name="loginWx" style="width: 24px; height: 24px;" />
</div>
</el-col>
<el-col :span="1">
<el-link href="https://element.eleme.io" target="_blank">帮助</el-link>
</el-col>
<el-col :span="3">
<img :src="getUserInfo.avatar" style="width: 48px; height: 48px; border-radius: 100px;">
<div style="display: flex; align-items: center; justify-content: center;">
<img :src="getUserInfo.avatar" style="width: 50px; height: 50px; border-radius: 100px;">
</div>
</el-col>
</el-row>
</el-header>
@ -76,31 +86,41 @@ export default {
},
mounted() {
this.menuIndex = this.$route.path
},
methods: {
activeMenuHandle(routerPath) {
this.menuIndex = routerPath
}
}
}
</script>
<style scoped>
.menuItem {
<style lang="scss" scoped>
.menu-item {
line-height: 80px;
height: 80px;
font-size: 19px;
text-align: left;
font-weight: 550;
float: right;
color: rgba(32, 91, 181, 100);
font-size: 20px;
&:hover {
cursor: pointer;
}
}
.el-menu.el-menu--horizontal {
border-bottom: none;
}
.homeHeaderView {
line-height: 20px;
.home-header-view {
line-height: 90px;
height: 80px;
background-color: rgba(255, 255, 255, 100);
color: rgba(16, 16, 16, 100);
font-size: 14px;
text-align: center;
}
.headerLogoImg {
width: 225px;
height: 62px;
.header-logo-img {
width: 225px;
height: 62px;
float: left;
}
}
</style>

6
vue.config.js

@ -50,7 +50,7 @@ const cdn = {
}
module.exports = {
publicPath: '',
publicPath: '/',
productionSourceMap: false,
devServer: {
disableHostCheck: true,
@ -58,8 +58,8 @@ module.exports = {
port: 8888,
// 开发环境默认开启反向代理,如果不需要请自行注释
proxy: {
'/': {
target: process.env.VUE_APP_API_ROOT,
'/tduck-api': {
target: 'http://localhost:8999/',
changeOrigin: true
}
}

48
yarn.lock

@ -3074,6 +3074,15 @@ cli-width@^3.0.0:
resolved "https://registry.npmjs.org/cli-width/-/cli-width-3.0.0.tgz#a2f48437a2caa9a22436e794bf071ec9e61cedf6"
integrity sha512-FxqpkPPwu1HjuN93Omfm4h8uIanXofW0RxVEW3k5RKx+mJJYSthzNhp32Kzxxy3YAEZ/Dc/EWN1vZRY0+kOhbw==
clipboard@^2.0.0:
version "2.0.6"
resolved "https://registry.yarnpkg.com/clipboard/-/clipboard-2.0.6.tgz#52921296eec0fdf77ead1749421b21c968647376"
integrity sha512-g5zbiixBRk/wyKakSwCKd7vQXDjFnAMGHoEyBogG/bw9kTD9GvdAvaoRR1ALcEzt3pVKxZR0pViekPMIS0QyGg==
dependencies:
good-listener "^1.2.2"
select "^1.1.2"
tiny-emitter "^2.0.0"
clipboardy@^2.3.0:
version "2.3.0"
resolved "https://registry.npm.taobao.org/clipboardy/download/clipboardy-2.3.0.tgz#3c2903650c68e46a91b388985bc2774287dba290"
@ -3871,6 +3880,11 @@ delayed-stream@~1.0.0:
resolved "https://registry.npm.taobao.org/delayed-stream/download/delayed-stream-1.0.0.tgz#df3ae199acadfb7d440aaae0b29e2272b24ec619"
integrity sha1-3zrhmayt+31ECqrgsp4icrJOxhk=
delegate@^3.1.2:
version "3.2.0"
resolved "https://registry.yarnpkg.com/delegate/-/delegate-3.2.0.tgz#b66b71c3158522e8ab5744f720d8ca0c2af59166"
integrity sha512-IofjkYBZaZivn0V8nnsMJGBr4jVLxHDheKSW88PyxS5QC4Vo9ZbZVvhzlSxY87fVq3STR6r+4cGepyHkcWOQSw==
depd@~1.1.2:
version "1.1.2"
resolved "https://registry.npm.taobao.org/depd/download/depd-1.1.2.tgz#9bcd52e14c097763e749b274c4346ed2e560b5a9"
@ -5257,6 +5271,13 @@ gonzales-pe@^4.3.0:
dependencies:
minimist "^1.2.5"
good-listener@^1.2.2:
version "1.2.2"
resolved "https://registry.yarnpkg.com/good-listener/-/good-listener-1.2.2.tgz#d53b30cdf9313dffb7dc9a0d477096aa6d145c50"
integrity sha1-1TswzfkxPf+33JoNR3CWqm0UXFA=
dependencies:
delegate "^3.1.2"
graceful-fs@^4.1.11, graceful-fs@^4.1.15, graceful-fs@^4.1.2, graceful-fs@^4.1.6, graceful-fs@^4.2.2:
version "4.2.3"
resolved "https://registry.npm.taobao.org/graceful-fs/download/graceful-fs-4.2.3.tgz#4a12ff1b60376ef09862c2093edd908328be8423"
@ -8680,6 +8701,11 @@ 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"
@ -9325,6 +9351,11 @@ select-hose@^2.0.0:
resolved "https://registry.npm.taobao.org/select-hose/download/select-hose-2.0.0.tgz#625d8658f865af43ec962bfc376a37359a4994ca"
integrity sha1-Yl2GWPhlr0Psliv8N2o3NZpJlMo=
select@^1.1.2:
version "1.1.2"
resolved "https://registry.yarnpkg.com/select/-/select-1.1.2.tgz#0e7350acdec80b1108528786ec1d4418d11b396d"
integrity sha1-DnNQrN7ICxEIUoeG7B1EGNEbOW0=
selfsigned@^1.10.7:
version "1.10.7"
resolved "https://registry.npm.taobao.org/selfsigned/download/selfsigned-1.10.7.tgz#da5819fd049d5574f28e88a9bcc6dbc6e6f3906b"
@ -10403,6 +10434,11 @@ timsort@^0.3.0:
resolved "https://registry.npm.taobao.org/timsort/download/timsort-0.3.0.tgz#405411a8e7e6339fe64db9a234de11dc31e02bd4"
integrity sha1-QFQRqOfmM5/mTbmiNN4R3DHgK9Q=
tiny-emitter@^2.0.0:
version "2.1.0"
resolved "https://registry.yarnpkg.com/tiny-emitter/-/tiny-emitter-2.1.0.tgz#1d1a56edfc51c43e863cbb5382a72330e3555423"
integrity sha512-NB6Dk1A9xgQPMoGqC5CVXn123gWyte215ONT5Pp5a0yt4nlEoO1ZWeCwpncaekPHXO60i47ihFnZPiRPjRMq4Q==
title-case@^2.1.0:
version "2.1.1"
resolved "https://registry.npm.taobao.org/title-case/download/title-case-2.1.1.tgz#3e127216da58d2bc5becf137ab91dae3a7cd8faa"
@ -10978,6 +11014,13 @@ vm-browserify@^1.0.1:
resolved "https://registry.npm.taobao.org/vm-browserify/download/vm-browserify-1.1.2.tgz?cache=0&sync_timestamp=1572870717730&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fvm-browserify%2Fdownload%2Fvm-browserify-1.1.2.tgz#78641c488b8e6ca91a75f511e7a3b32a86e5dda0"
integrity sha1-eGQcSIuObKkadfUR56OzKobl3aA=
vue-clipboard2@^0.3.1:
version "0.3.1"
resolved "https://registry.yarnpkg.com/vue-clipboard2/-/vue-clipboard2-0.3.1.tgz#6e551fb7bd384889b28b0da3b12289ed6bca4894"
integrity sha512-H5S/agEDj0kXjUb5GP2c0hCzIXWRBygaWLN3NEFsaI9I3uWin778SFEMt8QRXiPG+7anyjqWiw2lqcxWUSfkYg==
dependencies:
clipboard "^2.0.0"
vue-eslint-parser@^7.1.1:
version "7.1.1"
resolved "https://registry.npmjs.org/vue-eslint-parser/-/vue-eslint-parser-7.1.1.tgz#c43c1c715ff50778b9a7e9a4e16921185f3425d3"
@ -11022,6 +11065,11 @@ vue-meta@^2.4.0:
dependencies:
deepmerge "^4.2.2"
vue-qr@^2.3.0:
version "2.3.0"
resolved "https://registry.yarnpkg.com/vue-qr/-/vue-qr-2.3.0.tgz#d659ee9db2bc717a2b46bd0e7a5414e75a7a3bba"
integrity sha512-qcmMKNVz4dSZjXsUIQmK/QoODvOYg8+EyCaCynZfwcUJk4mjsevEv+z4uYoRz0Or1ET9UMwjV7/GQdHTSFCIIA==
vue-router@^3.4.8:
version "3.4.8"
resolved "https://registry.npmjs.org/vue-router/-/vue-router-3.4.8.tgz#2c06261d35d8075893470352d42d70b6287b8194"

Loading…
Cancel
Save