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 %}
相关文章
|
3天前
|
数据库 Python
Python实践:从零开始构建你的第一个Web应用
使用Python和轻量级Web框架Flask,你可以轻松创建Web应用。先确保安装了Python,然后通过`pip install Flask`安装Flask。在`app.py`中编写基本的&quot;Hello, World!&quot;应用,定义路由`@app.route(&#39;/&#39;)`并运行`python app.py`启动服务器。扩展应用,可添加新路由显示当前时间,展示Flask处理动态内容的能力。开始你的Web开发之旅吧!【6月更文挑战第13天】
|
7天前
|
Java Serverless 应用服务中间件
Serverless 应用引擎操作报错合集之部署python项目时,构建过程报错,怎么解决
Serverless 应用引擎(SAE)是阿里云提供的Serverless PaaS平台,支持Spring Cloud、Dubbo、HSF等主流微服务框架,简化应用的部署、运维和弹性伸缩。在使用SAE过程中,可能会遇到各种操作报错。以下是一些常见的报错情况及其可能的原因和解决方法。
|
2天前
|
数据采集 存储 大数据
深入理解Python中的生成器及其应用
本文详细介绍了Python中的生成器概念,包括其定义、工作原理、常见用法以及在实际项目中的应用。通过具体示例和代码分析,帮助读者更好地理解和运用生成器,提高编程效率。
|
2天前
|
机器学习/深度学习 自然语言处理 数据可视化
Python在数据科学中的应用与前景
本文探讨了Python在数据科学领域的广泛应用,分析了其作为数据科学首选编程语言的原因,并展望了未来的发展前景。
|
3天前
|
数据采集 机器学习/深度学习 数据可视化
数据挖掘实战:Python在金融数据分析中的应用案例
Python在金融数据分析中扮演关键角色,用于预测市场趋势和风险管理。本文通过案例展示了使用Python库(如pandas、numpy、matplotlib等)进行数据获取、清洗、分析和建立预测模型,例如计算苹果公司(AAPL)股票的简单移动平均线,以展示基本流程。此示例为更复杂的金融建模奠定了基础。【6月更文挑战第13天】
|
4天前
|
机器人 测试技术 持续交付
Python进行自动化测试测试框架的选择与应用
【6月更文挑战第9天】本文介绍了Python自动化测试的重要性及选择测试框架的考量因素,如功能丰富性、易用性、灵活性和集成性。文中列举了常用的Python测试框架,包括unittest、pytest、nose2和Robot Framework,并提供了使用pytest进行单元测试的示例代码。此外,还展示了如何使用Robot Framework进行验收测试和Web UI测试。选择合适的测试框架对提升测试效率和软件质量至关重要,团队应根据项目需求、社区支持、集成性和学习曲线等因素进行选择。通过不断学习和实践,可以优化自动化测试流程,确保软件的稳定性和可靠性。
12 0
|
7天前
|
存储 Serverless 数据库
Serverless 应用引擎产品使用合集之在Python中,如何实现SSE
阿里云Serverless 应用引擎(SAE)提供了完整的微服务应用生命周期管理能力,包括应用部署、服务治理、开发运维、资源管理等功能,并通过扩展功能支持多环境管理、API Gateway、事件驱动等高级应用场景,帮助企业快速构建、部署、运维和扩展微服务架构,实现Serverless化的应用部署与运维模式。以下是对SAE产品使用合集的概述,包括应用管理、服务治理、开发运维、资源管理等方面。
|
8天前
|
缓存 开发者 Python
Python中的装饰器应用及性能优化
本文探讨了Python中装饰器的作用以及如何应用装饰器来提高代码的可读性和灵活性。同时,我们还将介绍一些性能优化的技巧,帮助开发者更好地理解和利用装饰器来提升Python程序的执行效率。
|
算法 数据格式 Python
Python requests请求页面返回乱码问题
有时候在通过Python爬取网页数据的时候,比如抖音、快手等短视频数据;网页会返回乱码;这种乱码数据,不管是gb2312、utf-8、gbk、亦或者使用gbk的超集gb18030等编码都毫无用处。看下图。
Python requests请求页面返回乱码问题
|
3天前
|
Shell Python
GitHub星标破千Star!Python游戏编程的初学者指南
Python 是一种高级程序设计语言,因其简洁、易读及可扩展性日渐成为程序设计领域备受推崇的语言。 目前的编程书籍大多分为两种类型。第一种,与其说是教编程的书,倒不如说是在教“游戏制作软件”,或教授使用一种呆板的语言,使得编程“简单”到不再是编程。而第二种,它们就像是教数学课一样教编程:所有的原理和概念都以小的应用程序的方式呈现给读者。