鼎鼎知识库
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

迁移思路

涉及到的系统包括:

  • 总部运营后台
  • 开放平台
  • 写字楼版API
  • 写字楼版H5

涉及到的数据库:

  • 原有的自建关系数据库转到阿里数据库
  • 原有的自建时序数据库转到华为时序数据库

大致步骤

  • 总部运营后台:数据迁移至新数据库
  • 开放平台:写字楼版需要的接口,从新的时序数据库获取
  • 写字楼版API:迁移到华为云,搭建环境并迁移,修改配置
  • 写字楼版API:迁移到华为云,修改配置
  • 华为云配置域名和SSL,再修改配置

总部运营后台迁移数据

--Navicat连接阿里MySQL
--阿里云数据库创建新数据库:
	报错:当前用户无法创建数据库
	登录阿里云修,创建数据库,并授权给用户
--生成新数据库加密连接字符串:mId+I96JxaFog5Phi/KN+bWPGh4wnClNBzD5EvaEI5Z2vlYYeEYT9qGaRHz3y8Z+EXIzZiUWbl0gLmgoOJ+EZgzvikJpTpSfcf0UadGq/FW3MIjY1AZviTJ0lxOq0g3MSJwkEXx1wxn6xvpMoqyz1h0FdhJtbgCHJqSw1hV8b9Y31ibL+LSChtrd3h/FzlDL	
--确认数据库上下文:HdContext
--修改DD.HD.API中的连接字符串
--尝试生成数据库:dotnet ef database update -c HdContext
--种子化数据
	超级管理员
	创建总部
	创建项目版本
	
--修改生成环境的连接字符串	
--重启生产环境网站
--管理员登录
	登录失败
	确认登录接口:api/auth/token
	Postman登录,确认可以
	打开局域网防火墙:控制面板,系统和安全,启用或关闭,测试,跑通
	更新云端组件,还是有问题
	案例云数据库,设置白名单,允许总部运营应用程序所在服务器的IP,成功
--创建总部销售员:13811111111
--创建总部管理员:13822222222
--创建总部财务:13833333333
--创建总部CEO:13844444444

以下可以作为运维操作指导

--销售员登录:13811111111
--点击左侧"销售报批管理"
--点击右上角+按钮
--输入项目名称,并点击确认按钮
--点击"申请"按钮,在弹出窗口中点击确定按钮

--财务登录:13833333333
--点击左侧"财务审核管理"
--点击右侧通过按钮,在弹出窗口中点击确定按钮

--CEO登录:13844444444
--点击左侧"CEO审核管理"
--点击右侧通过按钮,在弹出窗口中点击确定按钮


--管理员登录:13822222222
--点击左侧"权限管理"--"组织管理",点击编辑按钮,填写如下字段,点击确定按钮
拼音名称:xunfei
缓存命名空间:OpenAPI_Office

--数据库运维人员为该项目创建新数据库:office_demo
--数据库运维人员生成office_demo的连接字符串:mId+I96JxaFog5Phi/KN+bWPGh4wnClNBzD5EvaEI5Z2vlYYeEYT9qGaRHz3y8Z+EXIzZiUWbl0gLmgoOJ+EZrCunEKimFlbeg+VD25AlNyLqV5z9kmRLuHs+oTS7mXR77uDQkUkjBEL4FJm3ThP5yCk8OU6SDuhNtGZIQQD2AdipFCTROYOcKtCqWy2i9y5
--打开DD.OfficeBuilding.Web项目
--替换appsettings.json中的连接字符串
	用新的加密连接字符串替换ConnectionStrings和ProjectsSetting中的office_demo对应的连接字符串
	替换ConnectionStrings中hd_new对应的连接字符串
--生成项目
--确认上下文名称:DDOfficeContext
--尝试迁移:dotnet ef database update -c DDOfficeContext


--管理员登录:13822222222
--点击左侧"项目管理",点击"项目数据库",填写如下,点击确定

关系数据库IP: rm-bp1a298l904sfi196no.mysql.rds.aliyuncs.com
关系数据库端口:3306
关系数据库名称: office_demo
关系数据库用户名:
关系数据库密码:  
关系数据库连接主键:office_demo
时序数据库IP:无
时序数据库名称:无
时序数据库用户名:无
时序数据库密码:无

--点击左侧"配置管理",点击"模块管理",点击右上角+按钮
--添加如下模块,点击确定按钮

187ED5311111  HTTP
187ED5322222  HTTP
187ED5333333  HTTP
187ED5344444  HTTP
187ED5355555  HTTP
187ED5366666  HTTP
187ED53338C4  HTTP
98CC4D213004  UDP  绑定到第三方大成

--点击绑定按钮,在弹出窗口中选择绑定项目,点击确定
--点击左侧"项目管理",点击"项目Banner管理"

--点击左侧"权限管理",点击"人员管理管理",准备添加电工(15613914966)
--点击右上角+,输入如下信息,点击确定按钮
--点击左侧"配置管理",点击"电工管理",点击绑定按钮
--选择绑定项目,点击确定按钮


--点击左侧"权限管理",点击"人员管理管理",准备添加办公楼版大楼游客(15762085260)
--点击左侧"权限管理",点击"人员管理管理",准备添加办公楼版大楼管理员(13811191763)

总部添加第三方合作方运维操作指导

--点击左侧"权限管理",点击"组织管理"
--点击右上角+,输入如下信息,点击确定
	层级:子
	子位置:鼎鼎总部
	组织名称:
	拼音名称:
	是否是总部:否
	是否是第三方开发者:是
	是否是项目:否
	缓存命名空间:咨询数据库管理员
	授权Key:咨询数据库管理员

开放平台迁移数据

关系数据库部分

--阿里云创建开放平台数据库:open_new
--确认开放平台的加密连接字符串:mId+I96JxaFog5Phi/KN+bWPGh4wnClNBzD5EvaEI5Z2vlYYeEYT9qGaRHz3y8Z+EXIzZiUWbl0gLmgoOJ+EZo5E9sbjV8zcVJLJ66xqZoFZ4piQd5Q6TaKIfVzmgJuafJFayudZD32ViHNbxCxg3PYa/Fl+JeIA+m6Ec5aWWyWsY/rqC18brJXXhrb4X4w9
--替换开发环境和生成环境中的appsetting部分
--关闭生产环境网站
--把原先open数据库导出
--把原先open数据库导入到新的open_new数据库
--开启生产环境网站

测试模块查询电量等

--确认新的时序数据Restful接口是否可用:http://116.63.236.99:6041/rest/sql
--确认开放平台老接口是否可用:
--更换开放平台相关接口使用新的时序数据库
--重新发布网站
--确认开放平台新接口是否可用
	请求power/random/byaddr失败
	确认新的时序数据库是否有OpenPower数据库,有这个数据,但没有相关模块的表数据
	发现账号密码写错,重新上传,调通

写字楼版迁移

几个网站

--一个写字楼版手机端接口网站
--一个写字楼版H5静态网站
--一个项目运营后台接口网站
--一个项目运营后台Web静态网站

大致思路

--搭建环境
--拷贝网站
--配置网站

搭建环境

--确定新服务器并登录
--确定服务器版本:cat /etc/version
--更新软件apt: sudo apt-get update
--安装nano: sudo apt-get install nano
--安装: sudo apt-get install apt-transport-https
--创建目录:mkdir downloads
--进入目录:cd downloads
--下载微软Product key:wget https://packages.microsoft.com/config/ubuntu/18.04/packages-microsoft-prod.deb
--安装:sudo dpkg -i packages-microsoft-prod.deb
--更新软件:sudo apt-get update
--安装.NET Core 3.0的SDK: sudo apt-get install dotnet-sdk-3.0
--确认是否安装:dotnet --list-sdks
--更新软件:sudo apt-get update
--安装Nginx:sudo apt-get install nginx
--查看状态:sudo systemctl status nginx
--查看Nginx网站是否正常:curl localhost
--由于写字楼版需要请求阿里数据库,所以需要把华为服务器IP加入阿里数据库的白名单

云端创建quartz数据库

--登录案例云数据库管理后天
--添加数据库:ddquartz
--Navicat登录:
--运行语句

# By: Ron Cordell - roncordell
#  I didn't see this anywhere, so I thought I'd post it here. This is the script from Quartz to create the tables in a MySQL database, modified to use INNODB instead of MYISAM.


# make sure you have UTF-8 collaction for best .NET interoperability
# CREATE DATABASE quartznet CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;

DROP TABLE IF EXISTS QRTZ_FIRED_TRIGGERS;
DROP TABLE IF EXISTS QRTZ_PAUSED_TRIGGER_GRPS;
DROP TABLE IF EXISTS QRTZ_SCHEDULER_STATE;
DROP TABLE IF EXISTS QRTZ_LOCKS;
DROP TABLE IF EXISTS QRTZ_SIMPLE_TRIGGERS;
DROP TABLE IF EXISTS QRTZ_SIMPROP_TRIGGERS;
DROP TABLE IF EXISTS QRTZ_CRON_TRIGGERS;
DROP TABLE IF EXISTS QRTZ_BLOB_TRIGGERS;
DROP TABLE IF EXISTS QRTZ_TRIGGERS;
DROP TABLE IF EXISTS QRTZ_JOB_DETAILS;
DROP TABLE IF EXISTS QRTZ_CALENDARS;

CREATE TABLE QRTZ_JOB_DETAILS(
SCHED_NAME VARCHAR(60) NOT NULL,
JOB_NAME VARCHAR(60) NOT NULL,
JOB_GROUP VARCHAR(60) NOT NULL,
DESCRIPTION VARCHAR(250) NULL,
JOB_CLASS_NAME VARCHAR(250) NOT NULL,
IS_DURABLE BOOLEAN NOT NULL,
IS_NONCONCURRENT BOOLEAN NOT NULL,
IS_UPDATE_DATA BOOLEAN NOT NULL,
REQUESTS_RECOVERY BOOLEAN NOT NULL,
JOB_DATA BLOB NULL,
PRIMARY KEY (SCHED_NAME,JOB_NAME,JOB_GROUP))
ENGINE=InnoDB;

CREATE TABLE QRTZ_TRIGGERS (
SCHED_NAME VARCHAR(60) NOT NULL,
TRIGGER_NAME VARCHAR(60) NOT NULL,
TRIGGER_GROUP VARCHAR(60) NOT NULL,
JOB_NAME VARCHAR(60) NOT NULL,
JOB_GROUP VARCHAR(60) NOT NULL,
DESCRIPTION VARCHAR(250) NULL,
NEXT_FIRE_TIME BIGINT(19) NULL,
PREV_FIRE_TIME BIGINT(19) NULL,
PRIORITY INTEGER NULL,
TRIGGER_STATE VARCHAR(16) NOT NULL,
TRIGGER_TYPE VARCHAR(8) NOT NULL,
START_TIME BIGINT(19) NOT NULL,
END_TIME BIGINT(19) NULL,
CALENDAR_NAME VARCHAR(60) NULL,
MISFIRE_INSTR SMALLINT(2) NULL,
JOB_DATA BLOB NULL,
PRIMARY KEY (SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP),
FOREIGN KEY (SCHED_NAME,JOB_NAME,JOB_GROUP)
REFERENCES QRTZ_JOB_DETAILS(SCHED_NAME,JOB_NAME,JOB_GROUP))
ENGINE=InnoDB;

CREATE TABLE QRTZ_SIMPLE_TRIGGERS (
SCHED_NAME VARCHAR(60) NOT NULL,
TRIGGER_NAME VARCHAR(60) NOT NULL,
TRIGGER_GROUP VARCHAR(60) NOT NULL,
REPEAT_COUNT BIGINT(7) NOT NULL,
REPEAT_INTERVAL BIGINT(12) NOT NULL,
TIMES_TRIGGERED BIGINT(10) NOT NULL,
PRIMARY KEY (SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP),
FOREIGN KEY (SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP)
REFERENCES QRTZ_TRIGGERS(SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP))
ENGINE=InnoDB;

CREATE TABLE QRTZ_CRON_TRIGGERS (
SCHED_NAME VARCHAR(60) NOT NULL,
TRIGGER_NAME VARCHAR(60) NOT NULL,
TRIGGER_GROUP VARCHAR(60) NOT NULL,
CRON_EXPRESSION VARCHAR(120) NOT NULL,
TIME_ZONE_ID VARCHAR(80),
PRIMARY KEY (SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP),
FOREIGN KEY (SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP)
REFERENCES QRTZ_TRIGGERS(SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP))
ENGINE=InnoDB;

CREATE TABLE QRTZ_SIMPROP_TRIGGERS
  (          
    SCHED_NAME VARCHAR(60) NOT NULL,
    TRIGGER_NAME VARCHAR(60) NOT NULL,
    TRIGGER_GROUP VARCHAR(60) NOT NULL,
    STR_PROP_1 VARCHAR(512) NULL,
    STR_PROP_2 VARCHAR(512) NULL,
    STR_PROP_3 VARCHAR(512) NULL,
    INT_PROP_1 INT NULL,
    INT_PROP_2 INT NULL,
    LONG_PROP_1 BIGINT NULL,
    LONG_PROP_2 BIGINT NULL,
    DEC_PROP_1 NUMERIC(13,4) NULL,
    DEC_PROP_2 NUMERIC(13,4) NULL,
    BOOL_PROP_1 BOOLEAN NULL,
    BOOL_PROP_2 BOOLEAN NULL,
    TIME_ZONE_ID VARCHAR(80) NULL,
    PRIMARY KEY (SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP),
    FOREIGN KEY (SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP) 
    REFERENCES QRTZ_TRIGGERS(SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP))
ENGINE=InnoDB;

CREATE TABLE QRTZ_BLOB_TRIGGERS (
SCHED_NAME VARCHAR(60) NOT NULL,
TRIGGER_NAME VARCHAR(60) NOT NULL,
TRIGGER_GROUP VARCHAR(60) NOT NULL,
BLOB_DATA BLOB NULL,
PRIMARY KEY (SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP),
INDEX (SCHED_NAME,TRIGGER_NAME, TRIGGER_GROUP),
FOREIGN KEY (SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP)
REFERENCES QRTZ_TRIGGERS(SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP))
ENGINE=InnoDB;

CREATE TABLE QRTZ_CALENDARS (
SCHED_NAME VARCHAR(60) NOT NULL,
CALENDAR_NAME VARCHAR(60) NOT NULL,
CALENDAR BLOB NOT NULL,
PRIMARY KEY (SCHED_NAME,CALENDAR_NAME))
ENGINE=InnoDB;

CREATE TABLE QRTZ_PAUSED_TRIGGER_GRPS (
SCHED_NAME VARCHAR(60) NOT NULL,
TRIGGER_GROUP VARCHAR(60) NOT NULL,
PRIMARY KEY (SCHED_NAME,TRIGGER_GROUP))
ENGINE=InnoDB;

CREATE TABLE QRTZ_FIRED_TRIGGERS (
SCHED_NAME VARCHAR(60) NOT NULL,
ENTRY_ID VARCHAR(140) NOT NULL,
TRIGGER_NAME VARCHAR(60) NOT NULL,
TRIGGER_GROUP VARCHAR(60) NOT NULL,
INSTANCE_NAME VARCHAR(60) NOT NULL,
FIRED_TIME BIGINT(19) NOT NULL,
SCHED_TIME BIGINT(19) NOT NULL,
PRIORITY INTEGER NOT NULL,
STATE VARCHAR(16) NOT NULL,
JOB_NAME VARCHAR(60) NULL,
JOB_GROUP VARCHAR(60) NULL,
IS_NONCONCURRENT BOOLEAN NULL,
REQUESTS_RECOVERY BOOLEAN NULL,
PRIMARY KEY (SCHED_NAME,ENTRY_ID))
ENGINE=InnoDB;

CREATE TABLE QRTZ_SCHEDULER_STATE (
SCHED_NAME VARCHAR(60) NOT NULL,
INSTANCE_NAME VARCHAR(60) NOT NULL,
LAST_CHECKIN_TIME BIGINT(19) NOT NULL,
CHECKIN_INTERVAL BIGINT(19) NOT NULL,
PRIMARY KEY (SCHED_NAME,INSTANCE_NAME))
ENGINE=InnoDB;

CREATE TABLE QRTZ_LOCKS (
SCHED_NAME VARCHAR(60) NOT NULL,
LOCK_NAME VARCHAR(40) NOT NULL,
PRIMARY KEY (SCHED_NAME,LOCK_NAME))
ENGINE=InnoDB;

CREATE INDEX IDX_QRTZ_J_REQ_RECOVERY ON QRTZ_JOB_DETAILS(SCHED_NAME,REQUESTS_RECOVERY);
CREATE INDEX IDX_QRTZ_J_GRP ON QRTZ_JOB_DETAILS(SCHED_NAME,JOB_GROUP);

CREATE INDEX IDX_QRTZ_T_J ON QRTZ_TRIGGERS(SCHED_NAME,JOB_NAME,JOB_GROUP);
CREATE INDEX IDX_QRTZ_T_JG ON QRTZ_TRIGGERS(SCHED_NAME,JOB_GROUP);
CREATE INDEX IDX_QRTZ_T_C ON QRTZ_TRIGGERS(SCHED_NAME,CALENDAR_NAME);
CREATE INDEX IDX_QRTZ_T_G ON QRTZ_TRIGGERS(SCHED_NAME,TRIGGER_GROUP);
CREATE INDEX IDX_QRTZ_T_STATE ON QRTZ_TRIGGERS(SCHED_NAME,TRIGGER_STATE);
CREATE INDEX IDX_QRTZ_T_N_STATE ON QRTZ_TRIGGERS(SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP,TRIGGER_STATE);
CREATE INDEX IDX_QRTZ_T_N_G_STATE ON QRTZ_TRIGGERS(SCHED_NAME,TRIGGER_GROUP,TRIGGER_STATE);
CREATE INDEX IDX_QRTZ_T_NEXT_FIRE_TIME ON QRTZ_TRIGGERS(SCHED_NAME,NEXT_FIRE_TIME);
CREATE INDEX IDX_QRTZ_T_NFT_ST ON QRTZ_TRIGGERS(SCHED_NAME,TRIGGER_STATE,NEXT_FIRE_TIME);
CREATE INDEX IDX_QRTZ_T_NFT_MISFIRE ON QRTZ_TRIGGERS(SCHED_NAME,MISFIRE_INSTR,NEXT_FIRE_TIME);
CREATE INDEX IDX_QRTZ_T_NFT_ST_MISFIRE ON QRTZ_TRIGGERS(SCHED_NAME,MISFIRE_INSTR,NEXT_FIRE_TIME,TRIGGER_STATE);
CREATE INDEX IDX_QRTZ_T_NFT_ST_MISFIRE_GRP ON QRTZ_TRIGGERS(SCHED_NAME,MISFIRE_INSTR,NEXT_FIRE_TIME,TRIGGER_GROUP,TRIGGER_STATE);

CREATE INDEX IDX_QRTZ_FT_TRIG_INST_NAME ON QRTZ_FIRED_TRIGGERS(SCHED_NAME,INSTANCE_NAME);
CREATE INDEX IDX_QRTZ_FT_INST_JOB_REQ_RCVRY ON QRTZ_FIRED_TRIGGERS(SCHED_NAME,INSTANCE_NAME,REQUESTS_RECOVERY);
CREATE INDEX IDX_QRTZ_FT_J_G ON QRTZ_FIRED_TRIGGERS(SCHED_NAME,JOB_NAME,JOB_GROUP);
CREATE INDEX IDX_QRTZ_FT_JG ON QRTZ_FIRED_TRIGGERS(SCHED_NAME,JOB_GROUP);
CREATE INDEX IDX_QRTZ_FT_T_G ON QRTZ_FIRED_TRIGGERS(SCHED_NAME,TRIGGER_NAME,TRIGGER_GROUP);
CREATE INDEX IDX_QRTZ_FT_TG ON QRTZ_FIRED_TRIGGERS(SCHED_NAME,TRIGGER_GROUP);

commit; 

--确定连接字符串

网站上传

--创建目录

sudo mkdir /var/www/publishapplication
sudo mkdir /var/www/publishapplication/office_api
sudo mkdir /var/www/publishapplication/office_client
sudo mkdir /var/www/publishapplication/project_api
sudo mkdir /var/www/publishapplication/project_client

--拷贝网站文件

拷贝office_api: 5000
拷贝office_client: 5011
拷贝project_api:5001
拷贝project_client: 5017

--开放5000-5020接口

把写字楼版手机端二级域名(不包含Manager的那个)指向到:123.60.21.158:5011
把项目管理后台二级域名(包含Manager的那个)指向到:123.60.21.158:5017

--确认Nginx的配置文件是否存在:ls /etc/nginx/sites-available
--编辑配置文件:nano /etc/nginx/sites-available/default

开始配置

--查看sites-available目录:ls -l /etc/nginx/sites-available
--查看sites-enabled目录:ls -l /etc/nginx/sites-enabled
/etc/nginx/sites-enabled/default与/etc/nginx/sites-available/default存在链接
如果解除链接:unlink default
如果添加链接:ln -t
--编辑:sudo nano /etc/nginx/sites-available/default

--创建写字楼版接口服务:sudo nano /etc/systemd/system/office.service


[Unit]
Description=Office Version

[Service]
WorkingDirectory=/var/www/publishapplication/office_api
ExecStart=/usr/bin/dotnet /var/www/publishapplication/office_api/DD.OfficeBuilding.Web.dll
Restart=always
# Restart service after 10 seconds if the dotnet service crashes:
RestartSec=10
KillSignal=SIGINT
SyslogIdentifier=dotnet-example
User=www-data
Environment=ASPNETCORE_ENVIRONMENT=Production
Environment=DOTNET_PRINT_TELEMETRY_MESSAGE=false

[Install]
WantedBy=multi-user.target

--启用写字楼版接口服务:sudo systemctl enable office.service
--启动写字楼版接口服务:sudo systemctl start office.service
--查看写字楼版接口服务:sudo systemctl status office.service

--创建项目服务:sudo nano /etc/systemd/system/project.service


[Unit]
Description=Project Version

[Service]
WorkingDirectory=/var/www/publishapplication/project_api
ExecStart=/usr/bin/dotnet /var/www/publishapplication/project_api/DD.Project.Web.dll
Restart=always
# Restart service after 10 seconds if the dotnet service crashes:
RestartSec=10
KillSignal=SIGINT
SyslogIdentifier=dotnet-example-project
User=www-data
Environment=ASPNETCORE_ENVIRONMENT=Production
Environment=DOTNET_PRINT_TELEMETRY_MESSAGE=false

[Install]
WantedBy=multi-user.target

--启用写字楼版接口服务:sudo systemctl enable project.service
--启动写字楼版接口服务:sudo systemctl start project.service
--查看写字楼版接口服务:sudo systemctl status project.service

--确定Nginx的根目录:/var/www/html
--查看目录: ls -l /var/www/html
--创建默认目录:mkdir /var/www/html/default
--创建文件: sudo nano /var/www/html/default/index.html
--编辑:sudo nano /etc/nginx/sites-available/default
--测试配置是否有问题:nginx -t
--重启:sudo systemctl restart nginx 或者 nginx -s reload
--最终:

拷贝office_api: 5001
拷贝office_client: 5011
拷贝project_api:5002
拷贝project_client: 5017

写字楼版手机端接口:http://moffice.ddingsafe.com/
写字楼版H5页面:http://moffice.ddingsafe.com/app
项目管理后台接口:http://officemaster.ddingsafe.com
项目管理后台Web页面: http://officemaster.ddingsafe.com/xunfei  
--电工账号:15613914966 

写字楼版API应用迁移和数据迁移

--Startup中配置反向代理
--修改appsettings中的配置
--发布网站

云端项目版API应用迁移和数据迁移

--Startup中配置反向代理
--修改appsettings中的配置
--发布网站

测试

--总部运营后台:http://47.103.61.198:5016/   

--电工登录报错:

DD.OfficeBuilding.Web.Controllers.MainController.Banners (DD.OfficeBuilding.Web):Object reference not set to an instance of an object.

DD.OfficeBuilding.Web.Controllers.MineController.UploadAvatar (DD.OfficeBuilding.Web):The type initializer for 'Gdip' threw an exception.

	--确定云端请求地址,在Postman修改:http://moffice.ddingsafe.com/
	--获取短信验证码:api/auth/shortCode
	--获取token:api/auth/token
		验证码已失效,请重新申请
		本地测试阿里云白名单运行本地IP通过就可以了
		postman再测试云端,提示Nginx报错,502 Bad Gateway
			上游服务器和网关/代理使用不一致的协议交换数据
			sudo nano /etc/nginx/sites-available/default
			查看总配置文件:cat /etc/nginx/nginx.conf
			确认错误日志: /var/log/nginx/error.log
			查看日志: cat /var/log/nginx/error.log
2021/04/30 15:58:59 [error] 560#560: *433 connect() failed (111: Connection refused) while connecting to upstream, client: 119.4.174.231, server: local_host, request: "POST /api/auth/token HTTP/1.1", upstream: "http://127.0.0.1:5000/api/auth/token", host: "moffice.ddingsafe.com"
			proxy_set_header Host $http_host;
			proxy_set_header X-Forward-For $remote_addr;
			无效
upstream office_server {
        server 127.0.0.1:5000;
}

upstream project_server {
        server 127.0.0.1:5001;
}
		无效
		server_name 127.0.0.1无效
		云端swagger测试,有时NGinx报错,有时报验证码已失效,请重新申请
		把接口地址改成api/auth/token1 Nginx不报错,5.1过后还是报错,改回来
		先给关闭服务:sudo systemctl stop office
		上传后重启服务:sudo systemctl start office
		报错:502 Bad Gateway
		确认错误日志:cat /var/log/nginx/error.log   详情: connect() failed (111: Connection refused) while connecting to upstream,这里的问题是其它接口没问题,就这个接口有问题。应该和这个接口的代码有关系。其中涉及到了缓存,是否nginx还没允许缓存?发现其它接口也是有问题的。感觉和路由有关系。配上一个路由后api/auth/token可以走通,但是api/auth/token还是走不通。新发现:第一次请求502,以后的请求验证码失效。
		查看配置文件:sudo nano /etc/nginx/sites-available/default
		确认是否有错:nginx -t
		重新加载:nginx -s reload
		似乎日志文件无法创建。确认office.service的用户:www-data
		查看所有用户:compgen -u
		赋给www-data用户权限:sudo chown -R www-data:www-data /var/www/publishapplication/office_api(非常关键!!!只有设置了这个才可以创建日志目录和文件)
		查看日志已创建:cat /var/www/publishapplication/office_api/Logs/Test/test-20210506.log
		最终解决,就是因为服务用户没有权限的问题。因为用到了IWebHostEnvironment
		同理赋给www-data用户权限:
			sudo chown -R www-data:www-data /var/www/publishapplication/project_api
			sudo chown -R www-data:www-data /var/www/publishapplication/office_client
			sudo chown -R www-data:www-data /var/www/publishapplication/project_client
	--电工账号:15613914966 
	--项目管理后台: http://officemaster.ddingsafe.com/xunfei  
	--大楼游客:15762085260 (密码:888888)
	--大楼管理员:13811191763(密码:888888)
	
--项目位置管理出错:
	总部地址:http://47.103.61.198:5016/#/setup/position
	原来接口:http://47.103.61.198:5015/api/Locations/getLocations
	现在接口:http://officemaster.ddingsafe.com/api/Locations/getLocations
	ip接口: http://123.60.21.158:5002/api/Locations/getLocations
		不允许跨域,配置了跨域,是否Nginx是否允许跨域
		sudo nano /etc/nginx/sites-available/default
	报错:Access-Control-Allow-Origin header contains multiple values, but only one is allowed
    报错:no access-control-allow-origin header is present on the requested resource
    报错:response to preflight request doesn't pass access control check
    报错:The value of the 'Access-Control-Allow-Origin' header in the response must not be the wildcard '*' 
    报错:Response to preflight request doesn't pass access control check: No 'Access-Control-Allow-Origin' header is present on the requested resource.
    最终解决:程序内加上,Nginx没有加上
--一个不该出现的模块出现了
	在开放平台里刚好这个模块的ProjectId和测试项目的ProjectId对上了
--保存头像出错
    cat  /var/www/publishapplication/office_api/App_Data/DDTraceLog/DDTrace-20210510.log
   
	MineController.UploadAvatar (DD.OfficeBuilding.Web):The type initializer for 'Gdip' threw an exception
	Mine\Commands\UploadAvatar.cs:line 106
	本地调试,阿里云数据库是有白名单
System.Drawing.Common 组件提供对GDI+图形功能的访问。它是依赖于GDI+的,那么在Linux上它如何使用GDI+,因为Linux上是没有GDI+的。Mono 团队使用C语言实现了GDI+接口,提供对非Windows系统的GDI+接口访问能力(个人认为是模拟GDI+,与系统图像接口对接),这个就是 libgdiplus。进而可以推测 System.Drawing.Common 这个组件实现时,对于非Windows系统肯定依赖了 ligdiplus 这个组件。如果我们当前系统不存在这个组件,那么自然会报错,找不到它,安装它即可解决。
	sudo apt-get update
	apt-get install libgdiplus -y
	ln -s /usr/lib/libgdiplus.so /usr/lib/gdiplus.dll
	问题解决
--模块列表无法展示开关数量
	会根据APIKey获取命名空间,正确的key是bde2d876-993d-440d-aba1-3a06007a25a3,命名空间是OpenAPI_Office
	从开放平台}api/breaker/data接口,可以获取到数据
	在DDOpenSetting下的Key不对
--头像显示上传成功,但是不显示
	在项目的wwwroot/imgs/avatar中有2143.png,
	在数据库中的用户,15613914966用户对应的Avator是2143.png没错
	查看日志:cat /var/www/publishapplication/office_api/App_Data/DDTraceLog/DDTrace-20210511.log
	输入网址:http://moffice.ddingsafe.com/imgs/avatar/2143.png 也无法查看
	nginx应该允许图片
	UploadAvatarCommandHandler
	报错:cat /var/www/publishapplication/office_api/App_Data/DDTraceLog/DDTrace-20210511.log
	路径拼接问题
--显示二维码图片
    cat /var/www/publishapplication/office_api/App_Data/DDTraceLog/DDTrace-20210511.log
	Parameter is not valid, System.Drawing.SafeNativeMethods.Gdip.CheckStatus
    GetQRCodeService.cs:line 74
    路径拼接问题
--项目运营后台网页无法打开
	确定网址:http://officemaster.ddingsafe.com/xunfei
	确认project服务是否开启,已开启
	确认nginx配置
		配置有遗漏
--项目运营后台无法登录
	确定网址:http://officemaster.ddingsafe.com/xunfei
	先查看nginx配置
	查看项目源代码
	办公楼版大楼游客(15762085260)
    办公楼版大楼管理员(13811191763)
     'http://officemaster.ddingsafe.com/auth/login' from origin 'http://moffice.ddingsafe.com:5002'
    vue客户端更改域名指向:http://officemaster.ddingsafe.com/api,重新发布
    http://moffice.ddingsafe.com:5002/api
 --操作员的权限选择没有
 --修改Ubuntu服务器日期格式
    错误原因:如果程序中的时区与系统不一样会造成错误
 	查看日期的格式:date (Wed May 12 09:32:24 CST 2021)
 	查看日期格式另外一种:date -R (Wed, 12 May 2021 09:38:13 +0800)
 	运行命令:tzselect
 	sudo ln -sf /usr/share/zoneinfo/Asia/Shanghai /etc/localtime
 	date -s "2007-08-03 14:15:00"
 	sudo hwclock --systohc 
 	timedatectl
 	
 	https://phoenixnap.com/kb/how-to-set-or-change-timezone-date-time-ubuntu
 	重新:timedatectl
 	timedatectl set-ntp yes
 	timedatectl set-ntp no
 	timedatectl set-time 10:23:
 	timedatectl set-time 2021-05-12
 	timedatectl set-ntp yes
 	timedatectl
 	timedatectl  list-timezones
 	让硬件和Local Timezone保持一致:timedatectl set-local-rtc 1
 	sudo reboot
 	时间格式依然不对,需要的时间格式:1990-01-02 12:00:00
 	查看时间格式:timedatectl status
 	原理:Windows上使用的是Windows time zone IDs, Linux使用的是IANA时区。
 	解决办法:添加NodaTime
 --非电工项目列表报警统计没有,负荷没有
    RealWarning中没有CompanyId
    BreakerData中A_WP没有值
    管理员:12311111111
    操作员:12322222222
 --电工登录无法查看刚刚创建的公司
 	公司名称:5-12...01, 5-12...02
    电工账号:15613914966
    接口:api/mine/projects
    电工的总部User主键是6,而在项目数据库的CompanyUser中并不存在UserId=6的情况。因为电工从来不会加入某个公司,所以写字楼版不会把电工加入到CompanyUser中
    解决
 --修改开关名称的权限似乎弄反了
 	接口:api/main/changeBreakerName
 	需求:如果是管理员,可以修改名称;如果是操作员,要看projectsettings中有无设置
    1b3a10c7-efa0-43f9-95f8-dd8034166de6  修改开关名称
     var OperationId = _operationsRepo.GetOperationIdByName("修改名称");没有对应上
 --电量报表,天周月
 	开放平台接口:http://47.103.61.198:5008/api/breaker/power/random/by
 	报错:GetElectrictyService.cs:line 516
 	时序数据库按天的数据没有加
 	解决
 --项目运营后台添加场景计划有问题
 	项目运营后台appsetting中DDOpenSetting的Url_Job改成写字楼版的url
 	目前:http://47.103.61.198:5005/api/scene/addSceneShedules
 	改成:http://moffice.ddingsafe.com/api/scene/addSceneShedules
 --首页最近60分钟负荷报表
  	接口api/main/projectPower
 	开放平台接口:http://47.103.61.198:5008/api/breaker/fuhe/byaddr
 	开放平台数据是否正确:select count(*) from breakerdatas
 	管理员:12311111111
 	向开放平台请求:187ED53338C4_2,1,187ED5311111_1,3,2
 	开放平台请求负荷的数据库弄错了
 	解决
 --首页最近60分钟负荷公司列表重复
 	前端问题
 --首页最近60分钟开关负荷一直变,是否是随机数?
 --超级管理员在创建公司时 勾选 “分配给后台管理员”选项,在公司管理列表中不应该显示当前公司
   先确定那个字段:IsAdmin=1
   确定接口:api/mine/projects 和 api/main/projects 
   解决
 --超级管理员新建公司后,让管理员扫描当前公司邀请码,返回超级管理员账号并未收到‘新朋友’通知
 	管理员:12311111111 UserId=10 
 	超级管理员:15613914966 
 	扫描公司:5-13测试-02 CompanyId=9
 	在CompanyUser中,CompanyId=9, UserId=10m RoleId=空 RoleName=空, IsAllowed=0, HasRole=0
 	接收新朋友接口:
 	展示新朋友列表接口:api/mine/newFriends
 --办公楼版服务端无法运行
 	Failed to bind to address http://127.0.0.1:5000: address already in use.
    查看端口占用情况:lsof -i:5000
    kill进程:kill 686
    查看nginx配置:sudo nano /etc/nginx/sites-available/default
    查看端口:ps -aux | grep 5000
    查看进程详情:ps -fp 1178
    sudo systemctl disable office 在开机时禁用服务
    sudo systemctl enable office 在开机时启用服务
    nginx -s stop
    端口被哪个程序占用:netstat -tunlp | grep 5000
    kill  778
    一会就被启动起来
    试着关闭nginx是否可以再次启动起来:nginx -s stop
    还是这样,kill之后马上又启动起来
    记住当前服务的位置:/etc/systemd/system/office.service
    记录当前服务的内容:
[Unit]
Description=Office Version

[Service]
WorkingDirectory=/var/www/publishapplication/office_api
ExecStart=/usr/bin/dotnet /var/www/publishapplication/office_api/DD.OfficeBuilding.Web.dll
Restart=always
# Restart service after 10 seconds if the dotnet service crashes:
RestartSec=10
KillSignal=SIGINT
SyslogIdentifier=dotnet-example
User=www-data
Environment=ASPNETCORE_ENVIRONMENT=Production
Environment=DOTNET_PRINT_TELEMETRY_MESSAGE=false

[Install]
WantedBy=multi-user.target

	开始删除服务
	sudo systemctl stop office
	sudo systemctl disable office
	rm /etc/systemd/system/office.service
	sudo systemctl daemon-reload

	重新进入程序所在目录:cd /var/www/publishapplication/office_api
	dotnet DD.OfficeBuilding.Web.dll
	提示5000端口被占用
	尝试关闭nginx: sudo systemctl status nginx  没有在启用状态
	重启再观察5000端口是否在启用,依然在启用,即使在nginx关闭的情况下
	写字楼版换成5003端口: sudo nano /etc/nginx/sites-available/default
    sudo systemctl start nginx
    cd /var/www/publishapplication/office_api
    dotnet DD.OfficeBuilding.Web.dll
    依然在报5000占用
    Program加UseUrl解决
    重新创建服务:/etc/systemd/system/office.service
    开机启用: sudo systemctl enable office
    开始服务: sudo systemctl start office
    查看服务状态: sudo systemctl status office
    重启Nginx: nginx -s reload
--项目管理后台,请求http://moffice.ddingsafe.com:5002/api/auth/login 502 Bad Gateway
	外部端口5002对应的本地上游服务器的端口是:127.0.0.1:5001
	确认project服务是否运行:正在运行,并且监听的端口是5000,这里感觉错了,应该监听,应该是Program中错了,应该监听5001
	上传程序并重启网站:sudo systemctl start project
	查看状态:sudo systemctl status project, 上游服务器的端口是:127.0.0.1:5001
	打开网站:http://moffice.ddingsafe.com:5002
	nginx -s reload
	问题解决。重要教训:项目Program.cs中的UseUrls("http://0.0.0.0:5001")一定要和Nginx的上游服务器中的端口对应一致!!!
--开关列表
   开关列表中显示的图标,分为三个状态(分别显示不同颜色):
   未设置定时、已设置定时、还有十分钟自动分断
(当前状态未发生改变)

--延时断电
   开关还有十分钟自动分断,可对开关进行延时断电操作
(当前不可进行设置延时)

--通知推送
   还有十分钟自动分断显示推送,点击推送跳转到通知页
(当前跳转到通知页看不到该推送)

模拟数据

--确认新时序数据库的账户信息
--确认模拟数据项目:DD.Mock.Web
--确认包含哪些接口:
	插入多天的实时数据:real/insert/days
	按天插入小时电量:power/insert/oneday
	插入一个月的小时电量:power/insert/onemonth
	插入一个月的天电量:power/insert/day/onemonth
	插入某个月的月电量:power/insert/month/onemonth
	插入历史报警记录:InsertWarningOneMonth
--选择数据库的原理:通过TUrl, TUsername, TPassword
--查看新时序数据库目前数据:test_power, test_real
   登录:./taos.exe -h 116.63.236.99 -u  -p 
   C:\Windows\System32\drivers\etc\hosts 文件中添加 116.63.236.99 ecs-dingding
   C:\TDengine\cfg\taos.cfg 中添加 firstEp 116.63.236.99:6030
   select ts, aa from super_real where mac='187ed5311111' and addr=1 limit 10;
   最新的数据是3.30日
--插入实时数据
	api/sx/real/insert/days
	报错:ShiXu\Commands\InsertRealByDaysNotification.cs:line 121,New\Services\ManageSuperReal.cs:line 177
	 select ts, aa from super_real where mac='187ed53338c4' and addr=1 limit 50;
	 select last(ts1,aa) from super_real where mac='187ed53338c4' and addr=1;
	 select count(*) from super_real;
--插入电量数据
	按小时:api/sx/power/insert/onemonth
	按天:api/sx/power/insert/day/onemonth
--确认所有的模块
	187ED53338C4 187ed53338c4
	187ED5311111 187ed5311111
	187ED5322222 187ed5322222
	187ED5333333 187ed5333333
	187ED5344444 187ed5344444
	187ED5355555 187ed5355555
	187ED5366666 187ed5366666