index.vue 79 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902190319041905190619071908190919101911191219131914191519161917191819191920192119221923192419251926192719281929193019311932193319341935193619371938193919401941194219431944194519461947194819491950195119521953195419551956195719581959196019611962196319641965196619671968196919701971197219731974197519761977197819791980198119821983198419851986198719881989199019911992199319941995199619971998199920002001200220032004200520062007200820092010201120122013201420152016201720182019202020212022202320242025202620272028202920302031203220332034203520362037203820392040204120422043204420452046204720482049205020512052205320542055205620572058205920602061206220632064206520662067206820692070207120722073207420752076207720782079208020812082208320842085208620872088208920902091209220932094209520962097209820992100210121022103210421052106210721082109211021112112211321142115211621172118211921202121212221232124212521262127212821292130213121322133213421352136213721382139214021412142214321442145214621472148214921502151215221532154215521562157215821592160216121622163216421652166216721682169217021712172217321742175217621772178217921802181218221832184218521862187218821892190219121922193219421952196219721982199220022012202220322042205220622072208220922102211221222132214221522162217221822192220222122222223222422252226222722282229223022312232223322342235223622372238223922402241
  1. <template>
  2. <div class="app-container">
  3. <el-form :model="queryParams" ref="queryForm" size="small" :inline="true" v-show="showSearch" label-width="100px">
  4. <el-form-item label="设备标识ID" prop="deviceId">
  5. <el-input v-model="queryParams.deviceId" placeholder="请输入设备标识ID" clearable @keyup.enter.native="handleQuery" />
  6. </el-form-item>
  7. <el-form-item label="设备型号" prop="deviceModel">
  8. <el-input v-model="queryParams.deviceModel" placeholder="请输入设备型号" clearable @keyup.enter.native="handleQuery" />
  9. </el-form-item>
  10. <el-form-item label="用户姓名" prop="name">
  11. <el-input v-model="queryParams.name" placeholder="请输入用户姓名" clearable @keyup.enter.native="handleQuery" />
  12. </el-form-item>
  13. <el-form-item label="发放方式" prop="grantType">
  14. <el-input v-model="queryParams.grantType" placeholder="请输入发放方式" clearable @keyup.enter.native="handleQuery" />
  15. </el-form-item>
  16. <el-form-item label="在线状态" prop="online_statis">
  17. <el-select v-model="queryParams.online_statis">
  18. <el-option label="离线" :value="0"></el-option>
  19. <el-option label="在线" :value="1"></el-option>
  20. </el-select>
  21. </el-form-item>
  22. <el-form-item label="最后在线时间" prop="offlinetime">
  23. <el-date-picker v-model="queryParams.offlinetime" type="datetime" placeholder="选择日期时间" :editable='false'
  24. value-format="yyyy-MM-dd HH:mm">
  25. </el-date-picker>
  26. </el-form-item>
  27. <el-form-item>
  28. <el-button type="primary" icon="el-icon-search" size="mini" @click="handleQuery">搜索</el-button>
  29. <el-button icon="el-icon-refresh" size="mini" @click="resetQuery">重置</el-button>
  30. </el-form-item>
  31. </el-form>
  32. <el-row :gutter="10" class="mb8">
  33. <el-col :span="1.5">
  34. <el-button type="primary" plain icon="el-icon-plus" size="mini" @click="handleAdd"
  35. v-hasPermi="['system:device:add']">新增</el-button>
  36. </el-col>
  37. <el-col :span="1.5">
  38. <el-button type="success" plain icon="el-icon-edit" size="mini" :disabled="single" @click="handleUpdate"
  39. v-hasPermi="['system:device:edit']">修改</el-button>
  40. </el-col>
  41. <el-col :span="1.5">
  42. <el-button type="danger" plain icon="el-icon-delete" size="mini" :disabled="multiple" @click="handleDelete"
  43. v-hasPermi="['system:device:remove']">删除</el-button>
  44. </el-col>
  45. <el-col :span="1.5">
  46. <el-button type="success" plain icon="el-icon-download" size="mini" @click="handleExport"
  47. v-hasPermi="['system:profile:export']">导出</el-button>
  48. </el-col>
  49. <el-col :span="1.5">
  50. <el-button type="warning" plain icon="el-icon-upload2" size="mini" @click="handleUpload"
  51. v-hasPermi="['system:manage:add']">导入</el-button>
  52. </el-col>
  53. <el-col :span="1.5">
  54. <el-button type="danger" plain icon="el-icon-circle-close" size="mini" @click="closePhone"
  55. v-hasPermi="['system:manage:add']">关闭拨号盘</el-button>
  56. </el-col>
  57. <el-col :span="1.5">
  58. <el-button type="success" plain icon="el-icon-circle-check" size="mini" @click="openPhone"
  59. v-hasPermi="['system:manage:add']">打开拨号盘</el-button>
  60. </el-col>
  61. <right-toolbar :showSearch.sync="showSearch" @queryTable="getList"></right-toolbar>
  62. </el-row>
  63. <el-table v-loading="loading" :data="deviceList" @selection-change="handleSelectionChange">
  64. <el-table-column type="selection" width="55" align="center" />
  65. <el-table-column label="设备标识ID" align="center" prop="deviceId" />
  66. <el-table-column label="设备型号" align="center" prop="deviceType" />
  67. <el-table-column label="SIM卡号" align="center" prop="simCode" />
  68. <el-table-column label="用户姓名" align="center" prop="name" />
  69. <el-table-column label="身份证号码" align="center" prop="sfzid" />
  70. <el-table-column label="手机号" align="center" prop="tel_one" />
  71. <el-table-column label="发放方式" align="center" prop="granttype" />
  72. <el-table-column label="在线状态" align="center" prop="online" />
  73. <el-table-column label="设备电量" align="center" prop="electric_quantity" />
  74. <el-table-column label="最后在线时间" align="center" prop="offlinetime" width="180">
  75. <!-- <template slot-scope="scope">
  76. <span>{{ parseTime(scope.row.createTime, '{y}-{m}-{d}') }}</span>
  77. </template> -->
  78. </el-table-column>
  79. <el-table-column label="操作" align="center" class-name="small-padding fixed-width" width="150px">
  80. <template slot-scope="scope">
  81. <el-button size="mini" type="text" icon="el-icon-edit" @click="handleUpdate(scope.row)"
  82. v-hasPermi="['system:device:edit']">修改</el-button>
  83. <el-button size="mini" type="text" icon="el-icon-delete" @click="handleDelete(scope.row)"
  84. v-hasPermi="['system:device:remove']">删除</el-button>
  85. <el-dropdown trigger="click" @command="openSetting($event, scope.row)">
  86. <span class="el-dropdown-link" style="color: #409EFF;">
  87. 更多<i class="el-icon-arrow-down el-icon--right"></i>
  88. </span>
  89. <el-dropdown-menu slot="dropdown">
  90. <el-dropdown-item command="settingOpen">设备设置</el-dropdown-item>
  91. <el-dropdown-item command="healthInterval">健康阈值设置</el-dropdown-item>
  92. <el-dropdown-item command="fenceOpen">电子围栏</el-dropdown-item>
  93. <el-dropdown-item command="health">健康指标</el-dropdown-item>
  94. <el-dropdown-item command="deviceLog">设备消息日志</el-dropdown-item>
  95. <!-- <el-dropdown-item command="settingLog">设置日志</el-dropdown-item> -->
  96. </el-dropdown-menu>
  97. </el-dropdown>
  98. </template>
  99. </el-table-column>
  100. </el-table>
  101. <pagination v-show="total > 0" :total="total" :page.sync="queryParams.pageNum" :limit.sync="queryParams.pageSize"
  102. @pagination="getList" />
  103. <!-- 添加或修改设备列对话框 -->
  104. <el-dialog :title="title" :visible.sync="open" width="1000px" append-to-body>
  105. <el-form ref="form" :model="form" :rules="rules" label-width="100px">
  106. <el-form-item label="设备属性">
  107. <!-- <el-radio-group v-model="form.deviceProper">
  108. <el-radio v-for="i in deviceAttribute" :key="i.dictValue" :label="i.dictValue">{{ i.dictLabel }}</el-radio>
  109. </el-radio-group> -->
  110. <el-radio v-model="deviceProp" label="1">个人</el-radio>
  111. </el-form-item>
  112. <el-form-item label="用户姓名" prop="name" class="inp">
  113. <el-input v-model="form.name" placeholder="请选择" disabled class="setting-inp">
  114. <el-button slot="append" icon="el-icon-search" @click="toSelect"></el-button>
  115. </el-input>
  116. </el-form-item>
  117. <el-row>
  118. <el-col :span="12">
  119. <el-form-item label="身份证号码" prop="sfzid" class="inp">
  120. <el-input v-model="form.sfzid" placeholder="请输入身份证号码" class="setting-inp" disabled />
  121. </el-form-item>
  122. </el-col>
  123. <el-col :span="12">
  124. <el-form-item label="手机号" prop="telno" class="inp">
  125. <el-input v-model="form.telno" placeholder="请输入手机号" class="setting-inp" disabled />
  126. </el-form-item>
  127. </el-col>
  128. </el-row>
  129. <el-row>
  130. <el-col :span="12">
  131. <el-form-item label="工厂" prop="factory">
  132. <el-select v-model="form.factory" class="setting-inp">
  133. <el-option v-for="i in factoryList" :key="i.dictValue" :value="i.dictValue"
  134. :label="i.dictLabel"></el-option>
  135. </el-select>
  136. </el-form-item>
  137. </el-col>
  138. <el-col :span="12">
  139. <el-form-item label="设备型号" prop="deviceModel">
  140. <el-select v-model="form.deviceModel" class="setting-inp">
  141. <el-option v-for="i in deviceModel" :key="i.dictValue" :value="i.dictValue"
  142. :label="i.dictLabel"></el-option>
  143. </el-select>
  144. </el-form-item>
  145. </el-col>
  146. </el-row>
  147. <el-row>
  148. <el-col :span="12">
  149. <el-form-item label="设备标识ID" prop="deviceId">
  150. <el-input v-model="form.deviceId" type="number" placeholder="请输入设备标识ID" class="setting-inp" />
  151. </el-form-item>
  152. </el-col>
  153. <el-col :span="12">
  154. <el-form-item label="SIM卡号" prop="simCode">
  155. <el-input v-model="form.simCode" type="number" placeholder="请输入SIM卡号" class="setting-inp" />
  156. </el-form-item>
  157. </el-col>
  158. </el-row>
  159. <el-row>
  160. <el-col :span="12">
  161. <el-form-item label="设备序列号" prop="serialNumber">
  162. <el-input v-model="form.serialNumber" placeholder="请输入设备序列号" class="setting-inp" />
  163. </el-form-item>
  164. </el-col>
  165. <el-col :span="12">
  166. <el-form-item label="发放方式" prop="grantType">
  167. <el-radio-group v-model="form.grantType">
  168. <el-radio v-for="i in grantType" :key="i.dictValue" :label="i.dictValue">{{ i.dictLabel }}</el-radio>
  169. </el-radio-group>
  170. </el-form-item>
  171. </el-col>
  172. </el-row>
  173. <template v-if="selectBuy">
  174. <el-row>
  175. <el-col :span="12">
  176. <el-form-item label="销售价格" prop="price">
  177. <el-input v-model="form.price" placeholder="请输入销售价格" class="setting-inp" />
  178. </el-form-item>
  179. </el-col>
  180. <el-col :span="12">
  181. <el-form-item label="服务费用" prop="cost">
  182. <el-input v-model="form.cost" placeholder="请输入服务费用" class="setting-inp" />
  183. </el-form-item>
  184. </el-col>
  185. </el-row>
  186. <el-form-item label="支付方式" prop="payment">
  187. <el-select v-model="form.payment" class="setting-inp">
  188. <el-option v-for="i in payment" :key="i.dictValue" :value="i.dictValue" :label="i.dictLabel"></el-option>
  189. </el-select>
  190. </el-form-item>
  191. </template>
  192. </el-form>
  193. <div slot="footer" class="dialog-footer">
  194. <el-button type="primary" @click="submitForm">确 定</el-button>
  195. <el-button @click="cancel">取 消</el-button>
  196. </div>
  197. </el-dialog>
  198. <el-dialog title="选择用户" :visible.sync="selectUser" width="1200px" append-to-body destroy-on-close>
  199. <el-form :model="userForm" label-width="80px">
  200. <el-row>
  201. <el-col :span="6">
  202. <el-form-item label="姓名" prop="name">
  203. <el-input v-model="userForm.name" class="search-inp"></el-input>
  204. </el-form-item>
  205. </el-col>
  206. <el-col :span="6">
  207. <el-form-item label="手机号" prop="telOne">
  208. <el-input v-model="userForm.telOne" class="search-inp"></el-input>
  209. </el-form-item>
  210. </el-col>
  211. <el-col :span="6">
  212. <el-form-item label="身份证号" prop="sfzid">
  213. <el-input v-model="userForm.telOne" class="search-inp"></el-input>
  214. </el-form-item>
  215. </el-col>
  216. <el-col :span="6">
  217. <el-form-item label="客户类型" prop="telOne">
  218. <el-select v-model="userForm.clientType" class="search-inp">
  219. <el-option v-for="i in clientType" :key="i.dictValue" :value="i.dictValue"
  220. :label="i.dictLabel"></el-option>
  221. </el-select>
  222. </el-form-item>
  223. </el-col>
  224. </el-row>
  225. <el-row>
  226. <!-- <el-col :span="12">
  227. <el-form-item label="家庭住址" prop="telOne">
  228. <el-input v-model="userForm.familyAddress" style="width: 500px;"></el-input>
  229. </el-form-item>
  230. </el-col> -->
  231. <el-col :span="12">
  232. <el-form-item>
  233. <el-button type="primary" icon="el-icon-search" size="mini" @click="searchUser">搜索</el-button>
  234. <el-button icon="el-icon-refresh" size="mini" @click="resetUser">重置</el-button>
  235. </el-form-item>
  236. </el-col>
  237. </el-row>
  238. </el-form>
  239. <el-table :data="userList" v-loading="loading" @selection-change="checkUser">
  240. <el-table-column type="selection" width="55" align="center" />
  241. <el-table-column label="姓名" align="center" prop="name" />
  242. <el-table-column label="性别" align="center" prop="sex" />
  243. <el-table-column label="年龄" align="center" prop="age" />
  244. <el-table-column label="手机号" align="center" prop="telOne" />
  245. <el-table-column label="身份证号" align="center" prop="sfzid" />
  246. <el-table-column label="家庭住址" align="center" prop="familyAddress" />
  247. </el-table>
  248. <pagination v-show="userTotal > 0" :total="userTotal" :page.sync="userForm.pageNum" :limit.sync="userForm.pageSize"
  249. @pagination="getUserList" />
  250. <el-row slot="footer" style="text-align: center;">
  251. <el-button style="width: 120px;margin: 0 30px" @click='checkUserCancel'>取消</el-button>
  252. <el-button type="primary" style="width: 120px;margin: 0 30px" @click='checkUserConfirm'>确定</el-button>
  253. </el-row>
  254. </el-dialog>
  255. <el-dialog title="设备设置" :visible.sync="settingOpen" width="1000px" append-to-body>
  256. <el-row :gutter="20" class="top">
  257. <el-col :span="5">设备ID:{{ setUser.deviceId }}</el-col>
  258. <el-col :span="5">{{ setUser.name }}</el-col>
  259. <el-col :span="5">{{ setUser.telno }}</el-col>
  260. </el-row>
  261. <el-row class="top">
  262. <el-col :span="5">
  263. <el-button type="warning">关机</el-button>
  264. </el-col>
  265. <el-col :span="5">
  266. <el-button type="warning">获取定位</el-button>
  267. </el-col>
  268. <el-col :span="5">
  269. <el-button type="warning">立即测量心率、血压</el-button>
  270. </el-col>
  271. </el-row>
  272. <el-row :gutter="20">
  273. <el-col :span="5">
  274. <el-menu default-active="sos" @select="selectSetting">
  275. <el-menu-item v-for="i in menuInfo" :key="i.dictValue" :index="i.dictValue">{{ i.dictLabel }}</el-menu-item>
  276. </el-menu>
  277. </el-col>
  278. <el-col :span="19">
  279. <el-form v-if="settingPage == 'sos'" label-width="180px" :model="sosForm">
  280. <el-form-item label="联系人1">
  281. <el-input class="setting-inp" v-model="sosForm.tel1"></el-input>
  282. </el-form-item>
  283. <el-form-item label="联系人2">
  284. <el-input class="setting-inp" v-model="sosForm.tel2"></el-input>
  285. </el-form-item>
  286. </el-form>
  287. <el-form v-if="settingPage == 'measureInterval'" label-width="180px" :model="intervalForm">
  288. <el-form-item label="定位间隔(分钟)">
  289. <el-input class="setting-inp" type="number" v-model="intervalForm.cr_interval"></el-input>
  290. </el-form-item>
  291. <el-form-item label="心率间隔(分钟)">
  292. <el-input class="setting-inp" type="number" v-model="intervalForm.hrt_interval"></el-input>
  293. </el-form-item>
  294. <el-form-item label="体温间隔(分钟)">
  295. <el-input class="setting-inp" type="number" v-model="intervalForm.wd_interval"></el-input>
  296. </el-form-item>
  297. <el-form-item label="血压间隔(分钟)">
  298. <el-input class="setting-inp" type="number" v-model="intervalForm.bld_interval"></el-input>
  299. </el-form-item>
  300. <el-form-item label="血氧间隔(分钟)">
  301. <el-input class="setting-inp" type="number" v-model="intervalForm.ox_interval"></el-input>
  302. </el-form-item>
  303. </el-form>
  304. <el-form v-if="settingPage == 'stepCount'" label-width="180px" :model="pedoForm">
  305. <el-form-item label="计步器状态">
  306. <el-switch v-model="pedoForm.isopen" active-value="1" inactive-value="0"></el-switch>
  307. </el-form-item>
  308. </el-form>
  309. <el-form v-if="settingPage == 'contacts'" label-width="100px" :model="telForm">
  310. <el-form-item label="联系人">
  311. <el-row :gutter="20">
  312. <el-col :span="5">
  313. <el-input style="width: 120px;" placeholder="姓名" v-model="telForm.name1"></el-input>
  314. </el-col>
  315. <el-col :span="5">
  316. <el-input class="setting-inp" placeholder="电话" v-model="telForm.tel1"></el-input>
  317. </el-col>
  318. </el-row>
  319. </el-form-item>
  320. <el-form-item label="联系人">
  321. <el-row :gutter="20">
  322. <el-col :span="5">
  323. <el-input style="width: 120px;" placeholder="姓名" v-model="telForm.name2"></el-input>
  324. </el-col>
  325. <el-col :span="5">
  326. <el-input class="setting-inp" placeholder="电话" v-model="telForm.tel2"></el-input>
  327. </el-col>
  328. </el-row>
  329. </el-form-item>
  330. <el-form-item label="联系人">
  331. <el-row :gutter="20">
  332. <el-col :span="5">
  333. <el-input style="width: 120px;" placeholder="姓名" v-model="telForm.name3"></el-input>
  334. </el-col>
  335. <el-col :span="5">
  336. <el-input class="setting-inp" placeholder="电话" v-model="telForm.tel3"></el-input>
  337. </el-col>
  338. </el-row>
  339. </el-form-item>
  340. </el-form>
  341. <el-form v-if="settingPage == 'clock'" label-width="80px" :model="clockForm">
  342. <div class="clock-item" v-for="item in clockList" :key="item.clockId">
  343. <el-form-item label="闹钟名称">
  344. <el-input class="clock-input" v-model="item.clockName"></el-input>
  345. <el-time-picker :editable="false" value-format="HH:mm" placeholder="请选择时间"
  346. v-model="item.time"></el-time-picker>
  347. <el-switch class="clock-switch" v-model="item.isopen"></el-switch>
  348. <el-button type="danger" icon="el-icon-delete" circle @click="deleteClock(item.clockId)"></el-button>
  349. </el-form-item>
  350. <el-form-item label="日期">
  351. <el-checkbox-group v-model="item.weeks">
  352. <el-checkbox v-for="i in clockDate" :key="i.dictValue" :label="i.dictValue">{{ i.dictLabel
  353. }}</el-checkbox>
  354. </el-checkbox-group>
  355. </el-form-item>
  356. </div>
  357. </el-form>
  358. <el-form v-if="settingPage == 'silentTime'" label-width="80px">
  359. <el-form-item label="时间" v-for="item in silentList" :key="item.id" style="margin: 20px 0;">
  360. <el-time-picker is-range :editable="false" v-model="item.timeRange" range-separator="至"
  361. start-placeholder="开始时间" end-placeholder="结束时间" value-format="HH:mm">
  362. </el-time-picker>
  363. <el-button type="danger" style="margin-left: 20px;" icon="el-icon-delete" circle
  364. @click="deleteSilent(item.id)"></el-button>
  365. </el-form-item>
  366. </el-form>
  367. <el-form v-if="settingPage == 'timeOnOff'" label-width="80px" :model="onoffForm">
  368. <el-form-item label="是否使用">
  369. <el-switch v-model="onoffForm.is_open"></el-switch>
  370. </el-form-item>
  371. <el-form-item label="开机时间">
  372. <el-time-picker :editable="false" v-model="onoffForm.bootup_time" value-format="HH:mm">
  373. </el-time-picker>
  374. </el-form-item>
  375. <el-form-item label="关机时间">
  376. <el-time-picker :editable="false" v-model="onoffForm.shutdown_time" value-format="HH:mm">
  377. </el-time-picker>
  378. </el-form-item>
  379. </el-form>
  380. <el-form v-if="settingPage == 'wearNotice'" label-width="120px" :model="wearForm">
  381. <el-form-item label="佩戴提醒状态">
  382. <el-switch v-model="wearForm.is_open"></el-switch>
  383. </el-form-item>
  384. </el-form>
  385. <el-form v-if="settingPage == 'fallNotice'" label-width="120px" :model="fallForm">
  386. <el-form-item label="跌倒提醒状态">
  387. <el-switch v-model="fallForm.is_open"></el-switch>
  388. </el-form-item>
  389. <el-form-item label="跌倒灵敏度">
  390. <el-radio-group v-model="fallForm.lsset_type">
  391. <el-radio v-for="i in sensitivityList" :key="i.dictValue" :value="i.dictValue"
  392. :label="i.dictLabel"></el-radio>
  393. </el-radio-group>
  394. </el-form-item>
  395. </el-form>
  396. <el-form v-if="settingPage == 'intercept'" label-width="120px">
  397. <el-form-item label="陌生人拦截">
  398. <el-switch v-model="intercept"></el-switch>
  399. </el-form-item>
  400. </el-form>
  401. </el-col>
  402. </el-row>
  403. <el-row slot="footer" style="text-align: center;">
  404. <el-button type="success" style="width: 120px;" @click="addList"
  405. v-if="['clock', 'silentTime'].indexOf(settingPage) != -1">新增</el-button>
  406. <el-button style="width: 120px;" @click="resetDeviceInfo">重置</el-button>
  407. <el-button type="primary" style="width: 120px;" @click="setDeviceInfo">保存</el-button>
  408. </el-row>
  409. </el-dialog>
  410. <el-dialog title="健康阈值设置" :visible.sync="healthInterval" width="1000px" append-to-body>
  411. <el-form label-width="100px" :data="deviceInterval">
  412. <el-row>
  413. <el-col :span="12">
  414. <el-form-item label="最大心率">
  415. <el-input v-model="deviceInterval.shouhuan_heart_max"></el-input>
  416. </el-form-item>
  417. </el-col>
  418. <el-col :span="12">
  419. <el-form-item label="最小心率">
  420. <el-input v-model="deviceInterval.shouhuan_heart_min"></el-input>
  421. </el-form-item>
  422. </el-col>
  423. </el-row>
  424. <el-row>
  425. <el-col :span="12">
  426. <el-form-item label="最大高压">
  427. <el-input v-model="deviceInterval.shouhuan_blood_high_max" type="number"></el-input>
  428. </el-form-item>
  429. </el-col>
  430. <el-col :span="12">
  431. <el-form-item label="最小高压">
  432. <el-input v-model="deviceInterval.shouhuan_blood_high_min" type="number"></el-input>
  433. </el-form-item>
  434. </el-col>
  435. </el-row>
  436. <el-row>
  437. <el-col :span="12">
  438. <el-form-item label="最大低压">
  439. <el-input v-model="deviceInterval.shouhuan_blood_low_max" type="number"></el-input>
  440. </el-form-item>
  441. </el-col>
  442. <el-col :span="12">
  443. <el-form-item label="最小低压">
  444. <el-input v-model="deviceInterval.shouhuan_blood_low_min" type="number"></el-input>
  445. </el-form-item>
  446. </el-col>
  447. </el-row>
  448. <el-row>
  449. <el-col :span="12">
  450. <el-form-item label="最大血氧">
  451. <el-input v-model="deviceInterval.shouhuan_oxygen_max" type="number"></el-input>
  452. </el-form-item>
  453. </el-col>
  454. <el-col :span="12">
  455. <el-form-item label="最小血氧">
  456. <el-input v-model="deviceInterval.shouhuan_oxygen_min" type="number"></el-input>
  457. </el-form-item>
  458. </el-col>
  459. </el-row>
  460. <el-row>
  461. <el-col :span="12">
  462. <el-form-item label="最大体温">
  463. <el-input v-model="deviceInterval.shouhuan_body_max" type="number"></el-input>
  464. </el-form-item>
  465. </el-col>
  466. <el-col :span="12">
  467. <el-form-item label="最小体温">
  468. <el-input v-model="deviceInterval.shouhuan_body_min" type="number"></el-input>
  469. </el-form-item>
  470. </el-col>
  471. </el-row>
  472. </el-form>
  473. <el-row slot="footer" style="text-align: center;">
  474. <el-button style="width: 120px;" @click="closeInterval">取消</el-button>
  475. <el-button type="primary" style="width: 120px;" @click="subDeviceInterval">保存</el-button>
  476. </el-row>
  477. </el-dialog>
  478. <el-dialog title='健康指标' :visible.sync="health" width="1000px" append-to-body>
  479. <el-row style="text-align: center;">
  480. <el-radio-group v-model="tab" style="margin:0 auto 30px;text-align: center;" @input="switchTab">
  481. <el-radio-button label="0">心率</el-radio-button>
  482. <el-radio-button label="1">血压</el-radio-button>
  483. <el-radio-button label="2">血氧</el-radio-button>
  484. <el-radio-button label="3">体温</el-radio-button>
  485. <el-radio-button label="4">计步</el-radio-button>
  486. <el-radio-button label="5">睡眠</el-radio-button>
  487. </el-radio-group>
  488. </el-row>
  489. <template v-if="tab == 0">
  490. <el-row>
  491. <div class="echart"></div>
  492. <el-table :data="rateInfo">
  493. <el-table-column label="时间" prop="createtime" align="center"></el-table-column>
  494. <el-table-column label="心率" prop="content" align="center"></el-table-column>
  495. <el-table-column label="操作" prop="" align="center"></el-table-column>
  496. </el-table>
  497. </el-row>
  498. </template>
  499. <template v-if="tab == 1">
  500. <el-row>
  501. <div class="echart"></div>
  502. <el-table :data="rateInfo">
  503. <el-table-column label="时间" prop="createtime" align="center"></el-table-column>
  504. <el-table-column label="舒张压" prop="blood_low_pressure" align="center"></el-table-column>
  505. <el-table-column label="收缩压" prop="blood_height_pressure" align="center"></el-table-column>
  506. <el-table-column label="操作" prop="" align="center"></el-table-column>
  507. </el-table>
  508. </el-row>
  509. </template>
  510. <template v-if="tab == 2">
  511. <el-row>
  512. <div class="echart"></div>
  513. <el-table :data="rateInfo">
  514. <el-table-column label="时间" prop="createtime" align="center"></el-table-column>
  515. <el-table-column label="血氧" prop="content" align="center"></el-table-column>
  516. <el-table-column label="操作" prop="" align="center"></el-table-column>
  517. </el-table>
  518. </el-row>
  519. </template>
  520. <template v-if="tab == 3">
  521. <el-row>
  522. <div class="echart"></div>
  523. <el-table :data="rateInfo">
  524. <el-table-column label="时间" prop="createtime" align="center"></el-table-column>
  525. <el-table-column label="体温" prop="content" align="center"></el-table-column>
  526. <el-table-column label="操作" prop="" align="center"></el-table-column>
  527. </el-table>
  528. </el-row>
  529. </template>
  530. <template v-if="tab == 4">
  531. <el-row>
  532. <div class="echart"></div>
  533. <el-table :data="rateInfo">
  534. <el-table-column label="时间" prop="createtime" align="center"></el-table-column>
  535. <el-table-column label="步数" prop="step_number" align="center"></el-table-column>
  536. <el-table-column label="操作" prop="" align="center"></el-table-column>
  537. </el-table>
  538. </el-row>
  539. </template>
  540. <template v-if="tab == 5">
  541. <el-row>
  542. <div class="echart"></div>
  543. <el-table :data="rateInfo">
  544. <el-table-column label="时间" prop="createtime" align="center"></el-table-column>
  545. <el-table-column label="翻滚次数" prop="roll_number" align="center"></el-table-column>
  546. <el-table-column label="操作" prop="" align="center"></el-table-column>
  547. </el-table>
  548. </el-row>
  549. </template>
  550. <pagination v-show="rateTotal > 0" :total="rateTotal" :page.sync="echartsQuery.pageNum"
  551. :limit.sync="echartsQuery.pageSize" @pagination="setEcharts(tab)" />
  552. </el-dialog>
  553. <el-dialog title="设备消息日志" :visible.sync="deviceLog" width="1000px" append-to-body>
  554. <el-table :data="deviceLogList">
  555. <!-- <el-table-column label="序号" prop=""></el-table-column> -->
  556. <el-table-column label="设备ID" prop="device_id"></el-table-column>
  557. <el-table-column label="用户姓名" prop="name"></el-table-column>
  558. <el-table-column label="测量时间" prop="createtime"></el-table-column>
  559. <el-table-column label="消息类型" prop="describe"></el-table-column>
  560. <!-- <el-table-column label="开始时间" prop=""></el-table-column>
  561. <el-table-column label="结束时间" prop=""></el-table-column>
  562. <el-table-column label="持续时间(分钟)" prop=""></el-table-column>
  563. <el-table-column label="说明" prop=""></el-table-column> -->
  564. </el-table>
  565. <pagination v-show="logTotal > 0" :total="logTotal" :page.sync="logQuery.pageNum" :limit.sync="logQuery.pageSize"
  566. @pagination="getDeviceLog" />
  567. </el-dialog>
  568. <el-dialog title="电子围栏" :visible.sync="fenceOpen" width="1200px" :before-close="beforeClose" destroy-on-close
  569. :close-on-click-modal="false">
  570. <div id="map">
  571. <el-row class="map-tool">
  572. <el-select size="mini" v-model="fenceName" @change="selectFence">
  573. <el-option v-for="item in fenceList" :key="item.name" :label="item.name" :value="item.name"></el-option>
  574. </el-select>
  575. <el-button size="mini" type="primary" style="margin-left: 10px;" @click="editAdd">新增</el-button>
  576. <el-button size="mini" type="warning" @click="editUpdate">修改</el-button>
  577. <el-button size="mini" type="danger" @click="editDelete">删除</el-button>
  578. </el-row>
  579. <el-form class="update-tool" :model="fenceInfo" label-width="70px" size="mini" v-show="fenceEdit">
  580. <el-form-item label="围栏名称">
  581. <el-input size="mini" v-model="fenceInfo.name"></el-input>
  582. </el-form-item>
  583. <el-form-item label="开始时间">
  584. <el-time-picker v-model="fenceInfo.start_time" value-format="timestamp" placeholder="选择日期时间">
  585. </el-time-picker>
  586. </el-form-item>
  587. <el-form-item label="结束时间">
  588. <el-time-picker v-model="fenceInfo.end_time" value-format="timestamp" placeholder="选择日期时间">
  589. </el-time-picker>
  590. </el-form-item>
  591. <el-form-item label="围栏类型">
  592. <el-select v-model="fenceInfo.type">
  593. <!-- <el-option v-for="i in fenceType" :key="i.dictValue" :value="i.dictValue" :label="i.dictLabel"></el-option> -->
  594. <el-option :value="1" label="禁止离开"></el-option>
  595. <el-option :value="2" label="禁止进入"></el-option>
  596. </el-select>
  597. </el-form-item>
  598. <el-form-item label="是否开启">
  599. <el-select v-model="fenceInfo.state">
  600. <el-option :value="1" label="是"></el-option>
  601. <el-option :value="0" label="否"></el-option>
  602. </el-select>
  603. </el-form-item>
  604. </el-form>
  605. <el-row class="edit" v-show="fenceEdit">
  606. <el-dropdown size="small" trigger="click" style="margin-right: 10px;" @command="switchFenceType">
  607. <el-button type="primary" size="small">
  608. {{ fenceBtn }}<i class="el-icon-arrow-down el-icon--right"></i>
  609. </el-button>
  610. <el-dropdown-menu slot="dropdown">
  611. <el-dropdown-item command="circle">圆形</el-dropdown-item>
  612. <!-- <el-dropdown-item command="rect">矩形</el-dropdown-item> -->
  613. <el-dropdown-item command="polygon">多边形</el-dropdown-item>
  614. </el-dropdown-menu>
  615. </el-dropdown>
  616. <el-button class="edit-btn" size="small" type="primary" @click="switchFenceType('circle')">重新绘制</el-button>
  617. <el-button class="edit-btn" size="small" type="primary" @click="editCancel">取消绘制</el-button>
  618. <el-button class="edit-btn" size="small" type="primary" @click="subFence">提交</el-button>
  619. </el-row>
  620. </div>
  621. </el-dialog>
  622. <el-dialog title="设置日志" :visible.sync="settingLog" width="1000px" append-to-body>
  623. <el-table>
  624. <el-table-column label="序号" prop=""></el-table-column>
  625. <el-table-column label="用户姓名" prop=""></el-table-column>
  626. <el-table-column label="开始时间" prop=""></el-table-column>
  627. <el-table-column label="结束时间" prop=""></el-table-column>
  628. <el-table-column label="接受内容" prop=""></el-table-column>
  629. <el-table-column label="发送指令" prop=""></el-table-column>
  630. <el-table-column label="发送内容" prop=""></el-table-column>
  631. <el-table-column label="设置内容" prop=""></el-table-column>
  632. <el-table-column label="发送状态" prop=""></el-table-column>
  633. </el-table>
  634. <pagination v-show="total > 0" :total="total" :page.sync="queryParams.pageNum" :limit.sync="queryParams.pageSize"
  635. @pagination="getList" />
  636. </el-dialog>
  637. <el-dialog :visible.sync="openToUpload" width="630px" append-to-body>
  638. <el-upload class="upload-demo" drag :action="uploadFileUrl" multiple style="text-align: center;"
  639. :before-upload="handleBeforeUpload" :headers="headers" :on-success="handleUploadSuccess" ref="fileUpload">
  640. <i class="el-icon-upload"></i>
  641. <div class="el-upload__text">将文件拖到此处,或<em>点击上传</em></div>
  642. <div class="el-upload__tip" slot="tip" style="font-size: 15px;line-height: 15px;">仅允许导入xls、xlsx格式文件
  643. <el-button type="text" @click="downloadTemplate">下载模板</el-button>
  644. </div>
  645. </el-upload>
  646. </el-dialog>
  647. </div>
  648. </template>
  649. <script>
  650. import {
  651. listDevice,
  652. getDevice,
  653. delDevice,
  654. addDevice,
  655. updateDevice,
  656. getHeartRate,
  657. getBloodRate,
  658. getOxygenRate,
  659. getTempRate,
  660. getStepRate,
  661. getRollRate,
  662. getDeviceLog,
  663. setDeviceInterval,
  664. addFence,
  665. getFenceList,
  666. deleteFence,
  667. updateFence,
  668. setDevice
  669. }
  670. from "@/api/system/device";
  671. import { listProfile, getProfile } from "@/api/system/profile";
  672. import * as echarts from "echarts";
  673. import AMapLoader from '@amap/amap-jsapi-loader';
  674. import { getToken } from "@/utils/auth";
  675. import axios from 'axios'
  676. export default {
  677. name: "Device",
  678. data() {
  679. return {
  680. deviceProp: '1',
  681. openToUpload: false,
  682. headers: {
  683. Authorization: "Bearer " + getToken(),
  684. },
  685. fileType: ["xlsx", "xls"],
  686. uploadFileUrl: process.env.VUE_APP_BASE_API + "/system/device/importData",
  687. // 计步器
  688. settingOpen: false,
  689. // 遮罩层
  690. loading: true,
  691. // 选中数组
  692. ids: [],
  693. // 非单个禁用
  694. single: true,
  695. // 非多个禁用
  696. multiple: true,
  697. // 显示搜索条件
  698. showSearch: true,
  699. // 总条数
  700. total: 0,
  701. // 设备列表格数据
  702. deviceList: [],
  703. // 弹出层标题
  704. title: "",
  705. // 是否显示弹出层
  706. open: false,
  707. // 查询参数
  708. queryParams: {
  709. pageNum: 1,
  710. pageSize: 10,
  711. deviceProper: null,
  712. userid: null,
  713. sfzid: null,
  714. telno: null,
  715. factory: null,
  716. deviceModel: null,
  717. deviceId: null,
  718. simCode: null,
  719. serialNumber: null,
  720. grantType: null,
  721. price: null,
  722. cost: null,
  723. payment: null,
  724. createTime: null
  725. },
  726. // 表单参数
  727. form: {},
  728. // 表单校验
  729. rules: {
  730. factory: [
  731. { required: true, message: '请选择厂商', trigger: 'change' }
  732. ],
  733. deviceModel: [
  734. { required: true, message: '请选择设备型号', trigger: 'change' }
  735. ],
  736. grantType: [
  737. { required: true, message: '请选择发放方式', trigger: 'change' }
  738. ],
  739. name: [
  740. { required: true, message: '请选择用户' }
  741. ],
  742. deviceId: [
  743. { required: true, message: '请输入设备ID', trigger: 'blur' }
  744. ]
  745. },
  746. menuInfo: [],
  747. settingPage: 'sos',
  748. clockList: [
  749. {
  750. clockName: null,
  751. time: null,
  752. isopen: true,
  753. weeks: [],
  754. clockId: Date.now()
  755. }
  756. ],
  757. silentList: [
  758. {
  759. timeRange: ['08:00', '09:00'],
  760. silentStatus: true,
  761. id: Date.now()
  762. }
  763. ],
  764. timeOnOff: {
  765. isuse: false,
  766. openTime: null,
  767. closeTime: null
  768. },
  769. wearStatus: false,
  770. intercept: false,
  771. fall: {
  772. status: false,
  773. sensitivity: null
  774. },
  775. sensitivityList: [],
  776. healthInterval: false,
  777. deviceLog: false,
  778. settingLog: false,
  779. deviceAttribute: [],
  780. factoryList: [],
  781. deviceModel: [],
  782. grantType: [],
  783. payment: [],
  784. selectBuy: false,
  785. userForm: {
  786. pageNum: 1,
  787. pageSize: 10,
  788. name: null,
  789. gender: null,
  790. age: null,
  791. telOne: null,
  792. sfzid: null,
  793. familyAddress: null,
  794. clientType: null
  795. },
  796. userList: [],
  797. userTotal: null,
  798. clientType: [],
  799. selectUser: false,
  800. userInfo: {},
  801. health: false,
  802. tab: 0,
  803. map: null,
  804. fenceOpen: false,
  805. fenceInfo: {},
  806. fenceName: null,
  807. echartsQuery: {
  808. device_id_code: null,
  809. pageNum: 1,
  810. pageSize: 10
  811. },
  812. rateInfo: [],
  813. rateTotal: null,
  814. deviceLogList: [],
  815. logQuery: {
  816. device_id: null,
  817. pageNum: 1,
  818. pageSize: 10,
  819. },
  820. logTotal: null,
  821. setUser: {},
  822. sosForm: {},
  823. intervalForm: {},
  824. pedoForm: {},
  825. telForm: {},
  826. clockForm: {},
  827. onoffForm: {},
  828. wearForm: {},
  829. fallForm: {},
  830. deviceInterval: {
  831. shouhuan_heart_max: null,
  832. shouhuan_heart_min: null,
  833. shouhuan_blood_high_max: null,
  834. shouhuan_blood_high_min: null,
  835. shouhuan_blood_low_max: null,
  836. shouhuan_blood_low_min: null,
  837. shouhuan_oxygen_max: null,
  838. shouhuan_oxygen_min: null,
  839. shouhuan_body_max: null,
  840. shouhuan_body_min: null
  841. },
  842. fenceEdit: false,
  843. fenceType: [],
  844. fenceBtn: '圆形',
  845. fence: null,
  846. fenceEditor: null,
  847. fenceData: {},
  848. fenceList: [],
  849. fenceName: null,
  850. add_flag: true,
  851. checkedFence: null,
  852. items: []
  853. };
  854. },
  855. created() {
  856. this.getList();
  857. this.getUserList()
  858. this.getDicts('sys_menu_info').then(res => {
  859. this.menuInfo = res.data
  860. })
  861. this.getDicts('sys_clock').then(res => {
  862. this.clockDate = res.data
  863. })
  864. this.getDicts('sys_fall_sensitivity').then(res => {
  865. this.sensitivityList = res.data
  866. })
  867. this.getDicts('sys_device_attribute').then(res => {
  868. this.deviceAttribute = res.data
  869. })
  870. this.getDicts('sys_factory').then(res => {
  871. res.data.map(item => {
  872. item.dictValue = Number(item.dictValue)
  873. })
  874. this.factoryList = res.data
  875. })
  876. this.getDicts('sys_payment').then(res => {
  877. this.payment = res.data
  878. })
  879. this.getDicts('sys_user_type').then(res => {
  880. this.clientType = res.data
  881. })
  882. },
  883. watch: {
  884. 'form.grantType': {
  885. handler(val) {
  886. if (val && val == 1) {
  887. this.selectBuy = true
  888. } else {
  889. this.selectBuy = false
  890. }
  891. }
  892. },
  893. },
  894. methods: {
  895. async closePhone() {
  896. let success = 0
  897. if (this.items.length > 0) {
  898. await Promise.allSettled(this.items.map(async item => {
  899. let obj = {}
  900. obj.facility_id = item.fid
  901. obj.device_id_code = item.deviceId
  902. obj.command = 'keybrd'
  903. obj.param = { is_open: 0 }
  904. await axios({
  905. method: 'POST',
  906. url: 'http://43.138.30.29:4200/index.php/api/shouhuan/createcommand',
  907. headers: {
  908. Authorization: getToken(),
  909. },
  910. data: obj,
  911. }).then(res => {
  912. if (res.data && res.data.code == 200) {
  913. success += 1
  914. } else {
  915. this.$modal.msgError(`${item.name}设置失败`)
  916. }
  917. })
  918. }))
  919. if (success == this.items.length) {
  920. this.$modal.msgSuccess('关闭成功')
  921. }
  922. }
  923. },
  924. async openPhone() {
  925. let success = 0
  926. if (this.items.length > 0) {
  927. await Promise.allSettled(this.items.map(async item => {
  928. let obj = {}
  929. obj.facility_id = item.fid
  930. obj.device_id_code = item.deviceId
  931. obj.command = 'keybrd'
  932. obj.param = { is_open: 1 }
  933. await axios({
  934. method: 'POST',
  935. url: 'http://43.138.30.29:4200/index.php/api/shouhuan/createcommand',
  936. headers: {
  937. Authorization: getToken(),
  938. },
  939. data: obj,
  940. }).then(res => {
  941. if (res.data && res.data.code == 200) {
  942. success += 1
  943. } else {
  944. this.$modal.msgError(`${item.name}设置失败`)
  945. }
  946. })
  947. }))
  948. if (success == this.items.length) {
  949. this.$modal.msgSuccess('打开成功')
  950. }
  951. }
  952. },
  953. subDeviceInterval() {
  954. setDeviceInterval(this.deviceInterval).then(res => {
  955. if (res.code == 200) {
  956. this.$modal.msgSuccess('设置成功')
  957. this.healthInterval = false
  958. this.deviceInterval = {
  959. shouhuan_heart_max: null,
  960. shouhuan_heart_min: null,
  961. shouhuan_blood_high_max: null,
  962. shouhuan_blood_high_min: null,
  963. shouhuan_blood_low_max: null,
  964. shouhuan_blood_low_min: null,
  965. shouhuan_oxygen_max: null,
  966. shouhuan_oxygen_min: null,
  967. shouhuan_body_max: null,
  968. shouhuan_body_min: null
  969. }
  970. }
  971. })
  972. },
  973. closeInterval() {
  974. this.healthInterval = false
  975. this.deviceInterval = {
  976. shouhuan_heart_max: null,
  977. shouhuan_heart_min: null,
  978. shouhuan_blood_high_max: null,
  979. shouhuan_blood_high_min: null,
  980. shouhuan_blood_low_max: null,
  981. shouhuan_blood_low_min: null,
  982. shouhuan_oxygen_max: null,
  983. shouhuan_oxygen_min: null,
  984. shouhuan_body_max: null,
  985. shouhuan_body_min: null
  986. }
  987. },
  988. selectSetting(e) {
  989. this.settingPage = e
  990. },
  991. async setDeviceInfo() {
  992. if (Object.keys(this.sosForm).length && this.settingPage == 'sos') {
  993. let arr = []
  994. arr.push(this.sosForm.tel1)
  995. arr.push(this.sosForm.tel2)
  996. let obj = {}
  997. obj.facility_id = this.setUser.fid
  998. obj.device_id_code = this.setUser.deviceId
  999. obj.command = 'sos'
  1000. obj.param = { tels: arr }
  1001. await axios({
  1002. method: 'POST',
  1003. url: 'http://43.138.30.29:4200/index.php/api/shouhuan/createcommand',
  1004. headers: {
  1005. Authorization: getToken(),
  1006. },
  1007. data: obj,
  1008. }).then(res => {
  1009. if (res.data && res.data.code == 200) {
  1010. let data = {
  1011. deviceIdCode: this.setUser.deviceId,
  1012. sostelno1: this.sosForm.tel1,
  1013. sostelno2: this.sosForm.tel2
  1014. }
  1015. setDevice(data).then(res1 => {
  1016. this.$modal.msgSuccess('设置成功')
  1017. })
  1018. } else {
  1019. this.$modal.msgError('SOS设置失败')
  1020. }
  1021. })
  1022. } else if (Object.keys(this.intervalForm).length && this.settingPage == 'measureInterval') {
  1023. let obj = {}
  1024. obj.facility_id = this.setUser.fid
  1025. obj.device_id_code = this.setUser.deviceId
  1026. obj.command = 'interval'
  1027. obj.param = this.intervalForm
  1028. await axios({
  1029. method: 'POST',
  1030. url: 'http://43.138.30.29:4200/index.php/api/shouhuan/createcommand',
  1031. headers: {
  1032. Authorization: getToken(),
  1033. },
  1034. data: obj,
  1035. }).then(res => {
  1036. if (res.data && res.data.code == 200) {
  1037. let data = {
  1038. deviceIdCode: this.setUser.deviceId,
  1039. gpsInterval: this.intervalForm.cr_interval,
  1040. heartInterval: this.intervalForm.hrt_interval,
  1041. bodyInterval: this.intervalForm.wd_interval,
  1042. bloodInterval: this.intervalForm.bld_interval,
  1043. oxygenInterval: this.intervalForm.ox_interval,
  1044. }
  1045. setDevice(data).then(res1 => {
  1046. this.$modal.msgSuccess('设置成功')
  1047. })
  1048. } else {
  1049. this.$modal.msgError('测量间隔设置失败')
  1050. }
  1051. })
  1052. } else if (Object.keys(this.pedoForm).length && this.settingPage == 'stepCount') {
  1053. let is_open = this.pedoForm.isopen ? 1 : 0
  1054. let obj = {}
  1055. obj.facility_id = this.setUser.fid
  1056. obj.device_id_code = this.setUser.deviceId
  1057. obj.command = 'pedo'
  1058. obj.param = { is_open: is_open }
  1059. await axios({
  1060. method: 'POST',
  1061. url: 'http://43.138.30.29:4200/index.php/api/shouhuan/createcommand',
  1062. headers: {
  1063. Authorization: getToken(),
  1064. },
  1065. data: obj,
  1066. }).then(res => {
  1067. if (res.data && res.data.code == 200) {
  1068. let data = {
  1069. deviceIdCode: this.setUser.deviceId,
  1070. stepStatus: this.pedoForm.isopen
  1071. }
  1072. setDevice(data).then(res1 => {
  1073. this.$modal.msgSuccess('设置成功')
  1074. })
  1075. } else {
  1076. this.$modal.msgError('计步设置失败')
  1077. }
  1078. })
  1079. } else if (Object.keys(this.telForm).length && this.settingPage == 'contacts') {
  1080. let arr = []
  1081. if (this.telForm.tel1 && this.telForm.name1) {
  1082. arr.push({ telno: this.telForm.tel1, name: this.telForm.name1 })
  1083. }
  1084. if (this.telForm.tel2 && this.telForm.name2) {
  1085. arr.push({ telno: this.telForm.tel2, name: this.telForm.name2 })
  1086. }
  1087. if (this.telForm.tel3 && this.telForm.name3) {
  1088. arr.push({ telno: this.telForm.tel3, name: this.telForm.name3 })
  1089. }
  1090. let obj = {}
  1091. obj.facility_id = this.setUser.fid
  1092. obj.device_id_code = this.setUser.deviceId
  1093. obj.command = 'phl'
  1094. obj.param = arr
  1095. await axios({
  1096. method: 'POST',
  1097. url: 'http://43.138.30.29:4200/index.php/api/shouhuan/createcommand',
  1098. headers: {
  1099. Authorization: getToken(),
  1100. },
  1101. data: obj,
  1102. }).then(res => {
  1103. if (res.data && res.data.code == 200) {
  1104. let data = {
  1105. deviceIdCode: this.setUser.deviceId
  1106. }
  1107. if (this.telForm.tel1 && this.telForm.name1) {
  1108. data.contactPer1 = this.telForm.tel1
  1109. data.contactTel1 = this.this.telForm.name1
  1110. }
  1111. if (this.telForm.tel2 && this.telForm.name2) {
  1112. data.contactPer2 = this.telForm.tel2
  1113. data.contactTel2 = this.this.telForm.name2
  1114. }
  1115. if (this.telForm.tel3 && this.telForm.name3) {
  1116. data.contactPer3 = this.telForm.tel3
  1117. data.contactTel3 = this.this.telForm.name3
  1118. }
  1119. this.setDevice(data).then(res1 => {
  1120. this.$modal.msgSuccess('设置成功')
  1121. })
  1122. } else {
  1123. this.$modal.msgError('通讯录设置失败')
  1124. }
  1125. })
  1126. } else if (Object.keys(this.onoffForm).length && this.settingPage == 'timeOnOff') {
  1127. this.onoffForm.is_open = this.onoffForm.is_open ? 1 : 0
  1128. let obj = {}
  1129. obj.facility_id = this.setUser.fid
  1130. obj.device_id_code = this.setUser.deviceId
  1131. obj.command = 'bootoff'
  1132. obj.param = this.onoffForm
  1133. await axios({
  1134. method: 'POST',
  1135. url: 'http://43.138.30.29:4200/index.php/api/shouhuan/createcommand',
  1136. headers: {
  1137. Authorization: getToken(),
  1138. },
  1139. data: obj,
  1140. }).then(res => {
  1141. if (res.data && res.data.code == 200) {
  1142. let data = {
  1143. deviceIdCode: this.setUser.deviceId,
  1144. timeStatus: this.onoffForm.is_open,
  1145. timeBegin: this.onoffForm.bootup_time,
  1146. timeEnd: this.onoffForm.shutdown_time
  1147. }
  1148. setDevice(data).then(res1 => {
  1149. this.$modal.msgSuccess('设置成功')
  1150. })
  1151. } else {
  1152. this.$modal.msgError('定时开关机设置失败')
  1153. }
  1154. })
  1155. } else if (Object.keys(this.wearForm).length && this.settingPage == 'wearNotice') {
  1156. this.wearForm.is_open = this.wearForm.is_open ? 1 : 0
  1157. let obj = {}
  1158. obj.facility_id = this.setUser.fid
  1159. obj.device_id_code = this.setUser.deviceId
  1160. obj.command = 'remove'
  1161. obj.param = this.wearForm
  1162. await axios({
  1163. method: 'POST',
  1164. url: 'http://43.138.30.29:4200/index.php/api/shouhuan/createcommand',
  1165. headers: {
  1166. Authorization: getToken(),
  1167. },
  1168. data: obj,
  1169. }).then(res => {
  1170. if (res.data && res.data.code == 200) {
  1171. let data = {
  1172. deviceIdCode: this.setUser.deviceId,
  1173. useStatus: this.wearForm.is_open,
  1174. }
  1175. setDevice(data).then(res1 => {
  1176. this.$modal.msgSuccess('设置成功')
  1177. })
  1178. } else {
  1179. this.$modal.msgError('定时开关机设置失败')
  1180. }
  1181. })
  1182. } else if (this.clockList.length && this.settingPage == 'clock') {
  1183. if (this.clockList.length) {
  1184. let hasValue = 0
  1185. this.clockList.map(item => {
  1186. if (item.time) {
  1187. hasValue += 1
  1188. }
  1189. if (item.weeks.length) {
  1190. item.type = 3
  1191. } else {
  1192. item.type = 1
  1193. }
  1194. })
  1195. if (hasValue != this.clockList.length) {
  1196. this.$modal.msgWarning('时间不能为空')
  1197. return
  1198. }
  1199. let obj = {}
  1200. obj.facility_id = this.setUser.fid
  1201. obj.device_id_code = this.setUser.deviceId
  1202. obj.command = 'remind'
  1203. obj.param = this.clockList
  1204. await axios({
  1205. method: 'POST',
  1206. url: 'http://43.138.30.29:4200/index.php/api/shouhuan/createcommand',
  1207. headers: {
  1208. Authorization: getToken(),
  1209. },
  1210. data: obj,
  1211. }).then(res => {
  1212. if (res.data && res.data.code == 200) {
  1213. this.$modal.msgSuccess('设置成功')
  1214. } else {
  1215. this.$modal.msgError('闹钟设置失败')
  1216. }
  1217. })
  1218. }
  1219. } else if (Object.keys(this.fallForm).length && this.settingPage == 'fallNotice') {
  1220. this.fallForm.is_open = this.onoffForm.is_open ? 1 : 0
  1221. let obj = {}
  1222. obj.facility_id = this.setUser.fid
  1223. obj.device_id_code = this.setUser.deviceId
  1224. obj.command = 'falldown'
  1225. obj.param = this.fallForm
  1226. await axios({
  1227. method: 'POST',
  1228. url: 'http://43.138.30.29:4200/index.php/api/shouhuan/createcommand',
  1229. headers: {
  1230. Authorization: getToken(),
  1231. },
  1232. data: obj,
  1233. }).then(res => {
  1234. if (res.data && res.data.code == 200) {
  1235. let data = {
  1236. deviceIdCode: this.setUser.deviceId,
  1237. fallStatus: this.fallForm.is_open,
  1238. levelStatus: this.fallForm.lsset_type
  1239. }
  1240. setDevice(data).then(res1 => {
  1241. this.$modal.msgSuccess('设置成功')
  1242. })
  1243. } else {
  1244. this.$modal.msgError('跌倒提醒设置失败')
  1245. }
  1246. })
  1247. }
  1248. },
  1249. resetDeviceInfo() {
  1250. this.sosForm = {}
  1251. this.intervalForm = {}
  1252. this.pedoForm = {}
  1253. this.telForm = {}
  1254. this.clockForm = {}
  1255. this.onoffForm = {}
  1256. this.wearForm = {}
  1257. this.fallForm = {}
  1258. this.clockList = [
  1259. {
  1260. clockName: null,
  1261. time: null,
  1262. isopen: true,
  1263. weeks: [],
  1264. clockId: Date.now()
  1265. }
  1266. ]
  1267. },
  1268. handleUploadSuccess(res, file) {
  1269. if (res.code != 200) {
  1270. this.$modal.msgError(`上传模板不正确,请重新上传`);
  1271. this.$modal.closeLoading()
  1272. this.$refs.fileUpload.handleRemove(file);
  1273. } else {
  1274. this.$modal.msgSuccess("导入成功");
  1275. this.$modal.closeLoading()
  1276. this.openToUpload = false
  1277. this.resetQuery()
  1278. }
  1279. },
  1280. handleBeforeUpload(file) {
  1281. // 校检文件类型
  1282. if (this.fileType) {
  1283. const fileName = file.name.split('.');
  1284. const fileExt = fileName[fileName.length - 1];
  1285. const isTypeOk = this.fileType.indexOf(fileExt) >= 0;
  1286. if (!isTypeOk) {
  1287. this.$modal.msgError(`文件格式不正确, 请上传${this.fileType.join("/")}格式文件!`);
  1288. return false;
  1289. }
  1290. }
  1291. this.$modal.loading("正在上传文件,请稍候...");
  1292. return true;
  1293. },
  1294. downloadTemplate() {
  1295. this.download('system/device/importTemplate', {
  1296. }, `user_template_${new Date().getTime()}.xlsx`)
  1297. },
  1298. handleUpload() {
  1299. this.openToUpload = true
  1300. },
  1301. switchTab(e) {
  1302. this.tab = e
  1303. this.echartsQuery.pageNum = 1
  1304. this.echartsQuery.pageSize = 10
  1305. this.setEcharts(e)
  1306. },
  1307. // 创建表格
  1308. setEcharts(tab) {
  1309. let mychart = echarts.init(document.querySelector('.echart'))
  1310. if (tab == 0) {
  1311. mychart.clear()
  1312. getHeartRate(this.echartsQuery).then(data => {
  1313. this.rateInfo = data.rows
  1314. this.rateTotal = data.total
  1315. let createTime = []
  1316. let heartBeat = []
  1317. this.rateInfo = this.rateInfo.reverse()
  1318. this.rateInfo.map(item => {
  1319. createTime.push(item.createtime)
  1320. heartBeat.push(item.content)
  1321. })
  1322. let option = {
  1323. xAxis: {
  1324. type: 'category',
  1325. data: createTime,
  1326. boundaryGap: false,
  1327. nameTextStyle: {
  1328. fontSize: 10
  1329. }
  1330. },
  1331. legend: {},
  1332. yAxis: {
  1333. type: 'value'
  1334. },
  1335. series: [
  1336. {
  1337. name: '心率',
  1338. data: heartBeat,
  1339. type: 'line'
  1340. }
  1341. ]
  1342. }
  1343. mychart.setOption(option)
  1344. })
  1345. } else if (tab == 1) {
  1346. mychart.clear()
  1347. getBloodRate(this.echartsQuery).then(data => {
  1348. this.rateInfo = data.rows
  1349. this.rateTotal = data.total
  1350. let createTime = []
  1351. let high = []
  1352. let low = []
  1353. this.rateInfo = this.rateInfo.reverse()
  1354. this.rateInfo.map(item => {
  1355. createTime.push(item.createtime)
  1356. high.push(item.blood_height_pressure)
  1357. low.push(item.blood_low_pressure)
  1358. })
  1359. let option = {
  1360. xAxis: {
  1361. type: 'category',
  1362. data: createTime,
  1363. boundaryGap: false,
  1364. nameTextStyle: {
  1365. fontSize: 10
  1366. }
  1367. },
  1368. legend: {},
  1369. yAxis: {
  1370. type: 'value'
  1371. },
  1372. series: [
  1373. {
  1374. name: '高压',
  1375. data: high,
  1376. type: 'line'
  1377. },
  1378. {
  1379. name: '低压',
  1380. data: low,
  1381. type: 'line'
  1382. }
  1383. ]
  1384. }
  1385. mychart.setOption(option)
  1386. })
  1387. } else if (tab == 2) {
  1388. mychart.clear()
  1389. getOxygenRate(this.echartsQuery).then(data => {
  1390. this.rateInfo = data.rows
  1391. this.rateTotal = data.total
  1392. let createTime = []
  1393. let heartBeat = []
  1394. this.rateInfo = this.rateInfo.reverse()
  1395. this.rateInfo.map(item => {
  1396. createTime.push(item.createtime)
  1397. heartBeat.push(item.content)
  1398. })
  1399. let option = {
  1400. xAxis: {
  1401. type: 'category',
  1402. data: createTime,
  1403. boundaryGap: false,
  1404. nameTextStyle: {
  1405. fontSize: 10
  1406. }
  1407. },
  1408. legend: {},
  1409. yAxis: {
  1410. type: 'value'
  1411. },
  1412. series: [
  1413. {
  1414. name: '血氧',
  1415. data: heartBeat,
  1416. type: 'line'
  1417. }
  1418. ]
  1419. }
  1420. mychart.setOption(option)
  1421. })
  1422. } else if (tab == 3) {
  1423. mychart.clear()
  1424. getTempRate(this.echartsQuery).then(data => {
  1425. this.rateInfo = data.rows
  1426. this.rateTotal = data.total
  1427. let createTime = []
  1428. let heartBeat = []
  1429. this.rateInfo = this.rateInfo.reverse()
  1430. this.rateInfo.map(item => {
  1431. createTime.push(item.createtime)
  1432. heartBeat.push(item.content)
  1433. })
  1434. let option = {
  1435. xAxis: {
  1436. type: 'category',
  1437. data: createTime,
  1438. boundaryGap: false,
  1439. nameTextStyle: {
  1440. fontSize: 10
  1441. }
  1442. },
  1443. legend: {},
  1444. yAxis: {
  1445. type: 'value'
  1446. },
  1447. series: [
  1448. {
  1449. name: '体温',
  1450. data: heartBeat,
  1451. type: 'line'
  1452. }
  1453. ]
  1454. }
  1455. mychart.setOption(option)
  1456. })
  1457. } else if (tab == 4) {
  1458. mychart.clear()
  1459. getStepRate(this.echartsQuery).then(data => {
  1460. this.rateInfo = data.rows
  1461. this.rateTotal = data.total
  1462. let createTime = []
  1463. let heartBeat = []
  1464. this.rateInfo = this.rateInfo.reverse()
  1465. this.rateInfo.map(item => {
  1466. createTime.push(item.createtime)
  1467. heartBeat.push(item.step_number)
  1468. })
  1469. let option = {
  1470. xAxis: {
  1471. type: 'category',
  1472. data: createTime,
  1473. boundaryGap: false,
  1474. nameTextStyle: {
  1475. fontSize: 10
  1476. }
  1477. },
  1478. legend: {},
  1479. yAxis: {
  1480. type: 'value'
  1481. },
  1482. series: [
  1483. {
  1484. name: '计步',
  1485. data: heartBeat,
  1486. type: 'line'
  1487. }
  1488. ]
  1489. }
  1490. mychart.setOption(option)
  1491. })
  1492. } else if (tab == 5) {
  1493. mychart.clear()
  1494. getRollRate(this.echartsQuery).then(data => {
  1495. this.rateInfo = data.rows
  1496. this.rateTotal = data.total
  1497. let createTime = []
  1498. let heartBeat = []
  1499. this.rateInfo = this.rateInfo.reverse()
  1500. this.rateInfo.map(item => {
  1501. createTime.push(item.createtime)
  1502. heartBeat.push(item.roll_number)
  1503. })
  1504. let option = {
  1505. xAxis: {
  1506. type: 'category',
  1507. data: createTime,
  1508. boundaryGap: false,
  1509. nameTextStyle: {
  1510. fontSize: 10
  1511. }
  1512. },
  1513. legend: {},
  1514. yAxis: {
  1515. type: 'value'
  1516. },
  1517. series: [
  1518. {
  1519. name: '翻滚次数',
  1520. data: heartBeat,
  1521. type: 'line'
  1522. }
  1523. ]
  1524. }
  1525. mychart.setOption(option)
  1526. })
  1527. }
  1528. },
  1529. // 提交围栏
  1530. subFence() {
  1531. this.fenceEditor.close()
  1532. if (this.add_flag) {
  1533. this.fenceInfo.deviceId = this.setUser.id
  1534. console.log(this.fenceInfo);
  1535. addFence(this.fenceInfo).then(res => {
  1536. if (res.code == 200) {
  1537. this.$modal.msgSuccess('添加成功')
  1538. this.fence = {}
  1539. this.getFence()
  1540. }
  1541. })
  1542. } else {
  1543. let data = {
  1544. name: this.fenceInfo.name,
  1545. type: this.fenceInfo.type,
  1546. start_time: this.fenceInfo.start_time,
  1547. end_time: this.fenceInfo.end_time,
  1548. deviceId: this.fenceInfo.deviceId,
  1549. id: this.fenceInfo.id,
  1550. state: this.fenceInfo.state,
  1551. geofence_type: this.fenceInfo.geofence_type,
  1552. }
  1553. if (this.fenceInfo.geofence_type == 0) {
  1554. data.center = this.fenceInfo.center,
  1555. data.radius = this.fenceInfo.radius
  1556. } else if (this.fenceInfo.geofence_type == 1) {
  1557. data.points = this.fenceInfo.points
  1558. }
  1559. console.log(data);
  1560. updateFence(data).then(res => {
  1561. if (res.code == 200) {
  1562. this.$modal.msgSuccess('修改成功')
  1563. this.getFence()
  1564. }
  1565. })
  1566. }
  1567. this.fenceEdit = false
  1568. },
  1569. // 切换围栏按钮
  1570. switchFenceType(e) {
  1571. if (this.fence) {
  1572. this.map.remove(this.fence)
  1573. this.fence = null
  1574. }
  1575. if (this.fenceEditor) {
  1576. this.fenceEditor.close()
  1577. this.fenceEditor = null
  1578. }
  1579. if (e == 'circle') {
  1580. delete this.fenceInfo.points
  1581. this.fenceBtn = '圆形'
  1582. this.fenceInfo.geofence_type = 0
  1583. let radius = 500
  1584. let lnglat = this.map.getCenter()
  1585. this.fence = new AMap.Circle({
  1586. center: lnglat,
  1587. radius: radius, //半径
  1588. borderWeight: 3,
  1589. fillOpacity: 0.4,
  1590. strokeStyle: 'dashed',
  1591. strokeDasharray: [10, 10],
  1592. // 线样式还支持 'dashed'
  1593. fillColor: '#1791fc',
  1594. zIndex: 50,
  1595. })
  1596. this.map.add(this.fence);
  1597. // 缩放地图到合适的视野级别
  1598. // this.map.setFitView([this.circle])
  1599. this.fenceEditor = new AMap.CircleEditor(this.map, this.fence)
  1600. this.fenceEditor.open()
  1601. this.fenceEditor.on('end', (e) => {
  1602. this.fenceInfo.radius = radius
  1603. this.fenceInfo.center = `${lnglat.lng},${lnglat.lat}`
  1604. })
  1605. this.fenceEditor.on('adjust', (e) => {
  1606. radius = e.radius
  1607. })
  1608. this.fenceEditor.on('move', (e) => {
  1609. lnglat = e.lnglat
  1610. })
  1611. } else if (e == 'rect') {
  1612. this.fenceBtn = '矩形'
  1613. let center = this.map.getCenter()
  1614. var southWest = new AMap.LngLat(center.lng + 0.01, center.lat + 0.005)
  1615. var northEast = new AMap.LngLat(center.lng - 0.01, center.lat - 0.005)
  1616. var bounds = new AMap.Bounds(southWest, northEast)
  1617. this.fence = new AMap.Rectangle({
  1618. bounds: bounds,
  1619. fillColor: 'blue',
  1620. fillOpacity: 0.5,
  1621. cursor: 'pointer',
  1622. zIndex: 50,
  1623. })
  1624. this.map.add(this.fence);
  1625. // 缩放地图到合适的视野级别
  1626. this.fenceEditor = new AMap.RectangleEditor(this.map, this.fence)
  1627. this.fenceEditor.open()
  1628. } else if (e == 'polygon') {
  1629. this.fenceBtn = '多边形'
  1630. this.fenceInfo.geofence_type = 1
  1631. delete this.fenceInfo.radius
  1632. delete this.fenceInfo.center
  1633. let center = this.map.getCenter()
  1634. let path = [
  1635. [center.lng - 0.01, center.lat + 0.005],
  1636. [center.lng + 0.01, center.lat + 0.005],
  1637. [center.lng + 0.01, center.lat - 0.005],
  1638. [center.lng - 0.01, center.lat - 0.005]
  1639. ]
  1640. this.fence = new AMap.Polygon({
  1641. path: path,
  1642. strokeColor: "#FF33FF",
  1643. strokeWeight: 6,
  1644. strokeOpacity: 0.2,
  1645. fillOpacity: 0.4,
  1646. fillColor: '#1791fc',
  1647. zIndex: 50,
  1648. bubble: true,
  1649. draggable: true,
  1650. })
  1651. this.map.add(this.fence);
  1652. this.fenceEditor = new AMap.PolygonEditor(this.map, this.fence);
  1653. this.fenceEditor.open();
  1654. this.fenceEditor.on('end', (e) => {
  1655. let arr = []
  1656. e.target._opts.path.map(item => {
  1657. arr.push(item.join(','))
  1658. })
  1659. this.fenceInfo.points = arr.join(';')
  1660. })
  1661. }
  1662. },
  1663. // 围栏新增
  1664. editAdd() {
  1665. if (this.fenceList.length < 3) {
  1666. this.fenceEdit = true
  1667. this.add_flag = true
  1668. this.fenceInfo.name = null
  1669. this.fenceInfo.start_time = null
  1670. this.fenceInfo.end_time = null
  1671. this.fenceInfo.type = null
  1672. this.fenceInfo.state = null
  1673. if (this.fence) {
  1674. this.map.remove(this.fence)
  1675. this.fence = null
  1676. }
  1677. if (this.fenceEditor) {
  1678. this.fenceEditor.close()
  1679. this.fenceEditor = null
  1680. }
  1681. if (this.fenceName) {
  1682. this.fenceName = null
  1683. }
  1684. if (this.fence == null) {
  1685. this.switchFenceType('circle')
  1686. }
  1687. } else {
  1688. this.$modal.msgError('最多只能创建三个围栏')
  1689. }
  1690. },
  1691. // 取消绘制
  1692. editCancel() {
  1693. this.fenceEdit = false
  1694. this.map.remove(this.fence)
  1695. this.fenceEditor.close()
  1696. this.fence = null
  1697. this.fenceEditor = null
  1698. },
  1699. // 修改围栏
  1700. editUpdate() {
  1701. if (this.fence) {
  1702. this.add_flag = false
  1703. this.fenceEdit = true
  1704. if (this.fenceEditor) {
  1705. this.fenceEditor.close()
  1706. }
  1707. if (this.fenceInfo.geofence_type == 0) {
  1708. this.fenceBtn = '圆形'
  1709. this.fenceEditor = new AMap.CircleEditor(this.map, this.fence)
  1710. let radius = this.fenceInfo.radius
  1711. let lnglat = new AMap.LngLat(this.fenceInfo.center.split(',')[0], this.fenceInfo.center.split(',')[1])
  1712. this.fenceEditor.open()
  1713. this.fenceEditor.on('end', (e) => {
  1714. this.fenceInfo.radius = radius
  1715. this.fenceInfo.center = `${lnglat.lng},${lnglat.lat}`
  1716. })
  1717. this.fenceEditor.on('adjust', (e) => {
  1718. radius = e.radius
  1719. })
  1720. this.fenceEditor.on('move', (e) => {
  1721. lnglat = e.lnglat
  1722. })
  1723. } else if (this.fenceInfo.geofence_type == 1) {
  1724. this.fenceBtn = '多边形'
  1725. this.fence.setOptions({ draggable: true })
  1726. this.fenceEditor = new AMap.PolygonEditor(this.map, this.fence);
  1727. this.fenceEditor.open();
  1728. this.fenceEditor.on('end', (e) => {
  1729. let arr = []
  1730. e.target._opts.path.map(item => {
  1731. arr.push(item.join(','))
  1732. })
  1733. this.fenceInfo.points = arr.join(';')
  1734. })
  1735. }
  1736. }
  1737. },
  1738. // 删除围栏
  1739. editDelete() {
  1740. deleteFence(this.fenceInfo.id).then(res => {
  1741. if (res.code == 200) {
  1742. this.$modal.msgSuccess('删除成功')
  1743. this.getFence()
  1744. if (this.fence) {
  1745. this.map.remove(this.fence)
  1746. this.fence = null
  1747. }
  1748. if (this.fenceEditor) {
  1749. this.fenceEditor.close()
  1750. this.fenceEditor = null
  1751. }
  1752. this.fenceName = null
  1753. }
  1754. })
  1755. },
  1756. // 选择围栏
  1757. selectFence(e) {
  1758. this.fenceList.map(item => {
  1759. if (item.name == e) {
  1760. if (this.fence) {
  1761. this.map.remove(this.fence)
  1762. }
  1763. if (this.fenceEditor) {
  1764. this.fenceEditor.close()
  1765. }
  1766. this.fenceInfo = JSON.parse(JSON.stringify(item))
  1767. this.getFenceInfo(item.key, item.sid, item.gfid).then(res => {
  1768. if (res.data.results[0].shape.radius) {
  1769. this.fenceInfo.center = res.data.results[0].shape.center
  1770. this.fenceInfo.radius = res.data.results[0].shape.radius
  1771. this.fenceInfo.geofence_type = 0
  1772. let lnglat = new AMap.LngLat(res.data.results[0].shape.center.split(',')[0], res.data.results[0].shape.center.split(',')[1])
  1773. this.fence = new AMap.Circle({
  1774. center: lnglat,
  1775. radius: res.data.results[0].shape.radius, //半径
  1776. borderWeight: 3,
  1777. fillOpacity: 0.4,
  1778. strokeStyle: 'dashed',
  1779. strokeDasharray: [10, 10],
  1780. // 线样式还支持 'dashed'
  1781. fillColor: '#1791fc',
  1782. zIndex: 50,
  1783. })
  1784. this.map.add(this.fence);
  1785. this.map.setCenter(lnglat)
  1786. this.map.setFitView([this.fence])
  1787. } else if (res.data.results[0].shape.points) {
  1788. let arr = res.data.results[0].shape.points.split(';')
  1789. let path = []
  1790. arr.map(item => {
  1791. path.push(item.split(','))
  1792. })
  1793. console.log(path);
  1794. this.fenceInfo.points = res.data.results[0].shape.points
  1795. this.fenceInfo.geofence_type = 1
  1796. this.fence = new AMap.Polygon({
  1797. path: path,
  1798. strokeColor: "#FF33FF",
  1799. strokeWeight: 6,
  1800. strokeOpacity: 0.2,
  1801. fillOpacity: 0.4,
  1802. fillColor: '#1791fc',
  1803. zIndex: 50,
  1804. bubble: true,
  1805. // draggable: true,
  1806. })
  1807. this.map.add(this.fence);
  1808. this.map.setFitView([this.fence])
  1809. }
  1810. })
  1811. }
  1812. })
  1813. },
  1814. // 获取围栏信息
  1815. getFenceInfo(key, sid, gfid) {
  1816. return new Promise((resolve, reject) => {
  1817. axios({
  1818. url: 'https://tsapi.amap.com/v1/track/geofence/list',
  1819. method: 'GET',
  1820. params: {
  1821. key: key,
  1822. sid: sid,
  1823. gfids: gfid,
  1824. outputshape: 1
  1825. }
  1826. }).then((res) => {
  1827. resolve(res.data)
  1828. })
  1829. })
  1830. },
  1831. // 创建地图
  1832. createMap() {
  1833. window._AMapSecurityConfig = {
  1834. securityJsCode: 'e91e92cbd76e89c48f3ff1d6180f288c'
  1835. }
  1836. AMapLoader.load({
  1837. key: 'c968deab485d6e688e7c68689722ffb4',
  1838. version: '2.0'
  1839. }).then(AMap => {
  1840. this.map = new AMap.Map('map', {
  1841. zoom: 15
  1842. })
  1843. this.map.plugin([
  1844. 'AMap.ToolBar',
  1845. 'AMap.Scale',
  1846. 'AMap.Geolocation',
  1847. 'AMap.CircleEditor',
  1848. 'AMap.RectangleEditor',
  1849. 'AMap.PolygonEditor',
  1850. 'AMap.CitySearch'], () => {
  1851. this.map.addControl(new AMap.ToolBar({
  1852. position: 'RT'
  1853. }))
  1854. this.map.addControl(new AMap.Scale())
  1855. var geolocation = new AMap.Geolocation({
  1856. enableHighAccuracy: true, // 是否使用高精度定位,默认:true
  1857. timeout: 10000, // 设置定位超时时间,默认:无穷大
  1858. offset: [10, 20], // 定位按钮的停靠位置的偏移量
  1859. zoomToAccuracy: true, // 定位成功后调整地图视野范围使定位位置及精度范围视野内可见,默认:false
  1860. position: 'RB' // 定位按钮的排放位置, RB表示右下
  1861. })
  1862. geolocation.getCurrentPosition((status, result) => {
  1863. if (status == 'complete') {
  1864. this.$modal.msgSuccess('定位成功')
  1865. this.map.setCenter([result.position.lng, result.position.lat])
  1866. } else {
  1867. // this.$modal.msgError('获取定位失败')
  1868. }
  1869. this.getFence()
  1870. });
  1871. // let citySearch = new AMap.CitySearch()
  1872. // citySearch.getLocalCity((status, result) => {
  1873. // if (status === 'complete' && result.info === 'OK') {
  1874. // console.log(result);
  1875. // let bounds = result.bounds;
  1876. // this.map.setBounds(bounds);
  1877. // }
  1878. // })
  1879. })
  1880. })
  1881. },
  1882. getFence() {
  1883. getFenceList(this.setUser.id).then(res => {
  1884. console.log('list', res);
  1885. if (res.code == 200) {
  1886. res.rows.map(item => {
  1887. item.start_time = item.startTime
  1888. item.end_time = item.endTime
  1889. })
  1890. this.fenceList = res.rows
  1891. }
  1892. })
  1893. },
  1894. getUserList() {
  1895. this.loading = true;
  1896. listProfile(this.userForm).then(response => {
  1897. response.rows.map(item => {
  1898. item.sex = item.gender == 0 ? '男' : item.gender == 1 ? '女' : ''
  1899. })
  1900. this.userList = response.rows;
  1901. this.userTotal = response.total;
  1902. this.loading = false;
  1903. });
  1904. },
  1905. beforeClose(done) {
  1906. this.map.destroy()
  1907. this.fenceName = null
  1908. this.fenceEdit = false
  1909. this.fenceInfo = {}
  1910. done()
  1911. },
  1912. searchUser() {
  1913. this.userForm.pageNum = 1
  1914. this.getUserList()
  1915. },
  1916. resetUser() {
  1917. this.userForm = {
  1918. pageNum: 1,
  1919. pageSize: 10,
  1920. name: null,
  1921. gender: null,
  1922. age: null,
  1923. telOne: null,
  1924. sfzid: null,
  1925. familyAddress: null,
  1926. clientType: null
  1927. }
  1928. this.getUserList()
  1929. },
  1930. checkUser(e) {
  1931. if (e.length > 1) return this.$modal.msgError('只能选择一人')
  1932. this.userInfo = e[0]
  1933. },
  1934. toSelect() {
  1935. this.selectUser = true
  1936. },
  1937. checkUserConfirm() {
  1938. if (Object.keys(this.userInfo).length) {
  1939. this.form.name = this.userInfo.name
  1940. this.form.sfzid = this.userInfo.sfzid
  1941. this.form.telno = this.userInfo.telOne
  1942. this.form.userid = this.userInfo.id
  1943. this.selectUser = false
  1944. } else {
  1945. this.$modal.msgError('请选择用户')
  1946. }
  1947. },
  1948. checkUserCancel() {
  1949. this.selectUser = false
  1950. this.userInfo = {}
  1951. },
  1952. addList() {
  1953. if (this.settingPage == 'clock') {
  1954. let obj = {
  1955. clockName: null,
  1956. time: null,
  1957. isopen: true,
  1958. weeks: [],
  1959. clockId: Date.now()
  1960. }
  1961. this.clockList.push(obj)
  1962. } else if (this.settingPage == 'silentTime') {
  1963. let obj = {
  1964. timeRange: [new Date(8, 0), new Date(9, 0)],
  1965. silentStatus: true,
  1966. id: Date.now()
  1967. }
  1968. this.silentList.push(obj)
  1969. }
  1970. },
  1971. deleteSilent(e) {
  1972. this.silentList.map((item, index) => {
  1973. if (item.id == e) {
  1974. this.silentList.splice(index, 1)
  1975. }
  1976. })
  1977. },
  1978. deleteClock(e) {
  1979. this.clockList.map((item, index) => {
  1980. if (item.clockId == e) {
  1981. this.clockList.splice(index, 1)
  1982. }
  1983. })
  1984. },
  1985. openSetting(e, row) {
  1986. this.echartsQuery.device_id_code = row.deviceId
  1987. this[e] = true
  1988. if (e == 'health') {
  1989. setTimeout(() => {
  1990. this.setEcharts(0)
  1991. }, 100);
  1992. } else if (e == 'fenceOpen') {
  1993. this.createMap()
  1994. this.setUser = row
  1995. } else if (e == 'deviceLog') {
  1996. this.getDeviceLog()
  1997. } else if (e == 'settingOpen') {
  1998. this.setUser = row
  1999. } else if (e == 'healthInterval') {
  2000. this.setUser = row
  2001. }
  2002. },
  2003. getDeviceLog() {
  2004. getDeviceLog(this.logQuery).then(res => {
  2005. this.deviceLogList = res.rows
  2006. this.deviceLogList.map(item => {
  2007. if (item.alarm_type == 0) {
  2008. item.describe = '无效'
  2009. } else if (item.alarm_type == 16) {
  2010. item.describe = 'SOS报警'
  2011. } else if (item.alarm_type == 17) {
  2012. item.describe = '低电量'
  2013. } else if (item.alarm_type == 20) {
  2014. item.describe = '手表未佩戴'
  2015. } else if (item.alarm_type == 21) {
  2016. item.describe = '跌倒报警'
  2017. } else if (item.alarm_type == 22) {
  2018. item.describe = '心率异常'
  2019. }
  2020. })
  2021. this.logTotal = res.total
  2022. })
  2023. },
  2024. /** 查询设备列列表 */
  2025. async getList() {
  2026. this.loading = true;
  2027. let { data: grantType } = await this.getDicts('sys_grant_type')
  2028. grantType.map(item => {
  2029. item.dictValue = Number(item.dictValue)
  2030. })
  2031. this.grantType = grantType
  2032. let { data: deviceModel } = await this.getDicts('sys_device_type')
  2033. deviceModel.map(item => {
  2034. item.dictValue = Number(item.dictValue)
  2035. })
  2036. this.deviceModel = deviceModel
  2037. let { data: fenceType } = await this.getDicts('sys_fence_type')
  2038. this.fenceType = fenceType
  2039. await listDevice(this.queryParams).then(response => {
  2040. this.deviceList = response.rows;
  2041. this.deviceList.map(item => {
  2042. if (item.deviceModel || item.deviceModel == 0) {
  2043. console.log(item.deviceModel);
  2044. item.deviceType = this.deviceModel[item.deviceModel].dictLabel
  2045. }
  2046. if (item.grantType || item.grantType == 0) {
  2047. item.granttype = this.grantType[item.grantType].dictLabel
  2048. }
  2049. item.online = item.online_statis == 1 ? '在线' : item.online_statis == 0 ? '离线' : ''
  2050. })
  2051. this.total = response.total;
  2052. this.loading = false;
  2053. });
  2054. },
  2055. // 取消按钮
  2056. cancel() {
  2057. this.open = false;
  2058. this.reset();
  2059. },
  2060. // 表单重置
  2061. reset() {
  2062. this.form = {
  2063. id: null,
  2064. deviceProper: null,
  2065. userid: null,
  2066. sfzid: null,
  2067. telno: null,
  2068. factory: null,
  2069. deviceModel: null,
  2070. deviceId: null,
  2071. simCode: null,
  2072. serialNumber: null,
  2073. grantType: null,
  2074. price: null,
  2075. cost: null,
  2076. payment: null,
  2077. createTime: null
  2078. };
  2079. this.resetForm("form");
  2080. },
  2081. /** 搜索按钮操作 */
  2082. handleQuery() {
  2083. this.queryParams.pageNum = 1;
  2084. this.getList();
  2085. },
  2086. /** 重置按钮操作 */
  2087. resetQuery() {
  2088. this.resetForm("queryForm");
  2089. this.handleQuery();
  2090. },
  2091. // 多选框选中数据
  2092. handleSelectionChange(selection) {
  2093. this.ids = selection.map(item => item.id)
  2094. this.items = selection.map(item => item)
  2095. this.single = selection.length !== 1
  2096. this.multiple = !selection.length
  2097. },
  2098. /** 新增按钮操作 */
  2099. handleAdd() {
  2100. this.reset();
  2101. this.open = true;
  2102. this.title = "添加设备";
  2103. },
  2104. /** 修改按钮操作 */
  2105. handleUpdate(row) {
  2106. this.reset();
  2107. const id = row.id || this.ids
  2108. getDevice(id).then(response => {
  2109. this.form = response.data;
  2110. console.log(this.form);
  2111. this.deviceList.map(item => {
  2112. if (item.id == id) {
  2113. this.form.name = item.name
  2114. }
  2115. })
  2116. this.open = true;
  2117. this.title = "修改设备";
  2118. });
  2119. },
  2120. /** 提交按钮 */
  2121. submitForm() {
  2122. this.$refs["form"].validate(valid => {
  2123. if (valid) {
  2124. if (this.form.id != null) {
  2125. updateDevice(this.form).then(response => {
  2126. this.$modal.msgSuccess("修改成功");
  2127. this.open = false;
  2128. this.getList();
  2129. });
  2130. } else {
  2131. // if (!this.form.name) {
  2132. // this.$modal.msgError('请选择用户')
  2133. // }
  2134. addDevice(this.form).then(response => {
  2135. this.$modal.msgSuccess("新增成功");
  2136. this.open = false;
  2137. this.getList();
  2138. });
  2139. }
  2140. }
  2141. });
  2142. },
  2143. /** 删除按钮操作 */
  2144. handleDelete(row) {
  2145. const ids = row.id || this.ids;
  2146. this.$modal.confirm('是否确认删除设备列编号为"' + ids + '"的数据项?').then(function () {
  2147. return delDevice(ids);
  2148. }).then(() => {
  2149. this.getList();
  2150. this.$modal.msgSuccess("删除成功");
  2151. }).catch(() => { });
  2152. },
  2153. /** 导出按钮操作 */
  2154. handleExport() {
  2155. this.download('system/device/export', {
  2156. ...this.queryParams
  2157. }, `device_${new Date().getTime()}.xlsx`)
  2158. }
  2159. }
  2160. };
  2161. </script>
  2162. <style scoped>
  2163. .top {
  2164. margin-bottom: 20px;
  2165. }
  2166. .setting-inp {
  2167. width: 350px;
  2168. }
  2169. .clock-item {
  2170. margin: 20px 0 0 0;
  2171. border-bottom: 1px solid #ccc;
  2172. }
  2173. .clock-input {
  2174. margin: 0 10px 0 0;
  2175. width: 200px;
  2176. }
  2177. .clock-switch {
  2178. margin: 0 20px;
  2179. }
  2180. .search-inp {
  2181. width: 200px
  2182. }
  2183. .inp /deep/ .el-input__inner {
  2184. color: #000 !important;
  2185. /* cursor: pointer; */
  2186. }
  2187. .echart {
  2188. margin: 0 auto;
  2189. width: 500px;
  2190. height: 250px;
  2191. }
  2192. #map {
  2193. position: relative;
  2194. width: 1160px;
  2195. height: 700px;
  2196. }
  2197. .map-tool {
  2198. position: relative;
  2199. padding: 10px;
  2200. z-index: 1;
  2201. }
  2202. .update-tool {
  2203. position: relative;
  2204. margin: 0px 0 0 10px;
  2205. padding: 10px;
  2206. width: 330px;
  2207. height: 240px;
  2208. background-color: rgba(255, 255, 255, .7);
  2209. z-index: 1;
  2210. }
  2211. .edit {
  2212. position: absolute;
  2213. bottom: 5px;
  2214. right: 5px;
  2215. z-index: 1;
  2216. }
  2217. .edit-btn {
  2218. width: 80px;
  2219. }
  2220. </style>