asignar-descarga.php 9.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322
  1. <style>
  2. .site-card {
  3. min-height: 100vh;
  4. width: 100%;
  5. padding: 20px;
  6. background: #ececec;
  7. }
  8. .content {
  9. width: 100%;
  10. height: 100%;
  11. }
  12. .full-width {
  13. width: 100%;
  14. }
  15. .codigo {
  16. width: 50%;
  17. height: 500px;
  18. background: #fff;
  19. }
  20. </style>
  21. <script type="text/babel">
  22. const url = "https://api.fourier.audio";
  23. const urlDescarga = "https://descarga.fourier.audio";
  24. const { LoadingOutlined } = window.icons;
  25. const { Card, Select, Spin, Row, Col, Form, Input, Button, Modal, DatePicker, Table, Popconfirm, Checkbox } = window.antd;
  26. const { Option } = Select;
  27. const { RangePicker } = DatePicker;
  28. const App = () => {
  29. const [loading, setLoading] = React.useState(true);
  30. const [estDisabled, setEstDisabled] = React.useState(false);
  31. const [grupos, setGrupos] = React.useState([]);
  32. const [estaciones, setEstaciones] = React.useState([]);
  33. const [estacion, setEstacion] = React.useState(null);
  34. const [modalVisible, setModalVisible] = React.useState(false);
  35. const [reiniciar, setReiniciar] = React.useState(false);
  36. const [data, setData] = React.useState([]);
  37. const [debug, setDebug] = React.useState(null);
  38. const [form] = Form.useForm();
  39. const loadingIcon = <LoadingOutlined style={{ fontSize: 24 }} spin />;
  40. let obtenerGrupos = async () => {
  41. const resp = await fetch(`${url}/na/grupo`)
  42. const json = await resp.json();
  43. setLoading(false);
  44. setGrupos(json.resultado);
  45. }
  46. React.useEffect(() => {
  47. obtenerGrupos();
  48. }, []);
  49. const onCityChange = async (id) => {
  50. setEstDisabled(true);
  51. const resp = await fetch(`${url}/na/grupo?id=${id}&expand=ciudades.monitoreable&ordenar=nombre`)
  52. const json = await resp.json();
  53. let ciudad = json.resultado[0].ciudades[0];
  54. let _estaciones = [];
  55. for(let estacion of ciudad.monitoreable) {
  56. _estaciones.push({
  57. "idCiudad": ciudad.id,
  58. "idEstacion": estacion.id,
  59. "clave": estacion.clave,
  60. "frecuencia": estacion.frecuencia,
  61. "siglas": estacion.siglas
  62. })
  63. }
  64. setEstaciones(_estaciones);
  65. setEstDisabled(false);
  66. }
  67. const onStationChange = async (id) => {
  68. for(let est of estaciones) {
  69. if(est.idEstacion == id) {
  70. setEstacion(est);
  71. break;
  72. }
  73. }
  74. }
  75. const confirmar = (f) => {
  76. let body = {
  77. idPc: f.idPc,
  78. fi: f.fechas[0].format(),
  79. ff: f.fechas[1].format(),
  80. reiniciar: reiniciar,
  81. estaciones: data
  82. }
  83. const fi = f.fechas[0].format("DD/MM/YYYY");
  84. const ff = f.fechas[1].format("DD/MM/YYYY");
  85. Modal.confirm({
  86. title: `¿Guardar ${body.estaciones.length} estaciones en PC "${body.idPc}" desde ${fi} hasta ${ff}?`,
  87. // content: <pre>{JSON.stringify(data)}</pre>,
  88. onOk: () => { handleOk(body) } ,
  89. });
  90. }
  91. const handleOk = async (cuerpo) => {
  92. let resp = await fetch(`/descarga/guardar`, {
  93. method: "POST",
  94. body: JSON.stringify(cuerpo),
  95. headers: {
  96. "Content-Type": "application/json"
  97. }
  98. });
  99. setDebug(cuerpo);
  100. form.setFieldsValue({ idPc: '' });
  101. setData([]);
  102. }
  103. const agregarEstacion = () => {
  104. if(estacion === null) {
  105. Modal.warning({
  106. title: 'No eligió una estación',
  107. content: 'Por favor seleccione una estación'
  108. });
  109. return;
  110. }
  111. const found = data.find(e => e.idEstacion === estacion.idEstacion);
  112. if(found) {
  113. Modal.warning({
  114. title: `La Estación ${estacion.siglas} ya se encuentra en la lista`
  115. });
  116. return;
  117. }
  118. let _data = [...data];
  119. _data.push({
  120. key: `${estacion.idCiudad}-${estacion.idEstacion}`,
  121. ...estacion,
  122. });
  123. form.setFieldsValue({ idEstacion: null })
  124. setEstacion(null);
  125. setData(_data);
  126. return;
  127. }
  128. const obtenerEstacionDelPC = async () => {
  129. let idPc = form.getFieldValue('idPc');
  130. if(!idPc) {
  131. Modal.warning({
  132. title: 'No eligió un PC',
  133. content: 'Por favor seleccione un PC'
  134. });
  135. return;
  136. }
  137. let resp = await fetch(`/estacion/por-pc?pc=${idPc}`);
  138. let data = await resp.json();
  139. setData(data.resultado);
  140. }
  141. const eliminar = (key) => {
  142. const _data = [...data];
  143. setData(_data.filter(item => item.key !== key) );
  144. }
  145. const columnas = [
  146. {
  147. title: 'ID Ciudad',
  148. dataIndex: 'idCiudad',
  149. key: '1',
  150. },
  151. {
  152. title: 'Clave',
  153. dataIndex: 'clave',
  154. key: '2',
  155. },
  156. {
  157. title: 'Eliminar',
  158. key: '3',
  159. render(r) {
  160. return (
  161. <Popconfirm
  162. title="¿Eliminar?"
  163. okText="OK"
  164. cancelText="Cancelar"
  165. onConfirm={() => eliminar(r.key)}>
  166. <a>Eliminar</a>
  167. </Popconfirm>
  168. )
  169. }
  170. }
  171. ];
  172. return (
  173. <div className="site-card">
  174. { loading
  175. ? <Spin indicator={loadingIcon} />
  176. : <Card className="content">
  177. <Form
  178. form={form}
  179. layout="vertical"
  180. onFinish={confirmar}
  181. >
  182. <Row gutter={8}>
  183. <Col md={8}>
  184. <Form.Item
  185. label="ID PC"
  186. name="idPc"
  187. rules={[{ required: true, message: 'Ingresa el ID del PC' }]}
  188. >
  189. <Input size="large" />
  190. </Form.Item>
  191. </Col>
  192. <Col md={8}>
  193. <Form.Item
  194. label="Rango de Fechas"
  195. name="fechas"
  196. rules={[{ required: true, message: 'Ingresa el Rango de Fechas' }]}
  197. >
  198. <RangePicker
  199. showTime={{
  200. hideDisabledOptions: true,
  201. defaultValue: [moment('00:00:00', 'HH:mm:ss'), moment('23:59:59', 'HH:mm:ss')],
  202. }}
  203. format="DD-MM-YYYY HH:mm:ss"
  204. size="large"
  205. />
  206. </Form.Item>
  207. </Col>
  208. <Col md={8}>
  209. <Form.Item
  210. label="&nbsp;"
  211. name="reiniciar"
  212. >
  213. <Checkbox size="large" checked={reiniciar} onChange={(e) => { setReiniciar(e.target.checked) }}>
  214. ¿Reiniciar descargas?
  215. </Checkbox>
  216. </Form.Item>
  217. </Col>
  218. </Row>
  219. <Row gutter={8}>
  220. <Col md={8}>
  221. <Form.Item
  222. label="Ciudad"
  223. name="idCiudad"
  224. >
  225. <Select
  226. showSearch
  227. size="large"
  228. style={{ width: '100%' }}
  229. placeholder="Elige un grupo"
  230. optionFilterProp="children"
  231. onChange={onCityChange}
  232. filterOption={(input, option) =>
  233. option.children.toLowerCase().indexOf(input.toLowerCase()) >= 0
  234. }
  235. >
  236. { grupos && grupos.map((item) => { return <Option key={`grupo-${item.id}`} value={item.id}>{item.nombre}</Option> }) }
  237. </Select>
  238. </Form.Item>
  239. </Col>
  240. <Col md={8}>
  241. <Form.Item
  242. label="Estación"
  243. name="idEstacion"
  244. >
  245. <Select
  246. disabled={estDisabled}
  247. showSearch
  248. size="large"
  249. style={{ width: '100%' }}
  250. placeholder="Elige una estación"
  251. optionFilterProp="children"
  252. onChange={onStationChange}
  253. filterOption={(input, option) =>
  254. option.children.toLowerCase().indexOf(input.toLowerCase()) >= 0
  255. }
  256. >
  257. { estaciones && estaciones.map((item) => { return <Option key={`est-${item.idEstacion}`} value={item.idEstacion}>{item.frecuencia} - {item.siglas} - {item.clave}</Option> }) }
  258. </Select>
  259. </Form.Item>
  260. </Col>
  261. <Col md={3}>
  262. <Form.Item label="&nbsp;" >
  263. <Button className="full-width" size="large" onClick={agregarEstacion}>Agregar</Button>
  264. </Form.Item>
  265. </Col>
  266. </Row>
  267. <Row gutter={8}>
  268. <Col md={16}>
  269. <Table className="full-width" dataSource={data} columns={columnas} />
  270. </Col>
  271. <Col md={3}>
  272. <Button className="full-width" size="large" onClick={obtenerEstacionDelPC}>Estaciones del PC</Button>
  273. </Col>
  274. </Row>
  275. <Row>
  276. <Col md={8}>
  277. <Form.Item label="&nbsp;" >
  278. <Button type="primary" htmlType="submit" size="large" style={{width: '100%'}}>Guardar</Button>
  279. </Form.Item>
  280. </Col>
  281. </Row>
  282. </Form>
  283. <Row>
  284. <Col className="full-width">
  285. {debug && <pre className="codigo"><code>{JSON.stringify(debug)}</code></pre>}
  286. </Col>
  287. </Row>
  288. </Card>
  289. }
  290. </div>
  291. );
  292. }
  293. ReactDOM.render(<App />, document.getElementById('root'));
  294. </script>