多屏协同的功能

  1. 可以在电脑上直接控制手机,可以打开任意APP,非常方便!
  2. 手机和电脑共享剪切板,共享文件,传输东西非常方便!

必备基本条件

  1. 有无线网卡的电脑,最好直接是笔记本
  2. 华为手机,系统是EMUI10+,芯片麒麟980+
  3. 破解版华为电脑管家软件

安装华为电脑管家软件

1.下载电脑管家

度盘链接:https://pan.baidu.com/s/1h-VGSrgPWK_PKUYfvSrHpw#list/path=%2F 密码:8j8c

2.安装电脑管家

3.替换文件util.dll

首先在打开任务管理器停止掉几个服务,都是huawei开头的,右键停止就好了。

关闭华为电脑管家的服务进程

然后用度盘链接里面的Util.dll 文件替换电脑管家安装目录下面的同名文件,安装目录一般在C:\Program Files\Huawei\PCManager。

4.重启大法

重启电脑,然后右下角就会出现电脑管家的图标,双击可以打开,点击我的手机,单击是通知中心的页面。

华为电脑管家

5.联接手机

连接手机时确保电脑的蓝牙和无线网卡是打开的,确保蓝牙和手机能够配对。扫码要使用手机上的华为浏览器或者智慧视觉扫码。

扫码链接

成功连接了电脑之后不能呼出手机的界面,怎么破

参照以下原理设置,比如先把电脑的wifi链接断开,然后扫码连接上手机,手机界面正常呈现到电脑端再开启电脑端的wifi。

原理

其实就是靠WIFI通信的,802.11n,建议把WIFI切成2.4G的话,就很流畅了,延迟非常小,总的来说还不错。
前提你手机必须开着wifi,但可以不连接网络,电脑也是同理,wifi网卡必须能使用,但可以不连接wifi网络。软件是靠开wifi热点的方式连接的,电脑的任务管理器可以看到多了个WIFI Direct连着手机。

还有个发现,手机分辨率会影响到你快速滑动页面的时候卡不卡,比如在B站这种很多图片的地方滑动,我是mate20pro原来强制开2K,滑动快会顿卡,那种网络卡顿的样子,我看任务管理器瞬时的通信流量可以到30Mbps这样,比较高

DNN这一平台使用数据库的是SQL server, 随着时间的推移,其容量逐渐递增,特别的如果系统出现一些异常情况,包括模块出错等,则更让数据库文件的体积增加得更为迅速。故此隔段时间,网站管理员有必要巡查监视下,如有必要则做清理动作。

检查db所有数据库表的使用状况

-- For storing values in the cursor
DECLARE @TableName VARCHAR(100);

   -- Cursor to get the name of all user tables from the sysobjects listing
   DECLARE [tableCursor] CURSOR FOR 
    SELECT [name]
    FROM [dbo].[sysobjects] 
    WHERE OBJECTPROPERTY([id], N'IsUserTable') = 1
   FOR READ ONLY;

   -- A procedure level temp table to store the results
   CREATE TABLE #TempTable (
       [tableName] VARCHAR(100),
      [numberofRows] VARCHAR(100),
       [reservedSize] VARCHAR(50),
       [dataSize] VARCHAR(50),
       [indexSize] VARCHAR(50),
       [unusedSize] VARCHAR(50)
   );

-- Open the cursor
OPEN [tableCursor];

-- Get the first table name from the cursor
FETCH NEXT FROM [tableCursor] INTO @TableName;
-- Loop until the cursor was not able to fetch
WHILE (@@Fetch_Status >= 0)
 BEGIN
     -- Dump the results of the sp_spaceused query to the temp table
      INSERT  #TempTable
          EXEC sp_spaceused @TableName;

      -- Get the next table name
     FETCH NEXT FROM [tableCursor] INTO @TableName;
   END

 -- Get rid of the cursor
 CLOSE [tableCursor];
 DEALLOCATE [tableCursor];

-- remove the text so we can convert the columns
UPDATE #TempTable 
SET [reservedSize] = REPLACE([reservedSize], N' KB', N''), 
    [dataSize] = REPLACE([dataSize], N' KB', N''), 
    [indexSize] = REPLACE([indexSize], N' KB', N''), 
    [unusedSize] = REPLACE([unusedSize], N' KB', N''); 

  -- convert the columns to INT so they will sort properly
  ALTER TABLE #TempTable ALTER COLUMN [reservedSize] INT NULL;
  ALTER TABLE #TempTable ALTER COLUMN [dataSize] INT NULL;
  ALTER TABLE #TempTable ALTER COLUMN [indexSize] INT NULL;
  ALTER TABLE #TempTable ALTER COLUMN [unusedSize] INT NULL;

  -- Select all records so we can use the reults
  SELECT * 
  FROM #TempTable 
  ORDER BY [dataSize] DESC, [reservedSize] DESC, [indexSize] DESC, [unusedSize] DESC;

-- Final cleanup!
DROP TABLE #TempTable;

清理数据库占用空间最大的TOP 3

/* TOP 3 with big TableSize*/
TRUNCATE TABLE [dbo].[sitelog];
TRUNCATE TABLE [dbo].[ScheduleHistory];
DELETE FROM [dbo].[EventLog];

自从2005年开始接触DNN这一平台以来,一直持续关注它的发展和整个生态圈的趋势,起初的确参与了很多,国内圈子也的确掀起一股小小的追捧,然而好景不长,陆续续续大家没了激情,DNN CMS在国内犹如昙花一现,大家转而找其他的替代品,比如Orchard等。不过我一直算还在这个圈子混,官网的资讯也在持续关注中,期盼它能有更好的未来。近期针对DNN9的升级做些功课,期待这次有更强大的性能提升。

DNN9的最佳升级路径

关于DNN9升级的技术文章和最佳实践:

此外还有一些小提示:

  1. 可备份数据库文件db_name.bak,拷贝该备份文件到网站根目录下的App_Data文件夹里,重命名为db_name.resources
  2. 创建一个app_offline.htm.exclude文件, 让其在你执行正式升级时生效(重命名为app_offline.htm)
  3. 默认升级链接 http://MYWEBSITE/install/install.aspx?mode=upgrade

DNN7.3 升级到 DNN9.3

  1. FTP下载网站根目录wwwroot到本地,创建本地测试应用程序localhost/xx_name,检查应用目录的权限配置是否正确, 比如network service, iis_user等
  2. 恢复数据库文件到测试应用,修改PortalAlias数据库表www.xx_name.com->localhost/xx_name
  3. 检查web.config,修改connectionString数据库连接字符串,验证web.config是否有效,比如可能需要删除节点
  4. 访问应用链接localhost/xx_name检验是否迁移到本地成功

其他关于DNN9的注意点

最近手头的华为Android手机越用越为臃肿,是不是提示需要清理内存及存储空间,DiskUsage这一App可以分析手机内存及SD卡包含的文件夹大小,以此来作为清理垃圾的依据也是不错,悲催的是DiskUsage只能在Google Play Store能安装,天朝的应用市场不够用了。故此有一下翻墙安装来源于Google Play Store的App这一曲线救国之道。

步骤如下:

  1. 浏览器打开google play store网站搜索某一应用:DiskUsage
  2. 复制浏览器地址url:https://play.google.com/store/apps/details?id=com.google.android.diskusage
  3. 打开网址https://apps.evozi.com/apk-downloader/,将其黏贴到网页的输入框中,并点击蓝色按钮【Generate Download Link】:
  4. 等页面中出现绿色按钮点击它,直到下载完成。

download app from google play store

最近有个新需求,鉴于Github已具备免费搭建私有仓库的功能,于是我们团队立即着手迁移部分项目到Github来(原本托管于Dropbox),目前效果良好。

我们需要的原本的仓库包括所有记录都能迁移到新库上,一开始找到的方案都只能迁移master和tag分支,其他分支branch还要一个一个来,麻烦得很。后来找最终解决方案,迁移所有记录包括所有的分支、标签、日志,一个不少。

GIT迁移全库

主要使用如下四行命令,建议直接在命令行窗口执行,比如DOS或Powershell:

git clone --mirror <URL to my OLD repo location>        //git clone --mirror http://xxxx.com/yyyy.git
cd <New directory where your OLD repo was cloned>       //cd yyyy.git
git remote set-url origin <URL to my NEW repo location> //git remote set-url origin https://github.com/youracount/yyyyNEW.git
git push -f origin 

基于Docker隔离环境的方式,我们可以用于快速创建虚拟环境来隔离不同的Python和其他软件包版本,而不再需要漫长的逐个安装过程,这无疑降低数据科研的入门门槛。

Docker常用命令

docker命令是你与Docker容器和镜像直接打交道所使用的主要命令。

docker   # docker 命令帮助

Commands:
    attach    Attach to a running container                 # 当前 shell 下 attach 连接指定运行镜像
    build     Build an image from a Dockerfile              # 通过 Dockerfile 定制镜像
    commit    Create a new image based changes              # 提交当前容器为新的镜像
    cp        Copy files/folders from the containers filesystem to the host path # 从容器中拷贝指定文件或者目录到宿主机中
    create    Create a new container                        # 创建一个新的容器,同 run,但不启动容器
    diff      Inspect changes on a container''s filesystem  # 查看 docker 容器变化
    events    Get real time events from the server          # 从 docker 服务获取容器实时事件
    exec      Run a command in an existing container        # 在已存在的容器上运行命令
    export    Stream the contents of a container as a tar archive # 导出容器的内容流作为一个 tar 归档文件[对应 import ]
    history   Show the history of an image                  # 展示一个镜像形成历史
    images    List images                                   # 列出系统当前镜像
    import    Create a new filesystem image from the contents of a tarball  # 从tar包中的内容创建一个新的文件系统映像[对应 export]
    info      Display system-wide information               # 显示系统相关信息
    inspect   Return low-level information on a container   # 查看容器详细信息
    kill      Kill a running container                      # kill 指定 docker 容器
    load      Load an image from a tar archive              # 从一个 tar 包中加载一个镜像[对应 save]
    login     Register or Login to the docker registry server  # 注册或者登陆一个 docker 源服务器
    logout    Log out from a Docker registry server         # 从当前 Docker registry 退出
    logs      Fetch the logs of a container                 # 输出当前容器日志信息
    port      Lookup the public-facing port which is NAT-ed to PRIVATE_PORT # 查看映射端口对应的容器内部源端口
    pause     Pause all processes within a container        # 暂停容器
    ps        List containers                               # 列出容器列表
    pull      Pull an image or a repository from the docker registry server # 从docker镜像源服务器拉取指定镜像或者库镜像
    push      Push an image or a repository to the docker registry server # 推送指定镜像或者库镜像至docker源服务器
    restart   Restart a running container                   # 重启运行的容器
    rm        Remove one or more containers                 # 移除一个或者多个容器
    rmi       Remove one or more images                     # 移除一个或多个镜像[无容器使用该镜像才可删除,否则需删除相关容器才可继续或 -f 强制删除]
    run       Run a command in a new container              # 创建一个新的容器并运行一个命令
    save      Save an image to a tar archive                # 保存一个镜像为一个 tar 包[对应 load]
    search    Search for an image on the Docker Hub         # 在 docker hub 中搜索镜像
    start     Start a stopped containers                    # 启动容器
    stop      Stop a running containers                     # 停止容器
    tag       Tag an image into a repository                # 给源中镜像打标签
    top       Lookup the running processes of a container   # 查看容器中运行的进程信息
    unpause   Unpause a paused container                    # 取消暂停容器
    version   Show the docker version information           # 查看 docker 版本号
    wait      Block until a container stops, then print its exit code   # 截取容器停止时的退出状态值

docker exec 进入正在运行的容器

docker exec -it db3 /bin/sh
docker exec -it d48b21a7e439 /bin/sh
# db3是后台容器的NAMES,d48b21a7e439是容器的进程ID, /bin/sh 是固定写法

docker commit 封装新的镜像

docker commit dfg7xxxx wherein/ubuntu:v2
docker commit -a="Baldwin Sun" -m="fixed some issue" dfg7xxxx wherein/ubuntu:v2
# -a, --author=""     Author (e.g., "John Hannibal Smith <hannibal@a-team.com>")
# -m, --message=""    Commit message
# -p, --pause=true    Pause container during commit

docker image #验证是否已生成新镜像

docker push 推送新镜像到Hub库

docker push wherein/ubuntu:v2
docker inspect wherein/ubuntu #验证提交镜像信息

docker 清理镜像和容器

删除容器: docker rm <Container ID>
删除所有容器: docker rm $(docker ps -a -q)
移除镜像: docker rmi <Container ID>
移除所有镜像: docker rmi $(docker ps -a -q)

Note: 在移除镜像前,你必须删除掉,所有依赖于该镜像的容器

参考链接:

Python逐渐成为数据分析的中流砥柱,而Pandas、Numpy更无疑是数据分析必备的利器工具,最近就尝试把之前在Power Query实现的工具转化让Python来完成,以此对比两者的优劣势,顺带温习Python3的某些特性。

辅助工具 jupyter notebook

jupyter notebook

数据清洗案例

# 清洗数据 参照Power Query的思路
import pandas as pd
import numpy as np

DATA_DIR = 'E:/加班计算助手/'
df = pd.read_excel(DATA_DIR + 'Contact_sum.xlsx') #, usecols='A:G')

# print(df.columns)
# print(df.dtypes)

df['年月']=df['年月'].astype(str) # 转化为字符类型
df['年月'] = df['年月'].apply(lambda x:x[:-2]) # 清洗数据, 把float64类型比如"201709.0"转化为"201709"

df_fixed = df.dropna(subset=['员工姓名', '员工编号'], how='any') # Define in which columns to look for missing values.

# 逆透视除了['员工姓名', '员工编号']之外的列
df_fixed = df_fixed.melt(id_vars=['员工编号','员工姓名','年月'],var_name='具体日期', value_name='加班小时')

df_fixed = df_fixed.dropna(subset=['加班小时'], how='any') # 再次过滤【加班小时】为空或NAN的记录

df_fixed['具体日期'] = df_fixed['具体日期'].astype(str)
df_fixed['具体日期'] = df_fixed['年月'] + df_fixed['具体日期'].apply(lambda x:x.zfill(2)) # 合并形成具体时间格式的字段

df_fixed['员工编号'] = df_fixed['员工编号'].astype(str)
df_fixed['员工编号'] = df_fixed['员工编号'].apply(lambda x:x.zfill(6)) # 合并形成具体时间格式'20170901'的字段

df_fixed = df_fixed.drop('年月',axis=1) # 删除指定列“年月”
df_fixed = df_fixed.reset_index(drop=True) # 重置索引
df_fixed

参考链接:

xxx

消除关联动态查询警告

如果在PQ查询中遇到

Formula.Firewall: 查询”xx”(步骤”xx”) 将引用其他查询或步骤,因此可能不会直接访问数据源。请重新生成此数据组合。

这样的问题,那是文件的隐私设置级别的原因:

查询警告

如此这般设置即可。

隐私设置

补齐位数

在做数据处理的时候经常要把表格内的数字处理XX位的一组数字。但是原始数据的位数不够则需要使用0来补充。手输是不可能的,使用自动补零的方法应该不错。

步骤或方法

  1. 选择你要补零的单元格点右键再选择进入设置单元格格式。
  2. 进入设置单元格格式的界面,在数字选项下点击自定义,类型中找到G/通用格式,然后在上面的方框内输入你要多少位置补零就输入多少个零,最后点击确定。

参考链接:excel表格位数不够自动补0的方法

PowerQuery动态汇总文件夹下的多个Excel文件

参考链接:

用PowerQuery动态汇总文件夹下的多个Excel文件(支持动态增删自动更新)

如何使用Power Query动态汇总文件夹下多个Excel文件

PowerQuery 补齐位数

比如编号或月份默认是1,而你需要的显示是类似”01”效果。

步骤或方法

新增一自定义列([Month]为原始列),套用以下公式即可:

Text.PadStart(Text.From([Month]),2,"0")

PowerQuery 分组合并同类项

比如某一列”课程”可能是”初级班”、”中级班”、”高级班”,而我们需要分组合并看看总共都参与了哪些班,最终的结果可能类似于”初级班、中级班、高级班”。

步骤或方法

分组并求和”课程”这一列,无疑应该是报错。修改函数,将分组操作生成公式中的

List.Sum([课程])

修改为

Text.Combine([课程], "、")

另外一种方法:

Group or Summarize Data in Excel with Power Query

任何一个系统都不可能把全部信息化覆盖完全,不可避免地,不同业务部门需要因地制材选型更合适的、更专业的系统。由此信息孤岛的形成也是必然的结果。随着信息化系统的落地和完善,信息共享、系统集成也是大势所趋。基础信息同步就是系统集成的第一步骤。
在此分享如何在通达OA二次开发一个定时同步任务 - 基础组织架构、人员信息的同步。

开发步骤

代码开发

整合第三方应用系统时,由于系统默认推荐使用IE兼容模式,若要用户每次都点击由极速模式切换为兼容模式,用户体验极其不好用。

安装部署

权限分配:TMD,OA的缓存能整死人。

总体来说,通达OA的工作流的确让信息化迈进了一个新的台阶,不过精细度和扩展性依旧很弱,故此改造和二次开发无可避免。在此列举一些案例:

OA精灵窗口默认启用兼容模式

需求

整合第三方应用系统时,由于系统默认推荐使用IE兼容模式,若要用户每次都点击由极速模式切换为兼容模式,用户体验极其不好用。

解决方法

打开安装目录比如D:\MYOA\webroot\inc文件夹下的url_config.ini 文件。

在文件末行增加 在后面加一行/general/erp/保存,重新登录OA精灵,凡是链接或调用该目录erp下的文件默认打开就是IE内核方式,遂满足用户的定制需求。

OA精灵打开定制大小的窗口

需求

整合第三方应用系统时,默认窗口有时不能满足需求,比如内容比较多的应用门户展示。

解决方法

在弹出的窗体调用的文件里,比如ssologin.php或http://xx.xx.xx.ip/client/login.jsp,加入如下JS语句:

<script Language="javascript">
//如果从OA精灵打开,则打开指定尺寸w/h大小的窗口
if(window.external && typeof window.external.OA_SMS != 'undefined')
{        
    var h = Math.min(1024, screen.availHeight - 180),
        w = Math.min(1690, screen.availWidth - 180);

    window.external.OA_SMS(w, h, "SET_SIZE");
}
</script>

以上语句,使得OA精灵弹出的窗体的尺寸能得到正确控制,以上语句最好放到JS其他编码的前面,以上语句对各类内核浏览器的WEB状态的显示无任何影响。

参考链接:http://club.tongda2000.com/forum.php?mod=viewthread&tid=16723&extra=&page=1

设置列表控件不可输入

需求

一旦列表控件绑定数据源,为了保证数据的正确性,禁止用户输入、让用户只能选择无疑是最便捷的方式。可惜目前为止通达OA依然没有实现这一功能,错误数据随处可见,用户体验极其糟糕。

解决方法

设计表单时添加辅助脚本JS来在客户端强制验证:

window.onload = function() { 
  jQuery('#LISTVIEW_DATA_99 input.ConcelBigInput').each(function(i){
    jQuery(this).keydown(function(){
      alert("禁止输入,请选择"); //attr('readonly','readonly');
      jQuery(this).val('');
    });
  });
};

注意:不能用jQuery(document).ready,因为你读取不到动态生成列表控件的TR;不能用attr(‘readonly’,’readonly’)方式,因为这样你无法把选择后的值赋值到列表的输入框里。

列表控件编辑时样式撑大覆盖整个页面

问题截图

解决方法

设计表单时添加辅助CSS样式如下:

table.LIST_VIEW{width:100%;}
tr.LIST_VIEW_HEADER td{padding:10px 2px;}
table.LIST_VIEW td input{padding:5px 2px;text-align:center;width:100%;}