python+jinjia+vant4编写多页面vue应用

简介: 111




python后端,需要使用base.html 作为公共模板, 各个页面分为 index.html  login.html regiester.html等


<!DOCTYPE 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;
        -ms-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: -webkit-box;
        -webkit-line-clamp: 2;
        -webkit-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 %}
相关文章
|
16小时前
|
JavaScript 前端开发 网络协议
从理论到实践:全面剖析Python Web应用中的WebSocket实时通信机制
【7月更文挑战第17天】WebSocket在实时Web应用中扮演重要角色,提供全双工通信,减少延迟。本文详述了Python中使用`websockets`库创建服务器的步骤,展示了一个简单的echo服务器示例,监听8765端口,接收并回显客户端消息。客户端通过JavaScript与服务器交互,实现双向通信。了解WebSocket的握手、传输和关闭阶段,有助于开发者有效利用WebSocket提升应用性能。随着实时需求增长,掌握WebSocket技术至关重要。
12 6
|
1天前
|
存储 缓存 安全
Python元组不可变序列的奥秘与应用方式
Python 中的元组(Tuple)是一种有序的、不可变的数据结构,它是序列的一种特殊形式,就像一个固定大小的盒子,一旦放入物品就无法更换或移除。 元组可以包含任何类型的数据,如数字、字符串甚至是其他元组。 相比列表,元组在很多场景下提供了更高效、安全的选择。
|
1天前
|
前端开发 JavaScript UED
Python Web应用中的WebSocket实战:前后端分离时代的实时数据交换
【7月更文挑战第16天】在前后端分离的Web开发中,WebSocket解决了实时数据交换的问题。使用Python的Flask和Flask-SocketIO库,后端创建WebSocket服务,监听并广播消息。前端HTML通过JavaScript连接到服务器,发送并显示接收到的消息。WebSocket适用于实时通知、在线游戏等场景,提升应用的实时性和用户体验。通过实战案例,展示了如何实现这一功能。
|
1天前
|
JavaScript 前端开发 UED
WebSocket在Python Web开发中的革新应用:解锁实时通信的新可能
【7月更文挑战第16天】WebSocket是实现Web实时通信的协议,与HTTP不同,它提供持久双向连接,允许服务器主动推送数据。Python有多种库如websockets和Flask-SocketIO支持WebSocket开发。使用Flask-SocketIO的简单示例包括定义路由、监听消息事件,并在HTML中用JavaScript建立连接。WebSocket提高了实时性、减少了服务器压力,广泛应用于聊天、游戏等场景。
10 1
|
1天前
|
并行计算 监控 数据处理
构建高效Python应用:并发与异步编程的实战秘籍,IO与CPU密集型任务一网打尽!
【7月更文挑战第16天】Python并发异步提升性能:使用`asyncio`处理IO密集型任务,如网络请求,借助事件循环实现非阻塞;`multiprocessing`模块用于CPU密集型任务,绕过GIL进行并行计算。通过任务类型识别、任务分割、避免共享状态、利用现代库和性能调优,实现高效编程。示例代码展示异步HTTP请求和多进程数据处理。
17 8
|
2天前
|
机器学习/深度学习 开发框架 数据可视化
我们可以从系统工程的角度来讨论如何优化组织架构,并给出一些可能涉及的Python应用领域的示例。
我们可以从系统工程的角度来讨论如何优化组织架构,并给出一些可能涉及的Python应用领域的示例。
17 0
|
2天前
|
算法 调度 Python
我将根据系统工程在交通运输领域的应用,给出一个简单的Python代码示例,用于模拟交通信号灯的控制,并对其进行详解。
我将根据系统工程在交通运输领域的应用,给出一个简单的Python代码示例,用于模拟交通信号灯的控制,并对其进行详解。
9 0
|
2天前
|
大数据 数据处理 API
性能飞跃:Python协程与异步函数在数据处理中的高效应用
【7月更文挑战第15天】在大数据时代,Python的协程和异步函数解决了同步编程的性能瓶颈问题。同步编程在处理I/O密集型任务时效率低下,而Python的`asyncio`库支持的异步编程利用协程实现并发,通过`async def`和`await`避免了不必要的等待,提升了CPU利用率。例如,从多个API获取数据,异步方式使用`aiohttp`并发请求,显著提高了效率。掌握异步编程对于高效处理大规模数据至关重要。
15 4
|
2天前
|
数据库 开发者 Python
实战指南:用Python协程与异步函数优化高性能Web应用
【7月更文挑战第15天】Python的协程与异步函数优化Web性能,通过非阻塞I/O提升并发处理能力。使用aiohttp库构建异步服务器,示例代码展示如何处理GET请求。异步处理减少资源消耗,提高响应速度和吞吐量,适用于高并发场景。掌握这项技术对提升Web应用性能至关重要。
23 10
|
3天前
|
消息中间件 安全 数据处理
Python中的并发编程:理解多线程与多进程的区别与应用
在Python编程中,理解并发编程是提高程序性能和响应速度的关键。本文将深入探讨多线程和多进程的区别、适用场景及实际应用,帮助开发者更好地利用Python进行并发编程。

热门文章

最新文章