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.

584 lines
19 KiB

1 year ago
1 year ago
11 months ago
12 months ago
11 months ago
12 months ago
11 months ago
12 months ago
11 months ago
12 months ago
11 months ago
12 months ago
11 months ago
12 months ago
11 months ago
12 months ago
1 year ago
1 year ago
1 year ago
1 year ago
12 months ago
11 months ago
1 year ago
12 months ago
1 year ago
12 months ago
1 year ago
11 months ago
1 year ago
12 months ago
11 months ago
1 year ago
11 months ago
1 year ago
1 year ago
1 year ago
12 months ago
11 months ago
1 year ago
12 months ago
1 year ago
12 months ago
1 year ago
11 months ago
1 year ago
12 months ago
11 months ago
1 year ago
12 months ago
1 year ago
12 months ago
1 year ago
11 months ago
1 year ago
12 months ago
11 months ago
1 year ago
1 year ago
1 year ago
11 months ago
1 year ago
1 year ago
12 months ago
1 year ago
12 months ago
1 year ago
1 year ago
1 year ago
12 months ago
1 year ago
1 year ago
1 year ago
12 months ago
1 year ago
1 year ago
1 year ago
12 months ago
1 year ago
12 months ago
1 year ago
1 year ago
1 year ago
11 months ago
1 year ago
12 months ago
1 year ago
11 months ago
1 year ago
11 months ago
1 year ago
12 months ago
1 year ago
1 year ago
12 months ago
1 year ago
1 year ago
12 months ago
1 year ago
12 months ago
1 year ago
12 months ago
1 year ago
12 months ago
1 year ago
1 year ago
12 months ago
1 year ago
12 months ago
1 year ago
12 months ago
1 year ago
12 months ago
1 year ago
12 months ago
1 year ago
12 months ago
1 year ago
12 months ago
1 year ago
12 months ago
1 year ago
1 year ago
11 months ago
1 year ago
12 months ago
1 year ago
12 months ago
1 year ago
1 year ago
1 year ago
12 months ago
1 year ago
1 year ago
11 months ago
12 months ago
1 year ago
1 year ago
12 months ago
1 year ago
12 months ago
1 year ago
1 year ago
12 months ago
1 year ago
12 months ago
11 months ago
1 year ago
1 year ago
12 months ago
1 year ago
12 months ago
1 year ago
1 year ago
12 months ago
1 year ago
12 months ago
1 year ago
1 year ago
12 months ago
1 year ago
12 months ago
11 months ago
11 months ago
11 months ago
12 months ago
1 year ago
1 year ago
1 year ago
1 year ago
12 months ago
1 year ago
12 months ago
1 year ago
12 months ago
1 year ago
12 months ago
1 year ago
12 months ago
1 year ago
12 months ago
1 year ago
12 months ago
1 year ago
1 year ago
12 months ago
1 year ago
12 months ago
1 year ago
12 months ago
1 year ago
12 months ago
1 year ago
12 months ago
1 year ago
12 months ago
11 months ago
12 months ago
1 year ago
1 year ago
1 year ago
12 months ago
1 year ago
12 months ago
1 year ago
12 months ago
1 year ago
1 year ago
12 months ago
1 year ago
11 months ago
12 months ago
1 year ago
12 months ago
1 year ago
1 year ago
12 months ago
1 year ago
12 months ago
1 year ago
12 months ago
1 year ago
1 year ago
1 year ago
12 months ago
11 months ago
1 year ago
1 year ago
1 year ago
12 months ago
11 months ago
1 year ago
1 year ago
12 months ago
1 year ago
1 year ago
12 months ago
1 year ago
12 months ago
1 year ago
12 months ago
1 year ago
12 months ago
1 year ago
  1. <template>
  2. <div>
  3. <!--组件主体-->
  4. <div :style="`height: ${tableHeight}px;font-size:14px;z-index:10;background-color: #f4f8ff;`">
  5. <div style="display: flex">
  6. <div>
  7. <div>
  8. <span>分诊房间:</span>
  9. <el-select v-model="LocalConfig.doctorCheck.queueRoom" placeholder="分诊房间" clearable filterable
  10. style="width: 100px" size="small">
  11. <el-option v-for="item in dict.room" :key="item.id" :label="item.displayName" :value="item.id" />
  12. </el-select>
  13. </div>
  14. <div>
  15. <el-cascader :options="dict.itemTypeTree" v-model="LocalConfig.doctorCheck.queueItemTypeIds"
  16. popper-class="example" style="width: 160px" :props="{
  17. checkStrictly: true,
  18. expandTrigger: 'hover',
  19. label: 'displayName',
  20. value: 'id',
  21. id: 'id',
  22. children: 'treeChildren',
  23. multiple: true,
  24. }" clearable filterable size="small" collapse-tags>
  25. </el-cascader>
  26. </div>
  27. </div>
  28. <div style="display: flex;flex-direction: column;justify-content: space-evenly;">
  29. <div>
  30. <el-button type="primary" class="commonbutton" :style="[
  31. { width: '40px' },
  32. { minWidth: '40px' },
  33. { height: '26px' },
  34. {
  35. backgroundColor: isSignIn == 'N' ? 'red' : '',
  36. }
  37. ]" :disabled="isSignIn == 'Y'" @click="btnIsSignIn('0')">签到</el-button>
  38. </div>
  39. <div>
  40. <el-button type="primary" class="commonbutton" style="width: 40px; min-width: 40px; height: 26px"
  41. :disabled="isSignIn == 'N'" @click="btnIsSignIn('1')">签退</el-button>
  42. </div>
  43. </div>
  44. </div>
  45. <!--
  46. <div>
  47. <span>候诊人员</span>
  48. <el-input placeholder="候诊人员" v-model="patientName" size="small" style="width: 125px;" clearable />
  49. </div>
  50. -->
  51. <div style="display: flex">
  52. <el-table :data="waitDetail" style="width: 100%" border highlight-current-row @row-click="rowClickWait"
  53. :row-style="{ height: '28px' }" :height="Math.floor((tableHeight - 72) / 3)">
  54. <el-table-column prop="queueRegisterNumber" label="号" min-width="30" align="center" />
  55. <el-table-column prop="patientName" label="姓名" min-width="80" align="center" />
  56. <el-table-column prop="isVip" label="Vip" min-width="40" align="center">
  57. <template slot-scope="scope">
  58. <div style="font-family: 'Microsoft YaHei'">
  59. {{ scope.row.isVip == "Y" ? "√" : "" }}
  60. </div>
  61. </template>
  62. </el-table-column>
  63. </el-table>
  64. <div style="margin-top: 20px">
  65. <div>
  66. <el-button type="primary" class="commonbutton" @click="btnCall(waitRow.queueRegisterId, '1')"
  67. style="width: 40px; min-width: 40px; height: 26px">呼叫</el-button>
  68. </div>
  69. <div style="margin: 10px 0">
  70. <el-button type="primary" class="commonbutton" @click="
  71. getQueueRegisterList(
  72. LocalConfig.doctorCheck.queueRoom,
  73. LocalConfig.doctorCheck.queueItemTypeIds
  74. )
  75. " style="width: 40px; min-width: 40px; height: 26px">刷新</el-button>
  76. </div>
  77. <div>
  78. <el-button type="primary" class="commonbutton" @click="fnQueue"
  79. style="width: 40px; min-width: 40px; height: 26px">排队</el-button>
  80. </div>
  81. </div>
  82. </div>
  83. <div style="margin-top: 6px">已呼人员</div>
  84. <div style="display: flex">
  85. <el-table :data="alreadyCalledDetail" style="width: 100%" border highlight-current-row
  86. @row-click="rowClickAlready" :row-style="{ height: '28px' }" :height="Math.floor((tableHeight - 72) / 3)">
  87. <el-table-column prop="queueRegisterNumber" label="号" min-width="30" align="center" />
  88. <el-table-column prop="patientName" label="姓名" min-width="80" align="center" />
  89. <el-table-column prop="isVip" label="Vip" min-width="40" align="center">
  90. <template slot-scope="scope">
  91. <div style="font-family: 'Microsoft YaHei'">
  92. {{ scope.row.isVip == "Y" ? "√" : "" }}
  93. </div>
  94. </template>
  95. </el-table-column>
  96. </el-table>
  97. <div style="margin-top: 20px">
  98. <div>
  99. <el-button type="primary" class="commonbutton" @click="btnCall(alreadyRow, '2')"
  100. style="width: 40px; min-width: 40px; height: 26px">过号</el-button>
  101. </div>
  102. </div>
  103. </div>
  104. <div style="margin-top: 6px">过号人员</div>
  105. <div style="display: flex">
  106. <el-table :data="overNumberDetail" style="width: 100%" border highlight-current-row @row-click="rowClickOver"
  107. :row-style="{ height: '28px' }" :height="Math.floor((tableHeight - 72) / 3)">
  108. <el-table-column prop="queueRegisterNumber" label="号" min-width="30" align="center" />
  109. <el-table-column prop="patientName" label="姓名" min-width="80" align="center" />
  110. <el-table-column prop="isVip" label="Vip" min-width="40" align="center">
  111. <template slot-scope="scope">
  112. <div style="font-family: 'Microsoft YaHei'">
  113. {{ scope.row.isVip == "Y" ? "√" : "" }}
  114. </div>
  115. </template>
  116. </el-table-column>
  117. </el-table>
  118. <div style="margin-top: 20px">
  119. <div>
  120. <el-button type="primary" class="commonbutton" @click="btnCall(overRow, '9')"
  121. style="width: 40px; min-width: 40px; height: 26px">重呼</el-button>
  122. </div>
  123. <div style="margin: 10px 0">
  124. <el-button type="primary" class="commonbutton" @click="btnCall(overRow, '0')"
  125. style="width: 40px; min-width: 40px; height: 26px">退回</el-button>
  126. </div>
  127. </div>
  128. </div>
  129. </div>
  130. <!--组件弹窗-->
  131. <div>
  132. <!-- 修改信息 -->
  133. <el-dialog title="分诊排队" :visible.sync="dialogWin.queue" width="800px" :append-to-body="true"
  134. :close-on-click-modal="false">
  135. <Queue :refParams="queueParams" />
  136. </el-dialog>
  137. </div>
  138. </div>
  139. </template>
  140. <script>
  141. import { mapState } from "vuex";
  142. import { getapi, postapi, putapi, deletapi } from "@/api/api";
  143. import {
  144. listOrderBy,
  145. setCheckStatusColor,
  146. deepCopy,
  147. } from "../../utlis/proFunc";
  148. import Queue from "../../components/queue/Queue.vue";
  149. export default {
  150. components: {
  151. Queue,
  152. },
  153. data() {
  154. return {
  155. queueParams: {},
  156. patientName: "",
  157. waitDetail: [],
  158. alreadyCalledDetail: [],
  159. overNumberDetail: [],
  160. waitRow: {},
  161. alreadyRow: {},
  162. overRow: {},
  163. LocalConfig: {
  164. doctorCheck: {
  165. // 医生诊台
  166. isQueue: "N", //启用分诊排队
  167. queueRoom: "", //默认分诊房间
  168. queueItemTypeIds: [], // 检查类别
  169. isBroadcast: "N", // 是否广播
  170. },
  171. },
  172. LocalConfigInit: {},
  173. interval: null, // 定时器句柄
  174. queue_after_call: 'N', // 呼叫后是否自动排队
  175. queue_refresh_interval: 15, // 叫号刷新时间间隔(秒)
  176. queue_play_voice_repeate_times: 2, // 语音重复播放次数
  177. queue_play_voice_repeate_interval: 1, // 语音重复播放时间间隔(秒)
  178. isSignIn: "N"//是否签到
  179. };
  180. },
  181. created() { },
  182. //挂载完成
  183. mounted() {
  184. this.fnMounted();
  185. },
  186. destroyed() {
  187. console.log("this.interval", JSON.stringify(this.interval));
  188. if (this.interval) clearInterval(this.interval);
  189. console.log("this.interval clearInterval", JSON.stringify(this.interval));
  190. },
  191. computed: {
  192. ...mapState([
  193. "window",
  194. "dialogWin",
  195. "dataTransOpts",
  196. "dict",
  197. "doctorCheck",
  198. ]),
  199. tableHeight() {
  200. return this.window.pageHeight < 600 ? 390 : this.window.pageHeight - 210;
  201. },
  202. },
  203. methods: {
  204. setCheckStatusColor,
  205. tableRowClassName({ row, rowIndex }) {
  206. //console.log('tableRowClassName',rowIndex,row)
  207. if (row.completeFlag === "0") {
  208. return "danger"; //未检
  209. } else if (row.completeFlag === "2") {
  210. return "info"; //弃检
  211. }
  212. return "";
  213. },
  214. async fnMounted() {
  215. this.LocalConfigInit = deepCopy(this.LocalConfig);
  216. let LocalConfig = window.localStorage.getItem("LocalConfig") || null;
  217. try {
  218. this.LocalConfig = Object.assign(
  219. {},
  220. deepCopy(this.LocalConfigInit),
  221. JSON.parse(LocalConfig) || {}
  222. );
  223. } catch (error) {
  224. console.log('window.localStorage.getItem("LocalConfig")', error);
  225. }
  226. if (this.LocalConfig.doctorCheck.isQueue == "Y") {
  227. this.dictInit().then((res) => {
  228. if (!this.LocalConfig.doctorCheck.queueRoom) {
  229. if (res.data.length > 0)
  230. this.LocalConfig.doctorCheck.queueRoom = res.data[0].id;
  231. }
  232. if (this.LocalConfig.doctorCheck.queueRoom)
  233. this.getQueueRegisterListByRoomId(
  234. this.LocalConfig.doctorCheck.queueRoom
  235. );
  236. });
  237. this.setQueueParams();
  238. try {
  239. let sysParam = await postapi(
  240. "/api/app/SysParmValue/GetSysParmValueBySysParmId",
  241. { sysParmId: "queue_refresh_interval" }
  242. );
  243. this.queue_refresh_interval = Number(sysParam.data || 15);
  244. } catch (error) {
  245. console.log(error);
  246. }
  247. // 叫号后是否自动排队
  248. try {
  249. let sysParam = await postapi(
  250. "/api/app/SysParmValue/GetSysParmValueBySysParmId",
  251. { sysParmId: "queue_after_call" }
  252. );
  253. this.queue_after_call = sysParam.data;
  254. } catch (error) {
  255. console.log(error);
  256. }
  257. // 壳端
  258. if (this.$peisAPI) {
  259. postapi("/api/app/SysParmValue/GetSysParmValueBySysParmId", {
  260. sysParmId: "queue_play_voice_repeate_times",
  261. }).then((res) => {
  262. if (res.code > -1)
  263. this.queue_play_voice_repeate_times = Number(res.data || 2);
  264. });
  265. postapi("/api/app/SysParmValue/GetSysParmValueBySysParmId", {
  266. sysParmId: "queue_play_voice_repeate_interval",
  267. }).then((res) => {
  268. if (res.code > -1)
  269. this.queue_play_voice_repeate_interval = Number(res.data || 1);
  270. });
  271. }
  272. // 启动自动刷新
  273. if (!this.interval && this.queue_refresh_interval != 0) {
  274. this.interval = setInterval(() => {
  275. this.getQueueRegisterList(
  276. this.LocalConfig.doctorCheck.queueRoom,
  277. this.LocalConfig.doctorCheck.queueItemTypeIds
  278. );
  279. }, this.queue_refresh_interval * 1000);
  280. }
  281. }
  282. },
  283. btnCall(refRow, completeFlag) {
  284. let prePatientRegisterId = ''
  285. let row = Object.assign({}, refRow);
  286. switch (completeFlag) {
  287. case "0": // 退回
  288. if (!row.queueRegisterId) {
  289. if (this.overNumberDetail.length > 0)
  290. row = this.overNumberDetail[0];
  291. }
  292. if (!row.queueRegisterId)
  293. this.$message.warning({
  294. showClose: true,
  295. message: "未可操作的数据,或未选择过号人员",
  296. });
  297. break;
  298. case "1": // 呼叫
  299. if (!row.queueRegisterId) {
  300. if (this.waitDetail.length > 0) row = this.waitDetail[0];
  301. }
  302. if (!row.queueRegisterId)
  303. this.$message.warning({
  304. showClose: true,
  305. message: "未可操作的数据,或未选择候诊人员",
  306. });
  307. if (this.alreadyCalledDetail.length > 0) prePatientRegisterId = this.alreadyCalledDetail[0].patientRegisterId
  308. break;
  309. case "2": // 过号
  310. if (!row.queueRegisterId) {
  311. if (this.alreadyCalledDetail.length > 0)
  312. row = this.alreadyCalledDetail[0];
  313. }
  314. if (!row.queueRegisterId)
  315. this.$message.warning({
  316. showClose: true,
  317. message: "未可操作的数据,或未选择已呼人员",
  318. });
  319. break;
  320. case "9": // 重呼
  321. if (!row.queueRegisterId) {
  322. if (this.overNumberDetail.length > 0)
  323. queueRegisterId = this.overNumberDetail[0];
  324. }
  325. if (!row.queueRegisterId)
  326. this.$message.warning({
  327. showClose: true,
  328. message: "未可操作的数据,或未选择过号人员",
  329. });
  330. break;
  331. }
  332. // "patientRegisterId": "3a143cf9-0b1b-7765-a90a-b087c4aad1b9",
  333. // "patientRegisterNo": "003485"
  334. // 叫号即调人员信息出来
  335. if (row.patientRegisterNo) {
  336. this.dataTransOpts.tableS.patient_register.patientRegisterNo =
  337. row.patientRegisterNo;
  338. this.dataTransOpts.refresh.patient_register.S++;
  339. }
  340. if (row.queueRegisterId && completeFlag != "9") {
  341. postapi("/api/app/QueueRegister/UpdateQueueRegisterStatus", {
  342. queueRegisterId: row.queueRegisterId,
  343. completeFlag,
  344. }).then((res) => {
  345. if (res.code > -1) {
  346. this.getQueueRegisterList(
  347. this.LocalConfig.doctorCheck.queueRoom,
  348. this.LocalConfig.doctorCheck.queueItemTypeIds
  349. );
  350. if (this.$peisAPI && completeFlag == "1") this.outShellCall(row);
  351. if (this.queue_after_call == 'Y' && prePatientRegisterId) return postapi('/api/app/QueueRegister/AutomaticQueuingRoom', {
  352. patientRegisterId: prePatientRegisterId
  353. })
  354. }
  355. });
  356. } else if (completeFlag == "9") {
  357. if (this.$peisAPI) this.outShellCall(row);
  358. }
  359. },
  360. // 调用壳呼叫 api
  361. outShellCall(row) {
  362. let roomName = "";
  363. postapi("/api/app/Room/Get", {
  364. roomId: this.LocalConfig.doctorCheck.queueRoom,
  365. })
  366. .then((res) => {
  367. if (res.code > -1) {
  368. roomName = res.data.displayName;
  369. return this.$peisAPI.getIsSpeechEnable();
  370. }
  371. })
  372. .then((res) => {
  373. if (res == "Y") return this.$peisAPI.speechConnect();
  374. })
  375. .then((res) => {
  376. // queue_play_voice_repeate_times: 2, // 语音重复播放次数
  377. // queue_play_voice_repeate_interval: 1, // 语音重复播放时间间隔(秒)
  378. let toOutShell = {
  379. SendText: `${row.patientName}${roomName}检查`,
  380. RepatPlayNum: this.queue_play_voice_repeate_times,
  381. Delay: this.queue_play_voice_repeate_interval,
  382. };
  383. return this.$peisAPI.speechSendText(JSON.stringify(toOutShell));
  384. })
  385. .catch((err) => {
  386. // console.log('呼叫失败', err)
  387. this.$message.error({ showClose: true, message: err });
  388. });
  389. },
  390. dictInit() {
  391. return new Promise((resolve, reject) => {
  392. postapi("/api/app/Room/GetList")
  393. .then((res) => {
  394. if (res.code > -1) {
  395. this.dict.room = res.data;
  396. // this.tableData = res.data.filter(e => {
  397. // return medicalCenterId ? (e.medicalCenterId == medicalCenterId) : e
  398. // });
  399. resolve(res);
  400. } else {
  401. reject(res.message);
  402. }
  403. })
  404. .catch((err) => {
  405. reject(err);
  406. });
  407. });
  408. },
  409. btnIsSignIn(signInFlag) {
  410. postapi("/api/app/RegisterCheck/CreateDoctorSignIn", {
  411. roomId: this.LocalConfig.doctorCheck.queueRoom,
  412. signInFlag: signInFlag
  413. }).then((res) => {
  414. if (res.code != -1) {
  415. if (signInFlag == '0') {
  416. this.isSignIn = 'Y'
  417. } else {
  418. this.isSignIn = 'N'
  419. }
  420. }
  421. })
  422. },
  423. getQueueRegisterList(roomId, itemType) {
  424. return new Promise((resolve, reject) => {
  425. this.waitDetail = [];
  426. this.alreadyCalledDetail = [];
  427. this.overNumberDetail = [];
  428. this.waitRow = {};
  429. this.alreadyRow = {};
  430. this.overRow = {};
  431. let itemTypeIds = [];
  432. itemType.forEach((e) => {
  433. e.forEach((item) => {
  434. itemTypeIds.push(item);
  435. });
  436. });
  437. if (roomId) {
  438. postapi("/api/app/QueueRegister/GetQueueRegisterListByRoomId", {
  439. roomId,
  440. itemTypeIds,
  441. })
  442. .then((res) => {
  443. if (res.code > -1) {
  444. this.waitDetail = res.data.waitDetail;
  445. this.alreadyCalledDetail = res.data.alreadyCalledDetail;
  446. this.overNumberDetail = res.data.overNumberDetail;
  447. resolve(res);
  448. } else {
  449. reject(res.message);
  450. }
  451. })
  452. .catch((err) => {
  453. reject(err);
  454. });
  455. } else {
  456. reject("请选择房间");
  457. }
  458. });
  459. },
  460. // 获取房间排队信息 ByRoomId
  461. getQueueRegisterListByRoomId(roomId) {
  462. if (!roomId) {
  463. this.$message.warning({ showClose: true, message: "请选择房间" });
  464. return;
  465. }
  466. postapi("/api/app/RegisterCheck/GetDoctorIsSignIn", {
  467. roomId: roomId
  468. }).then((res) => {
  469. this.isSignIn = res.data.isSignIn
  470. })
  471. this.getQueueRegisterList(
  472. roomId,
  473. this.LocalConfig.doctorCheck.queueItemTypeIds
  474. );
  475. },
  476. // 获取房间排队信息 ByRoomId
  477. getQueueRegisterListByItemTypeIds(itemTypeIds) {
  478. if (this.LocalConfig.doctorCheck.queueRoom) {
  479. this.getQueueRegisterList(
  480. this.LocalConfig.doctorCheck.queueRoom,
  481. itemTypeIds
  482. );
  483. }
  484. },
  485. setQueueParams() {
  486. this.queueParams.patientRegisterId =
  487. this.dataTransOpts.tableS.patient_register.id;
  488. },
  489. // 分诊排队
  490. fnQueue() {
  491. if (!this.queueParams.patientRegisterId) {
  492. this.$message.warning({ showClose: true, message: "未获取到人员信息" });
  493. return;
  494. }
  495. this.dataTransOpts.plus.queue++;
  496. this.dialogWin.queue = true;
  497. },
  498. // 选择候诊人员
  499. rowClickWait(row) {
  500. this.waitRow = row;
  501. this.queueParams = {
  502. patientRegisterId: row.patientRegisterId,
  503. };
  504. },
  505. // 选择过号人员
  506. rowClickAlready(row) {
  507. this.alreadyRow = row;
  508. this.queueParams = {
  509. patientRegisterId: row.patientRegisterId,
  510. };
  511. },
  512. // 选择过号人员
  513. rowClickOver(row) {
  514. this.overRow = row;
  515. },
  516. },
  517. //监听事件
  518. watch: {
  519. //体检人员未切换时 也可以强制刷新数据
  520. "dataTransOpts.refresh.register_check.M": {
  521. // immediate:true,
  522. handler(newVal, oldVal) {
  523. console.log(
  524. `watch 组合项目列表 newVal: ${newVal} oldVal: ${oldVal} patient_register.id: ${this.dataTransOpts.tableS.patient_register.id}`
  525. );
  526. if (newVal != oldVal) {
  527. this.fnMounted();
  528. }
  529. },
  530. },
  531. },
  532. };
  533. </script>
  534. <style scoped>
  535. ::v-deep .el-collapse-item__header {
  536. height: 32px;
  537. line-height: 32px;
  538. background-color: #f4f8ff;
  539. color: #303133;
  540. cursor: pointer;
  541. font-size: 14px;
  542. font-weight: 700;
  543. text-align: center;
  544. padding: 0 0 0 50px;
  545. }
  546. </style>