python后端,需要使用base.html 作为公共模板, 各个页面分为 index.html login.html regiester.html等
<html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <meta http-equiv="X-UA-Compatible" content="ie=edge"> <title>{% block title %}Default title{% endblock title %}</title> <link rel="stylesheet" href="https://res.wx.qq.com/t/wx_fed/weui-source/res/2.6.4/weui.css"/> <script src="https://cdn.jsdelivr.net/npm/jquery@3.3.1/dist/jquery.min.js"></script> <script src="https://cdn.jsdelivr.net/npm/js-base64@2.5.1/base64.min.js"></script> <script src="/redirectServer/static/etuiapp/js/flexible-0.3.4.js"></script> <!-- https://vant-contrib.gitee.io/vant/#/zh-CN/ --> <link rel="stylesheet" href="https://fastly.jsdelivr.net/npm/vant@4/lib/index.css" /> <script src="https://fastly.jsdelivr.net/npm/vue@3"></script> <script src="https://fastly.jsdelivr.net/npm/vant@4/lib/vant.min.js"></script> <link rel="stylesheet" href="/xxx/xxx/xxx/css/xxx.css"/> {% block head %} {% endblock head %} {% block style %} {% endblock style %} </head> <body> <div id="app"> {% block content %}{% endblock content %} </div> <script> // 检查版本更新 function checkUpdateJS(curVer) { console.log("checkUpdateJS, current ver: " + curVer); let url = '/xxxx/xxx/getNewesetVersionUrl?clientVer=' + curVer; $.getJSON(url, function (res) { //回调函数 console.log("checkUpdateJS 检查升级 res : " + JSON.stringify(res)); if(res.code == 0 && res.data != undefined && res.data != "") { let msg = "app有新的版本\n待下载完成后弹窗更新,请点击允许"; if(res.updateMessage != undefined && res.updateMessage != "") { msg += "\n本次更新内容:" + res.updateMessage; } vant.showConfirmDialog({ title: '升级提醒', message: msg, }).then(() => { // on confirm console.log("confirm"); if (typeof (DownloadUpdatePackage) != "undefined") { DownloadUpdatePackage.postMessage(res.data); } }).catch(() => { // on cancel }); } }); } // 导航栏跳转,点击 首页、任务、报告、我的 function globalJumpTo(toPath) { let oldUrl = window.location.href; let cleanUrl = oldUrl.split("?")[0]; let host = oldUrl.split("/")[2]; let columnNum = cleanUrl.split("/").length; let lastPart = cleanUrl.split("/")[columnNum-1]; let baseUrl = cleanUrl.replace(lastPart, ""); let newUrl = baseUrl + toPath; if(oldUrl.indexOf("?") != -1) { let params = oldUrl.split("?")[1]; let paramPairs = params.split("&"); for(let i=0;i<paramPairs.length;i++) { let param = paramPairs[i]; if(param.indexOf("dc=") != -1) { newUrl += '?' + param } } } console.log("jump to newUrl: ", newUrl); // 此处,不加setTimeout,偶尔会不生效。 简直是个奇怪的问题 // window.location.href = newUrl; setTimeout('window.location.href = "' + newUrl + '";' , 50); } function parseJsonIfStr(data) { let d = data; if(typeof data == "string") { d = JSON.parse(data); } return d; } function myUuid() { let s = []; let hexDigits = "0123456789abcdef"; for (let i = 0; i < 36; i++) { 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] = "-"; let uuid = s.join(""); uuid = uuid.split("-").join(""); return uuid; } // 适配多种大小的屏幕。使用淘宝方案: https://blog.csdn.net/qq_32614411/article/details/80980539/ </script> {% block script %} <script> let empty=null; </script> {% endblock script %} </body> </html>
index.html
{% extends "/base.html" %} {% block title %}欢迎页{% endblock title %} {% block content %} <div class="page"> <div class="page__bd" style="width:100%;height: 100%;position:fixed;background-color: #F7F7F7;"> <div class="weui-tab"> <van-dialog :show="show" message="提醒内容" @confirm="clickShowDialog"> </van-dialog> <div id="panel1" role="tabpanel" aria-labelledby="tab1" class="weui-tab__panel"> <div class="page__bd" style="padding-left:0.05rem; padding-top:0.05rem; padding-bottom:0.05rem;"> <div id="header" style="position: sticky;"> <van-space> <van-button color="linear-gradient(to right, #ff6034, #ee0a24)" size="mini" style="border-radius:10px;margin-left:10px;height:0.9rem;" round> <van-swipe vertical class="notice-swipe" :autoplay="2000" :touchable="false" :show-indicators="false"> <van-swipe-item>做任务</van-swipe-item> <van-swipe-item>赚佣金</van-swipe-item> </van-swipe> </van-button> <div class="weui-flex__item"> <input id="js_input1" style="width: 6.5rem; height:0.75rem; border-radius: 0.6rem; border: 1px solid #CCC; text-indent: 1em; outline:none" class="weui-input" type="text" placeholder="请输入" maxlength="16" /> </div> <div style="padding-left:0.2rem; padding-top:4px"> <img class="weui-media-box__thumb avatar" style="width:1.2rem;height:1.2rem" :src="userInfo.myAvatarUrl" alt=""> </div> </van-space> <div> <van-notice-bar mode="closeable" left-icon="volume-o" text="全局公告栏内容。"></van-notice-bar> </div> </div> <van-tabs v-model:active="active" shrink sticky style="margin-bottom: 40px;" @change="onTabChange"> <van-pull-refresh v-model="pullRefresh" @refresh="onRefresh"> <van-tab title="全部"> <van-loading v-if="loading==1" size="24px" vertical style="margin-top:2rem">加载中...</van-loading> <van-empty v-if="loading==0 && ideas.length==0" description="暂无结果"></van-empty> <div v-for="(idea, index) in ideas"> <div v-if="idea.ideaType === 1" class="card" > <div class="item" @click="onClickIdea(idea)"> <img :src="idea.images[0].url" alt=""> </div> <van-space style="width: 70%" direction="vertical" fill> <div class="title" @click="onClickIdea(idea)"> ${idea.title}</div> <div> <img class="cu-avatar round" :src="idea.accountObj.firstUserObj.avatarUrl"> </img> ${idea.accountObj.companyName} </div> <van-space> <text class="text-price text-red">售价 ${getRealPrice(idea)}</text> <text class="text-price text-grey" style="text-decoration:line-through">原价 ${getOriginPrice(idea)}</text> <text class="text-red">卖出 ${idea.soldNum == undefined ? 0 : idea.soldNum} 件</text> </van-space> <div class="flex justify-between"> <view v-if="idea.price" class="flex" style="align-items: center;"> <text class="text-red" style="margin-right: 5rpx;">每件赚</text> <view class="text-red text-price" style="font-size: 16px;"> ${idea.priceProfit} </view> <van-icon name="question-o" @click="clickShowDialog" /> </view> <van-button icon="share" color="linear-gradient(to right, #ff9700, #ed1c24)" style="height: 22px; font-size: 2px;" @click="onClickShare(idea)">带货</van-button> </div> </van-space> </div> <div v-if="idea.ideaType === 0" class="card"> <div class="item" @click="onClickIdea(idea)"> <img :src="idea.images[0].url" alt=""> </div> <van-space style="width: 70%" direction="vertical" fill> <div class="title" @click="onClickIdea(idea)"> ${idea.title}</div> <div> <img class="cu-avatar round" :src="idea.accountObj.firstUserObj.avatarUrl"> </img> ${idea.accountObj.companyName} </div> <view class="u-flex"> <view v-if="idea.regionName" class="cu-tag bg-gray radius"> ${getRegionName(idea.regionName)} </view> <div v-else class="cu-tag bg-gray radius">投放:全部地区</div> </view> <div class="flex justify-between"> <view v-if="idea.price" class="flex" style="align-items: center;"> <text class="text-red" style="margin-right: 5rpx;">赚</text> <view class="text-red text-price" style="font-size: 16px;"> ${idea.priceProfit} </view> <van-icon name="question-o" @click="clickShowDialog" /> </view> <van-button icon="share" color="linear-gradient(to right, #ff9700, #ed1c24)" style="height: 22px; font-size: 2px;" @click="onClickShare(idea)">推广</van-button> </div> </van-space> </div> <div v-if="idea.ideaType === 2" class="card"> <div class="app"> <div class="title">${idea.info.name.substring(0,6)}</div> <div class="appbody"> <img :src="idea.info.iconImage" alt=""> <div v-if="idea.info" class="flex-direction" style="flex: 1"> <div style="font-size: small;">${idea.info.desc}</div> <div style="font-weight: bolder; margin: 0.5em 0"> <van-rate v-model="idea.info.rate" allow-half color="#f3c14e" :size="15" /> </div> <div style="font-weight: bolder; justify-content: space-between; align-items: center;" class="flex"> <span style="font-size: small;color: rgba(50, 50, 50, 0.5);flex:1">版本号:${idea.info.version}</span> <span style="font-size: small;color: #ff970095; flex:1">赚¥${idea.priceProfit}元<van-icon name="question-o" @click="clickShowDialog" /></span> <div class="flex"> <a href="">隐私</a> <a href="">权限</a> </div> </div> </div> </div> <div class="_btn-download" @click="triggerDownloadApp(idea)">免费下载</div> <div v-if="idea.accountObj" class="footer" style="color: rgba(50, 50, 50, 0.5);"> ${idea.accountObj.companyName}</div> </div> </div> </div> </van-tab> <van-tab title="拉新"> <van-loading v-if="loading==1" size="24px" vertical style="margin-top:2rem">加载中...</van-loading> <van-empty v-if="loading==0 && ideas.length==0" description="暂无结果"></van-empty> <div v-for="(idea, index) in ideas"> <div v-if="idea.ideaType === 2" class="card"> <div class="app"> <div class="title">${idea.info.name.substring(0,6)}</div> <div class="appbody"> <img :src="idea.info.iconImage" alt=""> <div v-if="idea.info" class="flex-direction" style="flex: 1"> <div style="font-size: small;">${idea.info.desc}</div> <div style="font-weight: bolder; margin: 0.5em 0"> <van-rate v-model="idea.info.rate" allow-half color="#f3c14e" :size="15" /> </div> <div style="font-weight: bolder; justify-content: space-between; align-items: center;" class="flex"> <span style="font-size: small;color: rgba(50, 50, 50, 0.5);flex:1">版本号:${idea.info.version}</span> <span style="font-size: small;color: #ff970095; flex:1">赚¥${idea.priceProfit}元<van-icon name="question-o" @click="clickShowDialog" /></span> <div class="flex"> <a href="">隐私</a> <a href="">权限</a> </div> </div> </div> </div> <div class="_btn-download" @click="triggerDownloadApp(idea)">免费下载</div> <div v-if="idea.accountObj" class="footer" style="color: rgba(50, 50, 50, 0.5);"> ${idea.accountObj.companyName}</div> </div> </div> </div> </van-tab> <van-tab title="网推"> <van-loading v-if="loading==1" size="24px" vertical style="margin-top:2rem">加载中...</van-loading> <van-empty v-if="loading==0 && ideas.length==0" description="暂无结果"></van-empty> <div v-for="(idea, index) in ideas"> <div v-if="idea.ideaType === 0" class="card"> <div class="item"> <img :src="idea.images[0].url" alt=""> </div> <van-space style="width: 70%" direction="vertical" fill> <div class="title"> ${idea.title}</div> <div> <img class="cu-avatar round" :src="idea.accountObj.firstUserObj.avatarUrl"> </img> ${idea.accountObj.companyName} </div> <view class="u-flex"> <view v-if="idea.regionName" class="cu-tag bg-gray radius"> ${getRegionName(idea.regionName)} </view> <div v-else class="cu-tag bg-gray radius">投放:全部地区</div> </view> <div class="flex justify-between"> <view v-if="idea.price" class="flex" style="align-items: center;"> <text class="text-red" style="margin-right: 5rpx;">赚</text> <view class="text-red text-price" style="font-size: 16px;"> ${idea.priceProfit} </view> <van-icon name="question-o" @click="clickShowDialog" /> </view> <van-button icon="share" color="linear-gradient(to right, #ff9700, #ed1c24)" style="height: 22px; font-size: 2px;">推广</van-button> </div> </van-space> </div> </div> </van-tab> <van-tab title="好货"> <van-loading v-if="loading==1" size="24px" vertical style="margin-top:2rem">加载中...</van-loading> <van-empty v-if="loading==0 && ideas.length==0" description="暂无结果"></van-empty> <div v-for="(idea, index) in ideas"> <div v-if="idea.ideaType == 1" class="card"> <div class="item"> <img :src="idea.images[0].url" alt=""> </div> <van-space style="width: 70%" direction="vertical" fill> <div class="title"> ${idea.title}</div> <div> <img class="cu-avatar round" :src="idea.accountObj.firstUserObj.avatarUrl"> </img> ${idea.accountObj.companyName} </div> <van-space> <text class="text-price text-red">售价 ${getRealPrice(idea)}</text> <text class="text-price text-grey" style="text-decoration:line-through">原价 ${getOriginPrice(idea)}</text> <text class="text-red">卖出 ${idea.soldNum == undefined ? 0 : idea.soldNum} 件</text> </van-space> <div class="flex justify-between"> <view v-if="idea.price" class="flex" style="align-items: center;"> <text class="text-red" style="margin-right: 5rpx;">每件赚</text> <view class="text-red text-price" style="font-size: 16px;"> ${idea.priceProfit} </view> <van-icon name="question-o" @click="clickShowDialog" /> </view> <van-button icon="share" color="linear-gradient(to right, #ff9700, #ed1c24)" style="height: 22px; font-size: 2px;" @click="onClickShare(idea)">带货</van-button> </div> </van-space> </div> </div> </van-tab> </van-pull-refresh> </van-tabs> </div> </div> <van-tabbar v-model="tabActive"> <van-tabbar-item badge="3"> <span>首页</span> <template #icon="props"> <img :src="props.active ? tabIcon.home.active : tabIcon.home.inactive" /> </template> </van-tabbar-item> <van-tabbar-item> <span>报告</span> <template #icon="props"> <img :src="props.active ? tabIcon.report.active : tabIcon.report.inactive" /> </template> </van-tabbar-item> <van-tabbar-item @click="checkLoginAndJump('my')"> <span>我的</span> <template #icon="props"> <img :src="props.active ? tabIcon.my.active : tabIcon.my.inactive" /> </template> </van-tabbar-item> </van-tabbar> </div> </div> </div> {% endblock content %} {% block script %} <script type="text/javascript"> if (typeof (Toaster) != "undefined") { //Toaster.postMessage("flutter收到来自于网页的信息: 😄"); } // 上报点击数据 function uploadClickInfo(s) { let url = '/redirectServer/etuiapp/convertDownload'; console.log("received s: " + s); let req = JSON.parse(s); console.log("upload click info req: ", req); $.post(url, req, function (res) { //回调函数 console.log("convert download res : ", res); }); } </script> <script type="text/javascript"> const app = Vue.createApp({ delimiters: ["${", "}"], //vue变量使用 ${xxx} 形式 data() { window.danny = this return { userInfo: { nickName: '蓝色流星', roleType: 'C', phoneNum: '', userId: '', myAvatarUrl: 'https://6465-dev01-8gpbb3wb781836c1-1304695802.tcb.qcloud.la/static/avatar.png', }, loginFlag: -1, // 未初始化状态 tempName: "tempName123", active: 0, ideas: [], loading: 0, pullRefresh: false, tabActive: 0, appRate: 2.5, show: false, working: false, tabIcon: { home: { active: 'https://6465-dev01-8gpbb3wb781836c1-1304695802.tcb.qcloud.la/static/icon/B-homepage-checked.png', inactive: 'https://6465-dev01-8gpbb3wb781836c1-1304695802.tcb.qcloud.la/static/icon/B-homepage-unchecked.png', }, report: { active: 'https://6465-dev01-8gpbb3wb781836c1-1304695802.tcb.qcloud.la/static/icon/B-report-checked.png', inactive: 'https://6465-dev01-8gpbb3wb781836c1-1304695802.tcb.qcloud.la/static/icon/B-report-unchecked.png', }, my: { active: 'https://6465-dev01-8gpbb3wb781836c1-1304695802.tcb.qcloud.la/static/icon/mine-checked.png', inactive: 'https://6465-dev01-8gpbb3wb781836c1-1304695802.tcb.qcloud.la/static/icon/C-mine-unchecked.png', }, }, } }, computed: {}, methods: { splitEmail(email) { if (email != undefined && email.indexOf("@") != -1) { return email.split("@")[0]; } return email }, jumpTo(path) { // 调用全局函数,需要在vue methods中才能调用。在html中无法直接调用 globalJumpTo(path); }, checkLoginAndJump(path) { console.log("click jumpto, path: ", path); if (this.loginFlag == 1) { globalJumpTo(path); } if (this.loginFlag == 0) { globalJumpTo('login'); } }, fetchIdeas(ideaType) { this.loading = 1; var seed = window.localStorage.getItem("forceUseSeed"); var d = new Date(); seed += "_" + d.getDate(); var url = "/xxx/xxx/queryIdeasRandom?"; //url += "pageNum=1" if (ideaType != -1) { url += "&ideaType=" + ideaType; } $.getJSON(url).then((res) => { res.data.forEach(element => { this.ideas.push(element) }); console.log("ideas: ", this.ideas); this.loading = 0; }); }, triggerDownloadApp(ideaObj) { //console.log("loginFlag:", this.loginFlag); if (this.loginFlag != 1) { vant.showNotify({ type: 'warning', message: "登录后下载App才能获得奖励" }); return; } if (ideaObj.ideaType !== 2) { vant.showNotify({ type: 'warning', message: "创意类型不是app下载" }); return; } if (ideaObj.info == undefined) { vant.showNotify({ type: 'warning', message: "创意类型不是app下载" }); return; } if (this.userInfo.phoneNum == undefined || this.userInfo.phoneNum == "" || this.userInfo.userId == undefined || this.userInfo.userId == "") { vant.showNotify({ type: 'warning', message: "登录后下载App才能获得奖励" }); return; } if (typeof (DownloadApp) == "undefined") { vant.showNotify({ type: 'warning', message: "必须在E推App中才能操作" }); return; } var type_text = ['unknown','ethernet','wifi','2g','3g','4g','none']; var connection = navigator.connection||navigator.mozConnection||navigator.webkitConnection; if(typeof(connection.type) == "number"){ connection.type_text = type_text[connection.type]; }else{ connection.type_text = connection.type; } if(navigator.onLine == false) { vant.showNotify({ type: 'warning', message: "当前网络不通,请检查您的网络" }); return; } if(connection.type_text == 'wifi' || connection.type_text == 'ethernet') { this.triggerDownloadInner(ideaObj); } else { let self = this; // 弹框确认 vant.showConfirmDialog({ title: '流量提醒', message: '您当前正在使用移动网络,下载app会消耗流量。点击确认继续下载,点击取消不下载', }) .then(() => { // on confirm self.triggerDownloadInner(ideaObj); }) .catch(() => { // on cancel }); } }, triggerDownloadInner(ideaObj) { let clickId = myUuid(); let messageObj = { ideaId: ideaObj._id, ideaObj: ideaObj, phoneNum: this.userInfo.phoneNum, userId: this.userInfo.userId, downloadLink: ideaObj.info.downloadLink, clickId: clickId, } DownloadApp.postMessage(JSON.stringify(messageObj)); }, getOriginPrice(idea) { let originalPrice = 0; if (idea.ideaType === 1) { if (idea.models && idea.models.length > 0) { originalPrice = idea.models[0].originalPrice idea.models.forEach(m => { originalPrice = Math.min(originalPrice, m.originalPrice) }) } } return originalPrice; }, getRegionName(name) { // 后端存储时,存储了全部原始信息,展示时为了简洁,不展示重复的内容 let out = name; if (out.indexOf("全部地区-全部地区-全部地区") != -1) { out = out.replace("全部地区-全部地区-全部地区", "全部地区"); } if (out.indexOf("全部地区-全部地区") != -1) { out = out.replace("全部地区-全部地区", "全部地区"); } if (out != "全部地区") { out = "仅投放:" + out; } else { out = "投放:" + out; } return out; }, getMyUserInfo() { //console.log("get my user info"); let self = this; $.getJSON("/xxxx/xxxx/getMyUserInfo") .then((ret) => { if (ret.code == -99) { console.log("INFO: user not login") self.loginFlag = 0; } else { console.log("user info: ", JSON.stringify(ret.data)); self.loginFlag = 1; if (ret.data && ret.data.avatarUrl) { self.userInfo.myAvatarUrl = ret.data.avatarUrl; self.userInfo.phoneNum = ret.data.phoneNum; self.userInfo.userId = ret.data.openid; } } }); }, triggerCheckUpdate() { if (typeof (CheckUpdateFL) == "undefined") { // Do Nothing console.log("xudong debug CheckUpdateFL is null "); } else { console.log("in mount function, check update is called"); CheckUpdateFL.postMessage("check now"); } }, onClickShare(idea) { // 如果 this.userInfo.userId 为空,则属于未登录状态,跳转到登录页面 console.log("click share ideaId: " + idea._id); if(this.userInfo.userId == undefined || this.userInfo.userId == "") { // https://vant-ui.github.io/vant/#/zh-CN/dialog vant.showDialog({ title: '提示', message: '您尚未登录,请登录后操作', }).then(() => { globalJumpTo('login'); }); } else { // 属于已登录用户,且在小程序中注册了。则直接跳转到小程序分享页面。 let path = 'pages/preview/preview?ideaId=' + idea._id + '&f=app'; console.log("launch mini program: path: " + path); vant.showNotify({ type: 'success', message: "尝试调起E推小程序,如弹窗请点击允许" }); doLaunchMiniProgram(path); } }, onRefresh() { setTimeout(() => { let seed = myUuid(); window.localStorage.setItem("forceUseSeed", seed); switch (this.active) { case 1: this.ideas = this.ideas.filter(i => !(i.ideaType == 2)) this.fetchIdeas(2); break; case 2: this.ideas = this.ideas.filter(i => !(i.ideaType == 0)) this.fetchIdeas(0); break; case 3: this.ideas = this.ideas.filter(i => !(i.ideaType == 1)) this.fetchIdeas(1); break; default: this.ideas = []; this.fetchIdeas(-1); break; } this.pullRefresh = false; }, 1000); }, onTabChange() { switch (this.active) { case 1: if (this.ideas.filter(i => i.ideaType == 2).length == 0) { this.fetchIdeas(2); } break; case 2: if (this.ideas.filter(i => i.ideaType == 0).length == 0) { this.fetchIdeas(0); } break; case 3: if (this.ideas.filter(i => i.ideaType == 1).length == 0) { this.fetchIdeas(1); } break; } }, clickShowDialog() { this.show = !this.show }, debounce(func, delay) { console.log("debounce") let timer; // 定时器 return function () { let context = this; // 记录 this 值,防止在回调函数中丢失 let args = arguments; // 函数参数 // 标识是否立即执行 let isImmediately = !timer; //如果定时器存在,则清除定时器(如果没有,也没必要进行处理) timer ? clearTimeout(timer) : null; timer = setTimeout(() => { timer = null; }, delay); // isImmediately 为 true 则 执行函数(即首次触发事件) isImmediately ? func.apply(context, args) : null; } }, throttle(func, delay) { return (function () { if (this.working) { //休息时间 暂不接客 console.log("休息时间 暂不接客 ", this.working) return } console.log("干活:", this.working) this.working = true func(); setTimeout(() => { this.working = false; }, delay) })() }, }, mounted() { // 先初始化 ideaRandomSeed 字段 this.initRandomSeed(); this.getMyUserInfo(); this.fetchIdeas(-1); this.triggerCheckUpdate(); }, }); app.use(vant); app.mount('#app'); </script> <style> .avatar { width: 2rem; height: 2rem; border-radius: 50%; overflow: hidden; } .notice-swipe { height: 20px; line-height: 20px; } .van-tab--active { font-size: large; } :root { --van-tabs-bottom-bar-color: #fa5151; --van-tabs-bottom-bar-height: 5px; } .page { background-color: #F7F7F7; /* font-family: AlibabaPuHuiTi-3-55-Regular; */ } .card { margin: 10px 10px; padding: 10px; height: 3rem; background-color: #FFFFFF; display: flex; flex-align: start; border-radius: 2%; height: auto; } .item { margin: 0px 4px; width: 40%; } .item img { width: 100%; height: 135px; } .app { margin: 0px 4px; width: 100%; flex-direction: row; align-items: center; justify-content: left; /* font-family: AlibabaPuHuiTi-3-65-Medium; */ .title { font-size: medium; color: #fa5151; font-weight: bolder; margin-bottom: 0.2em; } .title::after { content: " - 免费下,能赚钱"; font-size: small; color: rgba(50, 50, 50, 0.9); ; } } .appbody { display: flex; /* align-items: center; */ } .app img { width: 100%; height: 100%; width: 2.2rem; height: 2.2rem; border-radius: 15%; margin: 0px 10px 10px 0px; } ._btn-download { display: flex; justify-content: center; align-items: center; height: 1rem; font-size: small; text-align: center; color: #ff9700; background-color: #ff970020; border-radius: 1em; margin-bottom: 10px; } .cu-avatar { width: 20px; height: 20px; border-radius: 5000px; } .title { font-size: medium; overflow: hidden; text-overflow: ellipsis; display: box; line-clamp: 2; box-orient: vertical; } </style> {% endblock script %}
login.html
{% extends "xxxx/base.html" %} {% block title %}登录{% endblock title %} {% block content %} <div id="main" class="main-warp"> <img style="width:100%; height:6rem;" src="https://6465-dev01-8gpbb3wb781836c1-1304695802.tcb.qcloud.la/static/login/login_header5.jpg"></img> <van-icon name="arrow-left" style="font-size: 0.6rem;color:white;position:fixed;top:0.4rem;left:0.2rem;" @click="goBack()"></van-icon> <div class="main-content" style=""> <h2 class="text-center">登录</h2> <div class="third-party-title" style="margin-top:1rem"> <h5 class="text-center"><span>使用微信账号登录</span></h5> </div> <div style="margin-top:0.9rem;" class="text-center" > <img style="width:1.5rem;height:1.5rem" src="https://6465-dev01-8gpbb3wb781836c1-1304695802.tcb.qcloud.la/static/login/wx_logo_02.jpg" @click="requireWeChatLogin()" /> </div> <div class="gap"> <div class="text-center" style="margin-top: 0.4rem"> <a href="javascript:;" class="link" @click="jumpTo('index')">返回首页</a> <span class="split-space"></span> <a href="javascript:;" class="link" @click="onClickRegister()">新用户注册</a> </div> </div> </div> </div> <link rel="stylesheet" href="https://cdn.bootcss.com/twitter-bootstrap/3.3.0/css/bootstrap.min.css"/> <link rel="stylesheet" href="/xxxx/static/etuiapp/css/login.css"/> {% endblock content %} {% block script %} <script> const app = Vue.createApp({ delimiters: ["${", "}"], //vue变量使用 ${xxx} 形式 data() { return { loginFlag: 1, phoneNum: '', password1: '', loadingCapthca: 0, loading: 0, captchaImage: '', captchaRid: '', captchaCode: '', }; }, computed: { }, methods: { doLogin() { // 进行注册逻辑 if(this.phoneNum == "") { vant.showNotify({ type: 'warning', message: "手机号不能为空" }); return; } if(this.password1 == "") { vant.showNotify({ type: 'warning', message: "密码不能为空" }); return; } if(this.captchaCode == "" || this.captchaImage == "" || this.captchaRid == "") { vant.showNotify({ type: 'warning', message: "验证码不能为空" }); return; } let url = '/xxxx/xxxx/login'; let req = { phoneNum: this.phoneNum, password1: this.password1, captchaCode: this.captchaCode, captchaRid: this.captchaRid, }; this.loading = 1; let self = this; $.post(url, req, function (res){ //回调函数 self.loading = 0; console.log("res : ", res); let d = parseJsonIfStr(res); console.log("do login res: ", d); if(d.code === 0) { vant.showNotify({ type: 'success', message: '登录成功' }); setTimeout(() => { self.jumpTo("index"); }, 500); } else { vant.showNotify({ type: 'warning', message: d.errMsg }); self.getOneCaptcha(); } }); }, initRandomSeed() { var seed = window.localStorage.getItem("forceUseSeed"); if(seed == undefined || seed == "") { seed = myUuid(); window.localStorage.setItem("forceUseSeed", seed); } }, jumpTo(path) { // 调用全局函数,需要在vue methods中才能调用。在html中无法直接调用 console.log("jumpt to path: ", path); globalJumpTo(path); }, goBack() { history.back(); }, getOneCaptcha() { this.captchaRid = ''; this.captchaImage = ''; if(this.loadingCapthca == 1) { return } this.loadingCapthca = 1; let url = '/xxxx/captcha/random_get_one'; $.getJSON(url).then((res) => { console.log("captcha res: ", res); this.captchaRid = res.r_id; this.captchaImage = res.data; this.loadingCapthca = 0 }); } }, components: { }, mounted() { this.getOneCaptcha(); }, }); app.use(vant); app.mount('#app'); </script> <style> </style> {% endblock script %}
my.html
{% extends "etuiapp/base.html" %} {% block title %}我的页面{% endblock title %} {% block content %} <div class="page" style="width:100%;height: 100%;position:fixed;background-color: #F7F7F7;"> <div class="weui-tab"> <div class="weui-tab"> <div id="panel1" role="tabpanel" aria-labelledby="tab1" class="weui-tab__panel" > <div class="my_header_card"> <van-row class="my_card_body_line" > <van-col span="4"> <img class="cu-avatar round margin-right-xs" style="width:1.2rem;height:1.2rem" :src="userInfo.avatarUrl"> </img> </van-col> <van-col span="17"> <van-row style="font-size:0.5rem"> ${userInfo.nickName} </van-row> <van-row style="font-size: 0.3rem"> <van-space> <span style="padding-left:0.3rem" @click="onClickLogout">退出登录</span> <van-icon @click="onClickLogout" name="user-o" /> </van-space> </van-row> </van-col> <van-col span="3"> <van-row class="vertical-center-parent"> <div class="vertical-center-child" @click="jumpTo('balance')"> <van-icon name="arrow" style="font-size: 0.6rem;"></van-icon> </div> </van-row> </van-col> </van-row> </div> <div v-if="loading==0"> <img src="https://6465-dev01-8gpbb3wb781836c1-1304695802.tcb.qcloud.la/banner/c-banner.png" alt="" style="width: 100%; height: 3rem;"> </div> <van-cell v-if="loading==0" value="查看" is-link> <template #title> <div class="my_cell flex"> <img src="https://6465-dev01-8gpbb3wb781836c1-1304695802.tcb.qcloud.la/static/my/task.png" alt=""> <div class="title"> <span>我的任务</span> <span class="subtitle">可以查看任务进度</span> </div> </div> </template> </van-cell> <van-cell v-if="loading==0" value="查看" is-link> <template #title> <div class="my_cell flex"> <img src="https://6465-dev01-8gpbb3wb781836c1-1304695802.tcb.qcloud.la/static/my/phone.png" alt=""> <div class="title"> <span>联系我们</span> <span class="subtitle">联系我们</span> </div> </div> </template> </van-cell> </div> </div> <van-tabbar v-model="tabActive"> <van-tabbar-item badge="3" @click="jumpTo('index')"> <span>首页</span> <template #icon="props"> <img :src="props.active ? tabIcon.home.active : tabIcon.home.inactive" /> </template> </van-tabbar-item> <van-tabbar-item> <span>报告</span> <template #icon="props"> <img :src="props.active ? tabIcon.report.active : tabIcon.report.inactive" /> </template> </van-tabbar-item> <van-tabbar-item> <span>我的</span> <template #icon="props"> <img :src="props.active ? tabIcon.my.active : tabIcon.my.inactive" /> </template> </van-tabbar-item> </van-tabbar> </div> </div> {% endblock content %} {% block script %} <script> if (typeof (Toaster) != "undefined") { //Toaster.postMessage("flutter收到来自于网页的信息: 😄"); } </script> <script> const app = Vue.createApp({ delimiters: ["${", "}"], //vue变量使用 ${xxx} 形式 data() { return { loading: 0, loadingTotalIncom: 0, userInfo: { nickName: '蓝色流星', roleType: 'C', phoneNum: '', avatarUrl: 'https://6465-dev01-8gpbb3wb781836c1-1304695802.tcb.qcloud.la/static/avatar.png', eBeanBalance: 0, }, sumIncome: { amount: 0, clickTotal: 0, convertTotal: 0, }, email: '', password: '', confirmPassword: '', tabActive: 2, tabIcon: { home: { active: 'https://6465-dev01-8gpbb3wb781836c1-1304695802.tcb.qcloud.la/static/icon/B-homepage-checked.png', inactive: 'https://6465-dev01-8gpbb3wb781836c1-1304695802.tcb.qcloud.la/static/icon/B-homepage-unchecked.png', }, report: { active: 'https://6465-dev01-8gpbb3wb781836c1-1304695802.tcb.qcloud.la/static/icon/B-report-checked.png', inactive: 'https://6465-dev01-8gpbb3wb781836c1-1304695802.tcb.qcloud.la/static/icon/B-report-unchecked.png', }, my: { active: 'https://6465-dev01-8gpbb3wb781836c1-1304695802.tcb.qcloud.la/static/icon/mine-checked.png', inactive: 'https://6465-dev01-8gpbb3wb781836c1-1304695802.tcb.qcloud.la/static/icon/C-mine-unchecked.png', }, }, }; }, computed: { }, methods: { jumpTo(path) { // 调用全局函数,需要在vue methods中才能调用。在html中无法直接调用 console.log("jump to page:", path); globalJumpTo(path); }, onClickChangeRole() { console.log("click change role") }, onClickLogout() { let url = '/xxx/xxx/logout'; let data = {}; let self = this; $.post(url, data, function (data){ //回调函数 console.log("do logout res: ", data); vant.showNotify({ type: 'success', message: '退出成功' }); setTimeout(() => { self.jumpTo("login"); }, 500); }); }, getMyUserInfo() { this.loading = 1; let self = this; let url = "/xxx/xxx/getMyUserInfo"; $.getJSON(url).then((ret) => { self.loading = 0 console.log("my info ret: ", JSON.stringify(ret)); this.userInfo.avatarUrl = ret.data.avatarUrl; this.userInfo.eBeanBalance = ret.data.eBeanBalance; this.userInfo.roleType = 'C'; this.userInfo.nickName = ret.data.nickName; if (ret.code == -99) { // 未登录,跳转到登录页 this.jumpTo("login"); } //self.getMyTotalIncome(); }); }, getMyTotalIncome() { this.loadingTotalIncom = 1; let url = '/redirectServer/etui_api/query_media_click_convert_sum'; $.getJSON(url).then((ret)=> { this.loadingTotalIncom = 0; console.log("total income: ", ret); if(ret.code == 0 && ret.data) { this.sumIncome.amount = ret.data.amount; this.sumIncome.clickTotal = ret.data.clickTotal; this.sumIncome.convertTotal = ret.data.convertTotal; } }); }, }, components: { }, mounted() { this.getMyUserInfo(); this.getMyTotalIncome(); }, }); app.use(vant); app.mount('#app'); </script> <style> .my_header_card { background-color: rgb(243, 193, 78); height: 4.5rem; margin: 0 0 0.1rem 0; color: #F7F7F7; } .my_card_body_line { padding-top: 0.5rem; padding-left: 0.8rem; padding-right: 0.3rem; } .my_card_body_data { padding: 0.5rem 1.2rem; justify-content: space-between; } .my_card_body_data span { font-size: 28px; } .my_cell div { display: flex; } .my_cell>img { width: 30%; height: 20%; margin-right: 10px; } .my_cell .title { flex-direction: column; margin-top: 6px; font-size: large; .subtitle { font-size: x-small; color: rgba(50, 50, 50, 0.5); } } .vertical-center-parent { width: 100%; height: 100%; align-items: center; justify-content: center; } .vertical-center-child { width: 0.7rem; height: 0.7rem; } </style> {% endblock script %}