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

331 lines
9.6 KiB

4 months ago
4 months ago
4 months ago
4 months ago
4 months ago
4 months ago
4 months ago
4 months ago
4 months ago
4 months ago
4 months ago
4 months ago
4 months ago
4 months ago
4 months ago
4 months ago
4 months ago
4 months ago
4 months ago
4 months ago
4 months ago
4 months ago
4 months ago
  1. import { useState, useEffect } from 'react';
  2. import { Button, Cascader, Input, message, Form } from 'antd';
  3. import {
  4. LoadingOutlined,
  5. } from '@ant-design/icons';
  6. import { getOrgListService } from '../../services/ktj/org';
  7. import { OrgItem } from '../../services/ktjTypes';
  8. import {bleItem, child, GwdItem, orgCascaderType, systemItem} from './types';
  9. import { sysSet } from '../../services/user/system';
  10. import { useAppDispatch, useAppSelector } from "../../utils/hooks";
  11. import { updateSystemAccountState, updateSystemOrgState } from '../../store/system/systemSlice';
  12. import {createWebSocket, sharedWsUrl} from "../../services/socket";
  13. import {start, stop, disconnect, connect} from "../../services/ble/ble";
  14. export default function Setting(){
  15. useEffect(()=>{
  16. queryRailData()
  17. // onBleStart()
  18. querySettingData()
  19. return ()=>{
  20. onBleStop()
  21. }
  22. },[])
  23. const dispatch = useAppDispatch();
  24. const deviceInfo = useAppSelector(store => store.context.device);
  25. const systemState = useAppSelector((store) => store.systemState);
  26. const [systemList, setSystemList] = useState<systemItem[]>([])
  27. const [accountInfo, setAccountInfo] = useState<systemItem>({})
  28. const [orgInfo, setOrgInfo] = useState<systemItem>({})
  29. const [orgValues, setOrgValues] = useState<string[]>([])
  30. const [bleList, setBleList] = useState<bleItem[]>([])
  31. // 创建 websocket 客户端
  32. const wsClient = createWebSocket(sharedWsUrl);
  33. function querySettingData(){
  34. let systemInfo = systemState.systemInfo
  35. setSystemList(systemInfo)
  36. }
  37. useEffect(() => {
  38. const subscription = wsClient.dataOb.subscribe(data => {
  39. // @ts-ignore
  40. if (data.messageType === "STATE" && data.path === "/api/ble/ble-list") {
  41. // @ts-ignore
  42. setBleList(data.data.map(item => {
  43. return {
  44. ...item,
  45. loading: item.address === connecting,
  46. }
  47. }))
  48. }
  49. });
  50. wsClient.connect();
  51. return () => subscription.unsubscribe();
  52. });
  53. useEffect(()=>{
  54. if(systemState.orgInfo){
  55. const cloneOrgItem = systemState.orgInfo
  56. let orgItem:systemItem = {
  57. id: cloneOrgItem.id,
  58. name: cloneOrgItem.name,
  59. code: cloneOrgItem.code,
  60. value: cloneOrgItem.value
  61. }
  62. setOrgInfo(orgItem)
  63. }
  64. }, [systemState.orgInfo])
  65. useEffect(()=>{
  66. if(systemState.accountInfo){
  67. const cloneAccountItem = systemState.accountInfo
  68. let accountInfo:systemItem = {
  69. id: cloneAccountItem.id,
  70. name: cloneAccountItem.name,
  71. code: cloneAccountItem.code,
  72. value: cloneAccountItem.value
  73. }
  74. setAccountInfo(accountInfo)
  75. }
  76. }, [systemState.accountInfo])
  77. useEffect(()=>{
  78. if(orgInfo && orgInfo.value){
  79. let orgIds:string[] = []
  80. const values:child[] = JSON.parse(orgInfo.value)
  81. values.map(item => {
  82. orgIds.push(item.value)
  83. })
  84. setOrgValues(orgIds)
  85. }
  86. }, [orgInfo])
  87. //获取铁路局数据
  88. const [KTJOrgList, setKTJOrgList] = useState<orgCascaderType[]>([]);
  89. function queryRailData(){
  90. getOrgListService().then((res) => {
  91. if (res && res.data) {
  92. let resData: OrgItem[] = res.data;
  93. let data = convertToCascaderData(resData)
  94. setKTJOrgList(data)
  95. }
  96. }).catch((e) => {});
  97. }
  98. function onOrgChange(value:string[], selectedOptions: orgCascaderType[]){
  99. if(selectedOptions && selectedOptions.length){
  100. let orgList = selectedOptions.map(item => {
  101. return {
  102. value:item.value,
  103. label:item.label
  104. }
  105. })
  106. const orgParams = {
  107. ...orgInfo,
  108. value:JSON.stringify(orgList)
  109. }
  110. sysSet(orgParams, "PUT").then(res=>{
  111. if(res.status === 0){
  112. dispatch(updateSystemOrgState(orgParams))
  113. message.success("修改成功")
  114. }
  115. })
  116. }
  117. }
  118. let newAccountInfo = {
  119. name:'',
  120. value: ''
  121. }
  122. function onSaveAccount(){
  123. const accountParams = {
  124. code:"UPLOAD_USERNAME",
  125. name:accountInfo.name,
  126. value:newAccountInfo.value,
  127. id:accountInfo.id
  128. }
  129. sysSet(accountParams, "PUT").then(res=>{
  130. if(res.status === 0){
  131. dispatch(updateSystemAccountState(accountParams))
  132. message.success("修改成功")
  133. }
  134. })
  135. }
  136. function onAccountChange(accountValue:string){
  137. newAccountInfo.name = accountInfo.name || '';
  138. newAccountInfo.value = accountValue;
  139. }
  140. function convertToCascaderData(data:OrgItem[]) {
  141. return data.map(item => {
  142. const newItem:orgCascaderType = {
  143. value: item.key,
  144. label: item.value,
  145. };
  146. if (item.gwdDicList && item.gwdDicList.length > 0) {
  147. newItem.children = item.gwdDicList.map(gwdItem => {
  148. const newGwdItem:GwdItem = {
  149. value: gwdItem.key,
  150. label: gwdItem.value,
  151. };
  152. if (gwdItem.railDicList && gwdItem.railDicList.length > 0) {
  153. newGwdItem.children = gwdItem.railDicList.map(railItem => ({
  154. value: railItem.key,
  155. label: railItem.value || railItem.input
  156. }));
  157. }
  158. return newGwdItem;
  159. });
  160. }
  161. return newItem;
  162. });
  163. }
  164. const [loading, setLoading] = useState(false);
  165. function onBleStart() {
  166. start().then(() => {
  167. setLoading(true);
  168. message.success('蓝牙开始扫描')
  169. })
  170. }
  171. function onBleStop() {
  172. stop().then(() => {
  173. })
  174. }
  175. let connecting = ''
  176. function bleConnect(address: string) {
  177. setBleList(bleList.map(item => {
  178. if (item.address === address) {
  179. item.loading = true
  180. }
  181. return item
  182. }))
  183. connecting = address;
  184. connect(address).then((res) => {
  185. if (res.status !== 0) {
  186. // @ts-ignore
  187. message.error(res.data?.info || res.message)
  188. return
  189. }
  190. message.success('蓝牙连接成功')
  191. }).finally(() => {
  192. setBleList(bleList.map(item => {
  193. if (item.address === address) {
  194. item.loading = false
  195. }
  196. return item
  197. }))
  198. connecting = '';
  199. })
  200. }
  201. function bleDisconnect() {
  202. disconnect().then(() => {
  203. message.success('蓝牙断开连接')
  204. })
  205. }
  206. const connectionStatus = () => {
  207. if (!deviceInfo.isConnected) {
  208. if (loading) {
  209. return (
  210. <section className='p-[20px]'>
  211. <div> <LoadingOutlined /></div>
  212. {bleList.map(item => {
  213. return <div key={item.address}>
  214. <div className={'flex justify-between w-1/4 pt-2.5'}>
  215. <p >
  216. <p className={'text-[16px] text-gray-400'}>{item.name}</p>
  217. <p className={'text-[12px] text-gray-400'}>{item.address}</p>
  218. </p>
  219. {
  220. item.connect ? <p className={'text-[12px] text-gray-400'}></p> : <Button loading={item.loading} type={'primary'} onClick={() =>bleConnect(item.address)}></Button>
  221. }
  222. </div>
  223. </div>
  224. })}
  225. </section>
  226. );
  227. }else {
  228. return (
  229. <Button className='m-[20px]' onClick={onBleStart}></Button>
  230. )
  231. }
  232. } else {
  233. if(deviceInfo.connectedType === 'UART_CHANNEL') {
  234. return (
  235. <div className='p-[20px]'>
  236. usb连接
  237. <div className="mt-[1rem] ml-[1.6rem]">sn码{deviceInfo.sn}</div>
  238. </div>
  239. )
  240. }else if(deviceInfo.connectedType === 'BLE_CHANNEL') {
  241. return (
  242. <div className='p-[20px]'>
  243. <Button className={'ml-[10px]'} onClick={bleDisconnect}></Button>
  244. <div className="mt-[1rem] ml-[1.6rem]">sn码{deviceInfo.sn}</div>
  245. </div>
  246. )
  247. }
  248. }
  249. };
  250. const saveSet = (item:systemItem, value:string) => {
  251. const params = {
  252. id:item.id,
  253. value
  254. }
  255. sysSet(params, "PUT").then(res=>{
  256. })
  257. }
  258. const form = () =>{
  259. return <Form
  260. name="basic"
  261. labelCol={{ span: 3, offset: 1 }}
  262. wrapperCol={{ span: 16 }}
  263. style={{ maxWidth: 600 }}
  264. autoComplete="off"
  265. >
  266. {
  267. systemList.map((item, index) => {
  268. return <Form.Item
  269. key={index}
  270. label={item.name}
  271. name={item.code}
  272. >
  273. {item.code === 'ORG' ?
  274. <Cascader className='w-[300px]' key={orgValues.length} defaultValue={orgValues} options={KTJOrgList} onChange={onOrgChange} placeholder="请选择局段线" />
  275. : <Input defaultValue={item.value} onBlur={(e) => saveSet(item, e.target.value)}/>}
  276. </Form.Item>
  277. })
  278. }
  279. </Form>
  280. }
  281. // @ts-ignore
  282. return <><div className={'pr-2.5 pl-2.5 w-full h-full'}>
  283. <div className={'h-full w-full bg-white p-10 rounded-2xl'}>
  284. <h1 className='text-[20px]'></h1>
  285. <section className='p-[20px]'>
  286. {form()}
  287. {/*<div>*/}
  288. {/* <span>铁路局:</span>*/}
  289. {/* <Cascader className='w-[300px]' key={orgValues.length} defaultValue={orgValues} options={KTJOrgList} onChange={onOrgChange} placeholder="请选择局段线" /></div>*/}
  290. {/*<div className='mt-[10px]'>*/}
  291. {/* <span> {accountInfo.name}:</span>*/}
  292. {/* <Input key={accountInfo.value} defaultValue={accountInfo.value} onChange={(e)=>{onAccountChange(e.target.value)}} className='w-[300px]'></Input>*/}
  293. {/* <Button className='ml-[10px]' size='small' type="primary" onClick={onSaveAccount}>保存</Button>*/}
  294. {/*</div>*/}
  295. </section>
  296. <h1 className='text-[20px]'></h1>
  297. {connectionStatus()}
  298. </div>
  299. </div>
  300. </>
  301. }