Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
Q
QM_TJ
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Analytics
Analytics
CI / CD
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
李增强
QM_TJ
Commits
1a9323f7
Commit
1a9323f7
authored
Jan 25, 2021
by
李增强
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
m
parent
dd668db1
Changes
9
Hide whitespace changes
Inline
Side-by-side
Showing
9 changed files
with
455 additions
and
191 deletions
+455
-191
lib/a.md
lib/a.md
+135
-0
lib/qm_tj.dart
lib/qm_tj.dart
+112
-175
lib/src/db.dart
lib/src/db.dart
+16
-13
lib/src/model/tj_app_model.dart
lib/src/model/tj_app_model.dart
+21
-0
lib/src/sql.dart
lib/src/sql.dart
+5
-2
lib/src/tj/app.dart
lib/src/tj/app.dart
+73
-0
lib/src/utils.dart
lib/src/utils.dart
+84
-0
pubspec.lock
pubspec.lock
+7
-0
pubspec.yaml
pubspec.yaml
+2
-1
No files found.
lib/a.md
0 → 100644
View file @
1a9323f7
# 1.APP启动
```
{
event_name: "app_stage",
device_id:"",
event_data: [{
inter: "4G", // 网络情况
app_channel: "", // APP下载渠道
app_version: "1.0.0", // APP版本号
type: 2, // 1:启动APP, 2:APP从后台回到前台
appear_time: "1611540208", // 启动时间
disappear_time: "1611540208",// 关闭时间
extras: { // 此数据为自定义数据
user_id: "66713", // 用户id
source: 2, // 来源
...
}
}]
}
```
# 2.页面游览
```
{
event_name: "page_scan",
event_data: [{
inter: "4G", // 网络情况
app_channel: "", // APP下载渠道
app_version: "1.0.0", // APP版本号
page_id: "com.qm.app.goods", // 页面ID
last_page_id: "com.qm.app.home", // 上一个页面ID
appear_time: "1611540208", // 启动时间
disappear_time: "1611540208", // 关闭时间
extras: { // 此数据为自定义数据
user_id: "66713", // 用户id
source: 2, // 来源
goods_id: "15112231541", // 商品ID
...
}
}]
}
```
# 3.点击
```
{
event_name: "elem_click",
event_data: [{
inter: "4G", // 网络情况
app_channel: "", // APP下载渠道
app_version: "1.0.0", // APP版本号
page_id: "com.qm.app.goods", // 页面ID
click_id: "button", // 点击ID
click_time: "1611540208", // 点击时间
extras: { // 此数据为自定义数据
user_id: "66713", // 用户id
source: 2, // 来源
goods_id: "15112231541", // 商品ID
...
}
}]
}
```
# 4.曝光
```
{
event_name: "elem_exposure",
event_data: [{
inter: "4G", // 网络情况
app_channel: "", // APP下载渠道
app_version: "1.0.0", // APP版本号
page_id: "com.qm.app.goods", // 页面ID
exposure_id: "order_good_list", // 曝光ID
exposure_time: "1611540208", // 曝光时间
extras: { // 此数据为自定义数据
user_id: "66713", // 用户id
source: 2, // 来源
goods_id: "15112231541", // 商品ID
...
}
}]
}
```
# API数据格式
```
{
device_id:"",
projects:[{
event_name: "app_stage",
...
},{
event_name: "page_scan",
...
},{
event_name: "elem_click",
...
},{
event_name: "elem_exposure",
...
},{
event_name: "app_stage",
...
},{
event_name: "page_scan",
...
},{
event_name: "elem_click",
...
},{
event_name: "elem_exposure",
...
}]
}
```
## 数据上报
1.
APP启动上报(回到前台)
2.
定时上报
## APP启动和页面游览上报
1.
APP启动(进入前台)->APP关闭(进入后台),算一次上报
2.
页面启动(进入前台)->页面关闭(进入后台),算一次上报
## APP被杀死上报
1.
APP被杀死时,APP和游览页面没有关闭关闭时间,正常情况无法算一次上报,在APP启动时直接上报所有
\ No newline at end of file
lib/qm_tj.dart
View file @
1a9323f7
...
...
@@ -2,88 +2,37 @@ library qm_tj;
import
'dart:convert'
;
import
'package:qm_tj/src/utils.dart'
;
import
'src/db.dart'
;
import
'src/http.dart'
;
import
'package:crypto/crypto.dart'
as
crypto
;
import
'src/tj/app.dart'
;
class
QMTJ
{
static
DB
_db
;
static
Http
_http
;
static
String
_appStartUpId
;
static
Future
<
bool
>
ready
;
static
bool
isDebug
=
false
;
static
App
_app
;
static
void
debug
()
{
isDebug
=
true
;
Utils
.
debug
()
;
}
static
init
()
async
{
_http
=
Http
(
scheme:
"http"
,
host:
"8.135.58.206"
,
port:
8802
);
_appStartUpId
=
_md5
(
_getDateNow
().
toString
());
ready
=
new
Future
<
bool
>(()
async
{
_db
=
new
DB
();
await
_db
.
init
();
return
true
;
});
_db
.
init
();
_app
=
App
(
_db
);
Future
.
delayed
(
Duration
(
seconds:
5
)).
then
((
value
)
{
uploadPageTj
();
});
}
/// APP 启动
static
void
appStart
({
int
source
,
Map
<
String
,
dynamic
>
extras
})
async
{
int
type
=
1
;
int
disappearTime
=
0
;
int
appearTime
=
_getDateNow
();
String
id
=
_appStartUpId
;
Map
<
String
,
dynamic
>
map
=
{
"id"
:
id
,
"type"
:
type
,
"source"
:
source
,
"disappear_time"
:
disappearTime
,
"appear_time"
:
appearTime
,
"extras"
:
json
.
encode
(
extras
),
};
await
ready
;
log
(
"appStart"
,
map
);
await
_db
.
db
.
insert
(
"app_tj"
,
map
);
}
/// APP 可见
static
void
appAppear
({
int
source
,
Map
<
String
,
dynamic
>
extras
})
async
{
// APP进入前台,重新生成启动id
_appStartUpId
=
_md5
(
_getDateNow
().
toString
());
int
type
=
2
;
int
disappearTime
=
0
;
int
appearTime
=
_getDateNow
();
String
id
=
_appStartUpId
;
Map
<
String
,
dynamic
>
map
=
{
"id"
:
id
,
"type"
:
type
,
"source"
:
source
,
"disappear_time"
:
disappearTime
,
"appear_time"
:
appearTime
,
"extras"
:
json
.
encode
(
extras
),
};
await
ready
;
log
(
"appAppear"
,
map
);
await
_db
.
db
.
insert
(
"app_tj"
,
map
);
static
void
onAppResume
({
Map
<
String
,
dynamic
>
extras
})
async
{
_app
.
onResume
(
extras:
extras
);
}
/// APP 不可见
static
void
appDisappear
()
async
{
int
disappearTime
=
_getDateNow
();
Map
<
String
,
dynamic
>
map
=
{
"id"
:
_appStartUpId
,
"disappear_time"
:
disappearTime
,
};
await
ready
;
log
(
"appDisappear"
,
map
);
_db
.
db
.
update
(
"app_tj"
,
{
"disappear_time"
:
disappearTime
},
where:
"id = ? and disappear_time = 0"
,
whereArgs:
[
_appStartUpId
]);
static
void
onAppPause
()
async
{
_app
.
onPause
();
}
/// PAGE 可见
...
...
@@ -92,46 +41,46 @@ class QMTJ {
String
pageId
,
String
lastPageId
,
Map
<
String
,
dynamic
>
extras
})
async
{
String
extrasStr
=
json
.
encode
(
extras
);
String
id
=
_md5
(
"
${pageId}
_
${lastPageId}
_
$extrasStr
"
);
int
disappearTime
=
0
;
int
appearTime
=
_getDateNow
();
Map
<
String
,
dynamic
>
map
=
{
"id"
:
id
,
"source"
:
source
,
"page_id"
:
pageId
,
"last_page_id"
:
lastPageId
,
"appear_time"
:
appearTime
,
"disappear_time"
:
disappearTime
,
"extras"
:
extrasStr
,
};
await
ready
;
log
(
"pageAppear"
,
map
);
await
_db
.
db
.
insert
(
"page_tj"
,
map
);
//
String extrasStr = json.encode(extras);
//
String id = _md5("${pageId}_${lastPageId}_$extrasStr");
//
int disappearTime = 0;
//
int appearTime = _getDateNow();
//
Map<String, dynamic> map = {
//
"id": id,
//
"source": source,
//
"page_id": pageId,
//
"last_page_id": lastPageId,
//
"appear_time": appearTime,
//
"disappear_time": disappearTime,
//
"extras": extrasStr,
//
};
// await _db.
ready;
//
log("pageAppear", map);
//
await _db.db.insert("page_tj", map);
}
/// PAGE 不可见
static
void
pageDisappear
(
{
String
pageId
,
String
lastPageId
,
Map
<
String
,
dynamic
>
extras
})
async
{
String
extrasStr
=
json
.
encode
(
extras
);
String
id
=
_md5
(
"
${pageId}
_
${lastPageId}
_
$extrasStr
"
);
int
disappearTime
=
_getDateNow
();
Map
<
String
,
dynamic
>
map
=
{
"id"
:
id
,
"page_id"
:
pageId
,
"last_page_id"
:
lastPageId
,
"disappear_time"
:
disappearTime
,
"extras"
:
extrasStr
,
};
await
ready
;
log
(
"pageDisappear"
,
map
);
await
_db
.
db
.
update
(
"page_tj"
,
{
"disappear_time"
:
disappearTime
,
},
where:
"id = ? and disappear_time = 0"
,
whereArgs:
[
id
]);
//
String extrasStr = json.encode(extras);
//
String id = _md5("${pageId}_${lastPageId}_$extrasStr");
//
int disappearTime = _getDateNow();
//
Map<String, dynamic> map = {
//
"id": id,
//
"page_id": pageId,
//
"last_page_id": lastPageId,
//
"disappear_time": disappearTime,
//
"extras": extrasStr,
//
};
// await _db.
ready;
//
log("pageDisappear", map);
//
await _db.db.update(
//
"page_tj",
//
{
//
"disappear_time": disappearTime,
//
},
//
where: "id = ? and disappear_time = 0",
//
whereArgs: [id]);
}
/// 点击
...
...
@@ -143,20 +92,20 @@ class QMTJ {
String
pageId
,
String
clickId
,
Map
<
String
,
dynamic
>
extras
})
async
{
int
clickTime
=
_getDateNow
();
String
extrasStr
=
json
.
encode
(
extras
);
String
id
=
_md5
(
"
${pageId}
_
${clickId}
_
${extrasStr}
_
${clickTime}
"
);
Map
<
String
,
dynamic
>
map
=
{
"id"
:
id
,
"source"
:
source
,
"page_id"
:
pageId
,
"click_id"
:
clickId
,
"click_time"
:
clickTime
,
"extras"
:
extrasStr
,
};
await
ready
;
log
(
"tap"
,
map
);
await
_db
.
db
.
insert
(
"tap_tj"
,
map
);
//
int clickTime = _getDateNow();
//
String extrasStr = json.encode(extras);
//
String id = _md5("${pageId}_${clickId}_${extrasStr}_${clickTime}");
//
Map<String, dynamic> map = {
//
"id": id,
//
"source": source,
//
"page_id": pageId,
//
"click_id": clickId,
//
"click_time": clickTime,
//
"extras": extrasStr,
//
};
// await _db.
ready;
//
log("tap", map);
//
await _db.db.insert("tap_tj", map);
}
/// 曝光
...
...
@@ -168,65 +117,62 @@ class QMTJ {
String
pageId
,
String
exposureId
,
Map
<
String
,
dynamic
>
extras
})
async
{
int
exposureTime
=
_getDateNow
();
String
extrasStr
=
json
.
encode
(
extras
);
String
id
=
_md5
(
"
${pageId}
_
${exposureId}
_
${extrasStr}
_
${exposureTime}
"
);
Map
<
String
,
dynamic
>
map
=
{
"id"
:
id
,
"source"
:
source
,
"page_id"
:
pageId
,
"exposure_id"
:
exposureId
,
"exposure_time"
:
exposureTime
,
"extras"
:
extrasStr
,
};
await
ready
;
log
(
"exposure"
,
map
);
await
_db
.
db
.
insert
(
"exposure_tj"
,
map
);
//
int exposureTime = _getDateNow();
//
String extrasStr = json.encode(extras);
//
String id = _md5("${pageId}_${exposureId}_${extrasStr}_${exposureTime}");
//
Map<String, dynamic> map = {
//
"id": id,
//
"source": source,
//
"page_id": pageId,
//
"exposure_id": exposureId,
//
"exposure_time": exposureTime,
//
"extras": extrasStr,
//
};
// await _db.
ready;
//
log("exposure", map);
//
await _db.db.insert("exposure_tj", map);
}
// 上传页面统计
static
void
uploadPageTj
()
async
{
await
ready
;
List
<
Map
>
list
=
await
_db
.
db
.
query
(
"page_tj"
,
limit:
100
,
offset:
0
);
if
(
list
.
length
==
0
)
{
return
;
}
List
<
String
>
ids
=
[];
list
=
list
.
map
((
e
)
{
var
item
=
{
"app_version"
:
'0.0.1'
,
"app_channel"
:
"APP渠道"
,
"devices_id"
:
'3A26610FFE43D5838DDE7A40BA2E3E2C'
,
"inter"
:
'4G'
,
"source"
:
e
[
'source'
],
"page_id"
:
e
[
'page_id'
],
"last_page_id"
:
e
[
'last_page_id'
],
"come_time"
:
e
[
'appear_time'
],
"out_time"
:
e
[
'disappear_time'
],
"extras"
:
json
.
decode
(
e
[
'extras'
])
};
ids
.
add
(
e
[
'id'
]);
Map
project
=
{
"event_name"
:
"page_scan"
,
"app"
:
"xx"
,
"event_info"
:
item
};
return
project
;
}).
toList
();
print
({
"project"
:
json
.
encode
(
list
)});
_http
.
post
(
"/collection"
,
{
"project"
:
json
.
encode
(
list
)}).
then
(
(
value
)
async
{
if
(
isDebug
)
{
log
(
"upload_page_tj"
,
Map
<
String
,
dynamic
>.
from
(
value
));
}
if
(
value
!=
null
&&
value
[
'code'
]
==
200
)
{
int
result
=
await
_db
.
db
.
rawDelete
(
"delete from page_tj where id in('
${ids.join("','")}
')"
);
log
(
"clear_page_tj"
,
Map
<
String
,
dynamic
>.
from
(
{
"olength"
:
list
.
length
,
"length"
:
result
}));
}
uploadPageTj
();
});
// await _db.ready;
// List<Map> list = await _db.db.query("page_tj", limit: 100, offset: 0);
// if (list.length == 0) {
// return;
// }
// List<String> ids = [];
// list = list.map((e) {
// var item = {
// "app_version": '0.0.1',
// "app_channel": "APP渠道",
// "devices_id": '3A26610FFE43D5838DDE7A40BA2E3E2C',
// "inter": '4G',
// "source": e['source'],
// "page_id": e['page_id'],
// "last_page_id": e['last_page_id'],
// "come_time": e['appear_time'],
// "out_time": e['disappear_time'],
// "extras": json.decode(e['extras'])
// };
// ids.add(e['id']);
// Map project = {
// "event_name": "page_scan",
// "app": "xx",
// "event_info": item
// };
// return project;
// }).toList();
// print({"project": json.encode(list)});
// }
// static Map<String, dynamic> getCommonParams() {
// return {
// "inter": "网络情况",
// "app_channel": "APP渠道",
// "app_version": "APP版本",
// "device_id": "设备ID",
// "source": "来源",
// };
}
/// 获取当前时间戳,单位:秒
...
...
@@ -241,13 +187,4 @@ class QMTJ {
var
digest
=
crypto
.
md5
.
convert
(
bytes
);
return
digest
.
toString
();
}
static
void
log
(
String
type
,
Map
<
String
,
dynamic
>
map
)
{
if
(!
isDebug
)
{
return
;
}
print
(
"
$type
=======================s===========================
$type
"
);
print
(
map
);
print
(
"
$type
=======================e===========================
$type
"
);
}
}
lib/src/db.dart
View file @
1a9323f7
...
...
@@ -5,21 +5,24 @@ import 'sql.dart';
class
DB
{
int
_version
=
1
;
Database
db
;
Future
<
bool
>
ready
;
/// 打开数据库
Future
init
()
async
{
var
databasesPath
=
await
getDatabasesPath
();
String
path
=
join
(
databasesPath
,
'qm_tj.db'
,
);
db
=
await
openDatabase
(
path
,
version:
_version
,
onCreate:
(
Database
db
,
int
version
)
async
{
await
db
.
execute
(
SQL_APP_TJ_TABLE
);
await
db
.
execute
(
SQL_PAGE_TJ_TABLE
);
await
db
.
execute
(
SQL_TAP_TJ_TABLE
);
await
db
.
execute
(
SQL_EXPOSURE_TJ_TABLE
);
void
init
()
{
ready
=
new
Future
<
bool
>(()
async
{
var
databasesPath
=
await
getDatabasesPath
();
String
path
=
join
(
databasesPath
,
'qm_tj.db'
,
);
db
=
await
openDatabase
(
path
,
version:
_version
,
onCreate:
(
Database
db
,
int
version
)
async
{
await
db
.
execute
(
SQL_APP_TJ_TABLE
);
await
db
.
execute
(
SQL_PAGE_TJ_TABLE
);
await
db
.
execute
(
SQL_TAP_TJ_TABLE
);
await
db
.
execute
(
SQL_EXPOSURE_TJ_TABLE
);
});
return
true
;
});
}
}
lib/src/model/tj_app_model.dart
0 → 100644
View file @
1a9323f7
enum
TJAppModelTypes
{
startUp
,
resume
}
class
TJAppModel
{
String
inter
;
String
appChannel
;
String
appVersion
;
TJAppModelTypes
type
;
int
appearTime
;
int
disappearTime
;
Map
<
String
,
dynamic
>
extras
;
TJAppModel
(
{
this
.
inter
,
this
.
appChannel
,
this
.
appVersion
,
this
.
type
,
this
.
appearTime
,
this
.
disappearTime
,
this
.
extras
});
}
lib/src/sql.dart
View file @
1a9323f7
...
...
@@ -3,10 +3,13 @@ String SQL_APP_TJ_TABLE = '''
CREATE TABLE app_tj (
id VARCHAR(32) ,
type TINYINT(4),
source INTEGER(10),
appear_time INTEGER(10),
disappear_time INTEGER(10),
extras VARCHAR(255)
extras VARCHAR(255),
inter VARCHAR(255),
app_channel VARCHAR(255),
app_version VARCHAR(255),
)
'''
;
// 页面可见或者不可见
...
...
lib/src/tj/app.dart
0 → 100644
View file @
1a9323f7
import
'dart:convert'
;
import
'../../src/db.dart'
;
import
'../../src/utils.dart'
;
class
App
{
DB
_db
;
String
_appStartUpId
;
App
(
DB
db
)
{
_db
=
db
;
}
/// APP回到前台
void
onResume
({
Map
<
String
,
dynamic
>
extras
})
async
{
int
type
=
2
;
int
disappearTime
=
0
;
int
appearTime
=
Utils
.
getDateNow
();
Map
<
String
,
dynamic
>
map
=
{
"id"
:
_appStartUpId
,
"type"
:
type
,
"appear_time"
:
appearTime
,
"disappear_time"
:
disappearTime
,
"extras"
:
json
.
encode
(
extras
)
};
Map
<
String
,
dynamic
>
common
=
await
Utils
.
getCommonParams
();
map
.
addAll
(
common
);
// APP 启动生成本次启动ID
if
(
_appStartUpId
==
null
)
{
type
=
1
;
_appStartUpId
=
Utils
.
md5
(
Utils
.
getDateNow
().
toString
());
}
await
_db
.
ready
;
Utils
.
log
(
"app onResume"
,
map
);
await
_db
.
db
.
insert
(
"app_tj"
,
map
);
}
/// APP进入后台
void
onPause
()
async
{
int
disappearTime
=
Utils
.
getDateNow
();
Map
<
String
,
dynamic
>
map
=
{
"id"
:
_appStartUpId
,
"disappear_time"
:
disappearTime
,
};
await
_db
.
ready
;
Utils
.
log
(
"app onPause"
,
map
);
await
_db
.
db
.
insert
(
"app_tj"
,
map
);
}
// 上传数据至接口
void
upload
()
async
{
await
_db
.
ready
;
List
<
Map
>
list
=
await
_db
.
db
.
query
(
"page_tj"
,
limit:
100
,
offset:
0
);
if
(
list
.
length
==
0
)
{
return
;
}
String
deviceId
=
await
Utils
.
getDeviceId
();
bool
result
=
await
Utils
.
uploadData
({
"device_id"
:
deviceId
,
"projects"
:
list
});
if
(
result
)
{
List
<
String
>
ids
=
list
.
map
((
e
)
=>
e
[
'id'
]).
toList
();
await
_db
.
db
.
rawDelete
(
"delete from page_tj where id in('
${ids.join("','")}
')"
);
}
if
(
Utils
.
isDebug
)
{
Utils
.
log
(
"upload_result"
,
{
"ok"
:
result
,
"length"
:
list
.
length
});
}
if
(
list
.
length
==
100
)
{
upload
();
}
}
}
lib/src/utils.dart
0 → 100644
View file @
1a9323f7
import
'dart:convert'
;
import
'http.dart'
;
import
'package:crypto/crypto.dart'
as
crypto
;
import
'package:package_info/package_info.dart'
;
class
Utils
{
static
String
channel
=
''
;
static
bool
isDebug
=
false
;
static
Http
_http
=
Http
(
scheme:
"http"
,
host:
"8.135.58.206"
,
port:
8802
);
/// 设置调试模式
static
void
debug
()
{
isDebug
=
true
;
}
/// 设置渠道
static
void
setChannel
(
String
s
)
{
channel
=
s
;
}
/// 获取当前时间戳,单位:秒
static
int
getDateNow
()
{
int
now
=
(
DateTime
.
now
().
millisecondsSinceEpoch
/
1000
).
floor
();
return
now
;
}
// md5编码
static
String
md5
(
String
data
)
{
var
bytes
=
utf8
.
encode
(
data
);
var
digest
=
crypto
.
md5
.
convert
(
bytes
);
return
digest
.
toString
();
}
// 获取app版本号
static
Future
<
String
>
getAppVersion
()
async
{
PackageInfo
packageInfo
=
await
PackageInfo
.
fromPlatform
();
String
version
=
packageInfo
.
version
;
return
version
;
}
// 获取网络类型
static
Future
<
String
>
getNetworkType
()
async
{
return
"4G"
;
}
// 获取设备ID
static
Future
<
String
>
getDeviceId
()
async
{
return
"3A26610FFE43D5838DDE7A40BA2E3E2C"
;
}
// 获取公共参数
static
Future
<
Map
<
String
,
dynamic
>>
getCommonParams
()
async
{
String
inter
=
await
Utils
.
getNetworkType
();
String
appVersion
=
await
Utils
.
getAppVersion
();
return
{
"inter"
:
inter
,
// 网络情况
"app_channel"
:
channel
,
// APP下载渠道
"app_version"
:
appVersion
,
// APP版本号
};
}
// 上传数据
static
Future
<
bool
>
uploadData
(
Map
<
String
,
dynamic
>
body
)
async
{
var
res
=
await
_http
.
post
(
"/collection"
,
body
);
if
(
isDebug
)
{
log
(
"upload-res"
,
res
);
}
if
(
res
!=
null
&&
res
[
'code'
]
==
200
)
{
return
true
;
}
return
false
;
}
static
void
log
(
String
type
,
Map
<
String
,
dynamic
>
map
)
{
if
(!
isDebug
)
{
return
;
}
print
(
"qm_tj:
$type
=======================s===========================
$type
"
);
print
(
"qm_tj:
$map
"
);
print
(
"qm_tj:
$type
=======================e===========================
$type
"
);
}
}
pubspec.lock
View file @
1a9323f7
...
...
@@ -88,6 +88,13 @@ packages:
url: "https://pub.flutter-io.cn"
source: hosted
version: "1.3.0-nullsafety.3"
package_info:
dependency: "direct main"
description:
name: package_info
url: "https://pub.flutter-io.cn"
source: hosted
version: "0.4.3+2"
path:
dependency: "direct main"
description:
...
...
pubspec.yaml
View file @
1a9323f7
...
...
@@ -13,7 +13,8 @@ dependencies:
sdk
:
flutter
sqflite
:
^1.3.2+2
path
:
^1.6.4
crypto
:
2.1.4
crypto
:
2.1.4
package_info
:
0.4.3+2
dev_dependencies
:
flutter_test
:
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment