@@ -0,0 +1,3 @@ | |||
.vscode | |||
node_modules | |||
dist |
@@ -0,0 +1,9 @@ | |||
# Browsers that we support | |||
> 1% | |||
last 2 versions | |||
not dead | |||
# Node.js that we support | |||
node >= 8.11.0 | |||
@@ -0,0 +1,2 @@ | |||
**/node_modules | |||
**/dist |
@@ -0,0 +1,2 @@ | |||
NODE_ENV='development' | |||
VUE_APP_SERVER_URL=https://localhost:8080 |
@@ -0,0 +1,2 @@ | |||
NODE_ENV='production' | |||
VUE_APP_SERVER_URL=https://127.0.0.1 |
@@ -0,0 +1,2 @@ | |||
NODE_ENV='test' | |||
VUE_APP_SERVER_URL=http://10.12.96.114:8082/ |
@@ -0,0 +1,23 @@ | |||
module.exports = { | |||
root: true, | |||
env: { | |||
node: true | |||
}, | |||
extends: [ | |||
// "eslint:recommended", | |||
"plugin:vue/base", | |||
"plugin:vue/essential", | |||
"plugin:vue/strongly-recommended", | |||
"plugin:vue/recommended", | |||
"@vue/prettier", | |||
"prettier/babel" | |||
], | |||
parserOptions: { | |||
parser: "babel-eslint" | |||
}, | |||
rules: { | |||
"no-console": process.env.NODE_ENV === "production" ? "warn" : "off", | |||
"no-debugger": process.env.NODE_ENV === "production" ? "warn" : "off" | |||
} | |||
}; |
@@ -0,0 +1,23 @@ | |||
.DS_Store | |||
node_modules | |||
/dist | |||
# local env files | |||
.env.local | |||
.env.*.local | |||
# Log files | |||
npm-debug.log* | |||
yarn-debug.log* | |||
yarn-error.log* | |||
# Editor directories and files | |||
.idea | |||
.vscode | |||
!.vscode/launch.json | |||
!.vscode/settings.json | |||
*.suo | |||
*.ntvs* | |||
*.njsproj | |||
*.sln | |||
*.sw? |
@@ -0,0 +1,5 @@ | |||
# For fix low severity vulnerability of package yargs-parser | |||
# registry=https://registry.npmjs.org | |||
# For speeding up jenkins compile process | |||
registry=https://registry.npm.taobao.org |
@@ -0,0 +1,10 @@ | |||
{ | |||
"eslintIntegration": true, | |||
"formatOnSave": false, | |||
"tabWidth": 4, | |||
"printWidth": 120, | |||
"arrowParens": "always" | |||
} |
@@ -0,0 +1,7 @@ | |||
{ | |||
"rules": { | |||
"selector-pseudo-element-no-unknown": [true, { | |||
"ignorePseudoElements": ["-webkit-media-controls-enclosure"] | |||
}] | |||
} | |||
} |
@@ -0,0 +1,12 @@ | |||
module.exports = { | |||
presets: ["@vue/cli-plugin-babel/preset"], | |||
plugins: [ | |||
[ | |||
"component", | |||
{ | |||
libraryName: "mint-ui", | |||
style: true | |||
} | |||
] | |||
] | |||
}; |
@@ -0,0 +1,96 @@ | |||
user www-data; | |||
worker_processes 1; | |||
error_log /var/log/nginx/error.log warn; | |||
pid /var/run/nginx.pid; | |||
events { | |||
worker_connections 1024; | |||
} | |||
http { | |||
include /etc/nginx/mime.types; | |||
default_type application/octet-stream; | |||
log_format main '$remote_addr($http_x_real_ip) - $remote_user [$time_local] ' | |||
'$ssl_protocol/$ssl_cipher ' | |||
'"$http_host($http_true_client_ip:$upstream_addr) $request" $status $body_bytes_sent ' | |||
'"$http_referer" "$http_user_agent" "$http_x_forwarded_for"' | |||
'\n'; | |||
access_log /var/log/nginx/access.log main; | |||
sendfile on; | |||
keepalive_timeout 65; | |||
gzip on; | |||
gzip_static on; | |||
gzip_vary on; | |||
gzip_disable "MSIE [1-6]\."; | |||
gzip_proxied expired no-cache no-store private auth; | |||
gzip_comp_level 1; | |||
gzip_min_length 10k; | |||
gzip_types | |||
text/plain | |||
text/css | |||
text/js | |||
text/javascript | |||
text/html | |||
text/xml | |||
text/x-component | |||
application/javascript | |||
application/x-javascript | |||
application/json | |||
application/xhtml+xml | |||
application/xml | |||
application/rss+xml | |||
application/x-font-ttf | |||
application/vnd.ms-fontobject | |||
font/truetype | |||
font/opentype | |||
image/svg+xml svg svgz; | |||
map $http_accept $webp_suffix { | |||
default ""; | |||
"~*webp" ".webp"; | |||
} | |||
map $msie $cache_control { | |||
"1" "private"; | |||
} | |||
map $msie $vary_header { | |||
default "Accept"; | |||
"1" ""; | |||
} | |||
server { | |||
listen 8888 ssl http2; | |||
listen [::]:8888 ssl http2; | |||
server_name test.cloudminds.com; | |||
ssl_certificate /etc/nginx/cert/214971167760195.pem; | |||
ssl_certificate_key /etc/nginx/cert/214971167760195.key; | |||
ssl_session_cache shared:SSL:10m; | |||
ssl_session_timeout 10m; | |||
ssl_protocols TLSv1 TLSv1.1 TLSv1.2; | |||
ssl_ciphers HIGH:!aNULL:!MD5; | |||
ssl_prefer_server_ciphers on; | |||
location / { | |||
root /srv/www/cloudia-fe-mall; | |||
index index.html; | |||
try_files $uri $uri/ /index.html; | |||
} | |||
location ~* .(jpe?g|png|gif|svg)$ { | |||
root /srv/www/cloudia-fe-mall; | |||
add_header Vary $vary_header; | |||
add_header Cache-Control $cache_control; | |||
try_files $uri$webp_suffix $uri =404; | |||
} | |||
error_page 500 502 503 504 /50x.html; | |||
location = /50x.html { | |||
root /usr/share/nginx/html; | |||
} | |||
} | |||
} |
@@ -0,0 +1,60 @@ | |||
{ | |||
"name": "aobei-aiman", | |||
"version": "1.0.0", | |||
"info": "奥北数字人", | |||
"private": true, | |||
"scripts": { | |||
"serve": "vue-cli-service serve --open", | |||
"build": "vue-cli-service build --modern --mode development", | |||
"build:test": "vue-cli-service build --modern --mode test", | |||
"build:prod": "vue-cli-service build --modern --mode production", | |||
"lint": "vue-cli-service lint --no-fix", | |||
"lint:fix": "vue-cli-service lint", | |||
"analyze": "cross-env ANALYZER=true npm run build:prod && webpack-bundle-analyzer --port 8123 dist/stats.json" | |||
}, | |||
"dependencies": { | |||
"axios": "^0.19.2", | |||
"core-js": "^3.6.4", | |||
"element-ui": "^2.15.10", | |||
"js-md5": "^0.7.3", | |||
"jsencrypt": "^3.2.1", | |||
"lodash": "^4.17.15", | |||
"mint-ui": "^2.2.13", | |||
"moment": "^2.29.4", | |||
"video.js": "^7.20.3", | |||
"videojs-flash": "^2.2.1", | |||
"vue": "^2.6.11", | |||
"vue-grid-layout": "^2.3.7", | |||
"vue-lazyload": "^1.3.3", | |||
"vue-navigation": "^1.1.4", | |||
"vue-router": "^3.1.6" | |||
}, | |||
"devDependencies": { | |||
"@amap/amap-jsapi-loader": "0.0.1", | |||
"@vue/cli-plugin-babel": "~4.3.0", | |||
"@vue/cli-plugin-eslint": "~4.3.0", | |||
"@vue/cli-plugin-router": "~4.3.0", | |||
"@vue/cli-plugin-vuex": "~4.3.0", | |||
"@vue/cli-service": "~4.3.0", | |||
"@vue/eslint-config-prettier": "^6.0.0", | |||
"babel-eslint": "^10.1.0", | |||
"babel-plugin-component": "^1.1.1", | |||
"babel-plugin-lodash": "^3.3.4", | |||
"compression-webpack-plugin": "^3.1.0", | |||
"copy-webpack-plugin": "^6.0.2", | |||
"cross-env": "^7.0.2", | |||
"eslint": "^6.7.2", | |||
"eslint-plugin-prettier": "^3.1.1", | |||
"eslint-plugin-vue": "^6.2.2", | |||
"imagemin-mozjpeg": "^8.0.0", | |||
"imagemin-webp-webpack-plugin": "^3.3.1", | |||
"imagemin-webpack-plugin": "^2.4.2", | |||
"jquery": "^3.6.1", | |||
"prettier": "^1.19.1", | |||
"sass": "^1.26.3", | |||
"sass-loader": "^8.0.2", | |||
"vue-awesome-swiper": "^3.1.3", | |||
"vue-template-compiler": "^2.6.11", | |||
"webpack-bundle-analyzer": "^3.7.0" | |||
} | |||
} |
@@ -0,0 +1,515 @@ | |||
{ | |||
"ttsControlEnable": true, | |||
"qp": { | |||
"type": 1, | |||
"equip_no": "2", | |||
"set_no": "2", | |||
"value": "AlarmCenter.ScreensAddin.ScreensCommand", | |||
"name": "全屏", | |||
"info": "已为您打开全屏", | |||
"top": 0 | |||
}, | |||
"fhsy": { | |||
"type": 1, | |||
"equip_no": "2", | |||
"set_no": "1701", | |||
"value": "AlarmCenter.ScreensAddin.ScreensCommand", | |||
"name": "首页", | |||
"info": "已返回首页", | |||
"top": 0 | |||
}, | |||
"af_open": { | |||
"type": 3, | |||
"path": "/api/real/Security/setup_SecurityOpenPage", | |||
"data": { | |||
"page_no": "2", | |||
"mes": "打开安防态势" | |||
}, | |||
"msg": "已为您打开安防态势" | |||
}, | |||
"af_camera_open":{ | |||
"type": 3, | |||
"path": "/api/real/Security/setup_CameraService", | |||
"data": { | |||
"page_no": "2", | |||
"mes": "园区监控", | |||
"equip_no":2, | |||
"value":1, | |||
"set_no": "" | |||
}, | |||
"msg": "已为您打开园区监控" | |||
}, | |||
"ny_open": { | |||
"type": 3, | |||
"path": "/api/real/Comprehensive/setup_EnergyOpenPage", | |||
"data": { | |||
"page_no": "5", | |||
"mes": "打开能源态势" | |||
}, | |||
"msg": "已为您打开能源态势" | |||
}, | |||
"xf_open": { | |||
"type": 3, | |||
"path": "/api/real/Comprehensive/setup_FireControlOpenPage", | |||
"data": { | |||
"page_no": "6", | |||
"mes": "打开消防态势" | |||
}, | |||
"msg": "已为您打开消防态势" | |||
}, | |||
"zhh_open": { | |||
"type": 3, | |||
"path": "/api/real/Comprehensive/setup_ComprehensiveOpenPage", | |||
"data": { | |||
"page_no": "1", | |||
"mes": "打开综合态势" | |||
}, | |||
"msg": "已为您打开综合态势" | |||
}, | |||
"zhh_company_open": { | |||
"type": 3, | |||
"path": "/api/real/Comprehensive/setup_CompanyInfo", | |||
"data": { | |||
"page_no": 1, | |||
"mes": "打开公司介绍", | |||
"companyFlag":1, | |||
"companyName":"" | |||
}, | |||
"msg": "#[companyInfo]" | |||
}, | |||
"ry_open": { | |||
"type": 3, | |||
"mes": "打开人员态势", | |||
"path": "/api/real/Person/post_PersonOpenPage", | |||
"data": { | |||
"page_no": "3", | |||
"mes": "打开人员态势" | |||
}, | |||
"msg": "", | |||
"after_exec": "ry_sj" | |||
}, | |||
"qqbj_open": { | |||
"type": 3, | |||
"path": "/api/real/Comprehensive/setup_GlobalOpenPage", | |||
"data": { | |||
"page_no": "7", | |||
"page_action":"1", | |||
"mes": "打开全球业务布局" | |||
}, | |||
"msg": "已为您打开全球业务布局" | |||
}, | |||
"cnbj_open": { | |||
"type": 3, | |||
"path": "/api/real/Comprehensive/setup_ChinaOpenPage", | |||
"data": { | |||
"page_no": "8", | |||
"page_action":"1", | |||
"mes": "打开中国业务布局" | |||
}, | |||
"msg": "已为您打开中国业务布局" | |||
}, | |||
"ab_open": { | |||
"type": 3, | |||
"mes": "打开奥北科技园", | |||
"path": "/api/real/Comprehensive/setup_ScienceParkOpenPage", | |||
"data": { | |||
"page_no": "9", | |||
"page_action": "1", | |||
"mes": "打开奥北科技园" | |||
}, | |||
"msg": "已为您打开奥北科技园" | |||
}, | |||
"ry_sj": { | |||
"type": 3, | |||
"path": "/api/real/Person/post_PeopleValue", | |||
"data": { | |||
"page_no": "3", | |||
"mes": "人员所有信息" | |||
}, | |||
"msg": "现在为您展示的是人员态势,当前20楼内总人数#[peopleCount]人,通过首层大堂闸机通行人数#[passCount]人,其中人脸识别#[faceCount]人,刷卡识别#[cardCount]人。" | |||
}, | |||
"ry_sb": { | |||
"type": 3, | |||
"path": "/api/real/Person/post_EquipCount", | |||
"data": { | |||
"page_no": "3", | |||
"mes": "设备状态统计" | |||
}, | |||
"msg": "当前设备在线#[onLineEquip]台,设备离线#[offLineEquip]台;在线率#[onLineROL]" | |||
}, | |||
"ry_zlry": { | |||
"type": 3, | |||
"mes": "今日在楼人员统计", | |||
"path": "/api/real/Person/post_PeopleCount", | |||
"data": { | |||
"page_no": "3", | |||
"mes": "今日在楼人员统计" | |||
}, | |||
"msg": "当前20楼内总人数#[peopleCount]人" | |||
}, | |||
"ry_sbzt": { | |||
"type": 3, | |||
"mes": "设备状态统计", | |||
"path": "/api/real/Person/post_EquipCount", | |||
"data": { | |||
"page_no": "3", | |||
"mes": "设备状态统计" | |||
}, | |||
"msg": "" | |||
}, | |||
"ry_rycr": { | |||
"type": 3, | |||
"mes": "人员出入统计", | |||
"path": "/api/real/Person/post_PeopleCountStatistics", | |||
"data": { | |||
"page_no": "3", | |||
"mes": "人员出入统计" | |||
}, | |||
"msg": "当前20楼内通过首层大堂闸机通行进入#[enterPeopleCount]人,离开#[leavPeopleCount]人。" | |||
}, | |||
"ry_dkzj": { | |||
"type": 3, | |||
"mes": "打开闸机", | |||
"path": "/api/real/Person/post_PersonPassRecord", | |||
"data": { | |||
"page_no": "3", | |||
"equip_no": "2", | |||
"set_no": "", | |||
"value": "1", | |||
"mes": "打开闸机" | |||
}, | |||
"setNoMapping": { | |||
"一号通道": 674, | |||
"二号通道": 673, | |||
"三号通道": 672, | |||
"四号通道": 671, | |||
"五号通道": 670, | |||
"一号闸机": 674, | |||
"二号闸机": 673, | |||
"三号闸机": 672, | |||
"四号闸机": 671, | |||
"五号闸机": 670 | |||
}, | |||
"msg": "已为您打开闸机" | |||
}, | |||
"tc_open": { | |||
"type": 3, | |||
"mes": "打开停车态势", | |||
"path": "/api/real/Person/post_PersonOpenPage", | |||
"data": { | |||
"page_no": "4", | |||
"mes": "打开停车态势" | |||
}, | |||
"msg": "", | |||
"after_exec": "tc_sj" | |||
}, | |||
"tc_zccl": { | |||
"type": 3, | |||
"mes": "注册车辆统计", | |||
"path": "/api/real/Park/post_RegisterCarCount", | |||
"data": { | |||
"page_no": "4", | |||
"mes": "注册车辆统计" | |||
}, | |||
"msg": "园区目前注册车辆数是#[registerCarCount]辆" | |||
}, | |||
"tc_sj": { | |||
"type": 3, | |||
"mes": "停车所有信息", | |||
"path": "/api/real/Park/post_CarValue", | |||
"data": { | |||
"page_no": "4", | |||
"mes": "停车所有信息" | |||
}, | |||
"msg": "现在为您展示的是停车态势,当前园区总车位数量是#[allParkCount],剩余车位数量是#[leveParkCount];注册车辆数是#[registerCarCount]辆;本日车辆进入数是#[enterCarCount],离开车辆数是#[leavCarCount]。" | |||
}, | |||
"tc_dqcw": { | |||
"type": 3, | |||
"mes": "当前车位统计", | |||
"path": "/api/real/Park/post_ParkCount", | |||
"data": { | |||
"page_no": "4", | |||
"mes": "当前车位统计" | |||
}, | |||
"msg": "园区目前总车位数量是#[allParkCount],剩余车位数量是#[leveParkCount]" | |||
}, | |||
"tc_crtj": { | |||
"type": 3, | |||
"mes": "车辆出入统计", | |||
"path": "/api/real/Park/post_CarCount", | |||
"data": { | |||
"page_no": "4", | |||
"mes": "车辆出入统计" | |||
}, | |||
"msg": "园区当日车辆进入数是#[enterCarCount],离开车辆数是#[leavCarCount]" | |||
}, | |||
"tc_jk": { | |||
"type": 3, | |||
"path": "/api/real/Park/post_OpenPark", | |||
"data": { | |||
"page_no": "4", | |||
"page_action":"1", | |||
"mes": "" | |||
}, | |||
"msg": "好的" | |||
}, | |||
"tc_sbzt": { | |||
"type": 3, | |||
"mes": "设备状态统计", | |||
"path": "/api/real/Park/post_EquipCount", | |||
"data": { | |||
"page_no": "4", | |||
"mes": "设备状态统计" | |||
}, | |||
"msg": "" | |||
}, | |||
"company_close": { | |||
"type": 3, | |||
"path": "api/real/Comprehensive/setup_CompanyInfo", | |||
"data": { | |||
"page_no": "4", | |||
"mes": "打开/关闭公司介绍", | |||
"companyFlag":0, | |||
"companyName":"" | |||
}, | |||
"msg": "关闭成功" | |||
}, | |||
"companys": [ | |||
"翰博尔", | |||
"华瑞", | |||
"山石网科", | |||
"索为", | |||
"中创腾瑞", | |||
"卓建国际", | |||
"道有道", | |||
"毫末", | |||
"先河环保", | |||
"恒泰证券", | |||
"来酷", | |||
"数据堂", | |||
"随锐", | |||
"臻和" | |||
], | |||
"companys_match": { | |||
"翰博尔":0, | |||
"翰博":0, | |||
"汉博尔":0, | |||
"汉伯尔":0, | |||
"华瑞": 1, | |||
"华瑞网研": 1, | |||
"山石网科": 2, | |||
"索为": 3, | |||
"所谓": 3, | |||
"中创腾瑞": 4, | |||
"卓建国际": 5, | |||
"着建国际": 5, | |||
"道有道": 6, | |||
"道友到": 6, | |||
"毫末": 7, | |||
"好没": 7, | |||
"先河环保": 8, | |||
"恒泰证券": 9, | |||
"来酷": 10, | |||
"数据堂": 11, | |||
"随锐科技": 12, | |||
"随锐": 12, | |||
"谁瑞": 12, | |||
"水位": 12, | |||
"谁为": 12, | |||
"真和": 13, | |||
"真核": 13 | |||
}, | |||
"companys_q": [ | |||
"翰博尔", | |||
"翰博", | |||
"汉博尔", | |||
"汉伯尔", | |||
"华瑞", | |||
"华瑞网研", | |||
"山石网科", | |||
"索为", | |||
"所谓", | |||
"中创腾瑞", | |||
"卓建国际", | |||
"着建国际", | |||
"道有道", | |||
"道友到", | |||
"毫末", | |||
"好没", | |||
"先河环保", | |||
"恒泰证券", | |||
"来酷", | |||
"数据堂", | |||
"随锐科技", | |||
"随锐", | |||
"谁瑞", | |||
"水瑞", | |||
"水位", | |||
"谁为", | |||
"真和", | |||
"真核" | |||
], | |||
"doors": [ | |||
"一号通道", | |||
"二号通道", | |||
"三号通道", | |||
"四号通道", | |||
"五号通道", | |||
"一号闸机", | |||
"二号闸机", | |||
"三号闸机", | |||
"四号闸机", | |||
"五号闸机" | |||
], | |||
"parks": [ | |||
"地上出入口", | |||
"B1停车场", | |||
"B2停车场" | |||
], | |||
"parksMapping": { | |||
"地上出入口": 0, | |||
"地上停车场": 0, | |||
"B1停车场": 1, | |||
"be停车场": 1, | |||
"b1停车场": 1, | |||
"负1停车场": 1, | |||
"负一停车场": 1, | |||
"附一停车场": 1, | |||
"B2停车场": 2, | |||
"b2停车场": 2, | |||
"br停车场": 2 | |||
}, | |||
"hbh": { | |||
"type": 2, | |||
"forward_answer": [ | |||
"好", | |||
"好的", | |||
"行", | |||
"可以", | |||
"好吧" | |||
], | |||
"positive_answer": [ | |||
"不好", | |||
"不可以", | |||
"不行" | |||
], | |||
"forward_text": "京信局的展台设计以北斗七星为灵感,展台分为三大区域,城市数据建设展示区、应用场景展示区、北京数字经济展示区。请问您想了解哪个区域呢?", | |||
"positive_text": "好吧,您先自己随便逛逛,有需要再叫我" | |||
}, | |||
"shoudaoduanxi": { | |||
"type": 2, | |||
"forward_answer": [ | |||
"是", | |||
"是的", | |||
"收到", | |||
"已收到", | |||
"收到了" | |||
], | |||
"positive_answer": [ | |||
"否", | |||
"没", | |||
"没收到", | |||
"我没收到", | |||
"还没收到", | |||
"没有", | |||
"没有收到", | |||
"未收到" | |||
], | |||
"forward_text": "您收到短信的手机号后四位是多少?", | |||
"positive_text": "额,抱歉,请您自行联系将要拜访的人员。", | |||
"req": "duanxin" | |||
}, | |||
"duanxin": { | |||
"type": 2, | |||
"forward_text": "已匹配到您的拜访记录,将为您打开闸机,请通行!", | |||
"forward_motion": "showRightHandBottom", | |||
"positive_text": "抱歉,未匹配到您的邀约记录,请您联系将要拜访的人员。", | |||
"positive_motion": "bow", | |||
"callback": 1 | |||
}, | |||
"clothes": { | |||
"SweetGirl": [ | |||
"suit_blue", | |||
"suit_red", | |||
"waistcoat_blue" | |||
], | |||
"BusinessGirl": [ | |||
"suit_green", | |||
"waistcoat_black" | |||
] | |||
}, | |||
"characters": [ | |||
"SweetGirl", | |||
"BusinessGirl" | |||
], | |||
"zhaohu": [ | |||
"你好", | |||
"您好", | |||
"小酷", | |||
"小酷小酷", | |||
"你好小酷", | |||
"hello" | |||
], | |||
"breakReqs": [ | |||
"停", | |||
"闭嘴", | |||
"住嘴", | |||
"stop", | |||
"shut up" | |||
], | |||
"helpReqs": [ | |||
"我找", | |||
"我来", | |||
"在嘛", | |||
"这里是", | |||
"来找", | |||
"送快递", | |||
"送外卖", | |||
"卢总", | |||
"王总" | |||
], | |||
"asks": { | |||
"mgr": "", | |||
"emp": "您已打卡成功", | |||
"emp2": "", | |||
"keyVisitor": "欢迎来到来酷智联,卢总已在办公室等您。", | |||
"keyVisitor2": "", | |||
"visitor": "好久不见,您先在会议室稍坐会,已通知到我的同事", | |||
"visitor2": "", | |||
"courier": "根据大厦防疫规定,快递外卖人员不可进入大厦,请您在大厦外联系相关人员。", | |||
"blackRole": "你是黑名单人员,不允许进入本公司,请赶快离开!", | |||
"default": "请问您是员工还是访客?" | |||
}, | |||
"normal": [ | |||
"很高兴为您服务", | |||
"您今天状态真好", | |||
"您今天心情挺好的吧", | |||
"问问我喜欢什么吧", | |||
"近来挺顺利的吧", | |||
"天渐凉,早晚记得多穿点" | |||
], | |||
"handleTtsTexts": [ | |||
"jdyl", | |||
"zdyl", | |||
"cqqd", | |||
"xxym", | |||
"tsym", | |||
"sjym", | |||
"szym" | |||
] | |||
} |
@@ -0,0 +1,85 @@ | |||
const Glod = { | |||
qp: { | |||
type: 1, | |||
equip_no: "2", | |||
set_no: "2", | |||
value: "AlarmCenter.ScreensAddin.ScreensCommand", | |||
info: "打开全屏" | |||
}, | |||
fhsy: { | |||
type: 1, | |||
equip_no: "2", | |||
set_no: "1701", | |||
value: "AlarmCenter.ScreensAddin.ScreensCommand", | |||
info: "返回首页" | |||
}, | |||
zhts: { | |||
type: 1, | |||
equip_no: "2", | |||
set_no: "103", | |||
value: "AlarmCenter.ScreensAddin.ScreensCommand", | |||
info: "打开综合态势" | |||
}, | |||
afts: { | |||
type: 1, | |||
equip_no: "2", | |||
set_no: "104", | |||
value: "AlarmCenter.ScreensAddin.ScreensCommand", | |||
info: "打开安防态势" | |||
}, | |||
ryts: { | |||
type: 1, | |||
equip_no: "2", | |||
set_no: "105", | |||
value: "AlarmCenter.ScreensAddin.ScreensCommand", | |||
info: "打开人员态势" | |||
}, | |||
tcts: { | |||
type: 1, | |||
equip_no: "2", | |||
set_no: "106", | |||
value: "AlarmCenter.ScreensAddin.ScreensCommand", | |||
info: "打开停车态势" | |||
}, | |||
nyts: { | |||
type: 1, | |||
equip_no: "2", | |||
set_no: "107", | |||
value: "AlarmCenter.ScreensAddin.ScreensCommand", | |||
info: "打开能源态势" | |||
}, | |||
xfts: { | |||
type: 1, | |||
equip_no: "2", | |||
set_no: "108", | |||
value: "AlarmCenter.ScreensAddin.ScreensCommand", | |||
info: "打开消防态势" | |||
}, | |||
xmdsxt: { | |||
type: 1, | |||
equip_no: "1005", | |||
set_no: "2", | |||
value: "AlarmCenter.ScreensAddin.ScreensCommand", | |||
info: "打开西门东侧摄像头" | |||
}, | |||
hys1bsxt: { | |||
type: 1, | |||
equip_no: "1005", | |||
set_no: "3", | |||
value: "AlarmCenter.ScreensAddin.ScreensCommand", | |||
info: "打开一号会议室北侧摄像头" | |||
}, | |||
dtmxsxt: { | |||
type: 1, | |||
equip_no: "1005", | |||
set_no: "4", | |||
value: "AlarmCenter.ScreensAddin.ScreensCommand", | |||
info: "打开大堂门口西侧摄像头" | |||
}, | |||
hbh: { | |||
type: 2, | |||
forward_text: | |||
"京信局的展台设计以北斗七星为灵感,展台分为三大区域,城市数据建设展示区、应用场景展示区、北京数字经济展示区。", | |||
positive_text: "好吧,您请自便" | |||
} | |||
}; |
@@ -0,0 +1,20 @@ | |||
<!DOCTYPE html> | |||
<html lang="en"> | |||
<head> | |||
<meta charset="utf-8"> | |||
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> | |||
<meta http-equiv="X-UA-Compatible" content="IE=edge"> | |||
<meta http-equiv="x-dns-prefetch-control" content="on" /> | |||
<meta name="viewport" content="width=device-width, initial-scale=1.0, minimum-scale=1.0, maximum-scale=1.0, user-scalable=no"> | |||
<link rel="icon" href="<%= BASE_URL %>favicon.ico"> | |||
<title><%= htmlWebpackPlugin.options.title %></title> | |||
</head> | |||
<body> | |||
<noscript> | |||
<strong>We're sorry but <%= htmlWebpackPlugin.options.title %> doesn't work properly without JavaScript enabled. Please enable it to continue.</strong> | |||
</noscript> | |||
<div id="app"></div> | |||
<!-- built files will be auto injected --> | |||
</body> | |||
</html> |
@@ -0,0 +1,106 @@ | |||
<template> | |||
<div id="app" class="no-scrollbar" style="width: 100%;"> | |||
<navigation> | |||
<router-view :style="content"></router-view> | |||
</navigation> | |||
</div> | |||
</template> | |||
<script> | |||
export default { | |||
name: "App", | |||
data() { | |||
return { | |||
isRouterAlive: true, | |||
chatData: [], | |||
weatherData: null, | |||
interactive: "", | |||
content: "", | |||
retryLoadClientType: 0 | |||
}; | |||
}, | |||
mounted() { | |||
window._ = _; | |||
Date.prototype.Format = function(fmt) { | |||
var o = { | |||
"M+": this.getMonth() + 1, // 月份 | |||
"d+": this.getDate(), // 日 | |||
"h+": this.getHours(), // 小时 | |||
"m+": this.getMinutes(), // 分 | |||
"s+": this.getSeconds(), // 秒 | |||
"q+": Math.floor((this.getMonth() + 3) / 3), // 季度 | |||
S: this.getMilliseconds() // 毫秒 | |||
}; | |||
if (/(y+)/.test(fmt)) fmt = fmt.replace(RegExp.$1, (this.getFullYear() + "").substr(4 - RegExp.$1.length)); | |||
for (var k in o) | |||
if (new RegExp("(" + k + ")").test(fmt)) | |||
fmt = fmt.replace( | |||
RegExp.$1, | |||
RegExp.$1.length === 1 ? o[k] : ("00" + o[k]).substr(("" + o[k]).length) | |||
); | |||
return fmt; | |||
}; | |||
} | |||
}; | |||
</script> | |||
<style lang="scss"> | |||
* { | |||
margin: 0; | |||
padding: 0; | |||
} | |||
html, | |||
body { | |||
width: 100%; | |||
height: 100%; | |||
overflow-x: hidden; | |||
overflow-y: hidden; | |||
} | |||
#app { | |||
width: 100%; | |||
height: 100%; | |||
font-family: Avenir, Helvetica, Arial, sans-serif; | |||
-webkit-font-smoothing: antialiased; | |||
-moz-osx-font-smoothing: grayscale; | |||
text-align: center; | |||
color: #2c3e50; | |||
} | |||
// 隐藏滚轮 | |||
.no-scrollbar { | |||
-ms-overflow-style: none; | |||
overflow: -moz-scrollbars-none; | |||
/*background-color: black;*/ | |||
-webkit-touch-callout: none; | |||
-webkit-user-select: none; | |||
-khtml-user-select: none; | |||
-moz-user-select: none; | |||
-ms-user-select: none; | |||
user-select: none; | |||
} | |||
.no-scrollbar::-webkit-scrollbar { | |||
width: 0 !important; | |||
} | |||
img { | |||
width: auto; | |||
height: auto; | |||
max-width: 100%; | |||
max-height: 100%; | |||
} | |||
img[lazy="loading"] { | |||
background-color: white; | |||
} | |||
.single-line-text { | |||
overflow: hidden; | |||
text-overflow: ellipsis; | |||
white-space: nowrap; | |||
display: block !important; | |||
text-align: left; | |||
-webkit-line-clamp: 1; | |||
-webkit-box-orient: vertical; | |||
} | |||
</style> |
@@ -0,0 +1,451 @@ | |||
export default { | |||
/** | |||
* 初始化SDK 传入onReceiveCmd, 用于接收nlp, a, reload等命令 | |||
* @param onReceiveCmd | |||
* @param config | |||
*/ | |||
init( | |||
onReceiveCmd, | |||
config = { | |||
jsHandleTts: false, | |||
jsHandleState: false | |||
} | |||
) { | |||
window.sendCmd = function(cmd, params) { | |||
if (cmd === "onBind") { | |||
ue.cloudminds.hue("onstart", JSON.stringify(config)); | |||
console.info("onStart event sent"); | |||
window.cloudiaConfig = params; | |||
if (params && params.SweetGirlClothes) { | |||
cloudiaConfig.girls = new Map(); | |||
cloudiaConfig.sweetGirlClothes = params.SweetGirlClothes.replace(" ", "").split(","); | |||
cloudiaConfig.girls.set("SweetGirl", cloudiaConfig.sweetGirlClothes); | |||
cloudiaConfig.allClothes = cloudiaConfig.girls.get("SweetGirl"); | |||
if (params.BusinessGirlClothes) { | |||
cloudiaConfig.businessGirlClothes = params.BusinessGirlClothes.replace(" ", "").split(","); | |||
cloudiaConfig.girls.set("BusinessGirl", cloudiaConfig.businessGirlClothes); | |||
} | |||
if (params.AncientGirlClothes) { | |||
cloudiaConfig.ancientGirlClothes = params.AncientGirlClothes.replace(" ", "").split(","); | |||
cloudiaConfig.girls.set("AncientGirl", cloudiaConfig.ancientGirlClothes); | |||
} | |||
} | |||
} | |||
return onReceiveCmd(cmd, params); | |||
}; | |||
}, | |||
reloadClothes() { | |||
if (cloudiaConfig && cloudiaConfig.SweetGirlClothes) { | |||
cloudiaConfig.allClothes = cloudiaConfig.girls.get(cloudiaConfig.currentCharacter); | |||
} | |||
}, | |||
isNotValidNum(value) { | |||
return !/(^[\-0-9][0-9]*(.[0-9]+)?)$/.test(value); | |||
}, | |||
isEmpty(obj) { | |||
return typeof obj === "undefined" || obj == null || obj === ""; | |||
}, | |||
/** | |||
* 显示toast | |||
* @param msg toast内容 | |||
*/ | |||
showToast(msg) { | |||
if (ue.cloudminds) { | |||
if (this.isEmpty(msg)) { | |||
console.warn("Invalid call:showToast"); | |||
return false; | |||
} | |||
ue.cloudminds.hue("showtoast", msg); | |||
return true; | |||
} | |||
return false; | |||
}, | |||
/** | |||
* 显示长toast | |||
* @param msg toast内容 | |||
*/ | |||
showLongToast(msg) { | |||
if (ue.cloudminds) { | |||
if (this.isEmpty(msg)) { | |||
console.warn("Invalid call:showLongToast"); | |||
return false; | |||
} | |||
ue.cloudminds.hue("showlongtoast", msg); | |||
return true; | |||
} | |||
return false; | |||
}, | |||
/** | |||
* 语音播报 | |||
* @param text 播报的内容 | |||
*/ | |||
playTts(text) { | |||
if (ue.cloudminds) { | |||
if (this.isEmpty(text)) { | |||
console.warn("Invalid call:playTts"); | |||
return false; | |||
} | |||
ue.cloudminds.hue("playtts", text); | |||
return true; | |||
} | |||
return false; | |||
}, | |||
/** | |||
* 修改浏览器位置 | |||
* @param left 浏览器距离屏幕左边的位置 | |||
* @param top 浏览器距离屏幕上边的位置 | |||
* @param right 浏览器距离屏幕右边的位置 | |||
* @param bottom 浏览器距离屏幕下边的位置 | |||
*/ | |||
updateBrowserLocation(left, top, right, bottom) { | |||
if ( | |||
this.isNotValidNum(left) || | |||
this.isNotValidNum(top) || | |||
this.isNotValidNum(right) || | |||
this.isNotValidNum(bottom) | |||
) { | |||
console.error("updateBrowserLocation 数据不合法"); | |||
return false; | |||
} | |||
if (ue.cloudminds) { | |||
// 蓝图端用的是","分隔方案 | |||
ue.cloudminds.hue("updatebrowserlocation", left + ", " + top + ", " + right + ", " + bottom); | |||
return true; | |||
} | |||
return false; | |||
}, | |||
/** | |||
* 修改虚拟人物位置 | |||
* @param locationX X坐标值 | |||
* @param locationY Y坐标值 | |||
* @param locationZ Z坐标值 | |||
* @param persistence 是否持久化保存 | |||
*/ | |||
updateCharacterLocation(locationX, locationY, locationZ, persistence = false) { | |||
if (this.isNotValidNum(locationX) || this.isNotValidNum(locationY) || this.isNotValidNum(locationZ)) { | |||
console.error("updateCharacterLocation 数据不合法"); | |||
return false; | |||
} | |||
if (ue.cloudminds) { | |||
ue.cloudminds.hue( | |||
"updatecharacterlocation", | |||
locationX + "#$*&@" + locationY + "#$*&@" + locationZ + "#$*&@" + persistence | |||
); | |||
return true; | |||
} | |||
return false; | |||
}, | |||
/** | |||
* 修改虚拟人物旋转角度 | |||
* @param rotationP P坐标值 | |||
* @param rotationY Y坐标值 | |||
* @param rotationR R坐标值 | |||
* @param persistence 是否持久化保存 | |||
*/ | |||
updateCharacterRotation(rotationP, rotationY, rotationR, persistence = false) { | |||
if (this.isNotValidNum(rotationP) || this.isNotValidNum(rotationY) || this.isNotValidNum(rotationR)) { | |||
console.error("updateCharacterRotation 数据不合法"); | |||
return false; | |||
} | |||
if (ue.cloudminds) { | |||
ue.cloudminds.hue( | |||
"updatecharacterrotation", | |||
rotationP + "#$*&@" + rotationY + "#$*&@" + rotationR + "#$*&@" + persistence | |||
); | |||
return true; | |||
} | |||
return false; | |||
}, | |||
/** | |||
* 播放动画 | |||
* @param name 动画名称 | |||
* @param status 动画状态 | |||
*/ | |||
playMotion(name, status = "") { | |||
if (ue.cloudminds) { | |||
if (this.isEmpty(name)) { | |||
console.warn("Invalid call:playMotion"); | |||
return false; | |||
} | |||
if (status.length === 0) { | |||
ue.cloudminds.hue("playmotion", name); | |||
} else { | |||
ue.cloudminds.hue("playmotion", name + "#$*&@" + status); | |||
} | |||
return true; | |||
} | |||
return false; | |||
}, | |||
/** | |||
* 设置表情 | |||
* @param exp 表情名称 | |||
* @param value 值 | |||
*/ | |||
setExpression(exp, value) { | |||
if (ue.cloudminds) { | |||
if (this.isEmpty(value) || this.isEmpty(exp)) { | |||
console.warn("Invalid call:setExpression"); | |||
return false; | |||
} | |||
ue.cloudminds.hue("setexpression", exp + "#$*&@" + value); | |||
return true; | |||
} | |||
return false; | |||
}, | |||
/** | |||
* @param color 背景墙颜色 | |||
*/ | |||
setBgWallColor(color) { | |||
if (ue.cloudminds) { | |||
ue.cloudminds.hue("setMapBgColor", color); | |||
return true; | |||
} | |||
return false; | |||
}, | |||
/** | |||
* @param wall 背景墙资源名称 | |||
*/ | |||
setBgWallResource(wall) { | |||
if (ue.cloudminds) { | |||
ue.cloudminds.hue("setMapBgResource", wall); | |||
return true; | |||
} | |||
return false; | |||
}, | |||
/** | |||
* 设置是否由js接管tts播报,接管之后,app将不负责播报,转而由js负责调用palytts进行播报 | |||
* @param enable | |||
*/ | |||
setJsPlayTtsEnabled(enable) { | |||
if (this.isEmpty(enable)) { | |||
console.warn("Invalid call:setJsPlayTtsEnabled"); | |||
return false; | |||
} | |||
if (ue.cloudminds) { | |||
ue.cloudminds.hue("setjsplayttsenabled", enable.toString()); | |||
} | |||
return true; | |||
}, | |||
/** | |||
* 设置是否由js接管state,接管之后,app将不切换state | |||
* @param enable | |||
*/ | |||
setJsHandleStateEnabled(enable) { | |||
if (this.isEmpty(enable)) { | |||
console.warn("Invalid call:setJsHandleStateEnabled"); | |||
return false; | |||
} | |||
if (ue.cloudminds) { | |||
ue.cloudminds.hue("setJsHandleStateEnabled", enable.toString()); | |||
return true; | |||
} | |||
return false; | |||
}, | |||
/** | |||
* 获取deviceId,调用成功之后会在onCmdReceived中收到deviceId的命令 | |||
* @deprecated 请改用getRobotInfoConfig("RobotId")方法 | |||
*/ | |||
getDeviceId() { | |||
if (ue.cloudminds) { | |||
ue.cloudminds.hue("getdeviceid"); | |||
return true; | |||
} | |||
return false; | |||
}, | |||
getRobotInfoConfig(key) { | |||
if (ue.cloudminds) { | |||
if (this.isEmpty(key)) { | |||
console.warn("Invalid call:getRobotInfoConfig"); | |||
return false; | |||
} | |||
return ue.cloudminds.hueget("getrobotinfoconfig", key); | |||
} | |||
return new Promise(function() { | |||
return ""; | |||
}); | |||
}, | |||
getGreetingMsg() { | |||
return this.getAppConfig(); | |||
}, | |||
getAppConfig() { | |||
if (ue.cloudminds) { | |||
return ue.cloudminds.hueget("getappconfig"); | |||
} | |||
return new Promise(function() { | |||
return ""; | |||
}); | |||
}, | |||
getCharacter() { | |||
if (ue.cloudminds) { | |||
return ue.cloudminds.hueget("getcharacterinfo"); | |||
} | |||
return new Promise(function() { | |||
return ""; | |||
}); | |||
}, | |||
setCharacter(cname) { | |||
if (this.isEmpty(cname)) { | |||
console.warn("Invalid call:setCharacter"); | |||
return false; | |||
} | |||
if (ue.cloudminds) { | |||
ue.cloudminds.hue("setcharacter", cname); | |||
if (cloudiaConfig) { | |||
cloudiaConfig.currentCharacter = cname; | |||
} | |||
this.reloadClothes(); | |||
return true; | |||
} | |||
return false; | |||
}, | |||
setClothes(name) { | |||
if (cloudiaConfig && cloudiaConfig.allClothes && !cloudiaConfig.allClothes.indexOf(name) < 0) { | |||
console.warn("Invalid call:setClothes:" + name); | |||
return false; | |||
} | |||
if (ue.cloudminds) { | |||
ue.cloudminds.hue("setClothes", name); | |||
return true; | |||
} | |||
return false; | |||
}, | |||
postMediaEvent(event) { | |||
if (this.isEmpty(event)) { | |||
console.warn("Invalid call:postMediaEvent"); | |||
return false; | |||
} | |||
if (ue.cloudminds) { | |||
ue.cloudminds.hue("postmediaevent", event); | |||
return true; | |||
} | |||
return false; | |||
}, | |||
setAsrWakeUpEnable(enable) { | |||
if (this.isEmpty(enable)) { | |||
console.warn("Invalid call:setAsrWakeUpEnable"); | |||
return false; | |||
} | |||
if (ue.cloudminds) { | |||
ue.cloudminds.hue("setAsrWakeUpEnable", enable.toString()); | |||
return true; | |||
} | |||
return false; | |||
}, | |||
stopPlayTts(playOK = false) { | |||
if (ue.cloudminds) { | |||
ue.cloudminds.hue("stopTts", playOK.toString()); | |||
return true; | |||
} | |||
return false; | |||
}, | |||
setWalkGreetingEnable(enable) { | |||
if (this.isEmpty(enable)) { | |||
console.warn("Invalid call:setWalkGreetEnable"); | |||
return false; | |||
} | |||
if (ue.cloudminds) { | |||
ue.cloudminds.hue("walkGreetEnable", enable.toString()); | |||
return true; | |||
} | |||
return false; | |||
}, | |||
setWallLocation(location) { | |||
if (this.isEmpty(location)) { | |||
console.warn("Invalid call:setWallLocation"); | |||
return false; | |||
} | |||
if (ue.cloudminds) { | |||
ue.cloudminds.hue("setbgwalllocation", location); | |||
return true; | |||
} | |||
return false; | |||
}, | |||
enterImmerseMode(immerse) { | |||
if (this.isEmpty(immerse)) { | |||
console.warn("Invalid call:enterImmerseMode"); | |||
return false; | |||
} | |||
if (ue.cloudminds) { | |||
ue.cloudminds.hue("enterImmerseMode", immerse.toString()); | |||
return true; | |||
} | |||
return false; | |||
}, | |||
startVideoTalk() { | |||
if (ue.cloudminds) { | |||
ue.cloudminds.hue("starttalk"); | |||
return true; | |||
} | |||
return false; | |||
}, | |||
stopVideoTalk() { | |||
if (ue.cloudminds) { | |||
ue.cloudminds.hue("endtalk"); | |||
return true; | |||
} | |||
return false; | |||
}, | |||
textTriggerNlp(text) { | |||
if (this.isEmpty(text)) { | |||
console.warn("Invalid call:textTriggerNlp"); | |||
return false; | |||
} | |||
if (ue.cloudminds) { | |||
ue.cloudminds.hue("texttriggernlp", text); | |||
return true; | |||
} | |||
return false; | |||
}, | |||
setVolume(vol) { | |||
if (this.isNotValidNum(vol)) { | |||
console.warn("Invalid call:setVolume:" + vol); | |||
return false; | |||
} | |||
if (ue.cloudminds) { | |||
ue.cloudminds.hue("setvolume", vol.toString()); | |||
return true; | |||
} | |||
return false; | |||
}, | |||
getVolume() { | |||
if (ue.cloudminds) { | |||
return ue.cloudminds.hueget("getcurvolume"); | |||
} | |||
return new Promise(function() { | |||
return "11"; | |||
}); | |||
}, | |||
downloadFiles(tag, urls) { | |||
if (ue.cloudminds) { | |||
ue.cloudminds.hue("downloadfiles", tag + "#$*&@" + urls); | |||
return true; | |||
} | |||
return false; | |||
}, | |||
updateCharacterScaleLevel(scaleLevel, persistence = false) { | |||
if (this.isNotValidNum(scaleLevel)) { | |||
console.warn("Invalid call:setVolume:" + persistence); | |||
return false; | |||
} | |||
if (ue.cloudminds) { | |||
ue.cloudminds.hue("setcharacterscale", scaleLevel + "#$*&@" + persistence); | |||
return true; | |||
} | |||
}, | |||
restartH5() { | |||
if (ue.cloudminds) { | |||
ue.cloudminds.hue("reopenbrowser"); | |||
} | |||
}, | |||
setState(state) { | |||
if (this.isEmpty(state)) { | |||
console.warn("Invalid call:setState"); | |||
return false; | |||
} | |||
if (ue.cloudminds) { | |||
ue.cloudminds.hue("setState", state); | |||
return true; | |||
} | |||
return false; | |||
} | |||
}; |
@@ -0,0 +1,684 @@ | |||
<template> | |||
<div :v-model="testing"> | |||
<div class="api-layout m-button"> | |||
<input | |||
type="button" | |||
value="一键自测" | |||
class="input-text input-button" | |||
style="margin: 0; width: 100%; text-align: center;" | |||
@click="testAllInterface(toast)" | |||
/> | |||
</div> | |||
<div :class="getValidClass(allInterfaces['interfaceShowToast'])"> | |||
<input v-model="toast" type="text" class="input-text" /> | |||
<input | |||
type="button" | |||
value="showToast" | |||
class="input-text input-button m-button" | |||
@click="interfaceShowToast()" | |||
/> | |||
</div> | |||
<div :class="getValidClass(allInterfaces['interfaceShowLongToast'])"> | |||
<input v-model="longToast" type="text" class="input-text" /> | |||
<input | |||
type="button" | |||
value="longToast" | |||
class="input-text input-button m-button" | |||
@click="interfaceShowLongToast()" | |||
/> | |||
</div> | |||
<div :class="iPlayTts ? 'api-layout' : getValidClass(allInterfaces['interfacePlayTts'])"> | |||
<input v-model="tts" type="text" class="input-text" /> | |||
<input type="button" value="playTts" class="input-text input-button" @click="interfacePlayTts()" /> | |||
</div> | |||
<div :class="getValidClass(allInterfaces['interfaceUpdateBrowserLocation'])"> | |||
<input v-model="bOffset" type="text" class="input-text" /> | |||
<input | |||
type="button" | |||
value="browser" | |||
class="input-text input-button" | |||
@click="interfaceUpdateBrowserLocation()" | |||
/> | |||
</div> | |||
<div :class="getValidClass(allInterfaces['interfaceUpdateCharacterLocation'])"> | |||
<input v-model="cLocation" type="text" class="input-text" /> | |||
<input | |||
type="button" | |||
value="location" | |||
class="input-text input-button m-button" | |||
@click="interfaceUpdateCharacterLocation()" | |||
/> | |||
</div> | |||
<div :class="getValidClass(allInterfaces['interfaceUpdateCharacterRotation'])"> | |||
<input v-model="cRotation" type="text" class="input-text" /> | |||
<input | |||
type="button" | |||
value="rotation" | |||
class="input-text input-button" | |||
@click="interfaceUpdateCharacterRotation()" | |||
/> | |||
</div> | |||
<div :class="getValidClass(allInterfaces['interfaceUpdateWallLocation'])"> | |||
<input v-model="bgLocation" type="text" class="input-text" /> | |||
<input | |||
type="button" | |||
value="WallLocation" | |||
class="input-text input-button m-button" | |||
@click="interfaceUpdateWallLocation()" | |||
/> | |||
</div> | |||
<div :class="getValidClass(allInterfaces['interfacePlayMotion'])"> | |||
<label class="input-text select_wrapper"> | |||
<select v-model="motion" class="input-text selection"> | |||
<option>idle</option> | |||
<option>nod</option> | |||
<option>shakeHead</option> | |||
<option>bow</option> | |||
<option>handWave</option> | |||
<option>showLeftHand</option> | |||
<option>showLeftHandTop</option> | |||
<option>showLeftHandBottom</option> | |||
<option>showRightHand</option> | |||
<option>showRightHandTop</option> | |||
<option>showRightHandBottom</option> | |||
<option>showBothHandBottom</option> | |||
</select> | |||
</label> | |||
<input | |||
type="button" | |||
value="playMotion" | |||
class="input-text input-button m-button" | |||
@click="interfacePlayMotion()" | |||
/> | |||
</div> | |||
<div :class="getValidClass(allInterfaces['interfaceSetBgWallColor']) + ' input-color-layout'"> | |||
<div class="input-text"> | |||
<span class="input-color-text">{{ wall }}</span> | |||
</div> | |||
<input | |||
id="color" | |||
type="color" | |||
name="color" | |||
value="#00f4ff" | |||
class="input-text input-color-button m-button" | |||
@change="interfaceSetBgWallColor()" | |||
/> | |||
</div> | |||
<div :class="getValidClass(allInterfaces['interfaceSetBgWallRes'])"> | |||
<label class="input-text select_wrapper"> | |||
<select v-model="wallRes" class="input-text selection"> | |||
<option>3DRoom</option> | |||
<option>SolidColor</option> | |||
<option>Landscape</option> | |||
</select> | |||
</label> | |||
<input | |||
type="button" | |||
value="setMapRes" | |||
class="input-text input-button m-button" | |||
@click="interfaceSetBgWallRes()" | |||
/> | |||
</div> | |||
<div :class="iGetRobotConfig ? 'api-layout' : getValidClass(allInterfaces['interfaceGetDeviceId'])"> | |||
<input v-model="deviceId" type="text" class="input-text" /> | |||
<input type="button" value="DeviceId" class="input-text input-button" @click="interfaceGetDeviceId()" /> | |||
</div> | |||
<div :class="iAppConfig ? 'api-layout' : getValidClass(allInterfaces['interfaceGetAppConfig'])"> | |||
<input v-model="appConfig" type="text" class="input-text" /> | |||
<input type="button" value="AppConfig" class="input-text input-button" @click="interfaceGetAppConfig()" /> | |||
</div> | |||
<div :class="getValidClass(allInterfaces['interfaceSetCharacter'])"> | |||
<label class="input-text select_wrapper"> | |||
<select v-model="character" class="input-text selection"> | |||
<option>SweetGirl</option> | |||
<option>BusinessGirl</option> | |||
<option>AncientGirl</option> | |||
</select> | |||
</label> | |||
<input | |||
type="button" | |||
value="setCharacter" | |||
class="input-text input-button m-button" | |||
@click="interfaceSetCharacter()" | |||
/> | |||
</div> | |||
<div :class="getValidClass(allInterfaces['interfaceSetClothes'])"> | |||
<label class="input-text select_wrapper"> | |||
<select v-model="clothes" class="input-text selection"> | |||
<option v-for="c in allClothes" :key="c">{{ c }}</option> | |||
</select> | |||
</label> | |||
<input | |||
type="button" | |||
value="setClothes" | |||
class="input-text input-button m-button" | |||
@click="interfaceSetClothes()" | |||
/> | |||
</div> | |||
<div :class="getValidClass(allInterfaces['interfacePostMediaEvent'])"> | |||
<label class="input-text select_wrapper"> | |||
<select v-model="mediaEvent" class="input-text selection"> | |||
<option>playing</option> | |||
<option>pause</option> | |||
<option>ended</option> | |||
</select> | |||
</label> | |||
<input | |||
type="button" | |||
value="postMediaEvent" | |||
class="input-text input-button m-button" | |||
@click="interfacePostMediaEvent()" | |||
/> | |||
</div> | |||
<div :class="iAsrWakeUp ? 'api-layout' : getValidClass(allInterfaces['interfaceSetAsrWakeUpEnable'])"> | |||
<input v-model="asrWakeUp" type="text" class="input-text" /> | |||
<input | |||
type="button" | |||
value="Asr Wake Up" | |||
class="input-text input-button" | |||
@click="interfaceSetAsrWakeUpEnable()" | |||
/> | |||
</div> | |||
<div :class="getValidClass(allInterfaces['interfaceStopPlayTts'])"> | |||
<input disabled type="text" class="input-text" /> | |||
<input | |||
type="button" | |||
value="StopPlayTts" | |||
class="input-text input-button m-button" | |||
@click="interfaceStopPlayTts()" | |||
/> | |||
</div> | |||
<div :class="getValidClass(allInterfaces['interfaceEnterImmerseMode'])"> | |||
<input v-model="immerseMode" type="text" class="input-text" /> | |||
<input | |||
type="button" | |||
value="immerseMode" | |||
class="input-text input-button m-button" | |||
@click="interfaceEnterImmerseMode()" | |||
/> | |||
</div> | |||
<div :class="getValidClass(allInterfaces['interfaceStartVideoTalk'])"> | |||
<input | |||
type="button" | |||
value="StartVideoTalk" | |||
class="input-text" | |||
style="width: 61vw;" | |||
@click="interfaceStartVideoTalk()" | |||
/> | |||
<input | |||
type="button" | |||
value="StopVideoTalk" | |||
class="input-text input-button m-button" | |||
@click="interfaceStopVideoTalk()" | |||
/> | |||
</div> | |||
<div :class="getValidClass(allInterfaces['interfaceSetVolume'])"> | |||
<input v-model="setValueText" type="text" class="input-text" /> | |||
<input type="button" value="setVolume" class="input-text input-button" @click="interfaceSetVolume()" /> | |||
</div> | |||
<div :class="iGetVolume ? 'api-layout' : getValidClass(allInterfaces['interfaceGetVolume'])"> | |||
<input v-model="getValueText" type="text" class="input-text" /> | |||
<input type="button" value="getVolume" class="input-text input-button" @click="interfaceGetVolume()" /> | |||
</div> | |||
<div :class="getValidClass(allInterfaces['interfaceDownloadFiles'])"> | |||
<input disabled type="text" class="input-text" /> | |||
<input | |||
type="button" | |||
value="downloadFiles" | |||
class="input-text input-button m-button" | |||
@click="interfaceDownloadFiles()" | |||
/> | |||
</div> | |||
<div :class="getValidClass(allInterfaces['interfaceTextTriggerNlp'])"> | |||
<input v-model="ttsText" type="text" class="input-text" /> | |||
<input | |||
type="button" | |||
value="TriggerNlp" | |||
class="input-text input-button m-button" | |||
@click="interfaceTextTriggerNlp()" | |||
/> | |||
</div> | |||
<div class="api-layout"> | |||
<input disabled type="text" class="input-text" /> | |||
<input type="button" value="LoadAd" class="input-text input-button" @click="loadAd()" /> | |||
</div> | |||
<div class="api-layout"> | |||
<p>cloudminds</p> | |||
</div> | |||
</div> | |||
</template> | |||
<script> | |||
var timer; | |||
import Cloudia from "../api/cloudia-sdk-v1.4.1"; | |||
export default { | |||
name: "DemoView", | |||
components: {}, | |||
data() { | |||
return { | |||
toast: "A Toast", | |||
longToast: "A Long Toast", | |||
tts: "1234567890", | |||
bOffset: "0, 0, 0, 0", | |||
cLocation: "-378.8,-0.7,448.3,false", | |||
cRotation: "0,179.5,0,false", | |||
motion: "bow", | |||
wall: "Change BG Color", | |||
wallRes: "3DRoom", | |||
exp: "smile, 1", | |||
mediaEvent: "playing", | |||
asrWakeUp: true, | |||
walkGreetEnable: true, | |||
cameraMode: "level", | |||
bgLocation: "1400,0,0", | |||
setValueText: 12, | |||
getValueText: 0, | |||
ttsText: "成都天气", | |||
deviceId: 0, | |||
testing: true, | |||
iPlayTts: true, | |||
iAsrWakeUp: true, | |||
iGetRobotConfig: true, | |||
iAppConfig: true, | |||
iGetVolume: true, | |||
allInterfaces: new Map(), | |||
cloudiaEvents: new Map(), | |||
appConfig: "", | |||
character: "SweetGirl", | |||
allClothes: [], | |||
clothes: "suit_blue", | |||
immerseMode: false, | |||
asrEnabled: true | |||
}; | |||
}, | |||
computed: {}, | |||
watch: {}, | |||
mounted() { | |||
let that = this; | |||
if (that.$parent.tabIndex == 1) { | |||
let getAllInterfaces = (obj) => | |||
Object.getOwnPropertyNames(obj).filter((item) => { | |||
if (typeof obj[item] === "function" && item.startsWith("interface")) { | |||
that.allInterfaces.set(item, 0); | |||
console.info(item); | |||
return item; | |||
} | |||
}); | |||
getAllInterfaces(this); | |||
} | |||
}, | |||
methods: { | |||
getValidClass(cond) { | |||
if (cond === undefined || cond === 0) { | |||
return "api-layout interface-init"; | |||
} else if (cond === 1) { | |||
return "api-layout interface-success"; | |||
} else { | |||
return "api-layout interface-fail"; | |||
} | |||
}, | |||
interfaceShowToast() { | |||
let result = Cloudia.showToast(this.toast); | |||
this.allInterfaces["interfaceShowToast"] = result ? 1 : 2; | |||
}, | |||
interfaceShowLongToast() { | |||
let result = Cloudia.showLongToast(this.longToast); | |||
this.allInterfaces["interfaceShowLongToast"] = result ? 1 : 2; | |||
}, | |||
interfacePlayTts() { | |||
let result = Cloudia.playTts(this.tts); | |||
if (result) { | |||
this.iPlayTts = true; | |||
timer && clearTimeout(timer); | |||
timer = setTimeout(() => { | |||
this.iPlayTts = false; | |||
this.allInterfaces["interfacePlayTts"] = this.cloudiaEvents["ttsPlay"] === 10 ? 1 : 2; | |||
}, 1500); | |||
} else { | |||
this.allInterfaces["interfacePlayTts"] = 2; | |||
} | |||
}, | |||
interfaceUpdateBrowserLocation() { | |||
this.bOffset = this.bOffset.replace(/ /g, ""); | |||
let offset = this.bOffset.split(","); | |||
let result = Cloudia.updateBrowserLocation(offset[0], offset[1], offset[2], offset[3]); | |||
this.allInterfaces["interfaceUpdateBrowserLocation"] = result ? 1 : 2; | |||
}, | |||
interfaceUpdateCharacterLocation() { | |||
this.cLocation = this.cLocation.replace(/ /g, ""); | |||
let location = this.cLocation.split(","); | |||
let result = Cloudia.updateCharacterLocation(location[0], location[1], location[2], location[3]); | |||
this.allInterfaces["interfaceUpdateCharacterLocation"] = result ? 1 : 2; | |||
}, | |||
interfaceUpdateCharacterRotation() { | |||
this.cRotation = this.cRotation.replace(/ /g, ""); | |||
let rotation = this.cRotation.split(","); | |||
let result = Cloudia.updateCharacterRotation(rotation[0], rotation[1], rotation[2], rotation[3]); | |||
this.allInterfaces["interfaceUpdateCharacterRotation"] = result ? 1 : 2; | |||
}, | |||
interfaceUpdateWallLocation() { | |||
let result = Cloudia.setWallLocation(this.bgLocation); | |||
this.allInterfaces["interfaceUpdateWallLocation"] = result ? 1 : 2; | |||
}, | |||
interfacePlayMotion() { | |||
this.motion = this.motion.replace(/ /g, ""); | |||
let params = this.motion.split(","); | |||
let result; | |||
if (params.length === 2) { | |||
result = Cloudia.playMotion(params[0], params[1]); | |||
} else { | |||
result = Cloudia.playMotion(params[0]); | |||
} | |||
this.allInterfaces["interfacePlayMotion"] = result ? 1 : 2; | |||
}, | |||
interfaceSetBgWallColor() { | |||
//通过使用 getElementById() 来访问 <color> 元素 | |||
let colorEl = document.getElementById("color"); | |||
console.info("selected color:" + colorEl.value); | |||
let color = colorEl.value.replace("#", ""); | |||
let r = parseInt(color.substring(0, 2), 16) / 255; | |||
let g = parseInt(color.substring(2, 4), 16) / 255; | |||
let b = parseInt(color.substring(4, 6), 16) / 255; | |||
// console.info("Selected color: rgb(" + r + ", " + g + ", " + b + ")"); | |||
let result = Cloudia.setBgWallColor(r + ", " + g + ", " + b); | |||
this.allInterfaces["interfaceSetBgWallColor"] = result ? 1 : 2; | |||
}, | |||
interfaceSetBgWallRes() { | |||
let result = Cloudia.setBgWallResource(this.wallRes); | |||
this.allInterfaces["interfaceSetBgWallRes"] = result ? 1 : 2; | |||
}, | |||
interfaceGetDeviceId() { | |||
let that = this; | |||
this.iGetRobotConfig = true; | |||
return Cloudia.getRobotInfoConfig("RobotId").then(function(ReturnValue) { | |||
if (ReturnValue !== undefined && ReturnValue.ReturnValue !== undefined) { | |||
that.deviceId = ReturnValue.ReturnValue; | |||
} | |||
that.allInterfaces["interfaceGetDeviceId"] = that.deviceId.length > 0 ? 1 : 2; | |||
that.iGetRobotConfig = false; | |||
}); | |||
}, | |||
interfaceGetAppConfig() { | |||
let that = this; | |||
this.iAppConfig = true; | |||
return Cloudia.getAppConfig().then(function(ReturnValue) { | |||
if (ReturnValue !== undefined && ReturnValue.ReturnValue !== undefined) { | |||
that.appConfig = ReturnValue.ReturnValue; | |||
} | |||
that.allInterfaces["interfaceGetAppConfig"] = that.appConfig.length > 0 ? 1 : 2; | |||
that.iAppConfig = false; | |||
}); | |||
}, | |||
interfaceSetCharacter() { | |||
let result = Cloudia.setCharacter(this.character); | |||
this.allClothes = cloudiaConfig.allClothes; | |||
this.clothes = this.allClothes[0]; | |||
this.allInterfaces["interfaceSetCharacter"] = result ? 1 : 2; | |||
return result; | |||
}, | |||
interfaceSetClothes() { | |||
let result = Cloudia.setClothes(this.clothes); | |||
this.allInterfaces["interfaceSetClothes"] = result ? 1 : 2; | |||
}, | |||
interfacePostMediaEvent() { | |||
let result = Cloudia.postMediaEvent(this.mediaEvent); | |||
this.allInterfaces["interfacePostMediaEvent"] = result ? 1 : 2; | |||
}, | |||
interfaceSetAsrWakeUpEnable() { | |||
let result = Cloudia.setAsrWakeUpEnable(this.asrWakeUp); | |||
if (result) { | |||
this.iAsrWakeUp = true; | |||
timer && clearTimeout(timer); | |||
timer = setTimeout(() => { | |||
if (this.cloudiaEvents["asrWakeUp"] === this.asrWakeUp ? 10 : 20) { | |||
this.allInterfaces["interfaceSetAsrWakeUpEnable"] = 1; | |||
} else { | |||
this.allInterfaces["interfaceSetAsrWakeUpEnable"] = 2; | |||
} | |||
this.iAsrWakeUp = false; | |||
}, 1000); | |||
} else { | |||
this.allInterfaces["interfaceSetAsrWakeUpEnable"] = 2; | |||
} | |||
}, | |||
interfaceStopPlayTts() { | |||
let result = Cloudia.stopPlayTts(false); | |||
this.allInterfaces["interfaceStopPlayTts"] = result ? 1 : 2; | |||
}, | |||
interfaceEnterImmerseMode() { | |||
let result = Cloudia.enterImmerseMode(this.immerseMode); | |||
this.allInterfaces["interfaceEnterImmerseMode"] = result ? 1 : 2; | |||
}, | |||
interfaceStartVideoTalk() { | |||
let result = Cloudia.startVideoTalk(); | |||
this.allInterfaces["interfaceStartVideoTalk"] = result ? 1 : 2; | |||
}, | |||
interfaceStopVideoTalk() { | |||
let result = Cloudia.stopVideoTalk(); | |||
this.allInterfaces["interfaceStopVideoTalk"] = result ? 1 : 2; | |||
}, | |||
interfaceSetVolume() { | |||
let result = Cloudia.setVolume(this.setValueText); | |||
this.allInterfaces["interfaceSetVolume"] = result ? 1 : 2; | |||
}, | |||
interfaceGetVolume() { | |||
this.iGetVolume = true; | |||
return Cloudia.getVolume().then((ReturnValue) => { | |||
if (ReturnValue !== undefined && ReturnValue.ReturnValue !== undefined) { | |||
this.getValueText = ReturnValue.ReturnValue; | |||
console.info("========:" + this.getValueText + ", " + this.setValueText); | |||
this.allInterfaces["interfaceGetVolume"] = | |||
this.getValueText.toString() === this.setValueText.toString() ? 1 : 2; | |||
} else { | |||
this.allInterfaces["interfaceGetVolume"] = 2; | |||
} | |||
this.iGetVolume = false; | |||
}); | |||
}, | |||
interfaceDownloadFiles() { | |||
let result = Cloudia.downloadFiles( | |||
"test", | |||
JSON.stringify([ | |||
{ | |||
name: "04070c61b7d40b5a90b98640645493cb.jpeg", | |||
url: "https://127.0.0.1" | |||
}, | |||
{ | |||
name: "112350h4wcwa94c9ch3oth.jpg", | |||
url: "https://127.0.0.1" | |||
} | |||
]) | |||
); | |||
this.allInterfaces["interfaceDownloadFiles"] = result ? 1 : 2; | |||
}, | |||
interfaceTextTriggerNlp() { | |||
let result = Cloudia.textTriggerNlp(this.ttsText); | |||
this.allInterfaces["interfaceTextTriggerNlp"] = result ? 1 : 2; | |||
}, | |||
getRandomInt(min, max) { | |||
min = Math.ceil(min); | |||
max = Math.floor(max); | |||
return Math.floor(Math.random() * (max - min)) + min; //不含最大值,含最小值 | |||
}, | |||
loadAd() { | |||
// TODO !!!!不同的环境需要切换不同的baseUrl!!!! | |||
let baseUrl = "https://127.0.0.1"; | |||
let timestamp = new Date().getTime(); | |||
// TODO 填写你自己的appId | |||
let appId = Config.appId; | |||
let nonceStr = this.getRandomInt(1000, 9999); | |||
// TODO 填写你自己的appSecret | |||
let appSecret = Config.appSecret; | |||
let sign = md5("appId" + appId + "timestamp" + timestamp + "nonceStr" + nonceStr + appSecret); | |||
// console.info("appId:" + appId); | |||
// console.info("appSecret:" + appSecret); | |||
// console.info("sign:" + sign); | |||
const headers = { | |||
"Content-Type": "application/json", | |||
appId: appId, | |||
timestamp: timestamp, | |||
nonceStr: nonceStr, | |||
sign: sign | |||
}; | |||
let url = "/crss-robot/ads/robotapi/v1/adSpace/get?pageCode=home&robotCode=" + this.deviceId; | |||
fetch(baseUrl + url, { headers }) | |||
.then(async (response) => { | |||
const data = await response.json(); | |||
if (!response.ok) { | |||
// get error message from body or default to response statusText | |||
const error = (data && data.message) || response.statusText; | |||
return Promise.reject(error); | |||
} | |||
console.info("load ad data success:" + JSON.stringify(data)); | |||
if (data.code === 0 && data.data && data.data.adList) { | |||
// 拼接完整URL | |||
data.data.adList.map((e) => { | |||
e.url = baseUrl + e.url; | |||
}); | |||
let adData = JSON.stringify(data.data.adList); | |||
// 下载广告数据,下载成功之后会在event事件中收到通知 | |||
Cloudia.downloadFiles("home", adData); | |||
console.info("ad data:" + adData); | |||
} else { | |||
console.warn("ad data is empty"); | |||
} | |||
}) | |||
.catch((error) => { | |||
console.error("load ad data error:" + error); | |||
}); | |||
}, | |||
interFun() { | |||
var ii = "qp"; | |||
this.handleCustomize(ii); | |||
}, | |||
insertNlp() { | |||
this.addMsgList(2, "测试一下,测试一下"); | |||
if (this.nplList.length > 10) { | |||
this.nplList.splice(10, this.nplList.length - 10); | |||
} | |||
this.nplList = [ | |||
{ question_id: new Date().getTime(), question_text: "test test", answer: "answer....." }, | |||
...this.nplList | |||
]; | |||
this.$axios | |||
.post(Config.serverDb + "/api/db/save", { | |||
id: new Date().getTime(), | |||
text: "test test", | |||
answer: "answer....." | |||
}) | |||
.then((res) => { | |||
console.log(res); | |||
}); | |||
}, | |||
testAllInterface() { | |||
let i = 0; | |||
for (let [key, value] of this.allInterfaces) { | |||
timer && clearTimeout(timer); | |||
timer = setTimeout(() => { | |||
this.testing = true; | |||
try { | |||
this[key](); | |||
} catch (e) { | |||
this.allInterfaces[key] = 2; | |||
console.error("interface exec failed:" + key + ", " + value + "----" + e); | |||
} | |||
this.testing = false; | |||
}, ++i * 1000); | |||
} | |||
} | |||
} | |||
}; | |||
</script> | |||
<style> | |||
.log { | |||
height: 100%; | |||
text-align: left; | |||
overflow-y: scroll; | |||
margin-right: 0; | |||
padding-right: 0; | |||
} | |||
.cmd { | |||
margin-left: 2vw; | |||
color: #803300; | |||
font-size: 4vh; | |||
display: inline-block; | |||
} | |||
.api-layout { | |||
margin-bottom: 0.5vh; | |||
justify-content: left; | |||
width: 100%; | |||
text-align: left; | |||
} | |||
.input-text { | |||
height: 6vh; | |||
line-height: 6vh; | |||
font-size: 3vh; | |||
color: black; | |||
text-align: left; | |||
width: 60vw; | |||
background-color: rgba(255, 255, 255, 0.4); | |||
border: none; | |||
padding-left: 1vw; | |||
} | |||
.select_wrapper { | |||
padding: 0; | |||
background-color: transparent; | |||
} | |||
.selection { | |||
padding: 0; | |||
width: 61vw; | |||
background-color: rgba(255, 255, 255, 0.4); | |||
} | |||
.input-button { | |||
width: 34vw; | |||
margin-left: 2vw; | |||
} | |||
.m-button { | |||
background-color: rgba(59, 140, 207, 0.5); | |||
} | |||
.input-color-layout { | |||
display: -webkit-box; | |||
} | |||
.input-color-text { | |||
font: 400 3vh Arial; | |||
text-align: left; | |||
display: contents; | |||
} | |||
.input-color-button { | |||
padding: 0; | |||
margin-left: 2vw; | |||
width: 34vw; | |||
display: flex; | |||
} | |||
.floats { | |||
position: absolute; | |||
right: 1vw; | |||
width: 48vw; | |||
text-align: right; | |||
} | |||
.interface-init { | |||
background-color: transparent; | |||
} | |||
.interface-success { | |||
background-color: #57b73b; | |||
} | |||
.interface-fail { | |||
background-color: #803300; | |||
} | |||
</style> |
@@ -0,0 +1,398 @@ | |||
<template> | |||
<div v-if="visible" :class="['json-view-container', theme, `deep-${currentDeep}`]"> | |||
<div | |||
:class="['json-view', length ? 'closeable' : '']" | |||
:style="{ fontSize: fontSize + 'px', lineHeight: lineHeight + 'px' }" | |||
> | |||
<!--icon-style-square--> | |||
<span v-if="length && iconStyle === 'square'" class="angle" @click="toggleClose"> | |||
<svg | |||
v-if="innerclosed" | |||
:fill="iconColors[0]" | |||
width="1em" | |||
height="1em" | |||
viewBox="0 0 1792 1792" | |||
style="vertical-align: middle; color: rgb(42, 161, 152); height: 1em; width: 1em;" | |||
> | |||
<path | |||
d="M1344 800v64q0 14-9 23t-23 9h-352v352q0 14-9 23t-23 9h-64q-14 0-23-9t-9-23v-352h-352q-14 0-23-9t-9-23v-64q0-14 9-23t23-9h352v-352q0-14 9-23t23-9h64q14 0 23 9t9 23v352h352q14 0 23 9t9 23zm128 448v-832q0-66-47-113t-113-47h-832q-66 0-113 47t-47 113v832q0 66 47 113t113 47h832q66 0 113-47t47-113zm128-832v832q0 119-84.5 203.5t-203.5 84.5h-832q-119 0-203.5-84.5t-84.5-203.5v-832q0-119 84.5-203.5t203.5-84.5h832q119 0 203.5 84.5t84.5 203.5z" | |||
></path> | |||
</svg> | |||
<svg | |||
v-if="!innerclosed" | |||
:fill="iconColors[1]" | |||
width="1em" | |||
height="1em" | |||
viewBox="0 0 1792 1792" | |||
style="vertical-align: middle; color: rgb(88, 110, 117); height: 1em; width: 1em;" | |||
> | |||
<path | |||
d="M1344 800v64q0 14-9 23t-23 9h-832q-14 0-23-9t-9-23v-64q0-14 9-23t23-9h832q14 0 23 9t9 23zm128 448v-832q0-66-47-113t-113-47h-832q-66 0-113 47t-47 113v832q0 66 47 113t113 47h832q66 0 113-47t47-113zm128-832v832q0 119-84.5 203.5t-203.5 84.5h-832q-119 0-203.5-84.5t-84.5-203.5v-832q0-119 84.5-203.5t203.5-84.5h832q119 0 203.5 84.5t84.5 203.5z" | |||
></path> | |||
</svg> | |||
</span> | |||
<!--icon-style-circle--> | |||
<span v-if="length && iconStyle === 'circle'" class="angle" @click="toggleClose"> | |||
<svg | |||
v-if="!innerclosed" | |||
viewBox="0 0 24 24" | |||
:fill="iconColors[0]" | |||
preserveAspectRatio="xMidYMid meet" | |||
style="vertical-align: middle; color: rgb(1, 160, 228); height: 1em; width: 1em;" | |||
> | |||
<path | |||
d="M12,20C7.59,20 4,16.41 4,12C4,7.59 7.59,4 12,4C16.41,4 20,7.59 20,12C20,16.41 16.41,20 12,20M12,2A10,10 0 0,0 2,12A10,10 0 0,0 12,22A10,10 0 0,0 22,12A10,10 0 0,0 12,2M7,13H17V11H7" | |||
></path> | |||
</svg> | |||
<svg | |||
v-if="innerclosed" | |||
viewBox="0 0 24 24" | |||
:fill="iconColors[1]" | |||
preserveAspectRatio="xMidYMid meet" | |||
style="vertical-align: middle; color: rgb(161, 106, 148); height: 1em; width: 1em;" | |||
> | |||
<path | |||
d="M12,20C7.59,20 4,16.41 4,12C4,7.59 7.59,4 12,4C16.41,4 20,7.59 20,12C20,16.41 16.41,20 12,20M12,2A10,10 0 0,0 2,12A10,10 0 0,0 12,22A10,10 0 0,0 22,12A10,10 0 0,0 12,2M13,7H11V11H7V13H11V17H13V13H17V11H13V7Z" | |||
></path> | |||
</svg> | |||
</span> | |||
<!--icon-style-triangle--> | |||
<span v-if="length && iconStyle === 'triangle'" class="angle" @click="toggleClose"> | |||
<svg | |||
v-if="!innerclosed" | |||
viewBox="0 0 15 15" | |||
:fill="iconColors[0]" | |||
style="vertical-align: top; color: #3c4047; height: 1em; width: 1em; padding-left: 2px;" | |||
> | |||
<path d="M0 5l6 6 6-6z"></path> | |||
</svg> | |||
<svg | |||
v-if="innerclosed" | |||
viewBox="0 0 15 15" | |||
:fill="iconColors[1]" | |||
style="vertical-align: top; color: #3c4047; height: 1em; width: 1em; padding-left: 2px;" | |||
> | |||
<path d="M0 14l6-6-6-6z"></path> | |||
</svg> | |||
</span> | |||
<div class="content-wrap"> | |||
<p :class="['first-line', length > 0 ? 'pointer' : '']" @click="toggleClose"> | |||
<span v-if="jsonKey" class="json-key">"{{ jsonKey }}": </span> | |||
<span v-if="length" | |||
>{{ prefix }}{{ innerclosed ? "..." + subfix : "" }} | |||
<span class="json-note">{{ innerclosed ? length + " items" : "" }}</span> | |||
</span> | |||
<span v-if="!length">{{ `${isArray ? "[]" : "{}"}${isLast ? "" : ","}` }}</span> | |||
</p> | |||
<div v-if="!innerclosed && length" class="json-body"> | |||
<template v-for="(item, index) in items"> | |||
<json-view | |||
v-if="item.isJSON" | |||
:key="index" | |||
:closed="isClose()" | |||
:data="item.value" | |||
:json-key="item.key" | |||
:current-deep="templateDeep + 1" | |||
:deep="deep" | |||
:icon-style="iconStyle" | |||
:theme="theme" | |||
:font-size="fontSize" | |||
:line-height="lineHeight" | |||
:icon-color="iconColors" | |||
:is-last="index === items.length - 1" | |||
:has-siblings="item.hasSiblings" | |||
/> | |||
<p v-else :key="index" class="json-item"> | |||
<span class="json-key">{{ isArray ? "" : '"' + item.key + '":' }}</span> | |||
<span :class="['json-value', getDataType(item.value)]"> | |||
{{ | |||
`${getDataType(item.value) === "string" ? '"' : ""}${formatValue(item.value)}${ | |||
getDataType(item.value) === "string" ? '"' : "" | |||
}${index === items.length - 1 ? "" : ","}` | |||
}} | |||
</span> | |||
</p> | |||
</template> | |||
<span v-if="!innerclosed" class="base-line"></span> | |||
</div> | |||
<p v-if="!innerclosed" class="last-line"> | |||
<span>{{ subfix }}</span> | |||
</p> | |||
</div> | |||
</div> | |||
</div> | |||
</template> | |||
<script> | |||
export default { | |||
name: "JsonView", | |||
props: { | |||
data: { | |||
// 传入的json数据 | |||
type: [Object, Array], | |||
required: true | |||
}, | |||
jsonKey: { | |||
// json的key值,用于第二层及二层以上的组件的key值 | |||
type: String, | |||
default: "" | |||
}, | |||
closed: { | |||
// 是否折叠 | |||
type: Boolean, | |||
default: false | |||
}, | |||
isLast: { | |||
//是否是最后一行 | |||
type: Boolean, | |||
default: true | |||
}, | |||
fontSize: { | |||
//字体大小 | |||
type: Number, | |||
default: 14 | |||
}, | |||
lineHeight: { | |||
//行高 | |||
type: Number, | |||
default: 24 | |||
}, | |||
deep: { | |||
// 展开深度 | |||
type: Number, | |||
default: 3 | |||
}, | |||
currentDeep: { | |||
// 当前为递归的第几层 | |||
type: Number, | |||
default: 1 | |||
}, | |||
iconStyle: { | |||
// 折叠icon样式 | |||
type: String, | |||
default: "square" | |||
}, | |||
iconColor: { | |||
//icon颜色 | |||
type: Array, | |||
default() { | |||
return []; | |||
} | |||
}, | |||
theme: { | |||
// 主题 | |||
type: String, | |||
default: "" | |||
}, | |||
hasSiblings: { | |||
// 是否有兄弟节点 | |||
type: Boolean, | |||
default: true | |||
} | |||
}, | |||
data() { | |||
return { | |||
innerclosed: this.closed, | |||
templateDeep: this.currentDeep, | |||
visible: false | |||
}; | |||
}, | |||
computed: { | |||
isArray() { | |||
return this.getDataType(this.data) === "array"; | |||
}, | |||
length() { | |||
return this.isArray ? this.data.length : Object.keys(this.data).length; | |||
}, | |||
subfix() { | |||
const data = this.data; | |||
if (this.isEmptyArrayOrObject(data)) { | |||
// 如果是空数组或空对象 | |||
return ""; | |||
} else { | |||
return (this.isArray ? "]" : "}") + (this.isLast ? "" : ","); | |||
} | |||
}, | |||
prefix() { | |||
return this.isArray ? "[" : "{"; | |||
}, | |||
items() { | |||
const json = this.data; | |||
if (this.isArray) { | |||
return json.map((item) => { | |||
const isJSON = this.isObjectOrArray(item); | |||
return { | |||
value: item, | |||
isJSON, | |||
key: "" | |||
}; | |||
}); | |||
} | |||
return Object.keys(json).map((key) => { | |||
const item = json[key]; | |||
const isJSON = this.isObjectOrArray(item); | |||
return { | |||
value: item, | |||
isJSON, | |||
key | |||
}; | |||
}); | |||
}, | |||
iconColors() { | |||
const { theme, iconColor } = this; | |||
if (iconColor.length === 2) { | |||
return iconColor; | |||
} else { | |||
if (theme === "one-dark") { | |||
return ["#747983", "#747983"]; | |||
} else if (theme === "vs-code") { | |||
return ["#c6c6c6", "#c6c6c6"]; | |||
} else { | |||
return ["#747983", "#747983"]; | |||
} | |||
} | |||
} | |||
}, | |||
watch: { | |||
closed() { | |||
this.innerclosed = this.closed; | |||
} | |||
}, | |||
mounted() { | |||
setTimeout(() => { | |||
this.visible = true; | |||
}, 0); | |||
}, | |||
methods: { | |||
formatValue(data) { | |||
if (data && data._isBigNumber) { | |||
return data.toString(10); | |||
} | |||
return data; | |||
}, | |||
getDataType(data) { | |||
return data && data._isBigNumber | |||
? "number" | |||
: Object.prototype.toString | |||
.call(data) | |||
.slice(8, -1) | |||
.toLowerCase(); | |||
}, | |||
isObjectOrArray(source) { | |||
return ["array", "object"].includes(this.getDataType(source)); | |||
}, | |||
toggleClose() { | |||
if (this.length === 0) { | |||
return; | |||
} | |||
if (this.innerclosed) { | |||
this.innerclosed = false; | |||
} else { | |||
this.innerclosed = true; | |||
} | |||
}, | |||
isClose() { | |||
return this.templateDeep + 1 > this.deep; | |||
}, | |||
isEmptyArrayOrObject(data) { | |||
// 空数组或者空对象 | |||
return [{}, []].map((item) => JSON.stringify(item)).includes(JSON.stringify(data)); | |||
} | |||
} | |||
}; | |||
</script> | |||
<style scoped lang="scss"> | |||
.json-view-container { | |||
background-color: transparent; | |||
&.deep-1 { | |||
// overflow: auto; | |||
padding-right: 10px; | |||
} | |||
.json-view { | |||
position: relative; | |||
display: block; | |||
width: 100%; | |||
height: 100%; | |||
white-space: nowrap; | |||
padding-left: 2rem; | |||
box-sizing: border-box; | |||
cursor: default; | |||
.json-note { | |||
color: #909399; | |||
font-size: 12px; | |||
font-style: italic; | |||
} | |||
.json-key { | |||
color: #8c6325; | |||
} | |||
.json-value { | |||
display: inline-block; | |||
color: #57b73b; | |||
word-break: break-all; | |||
white-space: normal; | |||
&.number { | |||
color: #2d8cf0; | |||
} | |||
&.string { | |||
color: #57b73b; | |||
} | |||
&.boolean { | |||
color: #eb3324; | |||
} | |||
&.null { | |||
color: #eb3324; | |||
} | |||
} | |||
.json-item { | |||
margin: 0; | |||
padding-left: 2rem; | |||
display: flex; | |||
} | |||
.first-line { | |||
padding: 0; | |||
margin: 0; | |||
&.pointer { | |||
cursor: pointer !important; | |||
} | |||
} | |||
.json-body { | |||
position: relative; | |||
padding: 0; | |||
margin: 0; | |||
.base-line { | |||
position: absolute; | |||
height: 100%; | |||
border-left: 1px dashed #bbb; | |||
top: 0; | |||
left: 2px; | |||
&:hover { | |||
} | |||
} | |||
} | |||
.last-line { | |||
padding: 0; | |||
margin: 0; | |||
} | |||
.angle { | |||
position: absolute; | |||
display: block; | |||
cursor: pointer; | |||
float: left; | |||
width: 20px; | |||
text-align: center; | |||
/*left: ~"calc(2rem - 18px)";*/ | |||
left: 12px; | |||
} | |||
} | |||
} | |||
</style> |
@@ -0,0 +1,193 @@ | |||
<template> | |||
<div class="recommendPage"> | |||
<swiper v-if="initOrNot" ref="videoSwiper" :options="swiperOption"> | |||
<swiper-slide v-for="(item, index) in mediaNews" :key="index"> | |||
<video | |||
v-if="item.type === 1" | |||
controls | |||
muted="muted" | |||
autoplay="autoplay" | |||
class="multimedia" | |||
style="width: 100%;object-fit: cover" | |||
@ended="endVideo(index)" | |||
> | |||
<source :src="item.url" type="video/mp4" /> | |||
</video> | |||
<img v-else :src="item.url" class="multimedia" style="width: 100%;object-fit: cover" /> | |||
</swiper-slide> | |||
</swiper> | |||
</div> | |||
</template> | |||
<script> | |||
import { swiper, swiperSlide } from "vue-awesome-swiper"; | |||
import "swiper/dist/css/swiper.css"; | |||
var timer; | |||
export default { | |||
name: "SwiperView", | |||
components: { | |||
swiper, | |||
swiperSlide | |||
}, | |||
data() { | |||
const files = require.context("@/assets/ads", true).keys(); | |||
let ads = []; | |||
console.log(ads); | |||
for (let url in files) { | |||
let temp = {}; | |||
console.log("../assets/ads/" + files[url]); | |||
temp.url = require("../assets/ads/" + files[url].substr(2)); | |||
temp.type = 0; | |||
if (files[url].endsWith("mp4")) { | |||
temp.type = 1; | |||
} | |||
ads.push(temp); | |||
} | |||
return { | |||
swiperOption: { | |||
speed: 1000, | |||
loop: false, | |||
observer: true, | |||
observeParents: true, | |||
autoplayDisableOnInteraction: false, | |||
allowTouchMove: false, | |||
pagination: { | |||
el: ".swiper-pagination", | |||
clickable: true | |||
}, | |||
on: { | |||
slideChangeTransitionEnd: () => { | |||
this.slideChangeTransitionEndHandle(); | |||
}, | |||
slideChangeTransitionStart: () => { | |||
this.slideChangeTransitionStartHandle(); | |||
}, | |||
//控制第一个slide切换 | |||
init: () => { | |||
this.initHandle(); | |||
} | |||
} | |||
}, | |||
initOrNot: false, | |||
mediaLastIndex: 0, | |||
mediaNews: ads | |||
}; | |||
}, | |||
computed: { | |||
swiper() { | |||
return this.$refs.videoSwiper.swiper; | |||
} | |||
}, | |||
watch: { | |||
mediaNews: { | |||
handler(newName, oldName) { | |||
if (newName.length > 0) { | |||
this.initOrNot = false; | |||
this.$nextTick(() => { | |||
this.initOrNot = true; | |||
}); | |||
} | |||
}, | |||
immediate: true, | |||
deep: true | |||
} | |||
}, | |||
mounted() {}, | |||
methods: { | |||
initHandle() { | |||
let that = this; | |||
timer && clearTimeout(timer); | |||
timer = setTimeout(function() { | |||
let swiper = that.$refs.videoSwiper.swiper; | |||
that.mediaNewsImgHandle(swiper); | |||
}, 200); | |||
}, | |||
mediaNewsImgHandle(swiper) { | |||
//刚切换到的activeIndex | |||
let changePointActiveIndex = swiper.activeIndex; | |||
if (swiper.activeIndex < this.mediaNews.length - 1) { | |||
timer && clearTimeout(timer); | |||
timer = setTimeout(function() { | |||
//要确认changePointActiveIndex是不是还是目前的activeIndex,是的话计时后执行,不是的话不执行 | |||
if (changePointActiveIndex === swiper.activeIndex) { | |||
swiper.slideNext(); | |||
} | |||
}, 5000); | |||
} else { | |||
timer && clearTimeout(timer); | |||
timer = setTimeout(function() { | |||
if (changePointActiveIndex === swiper.activeIndex) { | |||
swiper.slideTo(0, 0); | |||
} | |||
}, 5000); | |||
} | |||
}, | |||
slideChangeTransitionStartHandle() { | |||
let swiper = this.$refs.videoSwiper.swiper; | |||
if (this.mediaNews[this.mediaLastIndex].type === 1) { | |||
document.getElementsByClassName("multimedia")[this.mediaLastIndex].currentTime = 0; | |||
} | |||
}, | |||
slideChangeTransitionEndHandle() { | |||
console.log("end.."); | |||
let that = this; | |||
let swiper = that.$refs.videoSwiper.swiper; | |||
if (this.mediaNews[swiper.activeIndex].type === 0) { | |||
this.mediaNewsImgHandle(swiper); | |||
} else { | |||
if (this.mediaLastIndex.type === 1) { | |||
document.getElementsByClassName("multimedia")[this.mediaLastIndex].pause(); | |||
} | |||
document.getElementsByClassName("multimedia")[swiper.activeIndex].removeAttribute("muted"); | |||
document.getElementsByClassName("multimedia")[swiper.activeIndex].play(); | |||
// this.playVideo(this.mediaNews[swiper.activeIndex].url); | |||
} | |||
this.mediaLastIndex = swiper.activeIndex; | |||
}, | |||
endVideo(index) { | |||
let swiper = this.$refs.videoSwiper.swiper; | |||
if (index === swiper.activeIndex) { | |||
if (swiper.activeIndex < this.mediaNews.length - 1) { | |||
swiper.slideNext(); | |||
if (this.mediaNews[swiper.activeIndex].type === 1) { | |||
document.getElementsByClassName("multimedia")[swiper.activeIndex].removeAttribute("muted"); | |||
document.getElementsByClassName("multimedia")[swiper.activeIndex].play(); | |||
// this.playVideo(this.mediaNews[swiper.activeIndex].url); | |||
} | |||
} else { | |||
swiper.slideTo(0, 0); | |||
if (this.mediaNews[swiper.activeIndex].type === 1) { | |||
document.getElementsByClassName("multimedia")[swiper.activeIndex].removeAttribute("muted"); | |||
document.getElementsByClassName("multimedia")[swiper.activeIndex].play(); | |||
// this.playVideo(this.mediaNews[swiper.activeIndex].url); | |||
} | |||
} | |||
} | |||
} | |||
} | |||
}; | |||
</script> | |||
<style> | |||
.recommendPage .swiper-container { | |||
position: relative; | |||
width: 100%; | |||
height: 1920px; | |||
background: transparent; | |||
} | |||
.recommendPage .swiper-container .swiper-slide { | |||
width: 100%; | |||
//line-height: 1920px; | |||
background: transparent; | |||
color: #000; | |||
font-size: 16px; | |||
text-align: center; | |||
} | |||
swiper-slide img { | |||
object-fit: contain; | |||
} | |||
</style> |
@@ -0,0 +1,74 @@ | |||
<template> | |||
<div class="video-js-comp"> | |||
<video ref="videoPlayer" class="video-js vjs-fluid" controls /> | |||
</div> | |||
</template> | |||
<script> | |||
import videojs from "video.js"; | |||
import "videojs-flash"; | |||
import "video.js/dist/video-js.css"; | |||
import CN from "video.js/dist/lang/zh-CN.json"; | |||
videojs.addLanguage("zh-CN", CN); | |||
export default { | |||
name: "VideoPlayer", | |||
props: { | |||
options: { | |||
type: Object, | |||
default() { | |||
return {}; | |||
} | |||
}, | |||
dispose: { | |||
type: Boolean, | |||
required: true | |||
} | |||
}, | |||
data() { | |||
return { | |||
player: null | |||
}; | |||
}, | |||
watch: { | |||
dispose(newVal) { | |||
if (!newVal && this.player) { | |||
this.player.dispose(); | |||
} | |||
} | |||
}, | |||
mounted() { | |||
this.player = videojs(this.$refs.videoPlayer, this.options); | |||
this.videoPlayer = this.$refs.videoPlayer; | |||
console.log(this.player); | |||
console.log(this.videoPlayer); | |||
// 播放结束 | |||
var that = this; | |||
this.videoPlayer.addEventListener("ended", (e) => { | |||
// 重置状态 | |||
// this.videoVisiable = false; | |||
that.$parent.setVideoVisible(false); | |||
that.$parent.setTabindex(0); | |||
that.$parent.enterImmerseMode(false); | |||
}); | |||
} | |||
}; | |||
</script> | |||
<style lang="scss" scoped> | |||
.video-js-comp { | |||
width: 100%; | |||
height: 100%; | |||
position: relative; | |||
overflow: hidden; | |||
} | |||
video { | |||
display: block; | |||
min-height: 100%; | |||
min-width: 100%; | |||
position: absolute !important; | |||
top: 50% !important; | |||
left: 50% !important; | |||
transform: translate(-50%, -50%); | |||
} | |||
video:focus { | |||
outline: none; | |||
} | |||
</style> |
@@ -0,0 +1,68 @@ | |||
export default { | |||
qp: { | |||
equip_no: "2", | |||
set_no: "2", | |||
value: "AlarmCenter.ScreensAddin.ScreensCommand", | |||
info: "打开全屏" | |||
}, | |||
fhsy: { | |||
equip_no: "2", | |||
set_no: "1701", | |||
value: "AlarmCenter.ScreensAddin.ScreensCommand", | |||
info: "返回首页" | |||
}, | |||
zhts: { | |||
equip_no: "2", | |||
set_no: "103", | |||
value: "AlarmCenter.ScreensAddin.ScreensCommand", | |||
info: "打开综合态势" | |||
}, | |||
afts: { | |||
equip_no: "2", | |||
set_no: "104", | |||
value: "AlarmCenter.ScreensAddin.ScreensCommand", | |||
info: "打开安防态势" | |||
}, | |||
ryts: { | |||
equip_no: "2", | |||
set_no: "105", | |||
value: "AlarmCenter.ScreensAddin.ScreensCommand", | |||
info: "打开人员态势" | |||
}, | |||
tcts: { | |||
equip_no: "2", | |||
set_no: "106", | |||
value: "AlarmCenter.ScreensAddin.ScreensCommand", | |||
info: "打开停车态势" | |||
}, | |||
nyts: { | |||
equip_no: "2", | |||
set_no: "107", | |||
value: "AlarmCenter.ScreensAddin.ScreensCommand", | |||
info: "打开能源态势" | |||
}, | |||
xfts: { | |||
equip_no: "2", | |||
set_no: "108", | |||
value: "AlarmCenter.ScreensAddin.ScreensCommand", | |||
info: "打开消防态势" | |||
}, | |||
xmdsxt: { | |||
equip_no: "1005", | |||
set_no: "2", | |||
value: "AlarmCenter.ScreensAddin.ScreensCommand", | |||
info: "打开西门东侧摄像头" | |||
}, | |||
hys1bsxt: { | |||
equip_no: "1005", | |||
set_no: "3", | |||
value: "AlarmCenter.ScreensAddin.ScreensCommand", | |||
info: "打开一号会议室北侧摄像头" | |||
}, | |||
dtmxsxt: { | |||
equip_no: "1005", | |||
set_no: "4", | |||
value: "AlarmCenter.ScreensAddin.ScreensCommand", | |||
info: "打开大堂门口西侧摄像头" | |||
} | |||
}; |
@@ -0,0 +1,80 @@ | |||
export default { | |||
appId: "xxxxx", | |||
appSecret: "xxxxxxx", | |||
/** | |||
* @description 是否输出调试信息 | |||
*/ | |||
isDebuggable: process.env.NODE_ENV === "development" || process.env.NODE_ENV === "test", | |||
/** | |||
* @description api请求基础路径 | |||
*/ | |||
baseUrl: process.env.VUE_APP_SERVER_URL, | |||
/** | |||
* CMS URL | |||
*/ | |||
mediaApi: "http://127.0.0.1", | |||
/** | |||
* @description shop type | |||
*/ | |||
shopType: Object.freeze({ | |||
SHOP_DETAIL: 1, | |||
SHOP_MAP: 2, | |||
SHOP_LIST_ALL: 3, | |||
SHOP_LIST_FOOD: 4, | |||
SHOP_LIST_PLAY: 5, | |||
SHOP_LIST_CLOTH: 6, | |||
SHOP_LIST_KID: 7, | |||
SHOP_LIST_ON_SALE: 8, | |||
SHOP_LIST_ON_SERVICE: 9, | |||
SHOP_LIST_ON_BEAUTY: 10 | |||
}), | |||
isPortrait: true, | |||
storageKey: Object.freeze({ | |||
KEY_SHOP_DATA: "preloadShopData" | |||
}), | |||
listItemType: Object.freeze({ | |||
SHOP: 0, | |||
CHAT: 1 | |||
}), | |||
appTitle: "奥北科技园", | |||
username: "adminadmin", | |||
userpwd: "admin.123", | |||
// serverHj1: "http://192.168.1.254:8089", | |||
getKeyUrl: "http://tx.lecooai.com:47880/api/server/getkey_pc", | |||
serverHj: "http://dev.lecooai.com:47880", | |||
// serverHj: "http://192.168.1.254:8089", | |||
// serverHj: "http://39.105.85.176:63089", | |||
mouseServerAb: "http://39.105.85.176:63091", | |||
// serverDb: "http://39.105.85.176:63300", | |||
serverDb: "http://192.168.1.254:13000", | |||
padSocketUrl: "ws://192.168.124.4:9090", | |||
// padSocketUrl: "ws://192.168.10.65:8666", | |||
serverUrl: "http://192.168.10.65", | |||
openDoorUrl: "http://39.105.85.176:63330", | |||
serverPot: "/hj", | |||
userType: { | |||
mgr: 0, | |||
emp: 1, | |||
keyVisitor: 2, | |||
courier: 3, | |||
blackRole: 4, | |||
visitor: 5 | |||
}, | |||
userTypeCn: { | |||
0: "高管", | |||
1: "员工", | |||
2: "VIP客户", | |||
3: "快递", | |||
4: "黑名单", | |||
5: "访客" | |||
}, | |||
debug: true, | |||
faceDetectEnable: false, | |||
detectSleep: 6000, | |||
speakSleep: 60000, | |||
returnAdPage: 30000, | |||
currentScene: "lecoo1218" | |||
}; |
@@ -0,0 +1,19 @@ | |||
var connection = require('./sql.js') | |||
module.exports = { | |||
query: (callback) => { | |||
connection.query("select * from cmd order by created_at desc limit 20", function (error, results, fields) { | |||
console.log(results) | |||
callback(results); | |||
}) | |||
}, | |||
add : (obj, callback) => { | |||
connection.query('insert into cmd (question_id, question_text, answer) value (?, ?, ?)', [obj.id, obj.text, obj.answer], function (error, results) { | |||
console.log(results) | |||
callback(results); | |||
}) | |||
} | |||
} |
@@ -0,0 +1,90 @@ | |||
const { add, query } = require("../db/dbHelp"); | |||
const express = require("express"); | |||
const router = express.Router(); | |||
import Cloudia from "../api/cloudia-sdk-v1.4.1"; | |||
// 连接数据库 | |||
const jsonWrite = function(res, ret) { | |||
if (typeof ret === "undefined") { | |||
res.json({ | |||
code: "1", | |||
msg: "操作失败" | |||
}); | |||
} else { | |||
res.json(ret); | |||
} | |||
}; | |||
// 接口:增加信息sql,编辑修改信息sql1 | |||
router.post("/save", (req, res) => { | |||
const params = req.body; | |||
add(params, (result) => { | |||
jsonWrite(res, result); | |||
}); | |||
}); | |||
// 接口:用户管理分页接口查询 | |||
router.get("/getlist", (req, res) => { | |||
const params = req.body; | |||
console.log(params); | |||
alert(JSON.stringify(Cloudia)); | |||
alert("okokokok"); | |||
query((result) => { | |||
jsonWrite(res, result); | |||
}); | |||
}); | |||
const db = require("../db/mssql"); //注意改路径 | |||
router.get("/ms/detailMD", (req, res) => { | |||
console.log(db.sql); | |||
//根据时间查询的模板 | |||
var count = 0; | |||
var commonResult = []; | |||
db.sql( | |||
"SELECT PassType,count(1) as Count FROM HJ_PersonRecognition WHERE DateDiff(dd,DetectTime,getdate())=0 group by PassType order by PassType", | |||
function(err, result) { | |||
if (err) { | |||
console.log(err); | |||
return; | |||
} | |||
commonResult.push(...result.recordset); | |||
count++; | |||
if (count >= 3) { | |||
res.send(commonResult); | |||
} | |||
} | |||
); | |||
db.sql( | |||
"select '0' as Reserve1, count(1) as cnt from HJ_PersonRecognition as person where person.Reserve1 = '0' and DATEDIFF(DAY, person.DetectTime, GETDATE()) = 0 union select '1' as Reserve1, count(1) as cnt from HJ_PersonRecognition as person where person.Reserve1 = '1' and DATEDIFF(DAY, person.DetectTime, GETDATE()) = 0", | |||
function(err, result) { | |||
if (err) { | |||
console.log(err); | |||
return; | |||
} | |||
commonResult.push(...result.recordset); | |||
count++; | |||
if (count >= 3) { | |||
res.send(commonResult); | |||
} | |||
} | |||
); | |||
db.sql( | |||
"SELECT '0' as online, count(1) as num FROM HJ_EquipInfo WHERE Status = 1 and EquipTypeID = 3 union SELECT '1' as online, count(1) as num FROM HJ_EquipInfo WHERE (Status = 0 or Status = 2) and EquipTypeID = 3", | |||
function(err, result) { | |||
if (err) { | |||
console.log(err); | |||
return; | |||
} | |||
commonResult.push(...result.recordset); | |||
count++; | |||
if (count >= 3) { | |||
res.send(commonResult); | |||
} | |||
} | |||
); | |||
}); | |||
module.exports = router; |
@@ -0,0 +1,54 @@ | |||
/* | |||
mssql模块简单封装 | |||
*/ | |||
const mssql = require("mssql"); | |||
const db = {}; | |||
const config = { | |||
user: "sa", | |||
password: "123456", //改成你自己的 | |||
server: "192.168.1.254", //改成你自己的 | |||
database: "Yifangzhongxin", //改成你自己的 | |||
port: 1433, //改成你自己的 | |||
options: { | |||
encrypt: false // Use this if you're on Windows Azure | |||
}, | |||
pool: { | |||
min: 0, | |||
max: 10, | |||
idleTimeoutMillis: 3000 | |||
} | |||
}; | |||
//执行sql,返回数据. | |||
db.sql = function(sql, callBack) { | |||
const connection = new mssql.ConnectionPool(config, function(err) { | |||
if (err) { | |||
console.log(err); | |||
return; | |||
} | |||
const ps = new mssql.PreparedStatement(connection); | |||
ps.prepare(sql, function(err) { | |||
if (err) { | |||
console.log(err); | |||
return; | |||
} | |||
ps.execute("", function(err, result) { | |||
if (err) { | |||
console.log(err); | |||
return; | |||
} | |||
ps.unprepare(function(err) { | |||
if (err) { | |||
console.log(err); | |||
callback(err, null); | |||
return; | |||
} | |||
callBack(err, result); | |||
}); | |||
}); | |||
}); | |||
}); | |||
}; | |||
module.exports = db; |
@@ -0,0 +1,10 @@ | |||
var mysql = require("mysql"); | |||
// 连接数据库 | |||
var connection = mysql.createConnection({ | |||
host: "39.105.85.176", | |||
user: "root", | |||
password: "Lecooai@2021", | |||
database: "vue" | |||
}); | |||
module.exports = connection; |
@@ -0,0 +1,44 @@ | |||
import Vue from "vue"; | |||
import App from "@/App.vue"; | |||
import router from "@/router"; | |||
import _ from "lodash/core"; | |||
Vue.prototype._ = _; | |||
import "@/plugins/lazyload"; | |||
import "@/plugins/mintui"; | |||
import Navigation from "vue-navigation"; | |||
Vue.use(Navigation, { router }); | |||
import Axios from "axios"; | |||
Vue.prototype.$axios = Axios; | |||
import ElementUI from "element-ui"; //element-ui的全部组件 | |||
import "element-ui/lib/theme-chalk/index.css"; //element-ui的css | |||
Vue.use(ElementUI); //使用elementUI | |||
Vue.config.productionTip = false; | |||
import jquery from "jquery"; | |||
Vue.prototype.$ = jquery; | |||
let app = null; | |||
let count = 0; | |||
function bindData() { | |||
if (count == 1) { | |||
app = new Vue({ | |||
router, | |||
render: (h) => h(App) | |||
}).$mount("#app"); | |||
global.vm = app; | |||
} | |||
} | |||
Axios.get("./config.json").then((res) => { | |||
if (res.data) { | |||
count += 1; | |||
Vue.prototype.$cmdList = res.data; | |||
bindData(); | |||
} | |||
}); | |||
export default Vue; |
@@ -0,0 +1,284 @@ | |||
import Config from "../config"; | |||
import Cloudia from "../api/cloudia-sdk-v1.4.1"; | |||
import { genPreRemoteReq, genRyts } from "../utils/genTtsText"; | |||
import moment from "moment"; | |||
let timer; | |||
/** | |||
* 通用的方法和一些与业务无关的工具方法 | |||
* | |||
*/ | |||
const mixin = { | |||
data() { | |||
return { | |||
msg444: "hello" | |||
}; | |||
}, | |||
methods: { | |||
mixinMethod() { | |||
console.log(this.$cmdList); | |||
console.log(this.stateVal); | |||
console.log(this.msgList); | |||
// this.returnAdPage(); | |||
console.log(this.msg444 + ",这是mixin混入方法"); | |||
}, | |||
setVideoVisible(visible) { | |||
this.videoVisible = visible; | |||
}, | |||
setTabindex(tabIndex) { | |||
this.tabIndex = tabIndex; | |||
}, | |||
playVideo(src) { | |||
if (src) { | |||
this.picVisible = false; | |||
this.tabIndex = 5; | |||
this.playerOptions = { | |||
muted: false, | |||
language: "zh-CN", | |||
playbackRates: [0.5, 1.0, 1.5, 2.0], | |||
autoplay: true, | |||
controls: false, | |||
sources: [ | |||
{ | |||
type: "video/mp4", | |||
src: src | |||
} | |||
] | |||
}; | |||
this.videoVisible = true; | |||
this.enterImmerseMode(true); | |||
} else { | |||
} | |||
}, | |||
playPic(src) { | |||
if (src) { | |||
this.videoVisible = false; | |||
this.tabIndex = 5; | |||
this.picUrl = src; | |||
this.picVisible = true; | |||
} | |||
}, | |||
setProgressCode(key) { | |||
this.lastReq = key; | |||
}, | |||
sendMsg(type) { | |||
// Cloudia.textTriggerNlp("人员态势"); | |||
/*let obj = this.$cmdList["zhh_company_open"]; | |||
obj.data.companyName = "道有道"; | |||
console.log(obj);*/ | |||
/*if (this.rotationY > 360) { | |||
this.rotationY = 0.0; | |||
} else { | |||
this.rotationY += 0.2; | |||
} | |||
Cloudia.updateCharacterRotation(0.0, this.rotationY, 0.0);*/ | |||
let obj = this.$cmdList["ry_open"]; | |||
// obj.data.companyName = "道有道"; | |||
var that = this; | |||
genPreRemoteReq( | |||
obj, | |||
(result) => { | |||
that.consoleLog("success=====1"); | |||
console.log("success=====1"); | |||
// that.consoleLog(JSON.stringify(result)); | |||
var results = obj.msg.match(/#\[\w*]/g); | |||
console.log(results); | |||
obj.showMsg = obj.msg; | |||
if (!obj.after_exec) { | |||
for (var i in results) { | |||
var temp = results[i]; | |||
var iTemp = temp.replace("#[", ""); | |||
iTemp = iTemp.replace("]", ""); | |||
obj.showMsg = obj.showMsg.replace(temp, result.HttpData.data[iTemp]); | |||
} | |||
console.log(obj); | |||
that.addMsgList(2, obj.showMsg); | |||
} else { | |||
console.log(that.$cmdList[obj.after_exec]); | |||
let cobj = that.$cmdList[obj.after_exec]; | |||
genPreRemoteReq( | |||
cobj, | |||
(result) => { | |||
var results = cobj.msg.match(/#\[\w*]/g); | |||
cobj.showMsg = cobj.msg; | |||
for (var i in results) { | |||
var temp = results[i]; | |||
var iTemp = temp.replace("#[", ""); | |||
iTemp = iTemp.replace("]", ""); | |||
cobj.showMsg = cobj.showMsg.replace(temp, result.HttpData.data[iTemp]); | |||
} | |||
that.addMsgList(2, cobj.showMsg); | |||
}, | |||
(err) => { | |||
console.log(err); | |||
} | |||
); | |||
} | |||
}, | |||
(res) => { | |||
console.log("error======="); | |||
that.consoleLog("error=====1"); | |||
that.consoleLog(res); | |||
// that.consoleLog(JSON.stringify(res)); | |||
console.log(res); | |||
} | |||
); | |||
/*opendoor( | |||
(res) => {}, | |||
(err) => {} | |||
);*/ | |||
let a = "0"; | |||
let b = 0; | |||
/*alert(this._.isEqual(a, "" + b)); | |||
alert(this._.isEqual("" + b, a)); | |||
alert(a == b);*/ | |||
this.consoleLog("skudhfishdifosijdknfknsdf"); | |||
/*for (var i = 0; i < this.msgList.length; i++) { | |||
if (this.msgList[i].from == type) { | |||
this.msgList.splice(i, 1); | |||
} | |||
} | |||
let text = | |||
"奥北科技园由北京奥北兴华科贸中心有限公司投资开发,园区定位为“高端生态商务花园” 。项目总建筑面积约10.4万平方米,按照“中心绿化带串联起多个建筑”的规划构思,项目整体分为东、西、两个区域,东区为2栋甲级写字楼,西区为24栋小型花园式商务独栋办公楼 。"; | |||
this.addMsgList(2, text);*/ | |||
}, | |||
fhsy(callback) { | |||
var obj = this.$cmdList["fhsy"]; | |||
genPreRemoteReq( | |||
obj, | |||
(res) => { | |||
// that.addMsgList(2, obj.info); | |||
callback(res); | |||
}, | |||
(res) => { | |||
Cloudia.showLongToast(JSON.stringify(res)); | |||
} | |||
); | |||
}, | |||
returnAdPage() { | |||
/*this.tabIndex = 4; | |||
// this.tabIndex = 0; | |||
this.sleep = true; | |||
this.isSpeaking = false; | |||
this.lastReq = ""; | |||
this.msgList = [ | |||
{ | |||
from: 2, | |||
message: "您好,我是小酷。" | |||
} | |||
];*/ | |||
Cloudia.setClothes("suit_blue"); | |||
}, | |||
leaveAdPage() { | |||
this.tabIndex = 0; | |||
// this.tabIndex = 0; | |||
this.sleep = false; | |||
Cloudia.setClothes("suit_blue"); | |||
}, | |||
enterImmerseMode(mode) { | |||
Cloudia.enterImmerseMode(mode); | |||
}, | |||
showQrCode() { | |||
this.imgQrcode = true; | |||
timer && clearTimeout(timer); | |||
timer = setTimeout(function() { | |||
Cloudia.playMotion("showRightHandTop"); | |||
}, 1500); | |||
}, | |||
queryNlp() { | |||
let that = this; | |||
this.$axios.get(Config.serverDb + "/api/db/getlist", {}).then((res) => { | |||
that.nplList = res.data; | |||
}); | |||
}, | |||
changeCharacter() { | |||
var characters = this.$cmdList["characters"]; | |||
if (this.characterInd >= characters.length - 1) { | |||
this.characterInd = 0; | |||
} else { | |||
this.characterInd++; | |||
} | |||
Cloudia.setCharacter(characters[this.characterInd]); | |||
this.character = characters[this.characterInd]; | |||
this.clothesInd = 0; | |||
var clothes = this.$cmdList["clothes"][this.character]; | |||
Cloudia.setClothes(clothes[this.clothesInd]); | |||
}, | |||
changeCloth() { | |||
var clothes = this.$cmdList["clothes"][this.character]; | |||
if (this.clothesInd >= clothes.length - 1) { | |||
this.clothesInd = 0; | |||
} else { | |||
this.clothesInd++; | |||
} | |||
Cloudia.setClothes(clothes[this.clothesInd]); | |||
}, | |||
scrollMsgToBottom() { | |||
this.tabIndex = 0; | |||
let that = this; | |||
this.$nextTick(() => { | |||
let middle = that.$refs["middle"]; | |||
if (middle) middle.scrollTop = middle.scrollHeight; | |||
}); | |||
}, | |||
clickEvent() { | |||
this.clickNum++; | |||
if (this.clickNum >= 20) { | |||
this.close(); | |||
this.clickNum = 0; | |||
// alert(this.clickNum); | |||
} | |||
if (this.clickNum >= 15) { | |||
this.debug = !this.debug; | |||
this.showMsg = !this.showMsg; | |||
} | |||
}, | |||
_clearCache() { | |||
localStorage.clear(); | |||
}, | |||
hiddenDebug() { | |||
this.debug = false; | |||
}, | |||
containStr(array, text) { | |||
for (var i = 0; i < array.length; i++) { | |||
if (text.indexOf(array[i]) > -1) { | |||
return array[i]; | |||
} | |||
} | |||
return null; | |||
}, | |||
keysToArray(obj) { | |||
var array = []; | |||
for (var key in obj) { | |||
array.push(key); | |||
} | |||
return array; | |||
}, | |||
consoleLog(text) { | |||
let ts = new Date().getTime(); | |||
this.consoleList = { | |||
index: ts, | |||
message: text, | |||
time: moment(ts).format("mm:ss.SSS") | |||
}; | |||
}, | |||
close() { | |||
Cloudia.restartH5(); | |||
} | |||
} | |||
}; | |||
export default mixin; |
@@ -0,0 +1,321 @@ | |||
import Cloudia from "../api/cloudia-sdk-v1.4.1"; | |||
import Config from "../config"; | |||
import md5 from "js-md5"; | |||
var timer; | |||
const mixin_demo = { | |||
data() { | |||
return { | |||
toast: "A Toast", | |||
longToast: "A Long Toast", | |||
tts: "1234567890", | |||
bOffset: "0, 0, 0, 0", | |||
cLocation: "-378.8,-0.7,448.3,false", | |||
cRotation: "0,179.5,0,false", | |||
motion: "bow", | |||
wall: "Change BG Color", | |||
wallRes: "3DRoom", | |||
exp: "smile, 1", | |||
mediaEvent: "playing", | |||
asrWakeUp: true, | |||
walkGreetEnable: true, | |||
cameraMode: "level", | |||
bgLocation: "1400,0,0", | |||
setValueText: 12, | |||
getValueText: 0, | |||
ttsText: "成都天气", | |||
testing: true, | |||
iPlayTts: true, | |||
iAsrWakeUp: true, | |||
iGetRobotConfig: true, | |||
iAppConfig: true, | |||
iGetVolume: true, | |||
allInterfaces: new Map(), | |||
cloudiaEvents: new Map() | |||
}; | |||
}, | |||
methods: { | |||
getValidClass(cond) { | |||
if (cond === undefined || cond === 0) { | |||
return "api-layout interface-init"; | |||
} else if (cond === 1) { | |||
return "api-layout interface-success"; | |||
} else { | |||
return "api-layout interface-fail"; | |||
} | |||
}, | |||
interfaceShowToast() { | |||
let result = Cloudia.showToast(this.toast); | |||
this.allInterfaces["interfaceShowToast"] = result ? 1 : 2; | |||
}, | |||
interfaceShowLongToast() { | |||
let result = Cloudia.showLongToast(this.longToast); | |||
this.allInterfaces["interfaceShowLongToast"] = result ? 1 : 2; | |||
}, | |||
interfacePlayTts() { | |||
let result = Cloudia.playTts(this.tts); | |||
if (result) { | |||
this.iPlayTts = true; | |||
timer && clearTimeout(timer); | |||
timer = setTimeout(() => { | |||
this.iPlayTts = false; | |||
this.allInterfaces["interfacePlayTts"] = this.cloudiaEvents["ttsPlay"] === 10 ? 1 : 2; | |||
}, 1500); | |||
} else { | |||
this.allInterfaces["interfacePlayTts"] = 2; | |||
} | |||
}, | |||
interfaceUpdateBrowserLocation() { | |||
this.bOffset = this.bOffset.replace(/ /g, ""); | |||
let offset = this.bOffset.split(","); | |||
let result = Cloudia.updateBrowserLocation(offset[0], offset[1], offset[2], offset[3]); | |||
this.allInterfaces["interfaceUpdateBrowserLocation"] = result ? 1 : 2; | |||
}, | |||
interfaceUpdateCharacterLocation() { | |||
this.cLocation = this.cLocation.replace(/ /g, ""); | |||
let location = this.cLocation.split(","); | |||
let result = Cloudia.updateCharacterLocation(location[0], location[1], location[2], location[3]); | |||
this.allInterfaces["interfaceUpdateCharacterLocation"] = result ? 1 : 2; | |||
}, | |||
interfaceUpdateCharacterRotation() { | |||
this.cRotation = this.cRotation.replace(/ /g, ""); | |||
let rotation = this.cRotation.split(","); | |||
let result = Cloudia.updateCharacterRotation(rotation[0], rotation[1], rotation[2], rotation[3]); | |||
this.allInterfaces["interfaceUpdateCharacterRotation"] = result ? 1 : 2; | |||
}, | |||
interfaceUpdateWallLocation() { | |||
let result = Cloudia.setWallLocation(this.bgLocation); | |||
this.allInterfaces["interfaceUpdateWallLocation"] = result ? 1 : 2; | |||
}, | |||
interfacePlayMotion() { | |||
this.motion = this.motion.replace(/ /g, ""); | |||
let params = this.motion.split(","); | |||
let result; | |||
if (params.length === 2) { | |||
result = Cloudia.playMotion(params[0], params[1]); | |||
} else { | |||
result = Cloudia.playMotion(params[0]); | |||
} | |||
this.allInterfaces["interfacePlayMotion"] = result ? 1 : 2; | |||
}, | |||
interfaceSetBgWallColor() { | |||
//通过使用 getElementById() 来访问 <color> 元素 | |||
let colorEl = document.getElementById("color"); | |||
console.info("selected color:" + colorEl.value); | |||
let color = colorEl.value.replace("#", ""); | |||
let r = parseInt(color.substring(0, 2), 16) / 255; | |||
let g = parseInt(color.substring(2, 4), 16) / 255; | |||
let b = parseInt(color.substring(4, 6), 16) / 255; | |||
// console.info("Selected color: rgb(" + r + ", " + g + ", " + b + ")"); | |||
let result = Cloudia.setBgWallColor(r + ", " + g + ", " + b); | |||
this.allInterfaces["interfaceSetBgWallColor"] = result ? 1 : 2; | |||
}, | |||
interfaceSetBgWallRes() { | |||
let result = Cloudia.setBgWallResource(this.wallRes); | |||
this.allInterfaces["interfaceSetBgWallRes"] = result ? 1 : 2; | |||
}, | |||
interfaceGetDeviceId() { | |||
let that = this; | |||
this.iGetRobotConfig = true; | |||
return Cloudia.getRobotInfoConfig("RobotId").then(function(ReturnValue) { | |||
if (ReturnValue !== undefined && ReturnValue.ReturnValue !== undefined) { | |||
that.deviceId = ReturnValue.ReturnValue; | |||
} | |||
that.allInterfaces["interfaceGetDeviceId"] = that.deviceId.length > 0 ? 1 : 2; | |||
that.iGetRobotConfig = false; | |||
}); | |||
}, | |||
interfaceGetAppConfig() { | |||
let that = this; | |||
this.iAppConfig = true; | |||
return Cloudia.getAppConfig().then(function(ReturnValue) { | |||
if (ReturnValue !== undefined && ReturnValue.ReturnValue !== undefined) { | |||
that.appConfig = ReturnValue.ReturnValue; | |||
} | |||
that.allInterfaces["interfaceGetAppConfig"] = that.appConfig.length > 0 ? 1 : 2; | |||
that.iAppConfig = false; | |||
}); | |||
}, | |||
interfaceSetCharacter() { | |||
let result = Cloudia.setCharacter(this.character); | |||
this.allClothes = cloudiaConfig.allClothes; | |||
this.clothes = this.allClothes[0]; | |||
this.allInterfaces["interfaceSetCharacter"] = result ? 1 : 2; | |||
return result; | |||
}, | |||
interfaceSetClothes() { | |||
let result = Cloudia.setClothes(this.clothes); | |||
this.allInterfaces["interfaceSetClothes"] = result ? 1 : 2; | |||
}, | |||
interfacePostMediaEvent() { | |||
let result = Cloudia.postMediaEvent(this.mediaEvent); | |||
this.allInterfaces["interfacePostMediaEvent"] = result ? 1 : 2; | |||
}, | |||
interfaceSetAsrWakeUpEnable() { | |||
let result = Cloudia.setAsrWakeUpEnable(this.asrWakeUp); | |||
if (result) { | |||
this.iAsrWakeUp = true; | |||
timer && clearTimeout(timer); | |||
timer = setTimeout(() => { | |||
if (this.cloudiaEvents["asrWakeUp"] === this.asrWakeUp ? 10 : 20) { | |||
this.allInterfaces["interfaceSetAsrWakeUpEnable"] = 1; | |||
} else { | |||
this.allInterfaces["interfaceSetAsrWakeUpEnable"] = 2; | |||
} | |||
this.iAsrWakeUp = false; | |||
}, 1000); | |||
} else { | |||
this.allInterfaces["interfaceSetAsrWakeUpEnable"] = 2; | |||
} | |||
}, | |||
interfaceStopPlayTts() { | |||
let result = Cloudia.stopPlayTts(false); | |||
this.allInterfaces["interfaceStopPlayTts"] = result ? 1 : 2; | |||
}, | |||
interfaceEnterImmerseMode() { | |||
let result = Cloudia.enterImmerseMode(this.immerseMode); | |||
this.allInterfaces["interfaceEnterImmerseMode"] = result ? 1 : 2; | |||
}, | |||
interfaceStartVideoTalk() { | |||
let result = Cloudia.startVideoTalk(); | |||
this.allInterfaces["interfaceStartVideoTalk"] = result ? 1 : 2; | |||
}, | |||
interfaceStopVideoTalk() { | |||
let result = Cloudia.stopVideoTalk(); | |||
this.allInterfaces["interfaceStopVideoTalk"] = result ? 1 : 2; | |||
}, | |||
interfaceSetVolume() { | |||
let result = Cloudia.setVolume(this.setValueText); | |||
this.allInterfaces["interfaceSetVolume"] = result ? 1 : 2; | |||
}, | |||
interfaceGetVolume() { | |||
this.iGetVolume = true; | |||
return Cloudia.getVolume().then((ReturnValue) => { | |||
if (ReturnValue !== undefined && ReturnValue.ReturnValue !== undefined) { | |||
this.getValueText = ReturnValue.ReturnValue; | |||
console.info("========:" + this.getValueText + ", " + this.setValueText); | |||
this.allInterfaces["interfaceGetVolume"] = | |||
this.getValueText.toString() === this.setValueText.toString() ? 1 : 2; | |||
} else { | |||
this.allInterfaces["interfaceGetVolume"] = 2; | |||
} | |||
this.iGetVolume = false; | |||
}); | |||
}, | |||
interfaceDownloadFiles() { | |||
let result = Cloudia.downloadFiles( | |||
"test", | |||
JSON.stringify([ | |||
{ | |||
name: "04070c61b7d40b5a90b98640645493cb.jpeg", | |||
url: "https://127.0.0.1" | |||
}, | |||
{ | |||
name: "112350h4wcwa94c9ch3oth.jpg", | |||
url: "https://127.0.0.1" | |||
} | |||
]) | |||
); | |||
this.allInterfaces["interfaceDownloadFiles"] = result ? 1 : 2; | |||
}, | |||
interfaceTextTriggerNlp() { | |||
let result = Cloudia.textTriggerNlp(this.ttsText); | |||
this.allInterfaces["interfaceTextTriggerNlp"] = result ? 1 : 2; | |||
}, | |||
loadAd() { | |||
// TODO !!!!不同的环境需要切换不同的baseUrl!!!! | |||
let baseUrl = "https://127.0.0.1"; | |||
let timestamp = new Date().getTime(); | |||
// TODO 填写你自己的appId | |||
let appId = Config.appId; | |||
let nonceStr = this.getRandomInt(1000, 9999); | |||
// TODO 填写你自己的appSecret | |||
let appSecret = Config.appSecret; | |||
let sign = md5("appId" + appId + "timestamp" + timestamp + "nonceStr" + nonceStr + appSecret); | |||
// console.info("appId:" + appId); | |||
// console.info("appSecret:" + appSecret); | |||
// console.info("sign:" + sign); | |||
const headers = { | |||
"Content-Type": "application/json", | |||
appId: appId, | |||
timestamp: timestamp, | |||
nonceStr: nonceStr, | |||
sign: sign | |||
}; | |||
let url = "/crss-robot/ads/robotapi/v1/adSpace/get?pageCode=home&robotCode=" + this.deviceId; | |||
fetch(baseUrl + url, { headers }) | |||
.then(async (response) => { | |||
const data = await response.json(); | |||
if (!response.ok) { | |||
// get error message from body or default to response statusText | |||
const error = (data && data.message) || response.statusText; | |||
return Promise.reject(error); | |||
} | |||
console.info("load ad data success:" + JSON.stringify(data)); | |||
if (data.code === 0 && data.data && data.data.adList) { | |||
// 拼接完整URL | |||
data.data.adList.map((e) => { | |||
e.url = baseUrl + e.url; | |||
}); | |||
let adData = JSON.stringify(data.data.adList); | |||
// 下载广告数据,下载成功之后会在event事件中收到通知 | |||
Cloudia.downloadFiles("home", adData); | |||
console.info("ad data:" + adData); | |||
} else { | |||
console.warn("ad data is empty"); | |||
} | |||
}) | |||
.catch((error) => { | |||
console.error("load ad data error:" + error); | |||
}); | |||
}, | |||
interFun() { | |||
var ii = "qp"; | |||
this.handleCustomize(ii); | |||
}, | |||
insertNlp() { | |||
this.addMsgList(2, "测试一下,测试一下"); | |||
if (this.nplList.length > 10) { | |||
this.nplList.splice(10, this.nplList.length - 10); | |||
} | |||
this.nplList = [ | |||
{ question_id: new Date().getTime(), question_text: "test test", answer: "answer....." }, | |||
...this.nplList | |||
]; | |||
this.$axios | |||
.post(Config.serverDb + "/api/db/save", { | |||
id: new Date().getTime(), | |||
text: "test test", | |||
answer: "answer....." | |||
}) | |||
.then((res) => { | |||
console.log(res); | |||
}); | |||
}, | |||
queryNlp() { | |||
let that = this; | |||
this.$axios.get(Config.serverDb + "/api/db/getlist", {}).then((res) => { | |||
that.nplList = res.data; | |||
}); | |||
}, | |||
testAllInterface() { | |||
let i = 0; | |||
for (let [key, value] of this.allInterfaces) { | |||
timer && clearTimeout(timer); | |||
timer = setTimeout(() => { | |||
this.testing = true; | |||
try { | |||
this[key](); | |||
} catch (e) { | |||
this.allInterfaces[key] = 2; | |||
console.error("interface exec failed:" + key + ", " + value + "----" + e); | |||
} | |||
this.testing = false; | |||
}, ++i * 1000); | |||
} | |||
} | |||
} | |||
}; | |||
export default mixin_demo; |
@@ -0,0 +1,156 @@ | |||
import JsonView from "../components/JsonView"; | |||
import videoPlayer from "../components/VideoView"; | |||
import { Switch } from "mint-ui"; | |||
import { swiper, swiperSlide } from "vue-awesome-swiper"; | |||
import Config from "../config"; | |||
import { handleFaceType } from "../utils/handleTts"; | |||
let rec; //断线重连后,延迟5秒重新创建WebSocket连接 rec用来存储延迟请求的代码 | |||
let isConnect = false; | |||
const mixin_socket = { | |||
components: { | |||
JsonView, | |||
videoPlayer, | |||
swt: Switch, | |||
swiper, | |||
swiperSlide | |||
}, | |||
data() { | |||
return { | |||
webData: null, | |||
lastDetectTs: 0, | |||
lastPerson: {}, | |||
lastPersonId: 0, | |||
lastDetectObj: {}, | |||
lastPersonTs: 0 | |||
}; | |||
}, | |||
computed: {}, | |||
mounted() { | |||
if (Config.faceDetectEnable) { | |||
this.initWebSocket(); | |||
} | |||
}, | |||
destroyed() { | |||
this.websock && this.websock.close(); | |||
localStorage.clear(); | |||
}, | |||
methods: { | |||
initWebSocket() { | |||
const path = Config.padSocketUrl; // 后台给的websocket的ip地址 | |||
this.websock = new WebSocket(path); | |||
this.websock.onmessage = this.websocketOnMessage; | |||
this.websock.onopen = this.websocketOnOpen; | |||
this.websock.onerror = this.websocketOnError; | |||
this.websock.onclose = this.websocketClose; | |||
}, | |||
reConnect() { | |||
this.consoleLog("尝试重新连接"); | |||
if (isConnect) return; //如果已经连上就不在重连了 | |||
rec && clearTimeout(rec); | |||
let that = this; | |||
rec = setTimeout(function() { | |||
// 延迟5秒重连 避免过多次过频繁请求重连 | |||
that.initWebSocket(); | |||
}, 5000); | |||
}, | |||
// 连接建立成功的信号 | |||
websocketOnOpen() { | |||
this.consoleLog("初始化成功"); // 连接成功后就可以在这里写一些回调函数了 | |||
}, | |||
// 连接建立失败重连 | |||
websocketOnError() { | |||
// 如果报错的话,在这里就可以重新初始化websocket,这就是断线重连 | |||
// this.initWebSocket() | |||
this.consoleLog("WebSocket连接发生错误"); | |||
isConnect = false; //连接断开修改标识 | |||
this.reConnect(); //连接错误 需要重连 | |||
}, | |||
// 数据接收 | |||
websocketOnMessage(e) { | |||
let that = this; | |||
let obj = e.data; | |||
if (typeof obj != "object") { | |||
obj = JSON.parse(obj); | |||
} | |||
that.consoleLog( | |||
"id=" + | |||
(obj.id.length > 7 ? obj.id.substr(7) : obj.id) + | |||
",name=" + | |||
obj.name + | |||
",tag=" + | |||
obj.tag + | |||
",gender=" + | |||
obj.gender | |||
); | |||
// console.log(e.data); | |||
//非说话的状态下,用户说完话两秒后 | |||
let currentTs = new Date().getTime(); | |||
if (!that.execLocked && !that.isSpeaking && that.lastReq == "" && currentTs - that.lastQTs > 2000) { | |||
that.handleDetectedFace(obj); | |||
} | |||
}, | |||
// 数据发送 | |||
websocketSend(Data) { | |||
if (typeof Data == "object") { | |||
Data = JSON.stringify(Data); | |||
} | |||
this.consoleLog("send to serv:" + Data); | |||
this.websock.send(Data); // Data变量就是你想对后台说些啥,根据后端给你的接口文档传值进行交互 | |||
}, | |||
// 关闭的信号 | |||
websocketClose() { | |||
this.consoleLog("断开连接,重试连接"); | |||
isConnect = false; //连接断开修改标识 | |||
this.reConnect(); //服务器主动断开的情况下,需要重连 | |||
}, | |||
handleDetectedFace(obj) { | |||
let that = this; | |||
let currentTs = new Date().getTime(); | |||
let str = ""; | |||
if (obj && obj.id == -1) { | |||
//识别到脸 | |||
that.lastDetectTs = currentTs; | |||
that.leaveAdPage(); | |||
setTimeout(function() { | |||
that.playMotion("showLeftHand"); | |||
}, 600); | |||
return; | |||
} else if (obj && obj.id > 0) { | |||
//识别到人 | |||
if (that.lastReq == "moshengren") { | |||
that.lastReq = ""; | |||
} | |||
that.lastDetectTs = currentTs; | |||
that.lastDetectObj = obj; | |||
if (that.lastDetectObj.id === that.lastPerson.id) { | |||
that.lastPerson.name = that.lastDetectObj.name; | |||
that.lastPerson.tag = that.lastDetectObj.tag; | |||
} | |||
if ( | |||
(obj.id == that.lastPersonId && (currentTs - that.lastPersonTs >= 15000 || that.sleep)) || | |||
obj.id != that.lastPersonId | |||
) { | |||
that.lastPersonId = obj.id; | |||
that.lastPerson = obj; | |||
str += handleFaceType(that, obj); | |||
that.lastPersonTs = currentTs; | |||
that.sleep = false; | |||
that.tabIndex = 0; | |||
that.addMsgList(2, str); | |||
} | |||
} | |||
}, | |||
noDetectedFace() { | |||
let currentTs = new Date().getTime(); | |||
if (currentTs - this.lastDetectTs > 5000) { | |||
return true; | |||
} | |||
return false; | |||
} | |||
} | |||
}; | |||
export default mixin_socket; |
@@ -0,0 +1,7 @@ | |||
// 引入各种函数,便于做成npm包 | |||
// indexedDB 部分 | |||
import MetaHelp from './nf-meta/help.js' | |||
export { | |||
MetaHelp | |||
} |
@@ -0,0 +1,87 @@ | |||
import { reactive } from 'vue' | |||
// 从json文件加载meta | |||
import loadMetaFormJson from './loadmeta-json.js' | |||
// 从 webSQL加载meta | |||
import loadMetaFormSQL from './loadmeta-sql.js' | |||
// 把meta存入 indexedDB | |||
import { saveMetaAll, loadMeta } from './savemeta-db.js' | |||
/** | |||
* meta的help | |||
* * 从 json 加载 meta,存入 indexedDB | |||
* * 从 webSQL 加载 meta,存入 indexedDB | |||
* * 从 indexedDB 加载 meta, | |||
* * 把 meta 存入状态 | |||
*/ | |||
export default class MetaHelp { | |||
constructor (url) { | |||
this.jsonUrl = url, // json 的路径,axios 加载用 | |||
this.sqlHelp = null, // 访问 webSQL | |||
this.dbHelp = null, // 访问 indexedDB | |||
this.meta = reactive({ | |||
menu: {}, | |||
module: {}, | |||
service: {} | |||
}) | |||
} | |||
/** | |||
* 从 indexedDB 里面加载 meta | |||
* @returns | |||
*/ | |||
async loadMetaFromDB() { | |||
return await loadMeta(this.dbHelp) | |||
} | |||
/** | |||
* 把 meta 存入 state | |||
* @param {*} state 状态 | |||
* @param {*} meta 要存入的 meta。menu:数组;module:对象;service:对象 | |||
*/ | |||
toState(state, meta) { | |||
// 存入菜单,需要去重 | |||
meta.menu.forEach(_menu => { | |||
if (state.menu.findIndex((m) => m.id === _menu.id) < 0) { | |||
state.menu.push(_menu) | |||
} | |||
}) | |||
// 存入模块 | |||
Object.assign(state.module, meta.module) | |||
// 存入服务 | |||
Object.assign(state.service, meta.service) | |||
} | |||
/** | |||
* 从 webSQL 加载 meta,然后存入 indexedDB,并且返回 meta | |||
* @param {*} moduleId | |||
*/ | |||
async sqlToDB(moduleId = null) { | |||
console.log('MetaHelp 的 sqlToDB', this) | |||
const meta = await loadMetaFormSQL(this.sqlHelp) | |||
console.log('MetaHelp 的 SQL 读取出来的 meta ', meta) | |||
// 遍历,添加到 indexedDB | |||
saveMetaAll(this.dbHelp, meta) | |||
return meta | |||
} | |||
/** | |||
* 从 json 加载 meta,然后存入 indexedDB,并且返回 meta | |||
* @param {*} moduleId 模块ID | |||
* @returns | |||
*/ | |||
async loagMetaFromJson(moduleId = null) { | |||
console.log('MetaHelp 的 sqlToDB', this) | |||
const meta = await loadMetaFormJson(this.jsonUrl) | |||
console.log('MetaHelp 的 从json加载的meta:', meta) | |||
// 遍历,添加到 indexedDB | |||
saveMetaAll(this.dbHelp, meta) | |||
return meta | |||
} | |||
} |
@@ -0,0 +1,135 @@ | |||
// axios | |||
import axios from 'axios' | |||
/** | |||
* 加载 json 文件 整理成 meta 的格式,返回 | |||
*/ | |||
/** | |||
* 01 获取 json文件 的目录,因为json文件比较多,还希望实现热更新,所以做了个加载目录。 | |||
* * 应该加个随机数,便于即使更新。 | |||
* * 因为有缓存,所以不用怕过多访问的问题。 | |||
*/ | |||
const _loadFileDirectory = (jsonURL) => { | |||
return new Promise((resolve, reject) => { | |||
const _url = `${jsonURL}/dir.json?v=1` | |||
axios.get(_url).then((res) => { | |||
// console.log('dir -- 目录:', res) | |||
resolve(res.data) | |||
}).catch((res) => { | |||
reject(res) | |||
}) | |||
}) | |||
} | |||
/** | |||
* 整理加载的json,转成meta格式 | |||
*/ | |||
const _format = (res) => { | |||
const meta = { | |||
service: {}, | |||
module: {}, | |||
menu: res[0].data.menu | |||
} | |||
// 遍历meta,进行分类 | |||
res.forEach((re, index) => { | |||
if (index === 0) return // 第一个是菜单, | |||
const model = re.data | |||
if (typeof model.actions !== 'undefined') { | |||
// 后端API | |||
meta.service[model.moduleId] = model | |||
} else { | |||
// 模块的 meta | |||
if (typeof meta.module[model.moduleId] === 'undefined') { | |||
meta.module[model.moduleId] = { | |||
moduleId: model.moduleId | |||
} | |||
} | |||
// 开始判断 | |||
if (typeof model.btnOrder === 'object') { | |||
// 按钮 | |||
meta.module[model.moduleId].button = model | |||
} else if (typeof model.quickFind === 'object') { | |||
// 查询 | |||
meta.module[model.moduleId].find = model | |||
} else if (typeof model.idName === 'string') { | |||
// 列表 | |||
meta.module[model.moduleId].grid = model | |||
} else if (typeof model.formId !== 'undefined') { | |||
// 表单 | |||
if (typeof meta.module[model.moduleId].forms === 'undefined') { | |||
meta.module[model.moduleId].forms = {} | |||
} | |||
meta.module[model.moduleId].forms[model.formId] = model | |||
} | |||
} | |||
}) | |||
return meta | |||
} | |||
/** | |||
* axios 读取json文件,然后返回 | |||
* @param {*} josnDir 前端模块meta 的文件夹 | |||
* @param {*} serviveDir 后端服务meta 的文件夹 | |||
* @param {*} jsonURL 项目meta的url | |||
* @returns | |||
*/ | |||
const _loadMeta = (josnDir, serviveDir, jsonURL) => { | |||
return new Promise((resolve, reject) => { | |||
const actionName = ['button', 'find', 'grid'] | |||
// 加载json的 请求的 数组,交给 Promise.all 使用 | |||
const getMetaAxios = [] | |||
// 加入导航菜单 | |||
const _url = `${jsonURL}/menu.json` | |||
getMetaAxios.push(axios.get(_url)) | |||
// 前端meta 请求 加入数组 | |||
for (const key in josnDir) { | |||
const meta = josnDir[key] // 模块需要的表单 | |||
// 添加按钮、列表、查询 | |||
actionName.forEach(action => { | |||
const _url = `${jsonURL}module/${key}/${action}.json` | |||
getMetaAxios.push(axios.get(_url)) | |||
}) | |||
// 添加表单 | |||
meta.forEach(form => { | |||
const _url = `${jsonURL}module/${key}/${form}.json` | |||
getMetaAxios.push(axios.get(_url)) | |||
}) | |||
} | |||
// 后端API的meta 请求,也加入数组 | |||
serviveDir.forEach(api => { | |||
const _url = `${jsonURL}service/${api}.json` | |||
getMetaAxios.push(axios.get(_url)) | |||
}) | |||
// 一起发起所有json文件的请求 | |||
Promise.all(getMetaAxios).then((res) => { | |||
// console.log('data:', res) | |||
if (res[0].status === 200) { // statusText | |||
// json 数据 转换成 meta 格式 | |||
const meta = _format(res) | |||
console.log('----json--处理好后的--meta:--', meta) | |||
// 返回 meta | |||
resolve(meta) | |||
} | |||
}) | |||
}) | |||
} | |||
/** | |||
* 加载josn文件,整理后变成meta格式 | |||
* @param {string} jsonURL 项目meta的url | |||
* @returns 整理好的meta | |||
*/ | |||
const loadMetaFormJson = async (jsonURL) => { | |||
// 获取json的文件目录,便于 axios 加载 | |||
const dir = await _loadFileDirectory(jsonURL) | |||
return await _loadMeta(dir.jsonDir, dir.serviceDir, jsonURL) | |||
} | |||
export default loadMetaFormJson |
@@ -0,0 +1,206 @@ | |||
/** | |||
* 从 SQL 里面加载数据,整理成 meta 的格式 | |||
*/ | |||
/** | |||
* 把 webSQL 里的【菜单】数据变成 meta 的格式 | |||
*/ | |||
const _getMenuMetaBySQL = (data) => { | |||
const menu = [] | |||
data.forEach(m => { | |||
menu.push({ | |||
id: m.moduleId, | |||
componentKind: m.componentKind, | |||
icon: m.icon, | |||
moduleLevel: m.moduleLevel, | |||
parentId: m.parentId, | |||
title: m.title | |||
}) | |||
}) | |||
return menu | |||
} | |||
/** | |||
* 把 webSQL 里的【按钮】数据变成 meta 的格式 | |||
*/ | |||
const _getButtonMetaBySQL = (data) => { | |||
const meta = { | |||
moduleId: data.moduleId, | |||
btnOrder: [], | |||
itemMeta: {} | |||
} | |||
data.forEach(btn => { | |||
meta.btnOrder.push(btn.buttonId) | |||
meta.itemMeta[btn.buttonId] = btn | |||
}) | |||
return meta | |||
} | |||
/** | |||
* 把 webSQL 里的【列表】数据变成 meta 的格式 | |||
*/ | |||
const _getGridMetaBySQL = (grid, item) => { | |||
const meta = grid[0] | |||
meta.colOrder = meta.colOrder.split(',') | |||
meta.itemMeta = {} | |||
// meta.quickFind = meta.quickFind | |||
item.forEach(ctl => { | |||
// meta.colOrder.push(ctl.columnId) | |||
meta.itemMeta[ctl.columnId] = ctl | |||
}) | |||
return meta | |||
} | |||
/** | |||
* 把 webSQL 里的【查询】数据变成 meta 的格式 | |||
*/ | |||
const _getFindMetaBySQL = (find, item) => { | |||
const meta = find[0] | |||
meta.allFind = meta.allFind.split(',') | |||
meta.quickFind = meta.quickFind.split(',') | |||
meta.itemMeta = {} | |||
item.forEach(ctl => { | |||
// meta.quickFind.push(ctl.columnId) | |||
// meta.allFind.push(ctl.columnId) | |||
meta.itemMeta[ctl.columnId] = ctl | |||
}) | |||
return meta | |||
} | |||
/** | |||
* 把 webSQL 里的【表单】数据变成 meta 的格式 | |||
* * form 数组,包含多个 formId | |||
*/ | |||
const _getFormMetaBySQL = (forms, items) => { | |||
const meta = {} | |||
forms.forEach(fm => { | |||
meta[fm.formId] = fm | |||
meta[fm.formId].colOrder = meta[fm.formId].colOrder.split(',') | |||
meta[fm.formId].itemMeta = {} | |||
items.filter(a => a.formId === fm.formId).forEach(ctl => { | |||
meta[fm.formId].itemMeta[ctl.columnId] = ctl | |||
}) | |||
}) | |||
return meta | |||
} | |||
/** | |||
* 把 webSQL 里的【actions】数据变成 meta 的格式 | |||
*/ | |||
const _getActionMetaBySQL = (data) => { | |||
const actions = {} | |||
data.forEach(action => { | |||
actions[action.actionId] = { | |||
actionName: action.actionName, | |||
kind: action.kind, | |||
model: action.modelId | |||
} | |||
}) | |||
return actions | |||
} | |||
/** | |||
* 把 webSQL 里的【models】数据变成 meta 的格式 | |||
*/ | |||
const _getModelMetaBySQL = (data) => { | |||
const models = {} | |||
data.forEach(model => { | |||
models[model.actionId] = { | |||
tableName: model.tableName, | |||
idKey: model.idKey, | |||
cols: model.cols, | |||
pager: { | |||
orderBy: { roleId: false }, | |||
pagerIndex: 1, | |||
pagerSize: model.pagerSize, | |||
pagerTotal: 100 | |||
}, | |||
query: {} | |||
} | |||
}) | |||
return models | |||
} | |||
/** | |||
* 开发模式:从 webSQL 读取数据,转换成meta 的格式 | |||
* * 菜单meta、模块meta、service的meta | |||
* * 从 SQL 加载数据,转换格式,返回。 | |||
*/ | |||
const loadMetaFormSQL = async (sqlHelp) => { | |||
console.log('------webSQL 的 sqlHelp', sqlHelp) | |||
const tables = sqlHelp._tables | |||
// 存放 SQL 里面的 meta | |||
const meta = {} | |||
// 获取所有数据库里的 meta 数据 | |||
for (const key in tables) { | |||
const tt = tables[key] | |||
const tmp = await tt.list() | |||
meta[key] = Array.from(tmp) | |||
} | |||
console.log('------controller 的 meta', meta) | |||
// 返回的 meta | |||
const reMeta = { | |||
menu: _getMenuMetaBySQL(meta.nf_module), // 记录菜单 | |||
module: {}, // 模块 | |||
service: {} // service | |||
} | |||
const _tmp = (name, modId) => { | |||
return meta[name].filter((a) => a.moduleId === modId) | |||
} | |||
// 遍历菜单,变成 meta 的格式 | |||
for (let i = 0; i < meta.nf_module.length; i++) { | |||
const modId = meta.nf_module[i].moduleId | |||
const __moduleMeta = { // 记录模块的meta | |||
moduleId: modId, | |||
pager: {}, | |||
button: {}, | |||
grid: {}, | |||
find: {}, | |||
forms: {} | |||
} | |||
// 分页 | |||
// __moduleMeta.pager = this._getButtonMetaBySQL(meta[151].filter((a) => a.moduleId === modId)) | |||
// 列表 | |||
__moduleMeta.grid = _getGridMetaBySQL(_tmp('v_module_grid', modId), _tmp('v_module_grid_item', modId)) | |||
// 按钮 | |||
__moduleMeta.button = _getButtonMetaBySQL(_tmp('v_module_button', modId)) | |||
// 查询 | |||
__moduleMeta.find = _getFindMetaBySQL(_tmp('v_module_find', modId), _tmp('v_module_find_item', modId)) | |||
// 表单 | |||
__moduleMeta.forms = _getFormMetaBySQL(_tmp('v_module_form', modId), _tmp('v_module_form_item', modId)) | |||
// 记录 | |||
reMeta.module[modId] = __moduleMeta | |||
} | |||
// 遍历service,整理后端api | |||
for (let i = 0; i < meta.v_service.length; i++) { | |||
const service = meta.v_service[i] | |||
const serviceId = service.serviceId | |||
// 记录service | |||
const serviceMeta = { | |||
moduleId: serviceId, | |||
moduleName: service.serviceName, | |||
actions: {}, | |||
models: {} | |||
} | |||
const _tmp = (id) => { | |||
return meta[id].filter((a) => a.serviceId === serviceId) | |||
} | |||
serviceMeta.actions = _getActionMetaBySQL(_tmp('v_service_action', serviceId)) | |||
serviceMeta.models = _getModelMetaBySQL(_tmp('v_service_model', serviceId)) | |||
reMeta.service[serviceId] = serviceMeta | |||
} | |||
// 返回整理好的 meta | |||
return reMeta | |||
} | |||
export default loadMetaFormSQL |
@@ -0,0 +1,100 @@ | |||
/** | |||
* saveMeta:把 meta 的一个属性 存入 indexedDB 的一个对象仓库 | |||
* saveMetaAll:把 meta 存入 indexedDB | |||
* loadMeta:从 indexedDB 加载meta | |||
*/ | |||
/** | |||
* json、webSQL 的 meta,存入 indexedDB | |||
* @param {help} help 访问 indexedDB 的 help | |||
* @param {string} storeName 仓库名称 | |||
* @param {object} meta 要存入的对象,对象集合 | |||
* @returns 仅通知 | |||
*/ | |||
const saveMeta = (help, storeName, meta) => { | |||
const idName = { // 主键名称的字典 | |||
menuMeta: 'id', | |||
moduleMeta: 'moduleId', | |||
serviceMeta: 'moduleId' | |||
} | |||
return new Promise((resolve, reject) => { | |||
let count = 0 | |||
help.beginInit(storeName).then((store) => { | |||
count += Object.keys(meta).length | |||
if (count === 0) { | |||
resolve(null) | |||
} | |||
for (const key in meta) { | |||
// 先判断有没有,没有add;有了put | |||
store.get(meta[key][idName[storeName]]) | |||
.onsuccess = (event) => { | |||
// console.log('====== 要添加的key:', storeName + '_' + meta[key][idName[storeName]]) | |||
// console.log('====== 获取的 结果:', event.target.result) | |||
if (typeof event.target.result === 'undefined') { | |||
// 添加 | |||
store.add(meta[key]) // 添加一条meta | |||
.onsuccess = (event) => { | |||
count -= 1 | |||
if (count === 0) { | |||
resolve(event.target.result) | |||
} | |||
} | |||
} else { | |||
// 修改 | |||
store.put(meta[key]) // 修改一条meta | |||
.onsuccess = (event) => { | |||
count -= 1 | |||
if (count === 0) { | |||
resolve(event.target.result) | |||
} | |||
} | |||
} | |||
} | |||
} | |||
}) | |||
}) | |||
} | |||
/** | |||
* 把 meta 存入 indexedDB | |||
* @param {*} help indexedDB 的 help | |||
* @param {*} meta 要存入的 meta | |||
*/ | |||
const saveMetaAll = async (help, meta) => { | |||
await saveMeta(help, 'serviceMeta', meta.service) | |||
await saveMeta(help, 'moduleMeta', meta.module) | |||
await saveMeta(help, 'menuMeta', meta.menu) | |||
} | |||
/** | |||
* 从 indexedDB 里面加载 meta,并且返回 | |||
* @param {*} help indexedDB 的 help | |||
* @returns | |||
*/ | |||
const loadMeta = async (help) => { | |||
const state = { | |||
menu: [], | |||
module: {}, | |||
service: {} | |||
} | |||
state.menu = await help.getModel('menuMeta') | |||
const _module = await help.getModel('moduleMeta') | |||
const _service = await help.getModel('serviceMeta') | |||
for (const key in _module) { | |||
const m = _module[key] | |||
state.module[m.moduleId] = m | |||
} | |||
for (const key in _service) { | |||
const s = _service[key] | |||
state.service[s.moduleId] = s | |||
} | |||
return state | |||
} | |||
export { | |||
saveMetaAll, // 存入 meta | |||
saveMeta, // 存入一个属性 | |||
loadMeta // 加载 meta | |||
} |
@@ -0,0 +1,116 @@ | |||
/** | |||
* 一般查询方式的字典 | |||
*/ | |||
const _find = { | |||
401: (colValue, key) => colValue === key, // = | |||
403: (colValue, key) => colValue.includes(key), // 包含 | |||
405: (colValue, key) => colValue.indexOf(key) === 0, // 起始于 | |||
406: (colValue, key) => colValue.indexOf(key) + key.length === colValue.length, // 结束于 | |||
413: (colValue, key) => colValue > key, // > | |||
414: (colValue, key) => colValue >= key, // >= | |||
415: (colValue, key) => colValue < key, // < | |||
416: (colValue, key) => colValue <= key, // <= | |||
417: (colValue, key) => key[0] <= colValue && colValue <= key[1], // between | |||
418: (colValue, key) => key[0] < colValue && colValue <= key[1], // a < x <= b | |||
419: (colValue, key) => key[0] <= colValue && colValue < key[1], // a <= x < b | |||
420: (colValue, key) => key[0] < colValue && colValue < key[1] // a < x < b | |||
} | |||
/** | |||
* IDBKeyRange 的字典 | |||
*/ | |||
const _dicRange = { | |||
401: (_value) => IDBKeyRange.only(_value), // = | |||
// 403: (_value) => IDBKeyRange.only(_value), | |||
// 405: (_value) => IDBKeyRange.only(_value), | |||
// 406: (_value) => IDBKeyRange.only(_value), | |||
413: (_value) => IDBKeyRange.lowerBound(_value, true), // > | |||
414: (_value) => IDBKeyRange.lowerBound(_value), // >= | |||
415: (_value) => IDBKeyRange.upperBound(_value, true), // < | |||
416: (_value) => IDBKeyRange.upperBound(_value), // <= | |||
417: (_value) => IDBKeyRange.bound(_value[0], _value[1]), // between | |||
418: (_value) => IDBKeyRange.bound(_value[0], _value[1], true, false), // a < x <= b | |||
419: (_value) => IDBKeyRange.bound(_value[0], _value[1], false, true), // a <= x < b | |||
420: (_value) => IDBKeyRange.bound(_value[0], _value[1], true, true) // a < x < b | |||
} | |||
// 索引的排序方式,正序、倒序 | |||
// const _description = page.description || 'prev' // 默认倒序 | |||
/** | |||
* 遍历查询条件,找到对应的字段,做判断,有一个不符合就返回 false | |||
* @param {*} other 查询条件 | |||
* @param {*} model 要核对的对象 | |||
* @returns 是否符合 | |||
*/ | |||
const _check = (other, model) => { | |||
let re = true | |||
for (const key in other) { | |||
const colValue = model[key] // 被查询的内容 | |||
const kind = other[key][0] // 查询方式 | |||
const _key = other[key][1] // 查询条件的值 | |||
const _re = _find[kind](colValue, _key) // 验证 | |||
if (!_re) re = false | |||
} | |||
return re | |||
} | |||
/** | |||
* 处理索引和其他查询 | |||
* @param {*} indexNames 对象仓库已经设置的索引 | |||
* @param {*} query 查询条件 | |||
* @returns IDBKeyRange、其他查询条件、查询方式、回调查询 | |||
*/ | |||
const _toIndex = (indexNames, query) => { | |||
const re = { | |||
range: null, | |||
other: {}, | |||
find: (other, model) => _check(other, model), // 查询非索引字段 | |||
callback: () => {} // 回调查询,可以自定义查询方式 | |||
} | |||
// 匹配到的索引字段 | |||
let indexName = '' | |||
// 查询条件字段和索引字段,匹配一下,只匹配第一个索引字段 | |||
for (let i = 0; i < indexNames.length; i++) { | |||
// 索引字段名称 | |||
const _indexName = indexNames[i] | |||
if (typeof query[_indexName] !== 'undefined') { | |||
// 查询方式 | |||
const _kind = query[_indexName][0] | |||
// 查询的值 | |||
const _value = query[_indexName][1] | |||
// 查询条件里包含索引,记录,后面的就不管了。 | |||
// 匹配查询方式 | |||
re.range = _dicRange[_kind * 1](_value) | |||
// 没有的话,说明无法利用索引 | |||
if (typeof re.range === 'undefined') { | |||
re.range = null | |||
} else { | |||
indexName = _indexName | |||
} | |||
} | |||
if (indexName !== '') { | |||
// 退出循环 | |||
i = indexNames.length | |||
} | |||
} | |||
// 把其他的查询字段放在 other 里面 | |||
for (const key in query) { | |||
const _query = query[key] | |||
if (indexName !== key) { | |||
// 记录到其他查询条件里面 | |||
re.other[key] = _query | |||
} | |||
} | |||
return re | |||
} | |||
export default _toIndex |
@@ -0,0 +1,19 @@ | |||
import { unref, isReactive, toRaw } from 'vue' | |||
// 内部函数,如果是proxy,那么获取原型,否则会报错。 | |||
const _vueToObject = (obj) => { | |||
/* | |||
// 处理 ref | |||
let _object = unref(obj) | |||
// 处理 reactive | |||
if (isReactive(_object)) { | |||
// 如果是 vue 的 reactive 类型,那么获取原型,否则会报错 | |||
_object = toRaw(_object) | |||
} | |||
*/ | |||
const tmp = unref(obj) | |||
const _object = isReactive(tmp) ? toRaw(tmp): tmp | |||
return _object | |||
} | |||
export default _vueToObject |
@@ -0,0 +1,26 @@ | |||
/** | |||
* 初始化数据的时候使用的一个事务。 | |||
* * help._db 必然可用,不用判断。 | |||
*/ | |||
const beginInit = (help, storeName) => { | |||
return new Promise((resolve, reject) => { | |||
// | |||
const tranRequest = help._db.transaction(storeName, 'readwrite') | |||
const store = tranRequest.objectStore(storeName) // 获取store | |||
tranRequest.onerror = (event) => { | |||
console.log('读写事务出错:', event.target.error) | |||
// eslint-disable-next-line prefer-promise-reject-errors | |||
reject('读写事务出错:' + event.target.error) | |||
// tranRequest.abort() // 大概是回滚的意思。 | |||
} | |||
tranRequest.oncomplete = (event) => { | |||
// console.log('初始化数据事务完毕:', window.performance.now(), help._dataState) | |||
// help._dataState = 'done' | |||
} | |||
resolve(store) | |||
}) | |||
} | |||
export default beginInit |
@@ -0,0 +1,32 @@ | |||
/** | |||
* 开启一个读写的事务。需要判断 help._db 是否可用 | |||
* @param {*} help indexedDB 的 help | |||
* @param {Array} storeName 字符串的数组,对象仓库的名称 | |||
* @param {string} type readwrite:读写事务;readonly:只读事务;versionchange:允许执行任何操作,包括删除和创建对象存储和索引。 | |||
* @returns 读写事务 | |||
*/ | |||
const beginTran = (help, storeName, type = 'readwrite') => { | |||
return new Promise((resolve, reject) => { | |||
const _tran = () => { | |||
const tranRequest = help._db.transaction(storeName, type) | |||
tranRequest.onerror = (event) => { | |||
const err = `${type} 事务出错:${event.target.error}` | |||
console.log(err) | |||
reject(err) | |||
} | |||
resolve(tranRequest) | |||
tranRequest.oncomplete = (event) => { | |||
// console.log('beginReadonly 事务完毕:', window.performance.now()) | |||
} | |||
} | |||
if (help._db) { | |||
_tran() // 执行事务 | |||
} else { | |||
// 注册一个回调事件 | |||
help._regCallback.push(() => _tran()) | |||
} | |||
}) | |||
} | |||
export default beginTran |
@@ -0,0 +1,266 @@ | |||
// 加载操作函数 | |||
// 对象仓库的操作 | |||
import _clearStore from './store-clear.js' // 清空仓库里的全部对象 | |||
// model 的添加、修改、设置、获取、删除 | |||
import _addModel from './model-add.js' // 添加一个对象 | |||
import _putModel from './model-put.js' // 修改一个对象 | |||
import _setModel from './model-set.js' // 修改一个对象 | |||
import _getModel from './model-get.js' // 获取一个对象,或者全部(不能查询) | |||
import _delModel from './model-delete.js' // 删除一个对象 | |||
import _getCount from './model-count.js' // 获取仓库里的数量 | |||
// 对象的查询 | |||
import _listAll from './list-index.js' // 获取仓库里符合条件的对象,可以查询。 | |||
import _listPager from './list-pager.js' // 分页获取对象,可以查询 | |||
// 初始化和事务 | |||
import _beginInit from './begin-init.js' // 初始化时用的事务 | |||
import _beginTran from './begin-tran.js' // 事务 | |||
/** | |||
* indexedDB 的 help,基础功能的封装 | |||
* * 打开数据库,建立对象仓库,获取连接对象,实现增删改查 | |||
* * info 的结构: | |||
* * * dbFlag: '' // 数据库标识,区别不同的数据库 | |||
* * * dbConfig: { // 连接数据库 | |||
* * * * dbName: '数据库名称', | |||
* * * * ver: '数据库版本', | |||
* * * }, | |||
* * * stores: { | |||
* * * * storeName: { // 对象仓库名称 | |||
* * * * * id: 'id', // 主键名称 | |||
* * * * * index: { // 可以不设置索引 | |||
* * * * * * name: ture, // key:索引名称;value:是否可以重复 | |||
* * * * * } | |||
* * * * } | |||
* * * }, | |||
* * * init: (help) => {} // 完全准备好之后的回调函数 | |||
*/ | |||
export default class IndexedDBHelp { | |||
constructor (info) { | |||
this.myIndexedDB = window.indexedDB || window.webkitIndexedDB || window.mozIndexedDB || window.msIndexedDB | |||
if (!this.myIndexedDB) { | |||
console.log('您的浏览器不支持 IndexedDB') | |||
return | |||
} | |||
// 数据库名称和版本号 | |||
this._info = { | |||
dbName: info.dbConfig.dbName, | |||
ver: info.dbConfig.ver | |||
} | |||
// 记录连接数据库的对象, IDBDatabase 类型,因为open是异步操作,所以不能立即获得。 | |||
this._db = null | |||
// 记录仓库状态。new:新库或者版本升级后;old:有对象仓库了。 | |||
this._storeState = 'pending' | |||
/** | |||
* 注册回调事件。 | |||
* * 如果组件读写 indexedDB 的时还没有准备好的话, | |||
* * 可以来注册一个事件,等准备好了之后回调。 | |||
*/ | |||
this._regCallback = [] | |||
// 打开数据库,异步操作,大概需要几毫秒的时间。 | |||
this.dbRequest = this.myIndexedDB.open(this._info.dbName, this._info.ver) | |||
// 第一次,或者版本升级时执行,根据配置信息建立表 | |||
this.dbRequest.onupgradeneeded = (event) => { | |||
this._storeState = 'new' | |||
const db = event.target.result | |||
for (const key in info.stores) { | |||
const store = info.stores[key] | |||
if (db.objectStoreNames.contains(key)) { | |||
// 已经有仓库,验证一下是否需要删除原来的仓库 | |||
if (store.isClear) { | |||
// 删除原对象仓库,没有保存数据 | |||
db.deleteObjectStore(key) | |||
// 建立新对象仓库 | |||
const objectStore = db.createObjectStore(key, { keyPath: store.id }) | |||
// 建立索引 | |||
for (const key2 in store.index) { | |||
const unique = store.index[key2] | |||
objectStore.createIndex(key2, key2, { unique: unique }) | |||
} | |||
} | |||
} else { | |||
// 没有对象仓库,建立 | |||
const objectStore = db.createObjectStore(key, { keyPath: store.id }) /* 自动创建主键 autoIncrement: true */ | |||
// 建立索引 | |||
for (const key2 in store.index) { | |||
const unique = store.index[key2] | |||
objectStore.createIndex(key2, key2, { unique: unique }) | |||
} | |||
} | |||
} | |||
} | |||
// 数据库打开成功,记录连接对象 | |||
this.dbRequest.onsuccess = async (event) => { | |||
this._db = event.target.result // dbRequest.result | |||
// console.log('【1】成功打开数据库 onsuccess --- ', this._db) | |||
// 修改状态 | |||
if (this._storeState === 'pending') { | |||
this._storeState = 'old' | |||
} | |||
// 调用初始化的回调 | |||
if (typeof info.init === 'function') { | |||
await info.init(this) | |||
} | |||
// 调用组件注册的回调 | |||
this._regCallback.forEach(fn => { | |||
if (typeof fn === 'function') { | |||
fn() | |||
} | |||
}) | |||
} | |||
// 处理出错信息 | |||
this.dbRequest.onerror = (event) => { | |||
// 出错 | |||
console.log('打开数据库出错:', event.target.error) | |||
} | |||
} | |||
// versionchange 全能事务 | |||
// 初始化时批量添加对象的事务 | |||
beginInit (storeName) { | |||
return _beginInit(this, storeName) | |||
} | |||
// 读写的事务 | |||
beginWrite (storeName) { | |||
return _beginTran(this, storeName, 'readwrite') | |||
} | |||
// 只读的事务 | |||
beginReadonly (storeName) { | |||
return _beginTran(this, storeName, 'readonly') | |||
} | |||
/** | |||
* 删掉整个库 | |||
*/ | |||
deleteDB () { | |||
// 定义一个 Promise 的实例 | |||
const objectPromise = new Promise((resolve, reject) => { | |||
// 删掉整个数据库 | |||
const request = this.myIndexedDB.deleteDatabase(this._info.dbName) | |||
request.onsuccess = (event) => { // 没有触发 | |||
console.log('删掉整个数据库成功!', event) | |||
resolve(event) | |||
} | |||
request.onblocked = (event) => { // 这个会被触发 | |||
console.log('删除数据库的 blocked:', event) | |||
// Close connections here | |||
resolve(event) | |||
} | |||
request.onerror = (event) => { | |||
console.log('删除数据库的 error:', event) | |||
} | |||
}) | |||
return objectPromise | |||
} | |||
/** | |||
* 清空一个对象仓库的全部对象 | |||
* @param {string} storeName 对象仓库名称 | |||
* @param {IDBTransaction} tran 事务,可以为 null | |||
* @returns | |||
*/ | |||
clearStore (storeName, tran = null) { | |||
return _clearStore(this, storeName, tran) | |||
} | |||
/** | |||
* 添加一个对象 | |||
* @param {string} storeName 对象仓库名称 | |||
* @param {object} model 要添加的对象 | |||
* @param {IDBTransaction} tran 事务,可以为 null | |||
* @returns | |||
*/ | |||
addModel (storeName, model, tran = null) { | |||
return _addModel(this, storeName, model, tran) | |||
} | |||
/** | |||
* 修改一个对象 | |||
* @param {string} storeName 对象仓库名称 | |||
* @param {object} model 要修改的对象 | |||
* @param {number} id 对象主键ID | |||
* @param {IDBTransaction} tran 事务,可以为 null | |||
* @returns | |||
*/ | |||
putModel (storeName, model, id = null, tran = null) { | |||
return _putModel(this, storeName, model, id, tran) | |||
} | |||
/** | |||
* 添加或者修改一个对象 | |||
* @param {string} storeName 对象仓库名称 | |||
* @param {object} model 要添加或者修改的对象 | |||
* @param {number} id 对象主键ID,判断有无的依据 | |||
* @param {IDBTransaction} tran 事务,可以为 null | |||
* @returns | |||
*/ | |||
setModel (storeName, model, id = null, tran = null) { | |||
return _setModel(this, storeName, model, id, tran) | |||
} | |||
/** | |||
* 删除一个对象 | |||
* @param {string} storeName 对象仓库名称 | |||
* @param {object} id id 或者 model 要删除的对象 | |||
* @param {IDBTransaction} tran 事务,可以为 null | |||
* @returns | |||
*/ | |||
delModel (storeName, id, tran = null) { | |||
return _delModel(this, storeName, id, tran) | |||
} | |||
/** | |||
* 获取一个对象,或者仓库的全部对象 | |||
* @param {string} storeName 对象仓库名称 | |||
* @param {number} id null:获取仓库的全部对象;其他:对象ID值 | |||
* @param {IDBTransaction} tran 事务,可以为 null | |||
* @returns | |||
*/ | |||
getModel (storeName, id = null, tran = null) { | |||
return _getModel(this, storeName, id, tran) | |||
} | |||
/** | |||
* 获取对象仓库里全部对象的数量 | |||
* @param {string} storeName 对象仓库名称 | |||
* @param {IDBTransaction} tran 事务,可以为 null | |||
* @returns | |||
*/ | |||
getCount (storeName, tran = null) { | |||
return _getCount(this, storeName, tran ) | |||
} | |||
/** | |||
* 获取一个仓库的全部对象 | |||
* @param {string} storeName 对象仓库名称 | |||
* @param {object} query 查询条件 | |||
* @param {IDBTransaction} tran 事务,可以为 null | |||
* @returns | |||
*/ | |||
getList (storeName, query = {}, tran = null) { | |||
return _listAll(this, storeName, query, tran) | |||
} | |||
/** | |||
* 获取一个仓库的全部对象 | |||
* @param {string} storeName 对象仓库名称 | |||
* @param {object} query 查询条件 | |||
* @param {IDBTransaction} tran 事务,可以为 null | |||
* @returns | |||
*/ | |||
listPager (storeName, query = {}, tran = null) { | |||
return _listPager(this, storeName, query, tran) | |||
} | |||
} |
@@ -0,0 +1,149 @@ | |||
import { reactive } from 'vue' | |||
// 引入 indexedDB 的help | |||
import IndexedDB from './help.js' | |||
/** | |||
* 对 indexedDB 的 help 进行初始化 | |||
*/ | |||
export default { | |||
_indexedDBFlag: Symbol('nf-indexedDB-help'), | |||
_help: {}, // 访问数据库的实例 | |||
_stores: {}, // 存放对象,实现 foo.addModel(obj)的功能 | |||
/** | |||
* 根据参数创建一个数据库的实例,初始化数据库 | |||
* * 删表、建表、添加默认数据 | |||
* @param {*} info 参数 | |||
* @returns | |||
* * dbFlag: '数据库标识,区分多个数据库', | |||
* * dbConfig: { // 连接数据库 | |||
* * * dbName: 'vite2-blog', | |||
* * * ver: 1.0 | |||
* * }, | |||
* * init: () => {}, // 初始化完成后的回调函数 | |||
* * stores: { | |||
* * * storeName: { // 对象仓库名 | |||
* * * * id: 'id', // 主键名称 | |||
* * * * index: { | |||
* * * * * name: ture, // 索引:是否可以重复 | |||
* * * * }, | |||
* * * * isDeleteOldTable: false, // 是否删除之前的对象仓库 | |||
* * * } | |||
* * } | |||
*/ | |||
createHelp (info) { | |||
const indexedDBFlag = typeof info.dbFlag === 'undefined' ? | |||
this._indexedDBFlag : info.dbFlag | |||
// 连接数据库,获得实例。 | |||
const help = new IndexedDB(info) | |||
const __stores = {} | |||
// 存入静态对象,以便于支持保存多个不同的实例。 | |||
this._help[indexedDBFlag] = help // help | |||
this._stores[indexedDBFlag] = __stores // 仓库变对象 | |||
help._stores = __stores // 挂到 help 上面 | |||
// 把仓库变成对象的形式,避免写字符串的仓库名称 | |||
for (const key in info.stores) { | |||
__stores[key] = { | |||
add: (obj, tran = null) => help.addModel(key, obj, tran), | |||
get: (id = null, tran = null) => help.getModel(key, id, tran), | |||
count: (tran = null) => help.getCount(key, tran), | |||
put: (obj, tran = null) => { | |||
let _id = obj | |||
if (typeof obj === 'object') { | |||
_id = obj[info.stores[key].id] | |||
} | |||
return help.putModel(key, obj, _id, tran) | |||
}, | |||
set: (obj, tran = null) => { | |||
let _id = obj | |||
if (typeof obj === 'object') { | |||
_id = obj[info.stores[key].id] | |||
} | |||
return help.setModel(key, obj, _id, tran) | |||
}, | |||
del: (obj, tran = null) => { | |||
let _id = obj | |||
if (typeof obj === 'object') { | |||
_id = obj[info.stores[key].id] | |||
} | |||
return help.delModel(key, _id, tran) | |||
}, | |||
list: (query = {}, tran = null) => help.getList(key, query, tran), | |||
begin: () => help.beginWrite(key), | |||
beginWrite: () => help.beginWrite(key), | |||
beginReadonly: () => help.beginReadonly(key), | |||
// 给model 加上增删改查的函数 | |||
createModel: (model) => { | |||
class MyModel { | |||
constructor (_model) { | |||
for (const key in _model) { | |||
this[key] = _model[key] | |||
} | |||
} | |||
/** | |||
* 添加对象 | |||
* @param {*} tran 事务,可以为 null | |||
* @returns | |||
*/ | |||
add(tran = null) { | |||
return help.addModel(key, this, tran) | |||
} | |||
/** | |||
* 保存对象,无则添加、有则修改 | |||
* @param {*} tran 事务,可以为 null | |||
* @returns | |||
*/ | |||
save(tran = null) { | |||
const _id = this[info.stores[key].id] | |||
return help.setModel(key, this, _id, tran) | |||
} | |||
/** | |||
* 加载对象,获取对象 | |||
* @param {*} tran 事务,可以为 null | |||
*/ | |||
load(tran = null) { | |||
return new Promise((resolve, reject) => { | |||
// 套个娃 | |||
const _id = this[info.stores[key].id] | |||
help.getModel(key, _id, tran).then((res) => { | |||
Object.assign(this, res) | |||
resolve(res) | |||
}) | |||
}) | |||
} | |||
/** | |||
* 删除对象 | |||
* @param {*} tran 事务,可以为 null | |||
* @returns | |||
*/ | |||
del(tran = null) { | |||
const _id = this[info.stores[key].id] | |||
return help.delModel(key, _id, tran) | |||
} | |||
} | |||
const re = new MyModel(model) | |||
return reactive(re) | |||
} | |||
} | |||
} | |||
return help | |||
}, | |||
// 获取静态对象里的数据库实例 | |||
useDBHelp (_dbFlag) { | |||
const flag = typeof _dbFlag === 'undefined' ? | |||
this._indexedDBFlag : _dbFlag | |||
return this._help[flag] | |||
}, | |||
useStores (_dbFlag) { | |||
const flag = typeof _dbFlag === 'undefined' ? | |||
this._indexedDBFlag : _dbFlag | |||
return this._stores[flag] | |||
} | |||
} |
@@ -0,0 +1,101 @@ | |||
/** | |||
* 不分页获取数据,可以查询 | |||
* @param { dbHelp } help 访问数据库的实例 | |||
* @param { Object } storeName 对象仓库 | |||
* @param { Object } findInfo 查询条件 | |||
* @param { Object } pager 排序字段 | |||
* @returns 添加记录的ID | |||
* * findInfo 结构(查询条件): | |||
* * * { colName: [401, 11] } 字段名称,查询方式,查询关键字 | |||
* * pager 结构: | |||
* * * orderBy: { id: false } // 排序字段:字段名,false表示倒序。 | |||
*/ | |||
const getList = (help, storeName, findInfo = {}, pager = {}) => { | |||
const _start = page.start || 0 | |||
const _count = page.count || 0 | |||
const _end = _start + _count | |||
const _description = pager.description || 'prev' // 默认倒序 | |||
// 查询条件,按照主键或者索引查询 | |||
let keyRange = null | |||
if (typeof findInfo.indexName !== 'undefined') { | |||
if (typeof findInfo.indexKind !== 'undefined') { | |||
const id = findInfo.indexValue | |||
const dicRange = { | |||
'=': IDBKeyRange.only(id), | |||
'>': IDBKeyRange.lowerBound(id, true), | |||
'>=': IDBKeyRange.lowerBound(id), | |||
'<': IDBKeyRange.upperBound(id, true), | |||
'<=': IDBKeyRange.upperBound(id) | |||
} | |||
const betweenInfo = findInfo.betweenInfo | |||
switch (findInfo.indexKind) { | |||
case '=': | |||
case '>': | |||
case '>=': | |||
case '<': | |||
case '<=': | |||
keyRange = dicRange[findInfo.indexKind] | |||
break | |||
case 'between': | |||
keyRange = IDBKeyRange.bound(betweenInfo.v1, betweenInfo.v2, betweenInfo.v1isClose, betweenInfo.v2isClose) | |||
break | |||
} | |||
} | |||
} | |||
console.log('findObject - keyRange', keyRange) | |||
return new Promise((resolve, reject) => { | |||
const _getList = (__tran) => { | |||
const store = tranRequest.objectStore(storeName) | |||
let cursorRequest | |||
// 打开游标 | |||
cursorRequest = store.openCursor(keyRange, _description) | |||
// 使用游标查询对象并且返回 | |||
cursorRequest.onsuccess = (event) => { | |||
const cursor = event.target.result | |||
if (cursor) { | |||
if (_end === 0 || (cursorIndex >= _start && cursorIndex < _end)) { | |||
// 判断钩子函数 | |||
if (typeof findInfo.where === 'function') { | |||
if (findInfo.where(cursor.value, cursorIndex)) { | |||
dataList.push(cursor.value) | |||
cursorIndex++ | |||
} | |||
} else { // 没有设置查询条件 | |||
dataList.push(cursor.value) | |||
cursorIndex++ | |||
} | |||
} | |||
cursor.continue() | |||
} | |||
// tranRequest.commit() | |||
} | |||
tranRequest.oncomplete = (event) => { | |||
if (config.debug) { | |||
console.log('findObjectByIndex - dataList', dataList) | |||
} | |||
resolve(dataList) | |||
} | |||
tranRequest.onerror = (event) => { | |||
console.log('findObjectByIndex - onerror', event) | |||
reject(event) | |||
} | |||
} | |||
// 判断数据库是否打开 | |||
if (tranRequest === null) { | |||
// 自己开一个事务 | |||
help.beginReadonly([storeName]).then((tran) => { | |||
_getList(tran) | |||
tran.commit() // 可以快点提交事务,好吧其实也没快。 | |||
}) | |||
} else { | |||
_getList(tranRequest) | |||
} | |||
}) | |||
} | |||
export default getList |
@@ -0,0 +1,60 @@ | |||
import _toIndex from './_toIndex.js' | |||
/** | |||
* 用索引查询数据 | |||
* @param { IndexedDBHelp } help 访问数据库的实例 | |||
* @param { string } storeName 仓库名称(表名) | |||
* @param { Object } query 查询条件 | |||
* * query: { | |||
* * * keyName1: [401, xxx], // 第一个是索引, | |||
* * * keyName2: [402, xxx] // 后面的不算索引 | |||
* * } | |||
* @param { IDBTransaction } tranRequest 如果使用事务的话,需要传递开启事务时创建的连接对象 | |||
* @returns 要获取的对象 | |||
*/ | |||
const getList = (help, storeName, query = {}, tranRequest = null) => { | |||
return new Promise((resolve, reject) => { | |||
// 定义个函数,便于调用 | |||
const _getList = (__tran) => { | |||
const store = __tran.objectStore(storeName) | |||
// 分析查询条件,设置索引和其他条件 | |||
const { range, other, find } = _toIndex(store.indexNames, query) | |||
const keys = Object.keys(query) | |||
// 设置索引的查询条件 | |||
// 打开对象仓库或者索引 ? 不用索引,直接用对象仓库 : 使用索引 | |||
const dbRequest = range === null ? store : store.index(keys[0]) | |||
// // 直接开游标 : // 带条件的开游标 | |||
const cursor = range === null ? dbRequest.openCursor() : dbRequest.openCursor(range) | |||
const arr = [] // 返回的记录集 | |||
let i = 0 | |||
cursor.onsuccess = (event) => { // 打开成功 | |||
const res = event.target.result | |||
console.log('游标:' + i++, res) | |||
if (res) { | |||
// 判断其他查询条件 | |||
if (find(other, res.value)) { | |||
arr.push(res.value) | |||
} | |||
res.continue() // 继续下一个 | |||
} else { | |||
// 没有了 | |||
resolve(arr) // 返回对象 | |||
} | |||
} | |||
} | |||
// 判断数据库是否打开 | |||
if (tranRequest === null) { | |||
// 自己开一个事务 | |||
help.beginReadonly([storeName]).then((tran) => { | |||
_getList(tran) | |||
// tran.commit() // 可以快点提交事务,好吧其实也没快。 | |||
}) | |||
} else { | |||
_getList(tranRequest) | |||
} | |||
}) | |||
} | |||
export default getList |
@@ -0,0 +1,120 @@ | |||
/** | |||
* 获取分页列表数据 | |||
* @param { IndexedDBHelp } help 访问数据库的实例 | |||
* @param { string } storeName 仓库名称(表名) | |||
* @param { Object } model 对象(数据记录) | |||
* @param { IDBTransaction } tranRequest 如果使用事务的话,需要传递开启事务时创建的连接对象 | |||
* @returns 添加记录的ID | |||
* * meta 结构: | |||
* * * storeName: '', 对象仓库名 | |||
* * info 结构: | |||
* * * find: { | |||
* * * * indexName: 'groupId', | |||
* * * * indexKind: '=', // '>','>=','<','<=','between', | |||
* * * }, | |||
* * * pager: { | |||
* * * * start:开始, | |||
* * * * count:数量, | |||
* * * * description:'next' | |||
* * * * indexValue: 1, | |||
* * * * betweenInfo: { | |||
* * * * * v1:1, | |||
* * * * * v2:2, | |||
* * * * * v1isClose:true, | |||
* * * * * v2isClose:true, | |||
* * * * }, | |||
* * * * where:(object) => { | |||
* * * * * reutrn true/false | |||
* * * * } | |||
* * * } | |||
*/ | |||
export default function pager (help, storeName, info, tranRequest = null) { | |||
const _start = info.pager.start || 0 | |||
const _count = info.pager.count || 0 | |||
const _end = _start + _count | |||
const _description = info.pager.description || 'prev' // 默认倒序 | |||
// 查询条件,按照主键或者索引查询 | |||
let keyRange = null | |||
if (typeof info.find.indexName !== 'undefined') { | |||
if (typeof info.find.indexKind !== 'undefined') { | |||
const id = info.find.indexValue | |||
const dicRange = { | |||
'=': IDBKeyRange.only(id), | |||
'>': IDBKeyRange.lowerBound(id, true), | |||
'>=': IDBKeyRange.lowerBound(id), | |||
'<': IDBKeyRange.upperBound(id, true), | |||
'<=': IDBKeyRange.upperBound(id) | |||
} | |||
const betweenInfo = info.find.betweenInfo || '==' | |||
switch (findInfo.indexKind) { | |||
case '=': | |||
case '>': | |||
case '>=': | |||
case '<': | |||
case '<=': | |||
keyRange = dicRange[findInfo.indexKind] | |||
break | |||
case 'between': | |||
keyRange = IDBKeyRange.bound(betweenInfo.v1, betweenInfo.v2, betweenInfo.v1isClose, betweenInfo.v2isClose) | |||
break | |||
} | |||
} | |||
} | |||
console.log('pager - keyRange', keyRange) | |||
// 定义一个 Promise 的实例 | |||
return new Promise((resolve, reject) => { | |||
const dataList = [] | |||
// 定义个函数,便于调用 | |||
const _pager = (__tran) => { | |||
let cursorIndex = 0 | |||
const store = __tran.objectStore(storeName) | |||
let cursorRequest | |||
// 判断是否索引查询 | |||
if (typeof findInfo.indexName === 'undefined') { | |||
cursorRequest = store.openCursor(keyRange, _description) | |||
} else { | |||
cursorRequest = store | |||
.index(info.find.indexName) | |||
.openCursor(keyRange, _description) | |||
} | |||
cursorRequest.onsuccess = (event) => { | |||
const cursor = event.target.result | |||
if (cursor) { | |||
if (_end === 0 || (cursorIndex >= _start && cursorIndex < _end)) { | |||
// 判断钩子函数 | |||
if (typeof findInfo.where === 'function') { | |||
if (findInfo.where(cursor.value, cursorIndex)) { | |||
dataList.push(cursor.value) | |||
cursorIndex++ | |||
} | |||
} else { // 没有设置查询条件 | |||
dataList.push(cursor.value) | |||
cursorIndex++ | |||
} | |||
} | |||
cursor.continue() | |||
} | |||
// __tran.commit() | |||
} | |||
__tran.oncomplete = (event) => { | |||
if (config.debug) { | |||
console.log('oncomplete - pager - dataList', dataList) | |||
} | |||
resolve(dataList) | |||
} | |||
} | |||
if (tranRequest === null) { | |||
help.beginReadonly([storeName]).then((tran) => { | |||
// 自己开一个事务 | |||
_pager(tran) | |||
}) | |||
} else { | |||
// 使用传递过来的事务 | |||
_pager(tranRequest) | |||
} | |||
}) | |||
} |
@@ -0,0 +1,36 @@ | |||
import _vueToObject from './_toObject.js' | |||
/** | |||
* 添加对象 | |||
* @param { IndexedDBHelp } help 访问数据库的实例 | |||
* @param { string } storeName 仓库名称(表名) | |||
* @param { Object } model 对象(数据记录) | |||
* @param { IDBTransaction } tranRequest 如果使用事务的话,需要传递开启事务时创建的连接对象 | |||
* @returns 新对象的ID | |||
*/ | |||
export default function addModel (help, storeName, model, tranRequest = null) { | |||
console.log('添加对象的 this', this) | |||
// 取对象的原型,便于保存 reactive | |||
const _model = _vueToObject(model) | |||
// 定义一个 Promise 的实例 | |||
return new Promise((resolve, reject) => { | |||
// 定义个函数,便于调用 | |||
const _add = (__tran) => { | |||
__tran | |||
.objectStore(storeName) // 获取store | |||
.add(_model) // 添加对象 | |||
.onsuccess = (event) => { // 成功后的回调 | |||
resolve(event.target.result) // 返回对象的ID | |||
} | |||
} | |||
if (tranRequest === null) { | |||
help.beginWrite([storeName]).then((tran) => { | |||
// 自己开一个事务 | |||
_add(tran) | |||
}) | |||
} else { | |||
// 使用传递过来的事务 | |||
_add(tranRequest) | |||
} | |||
}) | |||
} |
@@ -0,0 +1,35 @@ | |||
/** | |||
* 获取对象 | |||
* @param { IndexedDBHelp } help 访问数据库的实例 | |||
* @param { string } storeName 仓库名称(表名) | |||
* @param { IDBTransaction } tran 如果使用事务的话,需要传递开启事务时创建的连接对象 | |||
* @returns 要获取的对象 | |||
*/ | |||
export default function getCount (help, storeName, tran = null) { | |||
return new Promise((resolve, reject) => { | |||
// 定义个函数,便于调用 | |||
const _getCount = (__tran) => { | |||
const store = __tran.objectStore(storeName) | |||
// console.log('对象仓库--', store) | |||
// 判断是获取一个,还是获取全部 | |||
const dbRequest = store.count() | |||
// console.log('dbRequest--', dbRequest) | |||
dbRequest.onsuccess = (event) => { // 成功后的回调 | |||
// console.log('-- 得到数据 --:', window.performance.now()) | |||
resolve(event.target.result) // 返回对象 | |||
} | |||
} | |||
// 判断数据库是否打开 | |||
if (tran === null) { | |||
// 自己开一个事务 | |||
help.beginReadonly([storeName]).then((tran) => { | |||
_getCount(tran) | |||
tran.commit() // 可以快点提交事务,好吧其实也没快。 | |||
}) | |||
} else { | |||
_getCount(tran) | |||
} | |||
}) | |||
} |
@@ -0,0 +1,33 @@ | |||
/** | |||
* 删除对象 | |||
* @param { IndexedDBHelp } help 访问数据库的实例 | |||
* @param { string } storeName 仓库名称(表名) | |||
* @param { string } id 对象的ID | |||
* @param { IDBTransaction } tranRequest 如果使用事务的话,需要传递开启事务时创建的连接对象 | |||
* @returns 添加记录的ID | |||
* * meta 结构: | |||
* * * tableName: '', 表名 | |||
* * * idKey: 'id', 主键字段名称 | |||
*/ | |||
export default function deleteData (help, storeName, id, tranRequest = null) { | |||
// 定义一个 Promise 的实例 | |||
return new Promise((resolve, reject) => { | |||
// 定义个函数,便于调用 | |||
const _delete = (__tran) => { | |||
__tran | |||
.objectStore(storeName) // 获取store | |||
.delete(id) // 删除一个对象 | |||
.onsuccess = (event) => { // 成功后的回调 | |||
resolve(event.target.result) | |||
} | |||
} | |||
// 判断是否有事务 | |||
if (tranRequest === null) { | |||
help.beginWrite([storeName]).then((tran) => { | |||
_delete(tran) | |||
}) | |||
} else { | |||
_delete(tranRequest) | |||
} | |||
}) | |||
} |
@@ -0,0 +1,36 @@ | |||
/** | |||
* 获取对象 | |||
* @param { IndexedDBHelp } help 访问数据库的实例 | |||
* @param { string } storeName 仓库名称(表名) | |||
* @param { Object } id 对象(提供id) | |||
* @param { IDBTransaction } tranRequest 如果使用事务的话,需要传递开启事务时创建的连接对象 | |||
* @returns 要获取的对象 | |||
*/ | |||
export default function getModel (help, storeName, id = null, tranRequest = null) { | |||
return new Promise((resolve, reject) => { | |||
// 定义个函数,便于调用 | |||
const _getModel = (__tran) => { | |||
const store = __tran.objectStore(storeName) | |||
// console.log('对象仓库--', store) | |||
// 判断是获取一个,还是获取全部 | |||
const dbRequest = id === null ? store.getAll() : store.get(id) | |||
// console.log('dbRequest--', dbRequest) | |||
dbRequest.onsuccess = (event) => { // 成功后的回调 | |||
// console.log('-- 得到数据 --:', window.performance.now()) | |||
resolve(event.target.result) // 返回对象 | |||
} | |||
} | |||
// 判断数据库是否打开 | |||
if (tranRequest === null) { | |||
// 自己开一个事务 | |||
help.beginReadonly([storeName]).then((tran) => { | |||
_getModel(tran) | |||
tran.commit() // 可以快点提交事务,好吧其实也没快。 | |||
}) | |||
} else { | |||
_getModel(tranRequest) | |||
} | |||
}) | |||
} |
@@ -0,0 +1,43 @@ | |||
import _vueToObject from './_toObject.js' | |||
/** | |||
* 修改对象,先依据ID获取对象,然后把model的属性叠加上去,最后put新对象 | |||
* @param { IndexedDBHelp } help 访问数据库的实例 | |||
* @param { string } storeName 仓库名称(表名) | |||
* @param { Object } model 对象(数据记录) | |||
* @param { string } id 对象的ID | |||
* @param { IDBTransaction } tranRequest 如果使用事务的话,需要传递开启事务时创建的连接对象 | |||
* @returns 添加记录的ID | |||
*/ | |||
export default function updateData (help, storeName, model, id, tranRequest = null) { | |||
const _model = _vueToObject(model) | |||
// 定义一个 Promise 的实例 | |||
return new Promise((resolve, reject) => { | |||
// 定义个函数,便于调用 | |||
const _update = (__tran) => { | |||
// 先获取对象,然后修改对象,最后存回去 | |||
const store = __tran.objectStore(storeName) // 获取store | |||
store.get(id) // 获取对象 | |||
.onsuccess = (event) => { // 成功后的回调 | |||
// 从仓库里提取对象,把修改值合并到对象里面。 | |||
const newObject = {} | |||
Object.assign(newObject, event.target.result, _model) | |||
// 修改数据 | |||
store.put(newObject) // 修改对象 | |||
.onsuccess = (event) => { // 成功后的回调 | |||
resolve(event.target.result) | |||
} | |||
} | |||
} | |||
// 判断是否自带事务 | |||
if (tranRequest === null) { | |||
help.beginWrite([storeName]).then((tran) => { | |||
// 自己开一个事务 | |||
_update(tran) | |||
}) | |||
} else { | |||
// 使用传递过来的事务 | |||
_update(tranRequest) | |||
} | |||
}) | |||
} |
@@ -0,0 +1,53 @@ | |||
import _vueToObject from './_toObject.js' | |||
/** | |||
* 添加或者修改对象,先依据ID判断是否有对象,无则添,有则改 | |||
* @param { IndexedDBHelp } help 访问数据库的实例 | |||
* @param { string } storeName 仓库名称(表名) | |||
* @param { Object } model 对象(数据记录) | |||
* @param { string } id 对象的ID | |||
* @param { IDBTransaction } tranRequest 如果使用事务的话,需要传递开启事务时创建的连接对象 | |||
* @returns 添加记录的ID | |||
*/ | |||
export default function setData (help, storeName, model, id, tranRequest = null) { | |||
const _model = _vueToObject(model) | |||
// 定义一个 Promise 的实例 | |||
return new Promise((resolve, reject) => { | |||
// 定义个函数,便于调用 | |||
const _set = (__tran) => { | |||
// 先获取对象,然后修改对象,最后存回去 | |||
const store = __tran.objectStore(storeName) // 获取store | |||
store.get(id) // 获取对象 | |||
.onsuccess = (event) => { // 成功后的回调 | |||
// 从仓库里提取对象,把修改值合并到对象里面。 | |||
const res = event.target.result | |||
if (typeof res === 'undefined') { | |||
// 没有对象添加 | |||
store.add(_model) // 添加对象 | |||
.onsuccess = (event) => { // 成功后的回调 | |||
resolve(event.target.result) // 返回对象的ID | |||
} | |||
} else { | |||
// 修改 | |||
const newObject = {} | |||
Object.assign(newObject, event.target.result, _model) | |||
// 修改数据 | |||
store.put(newObject) // 修改对象 | |||
.onsuccess = (event) => { // 成功后的回调 | |||
resolve(event.target.result) | |||
} | |||
} | |||
} | |||
} | |||
// 判断是否自带事务 | |||
if (tranRequest === null) { | |||
help.beginWrite([storeName]).then((tran) => { | |||
// 自己开一个事务 | |||
_set(tran) | |||
}) | |||
} else { | |||
// 使用传递过来的事务 | |||
_set(tranRequest) | |||
} | |||
}) | |||
} |
@@ -0,0 +1,30 @@ | |||
/** | |||
* 清空仓库 store 里的对象 | |||
* @param { IndexedDBHelp } help 访问数据库的实例 | |||
* @param { string } storeName 仓库名称(表名) | |||
* @param { IDBTransaction } tranRequest 如果使用事务的话,需要传递开启事务时创建的连接对象 | |||
* @returns | |||
*/ | |||
export default function deleteStore (help, storeName, tranRequest = null) { | |||
// 定义一个 Promise 的实例 | |||
return new Promise((resolve, reject) => { | |||
// 定义个函数,便于调用 | |||
const _clearStore = (__tran) => { | |||
__tran | |||
.objectStore(storeName) // 获取store | |||
.clear() // 删除store | |||
.onsuccess = (event) => { // 成功后的回调 | |||
resolve(event) // 返回对象的ID | |||
} | |||
} | |||
if (tranRequest === null) { | |||
help.beginWrite([storeName]).then((tran) => { | |||
// 自己开一个事务 | |||
_clearStore(tran) | |||
}) | |||
} else { | |||
// 使用传递过来的事务 | |||
_clearStore(tranRequest) | |||
} | |||
}) | |||
} |
@@ -0,0 +1,34 @@ | |||
/** | |||
* 内部函数,根据分页信息,设置 分页信息和排序字段 | |||
* @param { object } pager 分页和排序 | |||
* @returns order by 和 limit | |||
*/ | |||
const _getPager = (pager) => { | |||
const re = { | |||
orderBy: '', // 分页,可以不设置 | |||
limit: '' // 排序,可以不设置 | |||
} | |||
// 设置分页 order by 和 limit | |||
if (typeof pager !== 'undefined') { | |||
if (typeof pager.pagerIndex !== 'undefined') { | |||
// 用 limit 实现分页 | |||
const _pageSize = pager.pagerSize || 10 | |||
const index = _pageSize * (pager.pagerIndex - 1) | |||
re.limit = ` limit ${index}, ${_pageSize} ` | |||
} | |||
if (typeof pager.orderBy === 'object') { | |||
// 设置排序字段和方式 | |||
const arr = [] | |||
for (const key in pager.orderBy) { | |||
const col = key | |||
const isAsc = pager.orderBy[key] ? ' asc ' : ' desc ' | |||
arr.push(col + ' ' + isAsc) | |||
} | |||
re.orderBy = ` order by ${arr.join(',')}` | |||
} | |||
} | |||
return re | |||
} | |||
export default _getPager |
@@ -0,0 +1,82 @@ | |||
/** | |||
* 内部函数,根据查询条件,拼接查询用的SQL语句,where 后面的部分。 | |||
* @param {object} query 查询条件 | |||
* @returns where 后面的查询语句 | |||
*/ | |||
const _getWhereQuery = (query) => { | |||
// 查询条件 | |||
const findKind = { | |||
// 字符串 | |||
401: ' {col} = ? ', | |||
402: ' {col} <> ? ', | |||
403: ' {col} like ? ', | |||
404: ' {col} not like ? ', | |||
405: ' {col} like ? ', // 起始于 | |||
406: ' {col} like ? ', // 结束于 | |||
// 数字 | |||
411: ' {col} = ? ', | |||
412: ' {col} <> ? ', | |||
413: ' {col} > ? ', | |||
414: ' {col} >= ? ', | |||
415: ' {col} < ? ', | |||
416: ' {col} <= ? ', | |||
417: ' {col} between ? and ? ', | |||
// 日期 | |||
421: ' {col} = ? ', | |||
422: ' {col} <> ? ', | |||
423: ' {col} > ? ', | |||
424: ' {col} >= ? ', | |||
425: ' {col} < ? ', | |||
426: ' {col} <= ? ', | |||
427: ' {col} between ? and ? ', | |||
// 范围 | |||
441: ' {col} in (?)' | |||
} | |||
const _whereCol = [] // 查询字段 | |||
const _whereValue = [] // 查询参数 | |||
// 设置查询条件 | |||
for (const key in query) { | |||
const val = query[key] | |||
if (val[1] === '' || val[1] === null) continue | |||
_whereCol.push(findKind[val[0]].replace('{col}', key)) | |||
switch (val[0]) { | |||
case 403: // like | |||
case 404: // not like | |||
_whereValue.push('%' + val[1] + '%') | |||
break | |||
case 405: // like a% | |||
_whereValue.push(val[1] + '%') | |||
break | |||
case 406: // like %a | |||
_whereValue.push('%' + val[1]) | |||
break | |||
case 417: // between 数字 | |||
case 427: // between 日期 | |||
_whereValue.push(...val[1]) | |||
break | |||
case 441: // in | |||
_whereCol[_whereCol.length - 1] = | |||
_whereCol[_whereCol.length - 1] | |||
.replace('?', val[1].map(a => '?').join(',')) | |||
_whereValue.push(...val[1]) | |||
break | |||
default: | |||
_whereValue.push(val[1]) | |||
break | |||
} | |||
} | |||
const re = { | |||
whereQuery: '', | |||
whereValue: [] | |||
} | |||
// 如果没有查询添加,设置 1=1 占位 | |||
if (_whereCol.length > 0) { | |||
re.whereQuery = ` WHERE ${_whereCol.join(' and ')}`, | |||
re.whereValue = _whereValue | |||
} | |||
return re | |||
} | |||
export default _getWhereQuery |
@@ -0,0 +1,53 @@ | |||
/** | |||
* 实现添加数据的功能。拼接 insert 的 SQL语句 | |||
* @param { MySQLHelp } help 访问数据库的实例 | |||
* @param { Object } meta 表、字段 | |||
* @param { Object } model 数据 | |||
* @param { connection } cn 如果使用事务的话,需要传递开启事务时创建的连接对象 | |||
* @returns 添加记录的ID | |||
* * meta 结构: | |||
* * * tableName: '', 表名 | |||
* * * cols: { colName: '', ...} | |||
* * model 结构: | |||
* * * colName: value | |||
*/ | |||
export default function addData (help, meta, model, cn = null) { | |||
// 拼接添加用的SQL语句, | |||
// 提交SQL语句 | |||
// console.log('addData,开始运行 :') | |||
const myPromise = new Promise((resolve, reject) => { | |||
// 记录字段名称 | |||
const colNames = [] | |||
// 记录字段对应的值 | |||
const colValues = [] | |||
// 记录字段对应的占位符合 | |||
const cols = [] | |||
// 变量对象,记录 key和 value | |||
const colKeys = meta.cols || model | |||
for (const key in colKeys) { | |||
if (key.toLocaleLowerCase() === 'id') continue | |||
colNames.push(key) | |||
// 判断类型 | |||
if (typeof model[key] === 'object') { | |||
colValues.push(JSON.stringify(model[key])) | |||
} else { | |||
colValues.push(model[key]) | |||
} | |||
cols.push('?') | |||
} | |||
const sql = `INSERT INTO ${meta.tableName} ( ${colNames.join(',')} ) VALUES ( ${cols.join(',')} )` | |||
// console.log('insertSQL:', sql) | |||
help.query(sql, colValues, cn) | |||
.then((res) => { | |||
// 成功了,返回给调用者 | |||
resolve(res.insertId) | |||
}) | |||
.catch((err) => { | |||
reject(err) | |||
}) | |||
}) | |||
return myPromise | |||
} |
@@ -0,0 +1,31 @@ | |||
/** | |||
* 实现删除数据的功能。物理删除,delete from | |||
* @param { MySQLHelp } help 访问数据库的实例 | |||
* @param { Object } meta 表、字段 | |||
* @param { number|string } id 主键字段值 | |||
* @param { connection } cn 如果使用事务的话,需要传递开启事务时创建的连接对象 | |||
* @returns 添加记录的ID | |||
* * meta 结构: | |||
* * * tableName: '', 表名 | |||
* * * idKey: 'id', 主键字段名称 | |||
*/ | |||
export default function deleteData (help, meta, id, cn = null) { | |||
// 拼接添加用的SQL语句, | |||
// 提交SQL语句 | |||
// console.log('deleteData,开始运行 :') | |||
const myPromise = new Promise((resolve, reject) => { | |||
const sql = `DELETE FROM ${meta.tableName} WHERE ${meta.idKey}=?` | |||
console.log('sql-----delete:', sql, id) | |||
help.query(sql, [id], cn) | |||
.then((res) => { | |||
// 成功了,返回给调用者 | |||
resolve(res.rowsAffected) | |||
}) | |||
.catch((err) => { | |||
reject(err) | |||
}) | |||
}) | |||
return myPromise | |||
} |
@@ -0,0 +1,32 @@ | |||
/** | |||
* 实现删除数据的功能。逻辑删除,update set flag = 1 | |||
* @param { MySQLHelp } help 访问数据库的实例 | |||
* @param { Object } meta 表、字段 | |||
* @param { number|string } id 主键字段值 | |||
* @param { connection } cn 如果使用事务的话,需要传递开启事务时创建的连接对象 | |||
* @returns 添加记录的ID | |||
* * meta 结构: | |||
* * * tableName: '', 表名 | |||
* * * idKey: 'id', 主键字段名称 | |||
* * * delFlag: 'isDel', 逻辑删除,标记字段名称 | |||
*/ | |||
export default function deleteData (help, meta, id, cn = null) { | |||
// 拼接添加用的SQL语句, | |||
// 提交SQL语句 | |||
// console.log('deleteData,开始运行 :') | |||
const myPromise = new Promise((resolve, reject) => { | |||
const sql = `UPDATE ${meta.tableName} SET ${meta.delFlag} = 1 WHERE ${meta.idKey}=?` | |||
// console.log('sql:', sql) | |||
help.query(sql, [id], cn) | |||
.then((res) => { | |||
// 成功了,返回给调用者 | |||
resolve(res.rowsAffected) | |||
}) | |||
.catch((err) => { | |||
reject(err) | |||
}) | |||
}) | |||
return myPromise | |||
} |
@@ -0,0 +1,31 @@ | |||
/** | |||
* 依据主键字段,获取记录 | |||
* @param { MySQLHelp } help 访问数据库的实例 | |||
* @param { Object } meta 表、字段 | |||
* @param { number|string } id 主键字段值 | |||
* @param { connection } cn 如果使用事务的话,需要传递开启事务时创建的连接对象 | |||
* @returns 添加记录的ID | |||
* * meta 结构: | |||
* * * tableName: '', 表名 | |||
* * * idKey: 'id', 主键字段名称 | |||
*/ | |||
export default function getData (help, meta, id, cn = null) { | |||
// 拼接添加用的SQL语句, | |||
// 提交SQL语句 | |||
// console.log('getData,开始运行 :') | |||
const myPromise = new Promise((resolve, reject) => { | |||
const sql = `SELECT * FROM ${meta.tableName} WHERE ${meta.idKey || 'id'}=?` | |||
// console.log('SELECT -- sql:', sql, id) | |||
help.query(sql, [id], cn) | |||
.then((res) => { | |||
// 成功了,返回给调用者 | |||
resolve(res.rows) | |||
}) | |||
.catch((err) => { | |||
reject(err) | |||
}) | |||
}) | |||
return myPromise | |||
} |
@@ -0,0 +1,54 @@ | |||
import add from './data-add' | |||
import update from './data-update' | |||
/** | |||
* 实现添加/修改数据的功能。没有ID:添加,有ID:修改 | |||
* @param { MySQLHelp } help 访问数据库的实例 | |||
* @param { Object } meta 表、字段 | |||
* @param { Object } model 数据 | |||
* @param { number|string } id 主键字段值 | |||
* @param { connection } cn 如果使用事务的话,需要传递开启事务时创建的连接对象 | |||
* @returns 影响的行数 | |||
* * meta 结构: | |||
* * * tableName: '', 表名 | |||
* * * idKey: 'id', 主键字段名称 | |||
* * model 结构: | |||
* * * colName: value | |||
*/ | |||
export default function updateData (help, meta, model, id, cn = null) { | |||
// 拼接修改用的SQL语句, | |||
// console.log('updateData,开始运行 :') | |||
const myPromise = new Promise((resolve, reject) => { | |||
// 记录字段名称 | |||
const colNames = [] | |||
// 记录字段对应的值 | |||
const colValues = [] | |||
// 变量对象,记录 key和 value | |||
const colKeys = meta.cols || model | |||
for (const key in colKeys) { | |||
colNames.push(key + '=? ') | |||
if (typeof model[key] === 'object') { | |||
colValues.push(JSON.stringify(model[key], null, 2)) | |||
} else { | |||
colValues.push(model[key]) | |||
} | |||
} | |||
// 加入查询条件 | |||
colValues.push(id) | |||
const sql = `SELECT 1 FROM ${meta.tableName} WHERE ${meta.idKey || 'id'}=?` | |||
// console.log('updateSQL:', sql) | |||
help.query(sql, colValues, cn).then((res) => { | |||
add(help, meta, model, id, cn).then((res1) => { | |||
// 成功了,返回给调用者 | |||
resolve(res.rowsAffected) | |||
}) | |||
}).catch((err) => { | |||
reject(err) | |||
}) | |||
}) | |||
return myPromise | |||
} |
@@ -0,0 +1,50 @@ | |||
/** | |||
* 实现修改数据的功能。拼接 update 的 SQL语句 | |||
* @param { MySQLHelp } help 访问数据库的实例 | |||
* @param { Object } meta 表、字段 | |||
* @param { Object } model 数据 | |||
* @param { number|string } id 主键字段值 | |||
* @param { connection } cn 如果使用事务的话,需要传递开启事务时创建的连接对象 | |||
* @returns 影响的行数 | |||
* * meta 结构: | |||
* * * tableName: '', 表名 | |||
* * * idKey: 'id', 主键字段名称 | |||
* * model 结构: | |||
* * * colName: value | |||
*/ | |||
export default function updateData (help, meta, model, id, cn = null) { | |||
// 拼接修改用的SQL语句, | |||
// console.log('updateData,开始运行 :') | |||
const myPromise = new Promise((resolve, reject) => { | |||
// 记录字段名称 | |||
const colNames = [] | |||
// 记录字段对应的值 | |||
const colValues = [] | |||
// 变量对象,记录 key和 value | |||
const colKeys = meta.cols || model | |||
for (const key in colKeys) { | |||
colNames.push(key + '=? ') | |||
if (typeof model[key] === 'object') { | |||
colValues.push(JSON.stringify(model[key], null, 2)) | |||
} else { | |||
colValues.push(model[key]) | |||
} | |||
} | |||
// 加入查询条件 | |||
colValues.push(id) | |||
const sql = `UPDATE ${meta.tableName} SET ${colNames.join(',')} WHERE ${meta.idKey}=?` | |||
// console.log('updateSQL:', sql) | |||
help.query(sql, colValues, cn) | |||
.then((res) => { | |||
// 成功了,返回给调用者 | |||
resolve(res.rowsAffected) | |||
}) | |||
.catch((err) => { | |||
reject(err) | |||
}) | |||
}) | |||
return myPromise | |||
} |
@@ -0,0 +1,28 @@ | |||
/** | |||
* 删除数据库 | |||
* @param { MySQLHelp } help 访问数据库的实例 | |||
* @param { string } dbName 数据库名称 | |||
* @param { connection } cn 如果使用事务的话,需要传递开启事务时创建的连接对象 | |||
* @returns 添加记录的ID | |||
* * meta 结构: | |||
* * * tableName: '', 表名 | |||
* * * idKey: 'id', 主键字段名称 | |||
* * * delFlag: 'isDel', 逻辑删除,标记字段名称 | |||
*/ | |||
export default function deleteTable (help, dbName, cn = null) { | |||
const myPromise = new Promise((resolve, reject) => { | |||
const sql = `DROP database ${dbName} ` | |||
// console.log('sql:', sql) | |||
help.query(sql, [], cn) | |||
.then((res) => { | |||
// 成功了,返回给调用者 | |||
resolve(res) | |||
}) | |||
.catch((err) => { | |||
console.log('deleteDataBase-sql:', sql, err) | |||
reject(err) | |||
}) | |||
}) | |||
return myPromise | |||
} |
@@ -0,0 +1,203 @@ | |||
import _addModel from './data-add.js' // 添加一个对象 | |||
import _updateModel from './data-update.js' // 修改一个对象 | |||
import _getModel from './data-get.js' // 获取一个对象 | |||
import _deleteModel from './data-delete.js' // 删除一个对象 | |||
import _listAll from './list-all.js' // 获取仓库里全部对象 | |||
import _listCount from './list-count.js' // 统计对象数量 | |||
import _listPager from './list-pager.js' // 分页获取对象 | |||
/** | |||
* 基于 promise 封装 webSQL 的基本操作 | |||
* * 创建数据库连接 | |||
* * 提交SQL给数据库执行,得到返回结果 | |||
* * 共用函数 | |||
* * info 结构: | |||
* * * dbName: 'test', // 数据库名称 | |||
* * * ver: '1', // 版本,很重要 | |||
* * * size: '2', // 大小,自动 * 1024 * 1024 | |||
* * * description: '数据库描述' | |||
*/ | |||
export default class MySQLHelp { | |||
constructor (info) { | |||
if (!window.openDatabase) { | |||
console.log('您的浏览器不支持 webSQL') | |||
return | |||
} | |||
// 数据库连接信息 | |||
this._info = { | |||
dbName: info.dbName, | |||
ver: info.ver, | |||
size: info.size, | |||
description: info.infodescription | |||
} | |||
// 打开数据库 | |||
this.db = window.openDatabase( | |||
this._info.dbName, | |||
this._info.ver, | |||
this._info.description, | |||
this._info.size * 1024 * 1024) | |||
// console.log('\n db', this.db.version) | |||
} | |||
/** | |||
* 运行 SQL 语句,带参数,返回执行结果 | |||
* @param { string } sql SQL语句 | |||
* @param { array } param 参数 | |||
* @param { object } tran 参数 | |||
* @returns promise | |||
*/ | |||
query (sql, param = [], tran = null) { | |||
const promise1 = new Promise((resolve, reject) => { | |||
const _query = (tran) => { | |||
tran.executeSql(sql, param, | |||
(tx, results) => { resolve(results) }, | |||
(tx, err) => { | |||
console.log('query - sql:', sql, param, tx, err) | |||
reject(err) | |||
return true // 回滚 | |||
} | |||
) | |||
} | |||
if (tran === null) { | |||
this.begin().then((_tran) => { | |||
_query(_tran) | |||
}) | |||
} else { | |||
_query(tran) | |||
} | |||
}) | |||
return promise1 | |||
} | |||
/** | |||
* 开启一个事务,Promise 的方式 | |||
* @returns Promise 形式 | |||
*/ | |||
begin () { | |||
const myPromise = new Promise((resolve, reject) => { | |||
// 开启一个事务。 | |||
// console.log('★ 开启事务,promise 模式') | |||
this.db.transaction( | |||
(tran) => { resolve(tran) }, | |||
(tx, err) => { reject(err) } | |||
) | |||
}) | |||
return myPromise | |||
} | |||
/** | |||
* 提交一个事务 | |||
* @param { connection } tran 开启事务时创建的连接对象 | |||
* @returns 提交事务 | |||
*/ | |||
commit (tran) { | |||
const myPromise = new Promise((resolve, reject) => { | |||
// 提交事务 | |||
tran.commit((err) => { | |||
if (err) { | |||
console.log('事务提交失败', err) | |||
reject(err) | |||
} else { | |||
resolve() | |||
} | |||
}) | |||
}) | |||
return myPromise | |||
} | |||
/** | |||
* 关闭数据库 | |||
* @param { connection } tran 开启事务时创建的连接对象 | |||
*/ | |||
close (tran = null) { | |||
if (tran !== null) { | |||
// 归还连接对象。console.log('--close: tran', tran.threadId) | |||
tran.release() | |||
// console.log('\n[MySQL 事务,已经关闭数据库:] \n') | |||
} else { | |||
// 关闭连接 | |||
this.db.end((err) => { | |||
if (err) { | |||
console.error('关闭连接发生错误:', err) | |||
} else { | |||
// console.log('\n[MySQL 已经关闭数据库:]\n') | |||
} | |||
}) | |||
} | |||
} | |||
/** | |||
* 添加一条记录 | |||
* @param {string} meta 表名 | |||
* @param {object} model 要添加的记录 | |||
* @param {*} tran 事务,可以为null | |||
* @returns | |||
*/ | |||
addModel (meta, model, tran = null) { | |||
return _addModel(this, meta, model, tran) | |||
} | |||
/** | |||
* 修改一条记录 | |||
* @param {string} meta 表名 | |||
* @param {object} model 要添加的记录 | |||
* @param {*} tran 事务,可以为null | |||
* @returns | |||
*/ | |||
updateModel (meta, model, tran = null) { | |||
return _updateModel(this, meta, model, tran) | |||
} | |||
/** | |||
* 删除一条记录 | |||
* @param {string} tableName 表名 | |||
* @param {object} model 要添加的记录 | |||
* @param {*} tran 事务,可以为null | |||
* @returns | |||
*/ | |||
delModel (meta, model, tran = null) { | |||
return _deleteModel(this, meta, model, tran) | |||
} | |||
/** | |||
* 获取一条记录 | |||
* @param {string} tableName 表名 | |||
* @param {object} model 要添加的记录 | |||
* @param {*} tran 事务,可以为null | |||
* @returns | |||
*/ | |||
getModel (meta, model, tran = null) { | |||
return _getModel(this, meta, model, tran) | |||
} | |||
/** | |||
* 获取全部记录,可以查询 | |||
* @param {string} tableName 表名 | |||
* @param {object} model 要添加的记录 | |||
* @param {*} tran 事务,可以为null | |||
* @returns | |||
*/ | |||
listAll (meta, query, pager = {}, tran = null) { | |||
return _listAll(this, meta, query, pager, tran) | |||
} | |||
/** | |||
* 分页获取记录,可以查询 | |||
* @param {string} tableName 表名 | |||
* @param {object} model 要添加的记录 | |||
* @param {*} tran 事务,可以为null | |||
* @returns | |||
*/ | |||
async listPager (meta, query, pager, _count = 0, tran = null) { | |||
const count = _count === 0 ? await _listCount(this, meta, query, tran) : _count | |||
const list = await _listPager(this, meta, query, pager, tran) | |||
return { | |||
count, | |||
list | |||
} | |||
} | |||
} | |||
MySQLHelp.prototype.add = _addModel |
@@ -0,0 +1,152 @@ | |||
import webSQL from './help.js' | |||
// 维护 | |||
import createTable from './table-create.js' | |||
import deleteTable from './table-delete.js' | |||
export default { | |||
_webSQLFlag: Symbol('nf-webSQL-help'), | |||
_help: {}, // 访问数据库的实例 | |||
_tables: {}, // 把表变成对象 | |||
/** | |||
* 根据参数创建一个数据库的实例,初始化数据库 | |||
* * 删表、建表、添加默认数据 | |||
* @param {*} info 参数 | |||
* @returns 安装一个Vue的插件 | |||
* * dbFlag: '数据库标识', | |||
* * dbConfig: { // 连接数据库 | |||
* * * dbName: 'vite2-blog', | |||
* * * ver: 1.0, | |||
* * * remarks: '测试用的博客数据库', | |||
* * * size: 2 | |||
* * }, | |||
* * init: () => {}, | |||
* * tables: { | |||
* * * tableName: ['字段名称', '字段名称'] | |||
* * }, | |||
* * isDeleteOldTable: false, // 是否删除之前的表 | |||
*/ | |||
createHelp (info) { | |||
let webSQLFlag = this._webSQLFlag | |||
if (typeof info.dbFlag === 'string') { | |||
webSQLFlag = Symbol.for(info.dbFlag) | |||
} else if (typeof info.dbFlag === 'symbol') { | |||
webSQLFlag = info.dbFlag | |||
} | |||
const init = info.init | |||
// const tables = this._tables | |||
// 连接数据库 | |||
// eslint-disable-next-line new-cap | |||
const help = new webSQL(info.dbConfig) | |||
// 遍历配置,设置表的操作。 | |||
// 按照表(对象)的配置信息,设置操作实例 | |||
help.begin().then((cn) => { | |||
for (const key in info.tables) { | |||
const tableName = key | |||
const cols = Object.keys(info.tables[key]) | |||
// 判断要不要删除表 | |||
if (info.isDeleteOldTable) { | |||
// 删除表 | |||
deleteTable(help, tableName, cn) | |||
} | |||
// 建立表 | |||
createTable(help, tableName, cols, cn) | |||
} | |||
}) | |||
this._help[webSQLFlag] = help | |||
const newTable = {} | |||
help._tables = newTable | |||
this._tables[webSQLFlag] = newTable | |||
// 把表变成对象 | |||
for (const key in info.tables) { | |||
const meta = { | |||
tableName: key, | |||
cols: info.tables[key] | |||
} | |||
newTable[meta.tableName] = { | |||
add: (model, cn = null) => help.addModel(meta, model, cn), | |||
get: (id = null, cn = null) => help.getModel(meta, id, cn), | |||
put: (model, cn = null) => { | |||
let _id = model | |||
if (typeof model === 'object') { | |||
_id = model[info.stores[key].id] | |||
} | |||
return help.updateModel(meta, model, _id, cn) | |||
}, | |||
del: (model, cn = null) => { | |||
let _id = model | |||
if (typeof model === 'object') { | |||
_id = model[info.stores[key].id] | |||
} | |||
return help.delModel(meta, _id, cn) | |||
}, | |||
list: (query = {}, isDesc = false, cn = null) => { | |||
const pager = { | |||
orderBy: {} | |||
} | |||
pager.orderBy[Object.keys(meta.cols)[0]] = isDesc | |||
return help.listAll(meta, query, pager, cn) | |||
}, | |||
pager: (query = {}, _pager = null, _count = 0, cn = null) => { | |||
const pager = { | |||
pagerIndex: 1, | |||
pagerSize: 5, | |||
pagerTotal: 100, | |||
orderBy: {} | |||
} | |||
pager.orderBy[Object.keys(meta.cols)[0]] = false | |||
if (_pager !== null){ | |||
Object.assign(pager, _pager) | |||
} | |||
return help.listPager(meta, query, pager, _count, cn) | |||
}, | |||
begin: () => help.begin() | |||
} | |||
} | |||
if (typeof init === 'function') { | |||
init(help, newTable) | |||
} | |||
return { | |||
// 安装插件,不用 provide 注入了 | |||
install (app, options) { | |||
// 注入状态,用 symbol 作为标记,避免重名 | |||
// app.provide(webSQLFlag, { help, tables }) | |||
// 调用初始化,给全局状态赋值 | |||
} | |||
} | |||
}, | |||
// 获取数据库的连接实例 | |||
useSQLHelp (_dbFlag) { | |||
let flag = this._webSQLFlag | |||
if (typeof _dbFlag === 'string') { | |||
flag = Symbol.for(_dbFlag) | |||
} else if (typeof _dbFlag === 'symbol') { | |||
flag = _dbFlag | |||
} | |||
return this._help[flag] | |||
}, | |||
/** | |||
* 把表变成对象,可以直接用表.add/put/del/get等操作 | |||
* @param {*} _dbFlag | |||
* @returns | |||
*/ | |||
useTables (_dbFlag) { | |||
let flag = this._webSQLFlag | |||
if (typeof _dbFlag === 'string') { | |||
flag = Symbol.for(_dbFlag) | |||
} else if (typeof _dbFlag === 'symbol') { | |||
flag = _dbFlag | |||
} | |||
return this._tables[flag] | |||
} | |||
} |
@@ -0,0 +1,48 @@ | |||
import _getWhereQuery from './_where-query.js' | |||
import _getPager from './_pager-info.js' | |||
/** | |||
* 不分页获取数据,可以查询 | |||
* @param { MySQLHelp } help 访问数据库的实例 | |||
* @param { Object } meta 表、字段 | |||
* @param { Object } query 查询条件 | |||
* @param { Object } pager 排序字段 | |||
* @returns 添加记录的ID | |||
* * meta 结构: | |||
* * * tableName: '', 表名 | |||
* * * cols:{colName: '类型'}, 需要显示的字段 | |||
* * query 结构(查询条件): | |||
* * * { colName: [401, 11] } 字段名称,查询方式,查询关键字 | |||
* * pager 结构: | |||
* * * orderBy: { id: false } // 排序字段:字段名,false表示倒序。 | |||
*/ | |||
export default function listAll (help, meta, query, pager, cn = null) { | |||
// console.log('开始获取全部记录 :') | |||
const myPromise = new Promise((resolve, reject) => { | |||
// 查询条件和查询参数 | |||
const { whereQuery, whereValue } = _getWhereQuery(query) | |||
// 设置排序 | |||
const { orderBy } = _getPager(pager) | |||
// 设置显示的字段 | |||
const showCol = Object.keys(meta.cols) | |||
if (showCol.length === 0) { showCol.push('*') } | |||
// 拼接查询语句 | |||
const sql = `SELECT ${showCol.join(',')} FROM ${meta.tableName} ${whereQuery} ${orderBy}` | |||
// console.log('select-all-sql:', sql, whereValue) | |||
help.query(sql, whereValue, cn) | |||
.then((res) => { | |||
// 添加成功 | |||
// console.log('分页获取记录:', res) | |||
resolve(Array.from(res.rows)) | |||
}) | |||
.catch((err) => { | |||
// 出错了 | |||
console.log('获取全部记录失败了:', err) | |||
reject(err) | |||
}) | |||
}) | |||
return myPromise | |||
} |
@@ -0,0 +1,31 @@ | |||
import _getWhereQuery from './_where-query.js' | |||
import _getPager from './_pager-info.js' | |||
/** | |||
* 分页获取数据,可以查询 | |||
* @param { MySQLHelp } help 访问数据库的实例 | |||
* @param { Object } meta 表、字段 | |||
* @param { Object } query 查询条件 | |||
* @returns 添加记录的ID | |||
* * meta 结构: | |||
* * * tableName: '', 表名 | |||
* * * cols:{colName: '类型'}, 需要显示的字段 | |||
* * query 结构(查询条件): | |||
* * * { colName: [401, '查询关键字'] } 字段名称,查询方式,查询关键字 | |||
*/ | |||
export default function getCount (help, meta, query) { | |||
return new Promise((resolve, reject) => { | |||
// 查询条件和查询参数 | |||
const { whereQuery, whereValue } = _getWhereQuery(query) | |||
// 统计总数 | |||
const sql = `SELECT count(1) as count FROM ${meta.tableName} ${whereQuery} ` | |||
console.log('count-sql:', sql, whereValue) | |||
help.query(sql, whereValue).then((re) => { | |||
resolve(re.rows[0].count) | |||
}).catch((err) => { | |||
// 出错了 | |||
console.log('统计总记录数失败了:', err) | |||
reject(err) | |||
}) | |||
}) | |||
} |
@@ -0,0 +1,51 @@ | |||
import _getWhereQuery from './_where-query.js' | |||
import _getPager from './_pager-info.js' | |||
/** | |||
* 分页获取数据,可以查询 | |||
* @param { MySQLHelp } help 访问数据库的实例 | |||
* @param { Object } meta 表、字段 | |||
* @param { Object } query 查询条件 | |||
* @param { Object } pager 数据 | |||
* @returns 添加记录的ID | |||
* * meta 结构: | |||
* * * tableName: '', 表名 | |||
* * * cols:{colName: '类型'}, 需要显示的字段 | |||
* * query 结构(查询条件): | |||
* * * { colName: [401, 11] } 字段名称,查询方式,查询关键字 | |||
* * pager 结构: | |||
* * * pageSize: 20 // 一页显示多少条记录 | |||
* * * orderBy: { id: false } // 排序字段:字段名,false表示倒序。 | |||
* * * pageTotal: 100 // 符合查询条件的总记录数 | |||
* * * pageIndex: 1 // 显示第几页的记录,从 1 开始 | |||
*/ | |||
export default function listPager (help, meta, query, pager) { | |||
// console.log('开始分页 :') | |||
const myPromise = new Promise((resolve, reject) => { | |||
// 查询条件和查询参数 | |||
const { whereQuery, whereValue } = _getWhereQuery(query) | |||
// 设置排序和分页 | |||
const { orderBy, limit } = _getPager(pager) | |||
// 设置显示的字段 | |||
const showCol = Object.keys(meta.cols) | |||
if (showCol.length === 0) { showCol.push('*') } | |||
// 拼接查询语句 | |||
const sql = `SELECT ${showCol.join(',')} FROM ${meta.tableName} ${whereQuery} ${orderBy} ${limit}` | |||
console.log('select-pager-sql:', sql, whereValue) | |||
help.query(sql, whereValue) | |||
.then((res) => { | |||
// 添加成功 | |||
// console.log('分页获取记录:', res) | |||
resolve(Array.from(res.rows)) | |||
}) | |||
.catch((err) => { | |||
// 出错了 | |||
console.log('分页获取记录失败了:', err) | |||
reject(err) | |||
}) | |||
}) | |||
return myPromise | |||
} |
@@ -0,0 +1,40 @@ | |||
/** | |||
* 实现删除数据的功能。逻辑删除,update set flag = 1 | |||
* @param { MySQLHelp } help 访问数据库的实例 | |||
* @param { string } tableName 表名 | |||
* @param { array } cols 字段名集合,数组 | |||
* @param { connection } cn 如果使用事务的话,需要传递开启事务时创建的连接对象 | |||
* @returns 添加记录的ID | |||
* * meta 结构: | |||
* * * tableName: '', 表名 | |||
* * * idKey: 'id', 主键字段名称 | |||
* * * cols: {name: ''}, | |||
*/ | |||
export default function createTable (help, tableName, cols, cn = null) { | |||
const myPromise = new Promise((resolve, reject) => { | |||
// 记录字段名称,不设置类型了。 | |||
let _cols = [] | |||
if (typeof cols.length === 'number') { | |||
_cols = cols | |||
} else { | |||
_cols = Object.keys(cols) | |||
} | |||
_cols = _cols.filter(key => key.toLowerCase() !== 'id') | |||
const sql = `CREATE TABLE IF NOT EXISTS ${tableName} (id INTEGER PRIMARY KEY ASC, ${_cols.join(',')} )` | |||
// console.log('createSQL:', sql) | |||
// 调用事务,建立表 | |||
help.query(sql, [], cn) | |||
.then((res) => { | |||
resolve(res) | |||
}) | |||
.catch((err) => { | |||
console.log('createTable -sql:', sql, err) | |||
const stack = new Error() | |||
console.log('createTable -sql:', stack) | |||
reject(err) | |||
}) | |||
}) | |||
return myPromise | |||
} |
@@ -0,0 +1,28 @@ | |||
/** | |||
* 实现删除数据的功能。逻辑删除,update set flag = 1 | |||
* @param { MySQLHelp } help 访问数据库的实例 | |||
* @param { string } tableName 表名 | |||
* @param { connection } cn 如果使用事务的话,需要传递开启事务时创建的连接对象 | |||
* @returns 添加记录的ID | |||
* * meta 结构: | |||
* * * tableName: '', 表名 | |||
* * * idKey: 'id', 主键字段名称 | |||
* * * delFlag: 'isDel', 逻辑删除,标记字段名称 | |||
*/ | |||
export default function deleteTable (help, tableName, cn = null) { | |||
const myPromise = new Promise((resolve, reject) => { | |||
const sql = `DROP TABLE ${tableName} ` | |||
// console.log('sql:', sql) | |||
help.query(sql, [], cn) | |||
.then((res) => { | |||
// 成功了,返回给调用者 | |||
resolve(res) | |||
}) | |||
.catch((err) => { | |||
console.log('deleteTable - sql:', sql, err) | |||
reject(err) | |||
}) | |||
}) | |||
return myPromise | |||
} |
@@ -0,0 +1,31 @@ | |||
// 引入各种函数,便于做成npm包 | |||
// indexedDB 部分 | |||
import dbHelp from './nf-ws-indexeddb/help.js' | |||
import dbInstall from './nf-ws-indexeddb/install.js' | |||
// webSQL 部分 | |||
import sqlHelp from './nf-ws-websql/help.js' | |||
import sqlInstall from './nf-ws-websql/install.js' | |||
// indexedDB 部分 | |||
const dbCreateHelp = (info) => dbInstall.createHelp(info) | |||
const useDBHelp = (_dbFlag) => dbInstall.useDBHelp(_dbFlag) | |||
const useStores = (_dbFlag) => dbInstall.useStores(_dbFlag) | |||
// webSQL 部分 | |||
const sqlCreateHelp = (info) => sqlInstall.createHelp(info) | |||
const useSQLHelp = (_dbFlag) => sqlInstall.useSQLHelp(_dbFlag) | |||
const useTables = (_dbFlag) => sqlInstall.useTables(_dbFlag) | |||
export { | |||
// webSQL部分 | |||
sqlHelp, | |||
sqlCreateHelp, | |||
useSQLHelp, | |||
useTables, | |||
// indexedDB 部分 | |||
dbHelp, // indexedDB 的help | |||
dbCreateHelp, // 创建help,初始化设置 | |||
useDBHelp, // 组件里获取 help | |||
useStores // 组件里获取对象仓库,方便实现增删改查 | |||
} |
@@ -0,0 +1,126 @@ | |||
const manageStorage = (type) => { | |||
// type --- local: localStorage; | |||
// session:sessionStorage | |||
if (typeof type === 'undefined' || type === '') { type = 'local' } | |||
// 设置值 | |||
const setItem = (key, value) => { | |||
let v = value | |||
// 记录value的类型,默认是对象/数组 | |||
let valueType = typeof value | |||
// 依据类型做序列化 | |||
switch (valueType) { | |||
case 'object': | |||
// 判断是不是日期类型 | |||
if (value === null) { | |||
valueType = 'null' | |||
v = 'null' | |||
} else if (value instanceof Date) { | |||
// 保存数据的时间戳 | |||
valueType = 'date' | |||
v = value.valueOf() | |||
} else { | |||
// 对象、数组 | |||
v = JSON.stringify(value) | |||
} | |||
break | |||
case 'function': | |||
v = value.toString() | |||
break | |||
case 'undefined': | |||
valueType = 'undefined' | |||
v = 'undefined' | |||
break | |||
} | |||
// 把数据、数据类型和时间戳,一起保存 | |||
const object = { | |||
valueType: valueType, | |||
time: new Date().valueOf(), // 时间戳,判断是否过期 | |||
value: v | |||
} | |||
v = JSON.stringify(object) | |||
if (type === 'local') { | |||
localStorage.setItem(key, v) | |||
} else { | |||
sessionStorage.setItem(key, v) | |||
} | |||
} | |||
// 获取值 | |||
const getItem = (key) => { | |||
let str = '' | |||
// 判断存储方式 | |||
if (type === 'local') { | |||
str = localStorage.getItem(key) | |||
} else { | |||
str = sessionStorage.getItem(key) | |||
} | |||
// 判断是否为空 | |||
if (typeof str === 'undefined' || str === null || str === '') { | |||
return str | |||
} | |||
// 判断格式是否符合,没有太好的办法,暂时先这样。 | |||
if (str.indexOf('{"valueType":"') === -1) { | |||
return '' | |||
} | |||
console.log('-----------------------------------------') | |||
console.log('111存储的数据的类型:', typeof str) | |||
console.log('111存储的数据:', str) | |||
// 把存储的数据转换为对象 | |||
const object = JSON.parse(str) | |||
// 取值 | |||
let value = object.value | |||
// 判断存储之前的类型,做转换 | |||
switch (object.valueType) { | |||
case 'object':// 对象和数组 | |||
value = JSON.parse(value) | |||
break | |||
case 'function': // 不做转换 | |||
// value = object.value | |||
break | |||
case 'date': // 日期的时间戳 | |||
value = new Date(value) | |||
break | |||
case 'number': // 数字 | |||
value = parseInt(value) | |||
break | |||
case 'null': | |||
value = null | |||
break | |||
case 'undefined': | |||
value = undefined | |||
break | |||
} | |||
console.log('存储的数据的类型:') | |||
console.log(object.valueType, typeof value) | |||
console.log(object.valueType, Object.prototype.toString.call(value)) | |||
console.log('存储的数据:', value) | |||
return value | |||
} | |||
// removeItem | |||
const removeItem = (key) => { | |||
if (type === 'local') { | |||
localStorage.removeItem(key) | |||
} else { | |||
sessionStorage.removeItem(key) | |||
} | |||
} | |||
// clear | |||
const clear = (key) => { | |||
if (type === 'local') { | |||
localStorage.clear() | |||
} else { | |||
sessionStorage.clear() | |||
} | |||
} | |||
return { | |||
setItem, | |||
getItem, | |||
removeItem, | |||
clear | |||
} | |||
} |
@@ -0,0 +1,452 @@ | |||
// indexedDB.js,浏览器本地数据库操作 | |||
export default { | |||
// indexedDB兼容 | |||
indexedDB: window.indexedDB || window.webkitindexedDB || window.msIndexedDB || mozIndexedDB, | |||
// 打开数据库 | |||
// 新对象储存空间newStore参数:newStore.name、newStore.key | |||
// 新增对象存储空间要更改数据库版本 | |||
openDB: function (dbname, version, db, newStore, callback) { | |||
var version = version; | |||
var request = this.indexedDB.open(dbname, version); | |||
request.onerror = function (event) { | |||
console.log('IndexedDB数据库打开错误'); | |||
}; | |||
request.onsuccess = function (event) { | |||
db = event.target.result; | |||
if (callback && (typeof callback === 'function')) { | |||
callback(db); | |||
} | |||
}; | |||
// onupgradeneeded,调用创建新的储存空间 | |||
request.onupgradeneeded = function (event) { | |||
var db = event.target.result; | |||
if (newStore) { | |||
if (!db.objectStoreNames.contains(newStore.name)) { | |||
var objectStore = db.createObjectStore(newStore.name, { | |||
keyPath: newStore.key, | |||
}); | |||
objectStore.createIndex('counter_index', 'counter', { unique: false }); | |||
objectStore.createIndex('barcode_index', 'barcode', { unique: false }); | |||
objectStore.createIndex('qty_index', 'qty', { unique: false }); | |||
objectStore.createIndex('counter_code', ['counter', 'barcode'], { unique: false }); | |||
} | |||
} | |||
}; | |||
}, | |||
// 删除数据库 | |||
deleteDB: function (dbname, callback) { | |||
var deleteQuest = this.indexedDB.deleteDatabase(dbname); | |||
deleteQuest.onerror = function () { | |||
console.log('删除数据库出错'); | |||
}; | |||
deleteQuest.onsuccess = function () { | |||
if (callback && (typeof callback === 'function')) { | |||
callback(); | |||
} | |||
} | |||
}, | |||
// 关闭数据库 | |||
closeDB: function (dbname) { | |||
dbname.close(); | |||
console.log('数据库已关闭'); | |||
}, | |||
// 更新旧值,针对输入数量 | |||
putData: function (db, storename, dataArr, callback) { | |||
let mybarcode = ""; | |||
let QTY = ""; | |||
let key = ""; | |||
let counter = ""; | |||
let barcode = ""; | |||
let addtime = ""; | |||
dataArr.forEach(item => { | |||
mybarcode = item.barcode; | |||
QTY = item.qty; | |||
barcode = item.barcode; | |||
counter = item.counter; | |||
key = item.counterCode; | |||
addtime = item.addtime; | |||
}); | |||
this.getdatabycursor(db, storename).then(arr => { | |||
if (arr.length == 0) { | |||
//console.log("添加") | |||
var store = db.transaction(storename, 'readwrite').objectStore(storename), | |||
request; | |||
for (var i = 0, len = dataArr.length; i < len; i++) { | |||
request = store.put(dataArr[i]); | |||
request.onerror = function () { | |||
console.error('PUT添加数据报错'); | |||
}; | |||
request.onsuccess = function (result) { | |||
if (callback && (typeof callback === 'function')) { | |||
callback(); | |||
} | |||
}; | |||
} | |||
} | |||
else { | |||
this.read(db, storename, counter, barcode).then(x => { | |||
if (x) { | |||
//console.log("最新的值是" + QTY) | |||
this.updateDataByKey(db, storename, key, QTY, addtime).then(x => { | |||
if (callback && (typeof callback === 'function')) { | |||
callback(); | |||
} | |||
}); | |||
} | |||
else { | |||
//console.log("再次添加") | |||
var store = db.transaction(storename, 'readwrite').objectStore(storename), | |||
request; | |||
for (var i = 0, len = dataArr.length; i < len; i++) { | |||
request = store.put(dataArr[i]); | |||
request.onerror = function () { | |||
console.error('PUT添加数据报错'); | |||
}; | |||
request.onsuccess = function (result) { | |||
if (callback && (typeof callback === 'function')) { | |||
callback(); | |||
} | |||
}; | |||
} | |||
} | |||
}) | |||
} | |||
}) | |||
}, | |||
// 更新旧值 | |||
putDatas: function (db, storename, dataArr, callback) { | |||
let mybarcode = ""; | |||
let QTY = ""; | |||
let key = ""; | |||
let counter = ""; | |||
let barcode = ""; | |||
let addtime = ""; | |||
dataArr.forEach(item => { | |||
mybarcode = item.barcode; | |||
QTY = item.qty; | |||
key = item.counterCode; | |||
counter = item.counter; | |||
barcode = item.barcode; | |||
addtime = item.addtime; | |||
}); | |||
this.getdatabycursor(db, storename).then(arr => { | |||
if (arr.length == 0) { | |||
//console.log("添加") | |||
var store = db.transaction(storename, 'readwrite').objectStore(storename), | |||
request; | |||
for (var i = 0, len = dataArr.length; i < len; i++) { | |||
request = store.add(dataArr[i]); | |||
request.onerror = function () { | |||
console.error('PUT添加数据报错'); | |||
}; | |||
request.onsuccess = function (result) { | |||
if (callback && (typeof callback === 'function')) { | |||
callback(); | |||
} | |||
}; | |||
} | |||
} | |||
else { | |||
this.read(db, storename, counter, barcode).then(x => { | |||
if (x) { | |||
this.updateDataByKeys(db, storename, key, addtime).then(x => { | |||
this.getdata(db, storename).then(result => { | |||
if (callback && (typeof callback === 'function')) { | |||
callback(); | |||
} | |||
}); | |||
}); | |||
} | |||
else { | |||
//console.log("再次添加") | |||
//console.log("当前的值是"+barcode) | |||
var store = db.transaction(storename, 'readwrite').objectStore(storename), | |||
request; | |||
for (var i = 0, len = dataArr.length; i < len; i++) { | |||
request = store.add(dataArr[i]); | |||
request.onerror = function () { | |||
console.error('PUT添加数据报错'); | |||
}; | |||
request.onsuccess = function (result) { | |||
if (callback && (typeof callback === 'function')) { | |||
callback(); | |||
} | |||
}; | |||
} | |||
} | |||
}) | |||
} | |||
}) | |||
}, | |||
//根据key修改数量 | |||
updateDataByKey: function (db, storeName, value, QTY, addtime) { | |||
var transaction = db.transaction(storeName, 'readwrite'); | |||
var store = transaction.objectStore(storeName); | |||
var request = store.get(value); | |||
return new Promise((resolve, reject) => { | |||
request.onsuccess = function (e) { | |||
var stocktable = e.target.result; | |||
if (stocktable) { | |||
stocktable.qty = QTY; | |||
stocktable.addtime = addtime; | |||
resolve(store.put(stocktable)); | |||
} | |||
else { | |||
reject(false); | |||
} | |||
}; | |||
}) | |||
}, | |||
updateDataBycode: function (db, storeName, value, QTY) { | |||
var transaction = db.transaction(storeName, 'readwrite'); | |||
var store = transaction.objectStore(storeName); | |||
var request = store.get(value); | |||
return new Promise((resolve, reject) => { | |||
request.onsuccess = function (e) { | |||
var stocktable = e.target.result; | |||
if (stocktable) { | |||
stocktable.qty = QTY; | |||
resolve(store.put(stocktable)); | |||
} | |||
else { | |||
reject(false); | |||
} | |||
}; | |||
}) | |||
}, | |||
//根据key修改数量 | |||
updateDataByKeys: function (db, storeName, value, addtime, callback) { | |||
var transaction = db.transaction(storeName, 'readwrite'); | |||
var store = transaction.objectStore(storeName); | |||
var request = store.get(value); | |||
return new Promise((resolve, reject) => { | |||
//console.log(addtime) | |||
request.onsuccess = function (e) { | |||
var stocktable = e.target.result; | |||
if (stocktable) { | |||
stocktable.qty = QTY ; | |||
stocktable.addtime = addtime; | |||
resolve(store.put(stocktable)); | |||
} | |||
else { | |||
reject(false); | |||
} | |||
}; | |||
}) | |||
}, | |||
// 删除数据 | |||
deleteData: function (db, storename, key, callback) { | |||
var store = db.transaction(storename, 'readwrite').objectStore(storename); | |||
store.delete(key); | |||
if (callback && (typeof callback === 'function')) { | |||
callback(); | |||
} | |||
}, | |||
// 清空数据 | |||
clearData: function (db, storename, callback) { | |||
var store = db.transaction(storename, 'readwrite').objectStore(storename); | |||
store.clear(); | |||
if (callback && (typeof callback === 'function')) { | |||
callback(); | |||
} | |||
}, | |||
// 通过key获取数据 | |||
read: function (db, storeName, counter, barcode) { | |||
var transaction = db.transaction(storeName); | |||
var objectStore = transaction.objectStore(storeName); | |||
var currentdata = [counter, barcode]; | |||
var indexs = objectStore.index('counter_code'); | |||
var request = indexs.openCursor(IDBKeyRange.only(currentdata)); | |||
return new Promise((resolve, reject) => { | |||
request.onsuccess = function (e) { | |||
var cursor = e.target.result; | |||
if (cursor) { | |||
resolve(true); | |||
} | |||
else { | |||
resolve(false); | |||
} | |||
} | |||
}) | |||
}, | |||
// 通过barcode获取数据 | |||
reads: function (db, storeName, values) { | |||
var transaction = db.transaction(storeName); | |||
var objectStore = transaction.objectStore(storeName); | |||
var indexs = objectStore.index('barcode_index'); | |||
var data = []; | |||
var request = indexs.openCursor(IDBKeyRange.only(values)); | |||
return new Promise((resolve, reject) => { | |||
request.onsuccess = function (e) { | |||
var cursor = e.target.result; | |||
if (cursor) { | |||
data.push(cursor.value); | |||
// resolve(data); | |||
cursor.continue(); | |||
} | |||
else { | |||
resolve(data) | |||
} | |||
}; | |||
}) | |||
}, | |||
//根据counter索引查询数据 | |||
getdatabyCounter: function (db, storeName, values) { | |||
var transaction = db.transaction(storeName); | |||
var store = transaction.objectStore(storeName); | |||
var indexs = store.index('counter_index'); | |||
var datas = []; | |||
var request = indexs.openCursor(IDBKeyRange.only(values)) | |||
return new Promise((resolve, reject) => { | |||
request.onsuccess = function (e) { | |||
var cursor = e.target.result; | |||
if (cursor) { | |||
datas.push(cursor.value); | |||
cursor.continue(); | |||
} | |||
else { | |||
resolve(datas) | |||
} | |||
} | |||
}) | |||
}, | |||
//根据主键和索引查询 | |||
getAll: function (db, storeName, counter, barcode) { | |||
var transaction = db.transaction(storeName); | |||
var objectStore = transaction.objectStore(storeName); | |||
var counterCode = [counter, barcode]; | |||
var indexs = objectStore.index('counter_code'); | |||
var request = indexs.openCursor(IDBKeyRange.only(counterCode)); | |||
var data = []; | |||
return new Promise((resolve, reject) => { | |||
request.onsuccess = function (e) { | |||
var cursor = e.target.result; | |||
if (cursor) { | |||
data.push(cursor.value); | |||
//resolve(data); | |||
cursor.continue(); | |||
} | |||
else { | |||
resolve(data) | |||
} | |||
} | |||
}) | |||
}, | |||
//根据key查询数量是否存在 | |||
getqtyBykey: function (db, storeName, key) { | |||
var transaction = db.transaction(storeName); | |||
var objectStore = transaction.objectStore(storeName); | |||
var request = objectStore.get(key); | |||
request.onerror = function (event) { | |||
console.log('事务失败'); | |||
}; | |||
return new Promise((resolve, reject) => { | |||
request.onsuccess = function (event) { | |||
if (request.result) { | |||
//console.log(request.result.qty) | |||
resolve(request.result); | |||
} else { | |||
resolve(false); | |||
} | |||
}; | |||
}) | |||
}, | |||
// //通过游标遍历数据 | |||
getdatabycursor: function (db, storename) { | |||
var objectStore = db.transaction(storename).objectStore(storename); | |||
var dataList = []; | |||
var i = 0; | |||
return new Promise((resolve, reject) => { | |||
objectStore.openCursor().onsuccess = function (event) { | |||
var cursor = event.target.result; | |||
if (cursor) { | |||
dataList.push(cursor.value) | |||
cursor.continue(); | |||
} else { | |||
resolve(dataList); | |||
} | |||
}; | |||
}) | |||
}, | |||
//查询所有的柜台 | |||
getAllCounter: function (db, storename) { | |||
var transaction = db.transaction(storename); | |||
var store = transaction.objectStore(storename); | |||
var indexs = store.index('counter_index'); | |||
var data = []; | |||
return new Promise((resolve, reject) => { | |||
indexs.openCursor().onsuccess = function (e) { | |||
var cursor = e.target.result; | |||
if (cursor) { | |||
// console.log(cursor.value.counter); | |||
data.push(cursor.value.counter); | |||
resolve(data); | |||
cursor.continue(); | |||
} | |||
} | |||
}) | |||
}, | |||
getdata: function (db, storename) { | |||
var objectStore = db.transaction(storename).objectStore(storename); | |||
var data = []; | |||
return new Promise((resolve, reject) => { | |||
objectStore.openCursor().onsuccess = function (event) { | |||
var cursor = event.target.result; | |||
if (cursor) { | |||
data.push(cursor.value) | |||
resolve(data) | |||
} | |||
else { | |||
reject(false) | |||
} | |||
}; | |||
}) | |||
}, | |||
getqtybyqtyindex: function (db, storename) { | |||
var transaction = db.transaction(storename); | |||
var store = transaction.objectStore(storename); | |||
var indexs = store.index('qty_index'); | |||
var sum = 0; | |||
return new Promise((resolve, reject) => { | |||
indexs.openCursor().onsuccess = function (e) { | |||
var cursor = e.target.result; | |||
if (cursor) { | |||
sum += cursor.value.qty | |||
cursor.continue(); | |||
} | |||
else { | |||
resolve(sum) | |||
} | |||
} | |||
}) | |||
} | |||
} |
@@ -0,0 +1,10 @@ | |||
import Vue from "vue"; | |||
import VueLazyload from "vue-lazyload"; | |||
// https://github.com/hilongjw/vue-lazyload | |||
Vue.use(VueLazyload, { | |||
preLoad: 1.3, | |||
// loading: require("@/assets/ic_photo_loading.png"), | |||
error: require("@/assets/ic_photo_error.png"), | |||
attempt: 3 | |||
}); |
@@ -0,0 +1,16 @@ | |||
import Vue from "vue"; | |||
import { Indicator } from "mint-ui"; | |||
// Mint UI 使用文档: https://mint-ui.github.io/docs/#/zh-cn2 | |||
Vue.component(Indicator); | |||
// import isEmpty from "lodash/isEmpty"; | |||
Vue.prototype.showLoading = function(msg) { | |||
// if (isEmpty(msg)) { | |||
// msg = "加载中..."; | |||
// } | |||
return Indicator.open(msg); | |||
}; | |||
Vue.prototype.hideLoading = function() { | |||
return Indicator.close(); | |||
}; |
@@ -0,0 +1,149 @@ | |||
var websock = null; | |||
let rec; //断线重连后,延迟5秒重新创建WebSocket连接 rec用来存储延迟请求的代码 | |||
let isConnect = false; //连接标识 避免重复连接 | |||
let checkMsg = "heartbeat"; //心跳发送/返回的信息 服务器和客户端收到的信息内容如果如下 就识别为心跳信息 不要做业务处理 | |||
var globalCallback = function() {}; | |||
let createWebSocket = (url) => { | |||
try { | |||
initWebSocket(url); //初始化websocket连接 | |||
} catch (e) { | |||
console.log("尝试创建连接失败"); | |||
reConnect(url); //如果无法连接上webSocket 那么重新连接!可能会因为服务器重新部署,或者短暂断网等导致无法创建连接 | |||
} | |||
}; | |||
//定义重连函数 | |||
let reConnect = (url) => { | |||
console.log("尝试重新连接"); | |||
if (isConnect) return; //如果已经连上就不在重连了 | |||
rec && clearTimeout(rec); | |||
rec = setTimeout(function() { | |||
// 延迟5秒重连 避免过多次过频繁请求重连 | |||
createWebSocket(url); | |||
}, 5000); | |||
}; | |||
//设置关闭连接 | |||
let closeWebSocket = () => { | |||
webSocket.close(); | |||
}; | |||
//心跳设置 | |||
var heartCheck = { | |||
timeout: 20000, //每段时间发送一次心跳包 这里设置为20s | |||
timeoutObj: null, //延时发送消息对象(启动心跳新建这个对象,收到消息后重置对象) | |||
start: function() { | |||
this.timeoutObj = setTimeout(function() { | |||
if (isConnect) websock.send(checkMsg); | |||
}, this.timeout); | |||
}, | |||
reset: function() { | |||
clearTimeout(this.timeoutObj); | |||
this.start(); | |||
} | |||
}; | |||
// 初始化websocket | |||
function initWebSocket(ws) { | |||
// ws地址 -->这里是你的请求路径 | |||
websock = new WebSocket(ws); | |||
websock.onmessage = function(e) { | |||
websocketonmessage(e); | |||
}; | |||
websock.onclose = function(e) { | |||
websocketclose(e); | |||
}; | |||
websock.onopen = function() { | |||
websocketOpen(); | |||
// heartCheck.start(); | |||
}; | |||
// 连接发生错误的回调方法 | |||
websock.onerror = function() { | |||
console.log("WebSocket连接发生错误"); | |||
isConnect = false; //连接断开修改标识 | |||
reConnect(ws); //连接错误 需要重连 | |||
}; | |||
return websock; | |||
} | |||
// 实际调用的方法 | |||
function sendSock(agentData, callback) { | |||
globalCallback = callback; | |||
// console.log(globalCallback) | |||
if (websock.readyState === websock.OPEN) { | |||
// 若是ws开启状态 | |||
websocketsend(agentData); | |||
} else if (websock.readyState === websock.CONNECTING) { | |||
// 若是 正在开启状态,则等待1s后重新调用 | |||
setTimeout(function() { | |||
sendSock(agentData, callback); | |||
}, 1000); | |||
} else { | |||
// 若未开启 ,则等待1s后重新调用 | |||
setTimeout(function() { | |||
sendSock(agentData, callback); | |||
}, 1000); | |||
} | |||
} | |||
function getSock(callback) { | |||
globalCallback = callback; | |||
} | |||
// 数据接收 | |||
function websocketonmessage(e) { | |||
console.log(e.data); | |||
let O_o = JSON.parse(decodeUnicode(e.data)); | |||
if (!O_o) { | |||
heartCheck.reset(); | |||
} else { | |||
if (O_o.msg == "open success") { | |||
sessionStorage.setItem("wid", O_o.wid); | |||
} else { | |||
console.log(O_o); | |||
globalCallback(O_o); | |||
} | |||
} | |||
// globalCallback(JSON.parse(e.data)) | |||
function decodeUnicode(str) { | |||
str = str.replace(/\\/g, "%"); | |||
//转换中文 | |||
str = unescape(str); | |||
//将其他受影响的转换回原来 | |||
str = str.replace(/%/g, "\\"); | |||
//对网址的链接进行处理 | |||
str = str.replace(/\\/g, ""); | |||
return str; | |||
} | |||
} | |||
// 数据发送 | |||
function websocketsend(agentData) { | |||
console.log(JSON.stringify(agentData)); | |||
websock.send(JSON.stringify(agentData)); | |||
} | |||
// 关闭 | |||
function websocketclose(e) { | |||
console.log(e); | |||
isConnect = false; //断开后修改标识 | |||
console.log("connection closed (" + e.code + ")"); | |||
let url = e.currentTarget.url; | |||
reConnect(url); | |||
} | |||
// 创建 websocket 连接 | |||
function websocketOpen(e) { | |||
isConnect = true; | |||
console.log("连接成功"); | |||
} | |||
// initWebSocket(); | |||
// 将方法暴露出去 | |||
export { initWebSocket, sendSock, getSock, createWebSocket, closeWebSocket }; |
@@ -0,0 +1,134 @@ | |||
import axios from "axios"; | |||
import Cloudia from "../api/cloudia-sdk-v1.4.1"; | |||
import Vue from "vue"; | |||
let retry = 2; | |||
let retryDelay = 1000; | |||
class AxiosRequest { | |||
constructor(baseUrl, isDebuggable) { | |||
this.isDebuggable = isDebuggable; | |||
this.instance = axios.create({ | |||
baseURL: baseUrl, | |||
timeout: 10000, // 10s as default | |||
withCredentials: true, | |||
headers: { | |||
"Content-Type": "application/x-www-form-urlencoded;charset=UTF-8" | |||
} | |||
}); | |||
this.interceptors(); | |||
} | |||
get(url, params) { | |||
return this.request({ | |||
method: "get", | |||
url: url, | |||
params: params | |||
}); | |||
} | |||
post(url, params) { | |||
return this.request({ | |||
method: "post", | |||
url: url, | |||
headers: { | |||
"Content-Type": "application/json;charset=UTF-8" | |||
}, | |||
data: params | |||
}); | |||
} | |||
postForm(url, params) { | |||
return this.request({ | |||
method: "post", | |||
url: url, | |||
data: params, | |||
transformRequest: [ | |||
function(data) { | |||
let ret = ""; | |||
for (const it in data) { | |||
ret += encodeURIComponent(it) + "=" + encodeURIComponent(data[it]) + "&"; | |||
} | |||
return ret; | |||
} | |||
] | |||
}); | |||
} | |||
postFile(url, params) { | |||
return this.request({ | |||
method: "post", | |||
url: url, | |||
headers: { | |||
"Content-Type": "multipart/form-data" | |||
}, | |||
data: params, | |||
transformRequest: [ | |||
function(data) { | |||
const formData = new FormData(); | |||
for (const item in data) { | |||
formData.append(item, data[item]); | |||
} | |||
return formData; | |||
} | |||
] | |||
}); | |||
} | |||
request(options) { | |||
return this.instance(options); | |||
} | |||
interceptors() { | |||
let that = this; | |||
this.instance.interceptors.response.use( | |||
(res) => { | |||
const { data, status } = res; | |||
if (status > 200 && status < 400) { | |||
if (this.isDebuggable) { | |||
Cloudia.showToast(`http code: ${status}`); | |||
} | |||
} else if (status !== 200) { | |||
if (this.isDebuggable) { | |||
Cloudia.showToast(`http code: ${status}`); | |||
} else { | |||
console.error(`http error, code: ${status}`); | |||
Cloudia.showToast("请检查网络连接是否正常,稍后重试!"); | |||
} | |||
} | |||
if (data.resultInfo && data.resultInfo.resultCode !== "200") { | |||
Cloudia.showToast(`request error: ${data.resultInfo.resultMsg} (${data.resultInfo.resultCode})`); | |||
} | |||
return data; | |||
}, | |||
(error) => { | |||
Cloudia.showToast("请检查网络连接是否正常,稍后重试!"); | |||
console.error("网络加载失败"); | |||
var config = error.config; | |||
config.__retryCount = config.__retryCount || 0; | |||
if (config.__retryCount >= retry) { | |||
console.error("网络请求重试结束:" + config.__retryCount); | |||
Vue.prototype.hideLoading(); | |||
// Reject with the error | |||
return Promise.reject(error); | |||
} | |||
// Increase the retry count | |||
config.__retryCount += 1; | |||
console.error("网络请求开始重试:" + config.__retryCount); | |||
// Create new promise to handle exponential backoff | |||
return new Promise(function(resolve) { | |||
setTimeout(function() { | |||
resolve(); | |||
}, retryDelay); | |||
}).then(function() { | |||
return that.request(config); | |||
}); | |||
} | |||
); | |||
} | |||
} | |||
export default AxiosRequest; |
@@ -0,0 +1,41 @@ | |||
import request from "./request"; | |||
// https://{host-name}/api/apilist?api=Weather | |||
// location - 城市 | |||
// startTime - 2019-05-09/2019-05-09 12:00 | |||
// endTime - 2019-05-12/2019-05-12 12:00 | |||
// lang - Optional, en/cn/jp | |||
export const getWeatherDaily = (location, startTime, endTime, lang = "cn") => { | |||
console.info( | |||
"request corsapi/weather?api=Weather, params:location=" + | |||
location + | |||
", startTime=" + | |||
startTime + | |||
", endTime=" + | |||
endTime + | |||
", lang=" + | |||
lang | |||
); | |||
return request.get("corsapi/weather?api=WeatherNow", { | |||
location: location, | |||
lang: lang | |||
}); | |||
}; | |||
export const getWeatherWeekly = (location, startTime, endTime, lang = "cn") => { | |||
console.info( | |||
"request corsapi/weather?api=Weather, params:location=" + | |||
location + | |||
", startTime=" + | |||
startTime + | |||
", endTime=" + | |||
endTime + | |||
", lang=" + | |||
lang | |||
); | |||
return request.get("corsapi/weather?api=Weather", { | |||
location: location, | |||
startTime: startTime, | |||
endTime: endTime, | |||
lang: lang | |||
}); | |||
}; |
@@ -0,0 +1,5 @@ | |||
import AxiosRequest from "./axios"; | |||
import config from "@/config"; | |||
const request = new AxiosRequest(config.baseUrl, config.isDebuggable); | |||
export default request; |
@@ -0,0 +1,87 @@ | |||
const { add, query } = require("../db/dbHelp"); | |||
const express = require("express"); | |||
const router = express.Router(); | |||
// 连接数据库 | |||
const jsonWrite = function(res, ret) { | |||
if (typeof ret === "undefined") { | |||
res.json({ | |||
code: "1", | |||
msg: "操作失败" | |||
}); | |||
} else { | |||
res.json(ret); | |||
} | |||
}; | |||
// 接口:增加信息sql,编辑修改信息sql1 | |||
router.post("/save", (req, res) => { | |||
const params = req.body; | |||
console.log(params); | |||
add(params, (result) => { | |||
jsonWrite(res, result); | |||
}); | |||
}); | |||
// 接口:用户管理分页接口查询 | |||
router.get("/getlist", (req, res) => { | |||
const params = req.body; | |||
console.log(params); | |||
query((result) => { | |||
jsonWrite(res, result); | |||
}); | |||
}); | |||
const db = require("../db/mssql"); //注意改路径 | |||
router.get("/ms/detailMD", (req, res) => { | |||
console.log(db.sql); | |||
//根据时间查询的模板 | |||
var count = 0; | |||
var commonResult = []; | |||
db.sql( | |||
"SELECT PassType,count(1) as Count FROM HJ_PersonRecognition WHERE DateDiff(dd,DetectTime,getdate())=0 group by PassType order by PassType", | |||
function(err, result) { | |||
if (err) { | |||
console.log(err); | |||
return; | |||
} | |||
commonResult.push(...result.recordset); | |||
count++; | |||
if (count >= 3) { | |||
res.send(commonResult); | |||
} | |||
} | |||
); | |||
db.sql( | |||
"select 0 as Reserve1, count(1) as cnt from HJ_PersonRecognition as person where person.Reserve1 = '0' and DATEDIFF(DAY, person.DetectTime, GETDATE()) = 0 union select 1 as Reserve1, count(1) as cnt from HJ_PersonRecognition as person where person.Reserve1 = '1' and DATEDIFF(DAY, person.DetectTime, GETDATE()) = 0", | |||
function(err, result) { | |||
if (err) { | |||
console.log(err); | |||
return; | |||
} | |||
commonResult.push(...result.recordset); | |||
count++; | |||
if (count >= 3) { | |||
res.send(commonResult); | |||
} | |||
} | |||
); | |||
db.sql( | |||
"SELECT 0 as online, count(1) as num FROM HJ_EquipInfo WHERE Status = 1 and EquipTypeID = 3 union SELECT 1 as online, count(1) as num FROM HJ_EquipInfo WHERE (Status = 0 or Status = 2) and EquipTypeID = 3", | |||
function(err, result) { | |||
if (err) { | |||
console.log(err); | |||
return; | |||
} | |||
commonResult.push(...result.recordset); | |||
count++; | |||
if (count >= 3) { | |||
res.send(commonResult); | |||
} | |||
} | |||
); | |||
}); | |||
module.exports = router; |
@@ -0,0 +1,21 @@ | |||
import Vue from "vue"; | |||
import VueRouter from "vue-router"; | |||
import ApiDemo from "../views/ApiDemo"; | |||
Vue.use(VueRouter); | |||
const routes = [ | |||
{ | |||
path: "/", | |||
name: "ApiDemo", | |||
component: ApiDemo | |||
} | |||
]; | |||
const router = new VueRouter({ | |||
mode: "history", | |||
base: process.env.BASE_URL, | |||
routes | |||
}); | |||
export default router; |
@@ -0,0 +1,42 @@ | |||
const ws = require("nodejs-websocket"); | |||
console.log("开始建立连接..."); | |||
const socket = ws | |||
.createServer(function(conn) { | |||
let msg = { id: "211", times: 0, name: "王武", tag: "" }; | |||
let intval = setInterval(() => { | |||
if (conn.readyState == 1) { | |||
conn.sendText(JSON.stringify(msg)); | |||
} else { | |||
clearInterval(intval); | |||
} | |||
}, 2000); | |||
conn.on("text", function(str) { | |||
/* console.log("message:" + str); | |||
let msg = { data: { on: 1, face: "hhhh" } }; | |||
// let msg = "你好,这里是是日前端~"; | |||
// let msg = 'websocket处于正常状态' | |||
setInterval(() => { | |||
conn.sendText(JSON.stringify(msg)); | |||
}, 3000);*/ | |||
}); | |||
conn.on("connect", function(code) { | |||
let msg = { data: { on: 1, face: "hhhh" } }; | |||
// let msg = "你好,这里是是日前端~"; | |||
// let msg = 'websocket处于正常状态' | |||
setInterval(() => { | |||
conn.sendText(JSON.stringify(msg)); | |||
}, 3000); | |||
}); | |||
conn.on("close", function(code, reason) { | |||
console.log("关闭连接"); | |||
}); | |||
conn.on("error", function(code, reason) { | |||
console.log("异常关闭", code, reason); | |||
}); | |||
}) | |||
.listen(8666); | |||
console.log("WebSocket建立完毕"); | |||
module.exports = socket; |
@@ -0,0 +1,28 @@ | |||
// node 后端服务器 | |||
const dbRouter = require("../router/dbRouter"); | |||
const bodyParser = require("body-parser"); | |||
const express = require("express"); | |||
const app = express(); | |||
//采用设置所有均可访问的方法解决跨域问题 | |||
app.all("*", function(req, res, next) { | |||
//设置允许跨域的域名,*代表允许任意域名跨域 | |||
res.header("Access-Control-Allow-Origin", "*"); | |||
//允许的header类型 | |||
res.header("Access-Control-Allow-Headers", "content-type"); | |||
//跨域允许的请求方式 | |||
res.header("Access-Control-Allow-Methods", "DELETE,PUT,POST,GET,OPTIONS"); | |||
if (req.method.toLowerCase() == "options") res.send(200); | |||
//让options尝试请求快速结束 | |||
else next(); | |||
}); | |||
// 以json格式返回出去 | |||
app.use(bodyParser.json()); | |||
app.use(bodyParser.urlencoded({ extended: false })); | |||
// 后端api路由 | |||
app.use("/api/db", dbRouter); | |||
// 监听端口 | |||
app.listen(13000); | |||
console.log("success listen at port:13000......"); |
@@ -0,0 +1,24 @@ | |||
$base-width: 540; | |||
$base-height: 976; | |||
$border-radius: 4px; | |||
@function vw($px) { | |||
@return $px / $base-width * 100vw; | |||
} | |||
@function vh($px) { | |||
@return $px / $base-height * 100vh; | |||
} | |||
@function vmax($px) { | |||
@return $px / $base-height * 100vh; | |||
} | |||
@function vmin($px) { | |||
@return $px / $base-width * 100vw; | |||
} | |||
@function rem($px) { | |||
@return $px / $base-width * 100vw; | |||
} |
@@ -0,0 +1,172 @@ | |||
import Config from "../config"; | |||
import axios from "axios"; | |||
import { encrypt } from "./jsencrypt"; | |||
export const genRyts = (callback, err) => { | |||
axios | |||
.get(Config.serverDb + "/api/db/ms/detailMD", {}) | |||
.then((res3) => { | |||
var result = res3.data; | |||
var inNum = 0; | |||
var outNum = 0; | |||
var faceNum = 0; | |||
var cardNum = 0; | |||
var onlineNum = 0; | |||
var offlineNum = 0; | |||
for (var item in result) { | |||
if (result[item]["online"] && result[item]["online"] == 0) { | |||
onlineNum = result[item]["num"]; | |||
} else if (result[item]["online"] && result[item]["online"] == 1) { | |||
offlineNum = result[item]["num"]; | |||
} else if (result[item]["Reserve1"] && result[item]["Reserve1"] == 0) { | |||
inNum = result[item]["cnt"]; | |||
} else if (result[item]["Reserve1"] && result[item]["Reserve1"] == 1) { | |||
outNum = result[item]["cnt"]; | |||
} else if (result[item]["PassType"] && result[item]["PassType"] == 0) { | |||
cardNum = result[item]["Count"]; | |||
} else if (result[item]["PassType"] && result[item]["PassType"] == 1) { | |||
faceNum = result[item]["Count"]; | |||
} | |||
} | |||
/* var str = | |||
"现在为您展示的是人员态势,当前20楼内总人数" + | |||
(inNum - outNum) + | |||
"人,通过首层大堂闸机通行人数" + | |||
(inNum + outNum) + | |||
"人,其中人脸识别" + | |||
faceNum + | |||
"人,刷卡识别" + | |||
cardNum + | |||
"人。";*/ | |||
var str = "已为您打开人员态势"; | |||
//人脸识别面板机、门禁闸机" + | |||
// onlineNum + | |||
// "台在线,在线率100%。 | |||
callback(str); | |||
}) | |||
.catch((res) => { | |||
err(res); | |||
}); | |||
}; | |||
export const genPreRemoteReq = (obj, callback, errCallback) => { | |||
var myHeaders = new Headers(); | |||
myHeaders.append("Content-Type", "application/json"); | |||
myHeaders.append("Cookie", "ASP.NET_SessionId="); | |||
var raw = JSON.stringify({ | |||
username: "adminadmin", | |||
userpwd: | |||
"Og4mnsq5AsZc+RfESX8eC9QS2aa9vEDC8Tp7c8S2ZY+d/BuNeEMoFc5Y9ycMhwWQ/gMsAWPsRaGgAvUt09WzOkdWYzlImrZrLfqa4/B26m7TtAigun5tNHCbpEb/ojjlGNmH4tQbszPwMfV6QFgYj6gAecVPYZQXOt7hdjEHdSQ=", | |||
verificationCode: 2222 | |||
}); | |||
var requestOptions = { | |||
method: "POST", | |||
headers: myHeaders, | |||
body: raw, | |||
redirect: "follow" | |||
}; | |||
// fetch("http://192.168.1.254:8089/api/server/getkey_pc", requestOptions) | |||
fetch("/getKey", requestOptions) | |||
.then((response) => response.text()) | |||
.then((res1) => { | |||
console.log(res1); | |||
res1 = JSON.parse(res1); | |||
console.log(res1); | |||
let resData = res1.HttpData.data; | |||
var myHeaders = new Headers(); | |||
myHeaders.append("Authorization", resData.appkey + "-" + resData.infokey); | |||
myHeaders.append("Referer", Config.serverHj); | |||
myHeaders.append("Content-Type", "application/json"); | |||
myHeaders.append("Cookie", "ASP.NET_SessionId="); | |||
var raw = JSON.stringify({ | |||
data: obj.data | |||
}); | |||
var requestOptions = { | |||
method: "POST", | |||
headers: myHeaders, | |||
body: raw, | |||
redirect: "follow" | |||
}; | |||
// fetch(Config.serverPot + obj.path + "?_r=" + Math.random(), requestOptions) | |||
fetch("/hj" + obj.path + "?_r=" + Math.random(), requestOptions) | |||
// fetch("http://192.168.1.254:8088" + obj.path + "?_r=" + Math.random(), requestOptions) | |||
.then((response) => response.text()) | |||
.then((result) => { | |||
console.log(result); | |||
result = JSON.parse(result); | |||
console.log(result); | |||
callback(result); | |||
}) | |||
.catch((error) => { | |||
console.log("error", error); | |||
errCallback(error); | |||
}); | |||
}) | |||
.catch((error) => console.log("error", error)); | |||
/*axios | |||
.post("http://192.168.1.254:8089/api/server/getkey_pc", { | |||
// .post("/getKey", { | |||
username: Config.username, | |||
userpwd: encrypt(Config.userpwd), | |||
verificationCode: "2222" | |||
}) | |||
.then((res1) => { | |||
let resData = res1.data.HttpData.data; | |||
var myHeaders = new Headers(); | |||
myHeaders.append("Authorization", resData.appkey + "-" + resData.infokey); | |||
myHeaders.append("Referer", Config.serverHj); | |||
myHeaders.append("Content-Type", "application/json"); | |||
myHeaders.append("Cookie", "ASP.NET_SessionId="); | |||
var raw = JSON.stringify({ | |||
data: obj.data | |||
}); | |||
var requestOptions = { | |||
method: "POST", | |||
headers: myHeaders, | |||
body: raw, | |||
redirect: "follow" | |||
}; | |||
// fetch(Config.serverPot + obj.path + "?_r=" + Math.random(), requestOptions) | |||
fetch("http://192.168.1.254:8088" + obj.path + "?_r=" + Math.random(), requestOptions) | |||
.then((response) => response.text()) | |||
.then((result) => { | |||
console.log(result); | |||
result = JSON.parse(result); | |||
console.log(result); | |||
callback(result); | |||
}) | |||
.catch((error) => { | |||
console.log("error", error); | |||
errCallback(error); | |||
}); | |||
}) | |||
.catch((res) => { | |||
errCallback(res); | |||
});*/ | |||
}; | |||
export const genRemoteReq = (resData, obj, callback, errCallback) => { | |||
axios | |||
.post(Config.serverHj + "/api/real/setup_service", obj, { | |||
headers: { Authorization: resData.appkey + "-" + resData.infokey } | |||
}) | |||
.then(() => { | |||
callback(); | |||
}) | |||
.catch((res) => { | |||
errCallback(res); | |||
}); | |||
}; |