admin管理员组

文章数量:1437145

Power BI数据+工作计划推送到手机

假设这样的工作场景,Power BI有不同门店的数据:

现在依据数据好坏为门店制定下一步工作计划。例如,点击宁波市江南路这一行,弹出对话框:

对话框已自动写入了该店铺的各项数据,对话框内容可以修改,接下来把对应计划写到数据下面,并点击发送按钮:

信息被迅速推送到手机,手机首页可以设置小组件以便随时查看。工作完成可以删除条目或者打对勾,实时在手机更新进度。

视频演示:

以上所有功能仅使用一个度量值生成,原理是DAX+HTML,HTML生成表格,JS调用浮墨Flomo笔记API(其他笔记APP如果有API推送功能,道理相同)将数据和工作计划从Power BI推送到手机端。

度量值如下,把度量值放入HTML Content视觉对象即可正常使用。使用时,需要把度量值中的维度、指标换成你模型中的数据,并将API进行替换。

代码语言:javascript代码运行次数:0运行复制
HTML表格.工作计划 = 
VAR t =
    ADDCOLUMNS (
        VALUES ( '店铺资料'[店铺名称] ),
        "销售业绩", FORMAT ( [M.销售业绩], "#,#" ),
        "业绩达成率", FORMAT ( [M.业绩达成率], "0%" ),
        "销售折扣", FORMAT ( [M.销售折扣], "0.00" ),
        "连带率", FORMAT ( [M.客单量], "0.00" ),
        "客单价", FORMAT ( [M.客单价], "#,#" )
    )
VAR HTML_Text =
    CONCATENATEX (
        t,
        "<tr data-store='" & [店铺名称] & "' 
             data-sales='" & [销售业绩] & "' 
             data-ach='" & [业绩达成率] & "' 
             data-md='" & [销售折扣] & "' 
             data-upt='" & [连带率] & "' 
             data-atv='" & [客单价] & "' 
             style='cursor:pointer;'>
            <td style='text-align:left;'>" & [店铺名称] & "</td>
            <td style='text-align:right;'>" & [销售业绩] & "</td>
            <td style='text-align:right;'>" & [业绩达成率] & "</td>
            <td style='text-align:right;'>" & [销售折扣] & "</td>
            <td style='text-align:right;'>" & [连带率] & "</td>
            <td style='text-align:right;'>" & [客单价] & "</td>
        </tr>"
    )
RETURN "
<head>
<style>
table {
    font-family: Arial, sans-serif;
    border-collapse: collapse;
    width: 100%;
}
th {
    background-color: #f2f2f2;
    text-align: left;
    padding: 8px;
}
td {
    padding: 8px;
    border-bottom: 1px solid #ddd;
}
th:nth-child(1) {
    text-align: left;
}
th:nth-child(n+2) {
    text-align: right;
}
.dialog {
    display: none;
    position: fixed;
    top: 50%;
    left: 50%;
    transform: translate(-50%, -50%);
    background: white;
    padding: 20px;
    border: 1px solid #ddd;
    box-shadow: 0 0 10px rgba(0,0,0,0.1);
    z-index: 1000;
    width: 500px;
    border-radius: 5px;
}
.dialog-header {
    display: flex;
    justify-content: space-between;
    align-items: center;
    margin-bottom: 15px;
    padding-bottom: 10px;
    border-bottom: 1px solid #eee;
}
.close-btn {
    font-size: 24px;
    font-weight: bold;
    color: #999;
    cursor: pointer;
    border: none;
    background-color: #f0f0f0; 
    line-height: 1;
    padding: 0;
    width: 30px;
    height: 30px;
    border-radius: 50%;
    display: flex;
    align-items: center;
    justify-content: center;
}
.close-btn:hover {
    color: #333;
    background-color: #e0e0e0; 
}
.dialog textarea {
    width: 100%;
    height: 120px;
    margin-bottom: 15px;
    padding: 8px;
    border: 1px solid #ddd;
    border-radius: 4px;
    resize: vertical;
}
.dialog button {
    padding: 8px 16px;
    background-color: #4CAF50;
    color: white;
    border: none;
    border-radius: 4px;
    cursor: pointer;
    font-size: 14px;
}
.dialog button:hover {
    background-color: #45a049;
}
#response {
    margin-top: 10px;
    padding: 10px;
    display: none;
    border-radius: 4px;
}
.success {
    background-color: #dff0d8;
    color: #3c763d;
    border: 1px solid #d6e9c6;
}
.error {
    background-color: #f2dede;
    color: #a94442;
    border: 1px solid #ebccd1;
}
</style>
</head>
<body>
<table id='storeTable'>
  <tr>
    <th>店铺名称</th>
    <th>销售业绩</th>
    <th>业绩达成率</th>
    <th>销售折扣</th>
    <th>连带率</th>
    <th>客单价</th>
  </tr>" & 
HTML_Text & "
</table>
<div id='dialog' class='dialog'>
    <div class='dialog-header'>
        <h3 style='margin:0;'>发送工作计划</h3>
        <button class='close-btn' id='closeDialog'>&times;</button>
    </div>
    <textarea id='flomoContent'></textarea>
    <button id='submitBtn'>发送</button>
    <div id='response'></div>
</div>
<script>
document.getElementById('storeTable').addEventListener('click', function(e) {
    const row = e.target.closest('tr');
    if (!row || !row.dataset.store) return;
    
    const storeName = row.dataset.store;
    const sales = row.dataset.sales;
    const ach = row.dataset.ach;
    const md = row.dataset.md;
    const upt = row.dataset.upt;
    const atv = row.dataset.atv;
    
    const defaultText = `#工作计划 ${storeName}销售业绩${sales}元,业绩达成率${ach},销售折扣${md},连带率${upt},客单价${atv}`;
    document.getElementById('flomoContent').value = defaultText;
    document.getElementById('dialog').style.display = 'block';
    document.getElementById('response').style.display = 'none';
});
document.getElementById('submitBtn').addEventListener('click', function() {
    const content = document.getElementById('flomoContent').value.trim();
    const responseDiv = document.getElementById('response');
    
    if (!content) {
        responseDiv.textContent = '请填写内容';
        responseDiv.className = 'error';
        responseDiv.style.display = 'block';
        return;
    }
    
    const data = {
        content: content
    };
    
    // 替换flomo API地址
    fetch(' /', {
        method: 'POST',
        headers: {
            'Content-Type': 'application/json',
        },
        body: JSON.stringify(data)
    })
    .then(response => {
        if (response.ok) {
            return response.json();
        }
        throw new Error('网络响应不正常');
    })
    .then(data => {
        responseDiv.textContent = '发送成功!';
        responseDiv.className = 'success';
        responseDiv.style.display = 'block';
        setTimeout(() => {
            document.getElementById('dialog').style.display = 'none';
        }, 1000);
    })
    .catch(error => {
        responseDiv.textContent = '发送失败: ' + error.message;
        responseDiv.className = 'error';
        responseDiv.style.display = 'block';
        console.error('Error:', error);
    });
});
//公众号wujunmin
document.getElementById('closeDialog').addEventListener('click', function() {
    document.getElementById('dialog').style.display = 'none';
});
//公众号wujunmin
window.addEventListener('click', function(event) {
    const dialog = document.getElementById('dialog');
    if (event.target === dialog) {
        dialog.style.display = 'none';
    }
});
</script>
</body>"

以上是单人推送,群组一对一推送可以考虑函数判断USERNAME对笔记API进行切换。

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。原始发表:2025-04-30,如有侵权请联系 cloudcommunity@tencent 删除推送bi工作手机数据

本文标签: Power BI数据工作计划推送到手机