Add.vue 7.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312
  1. <template>
  2. <a-modal
  3. v-model:visible="visible"
  4. :maskClosable="false"
  5. :width="580"
  6. :bodyStyle="{ height: '480px', 'overflow-y': 'auto' }"
  7. cancelText="取消"
  8. okText="确定"
  9. @ok="handleOk"
  10. >
  11. <template #title>
  12. <div ref="modalTitleRef" style="width: 100%; cursor: move">
  13. {{ isAdd ? "添加设备" : "编辑设备" }}
  14. </div>
  15. </template>
  16. <template #modalRender="{ originVNode }">
  17. <div :style="transformStyle">
  18. <component :is="originVNode" />
  19. </div>
  20. </template>
  21. <a-form
  22. ref="formRef"
  23. :model="formState"
  24. name="basic"
  25. label-align="left"
  26. :label-col="{ span: 4 }"
  27. :wrapper-col="{ span: 20 }"
  28. autocomplete="off"
  29. layout="vertical"
  30. >
  31. <!-- <a-form-item :wrapper-col="{ offset: 0, span: 24 }"
  32. label="ID"
  33. name="id"
  34. :rules="[{ required: false, message: '请输入设备编号!' }]">
  35. <a-input size="large" v-model:value="formState.id" />
  36. </a-form-item> -->
  37. <a-form-item
  38. :wrapper-col="{ offset: 0, span: 24 }"
  39. label="产品"
  40. name="productId"
  41. :rules="[{ required: true, message: '请输入设备名称!' }]"
  42. >
  43. <!-- <a-input size="large" v-model:value="formState.productId" /> -->
  44. <a-select
  45. size="large"
  46. v-model:value="formState.productId"
  47. :options="options"
  48. ></a-select>
  49. </a-form-item>
  50. <a-form-item
  51. :wrapper-col="{ offset: 0, span: 24 }"
  52. label="设备编号"
  53. name="mac"
  54. :rules="[{ required: true, message: '请输入设备编号!' }]"
  55. >
  56. <a-input size="large" v-model:value="formState.mac" />
  57. </a-form-item>
  58. <!-- <a-form-item :wrapper-col="{ offset: 0, span: 24 }"
  59. label="设备名称"
  60. name="name"
  61. :rules="[{ required: true, message: '请输入设备名称!' }]">
  62. <a-input size="large" v-model:value="formState.name" />
  63. </a-form-item> -->
  64. <a-form-item
  65. :wrapper-col="{ offset: 0, span: 24 }"
  66. label="IP"
  67. name="ipAddress"
  68. >
  69. <a-input size="large" v-model:value="formState.ipAddress" />
  70. </a-form-item>
  71. <a-form-item
  72. :wrapper-col="{ offset: 0, span: 24 }"
  73. label="网关"
  74. name="gateWay"
  75. >
  76. <a-input size="large" v-model:value="formState.gateWay" />
  77. </a-form-item>
  78. <a-form-item
  79. :wrapper-col="{ offset: 0, span: 24 }"
  80. label="子网掩码"
  81. name="netMask"
  82. >
  83. <a-input size="large" v-model:value="formState.netMask" />
  84. </a-form-item>
  85. <a-form-item
  86. :wrapper-col="{ offset: 0, span: 24 }"
  87. label="通信MAC"
  88. name="netMac"
  89. >
  90. <a-input size="large" v-model:value="formState.netMac" />
  91. </a-form-item>
  92. <a-form-item
  93. :wrapper-col="{ offset: 0, span: 24 }"
  94. label="描述"
  95. name="description"
  96. :rules="[{ required: false, message: '请输入设备名称!' }]"
  97. >
  98. <!-- <a-input size="large" v-model:value="formState.name" /> -->
  99. <a-textarea
  100. v-model:value="formState.description"
  101. placeholder="请输入描述"
  102. allow-clear
  103. />
  104. </a-form-item>
  105. <!-- <a-form-item :wrapper-col="{ offset: 0, span: 24 }">
  106. <a-button style="background: #0058FF;"
  107. size="large" block type="primary" html-type="submit">登录</a-button>
  108. </a-form-item> -->
  109. </a-form>
  110. </a-modal>
  111. </template>
  112. <script setup lang="ts">
  113. import {
  114. ref,
  115. computed,
  116. CSSProperties,
  117. watch,
  118. watchEffect,
  119. onMounted,
  120. onUnmounted,
  121. reactive,
  122. } from "vue";
  123. import { AddDeviceParams } from "@/api/model";
  124. import { post } from "@/network/axios";
  125. import { message } from "ant-design-vue";
  126. import { resetProperties } from "@/utils";
  127. import { useDraggable } from "@vueuse/core";
  128. const modalTitleRef = ref<HTMLElement>();
  129. const formRef = ref<any>(null);
  130. const visible = ref<boolean>(false);
  131. const isAdd = ref<boolean>(true);
  132. const { x, y, isDragging } = useDraggable(modalTitleRef);
  133. // 属性
  134. // const props = defineProps()
  135. // 事件
  136. const emits = defineEmits(["onSuccess"]);
  137. // 选项
  138. const options = reactive<any[]>([
  139. {
  140. value: "123",
  141. label: "网络泵",
  142. },
  143. {
  144. value: "456",
  145. label: "化疗泵",
  146. },
  147. {
  148. value: "789",
  149. label: "其他",
  150. },
  151. ]);
  152. // 添加
  153. const formState = reactive<AddDeviceParams>({
  154. id: undefined,
  155. mac: "",
  156. name: "",
  157. productId: "",
  158. netMac: "",
  159. description: "",
  160. gateWay: "",
  161. netMask: "",
  162. ipAddress: "",
  163. });
  164. const save = function () {
  165. let url = "";
  166. if (isAdd.value) {
  167. url = "/device/add";
  168. } else {
  169. url = "/device/edit";
  170. }
  171. post({ url, data: formState }, (result: any) => {
  172. console.log(result);
  173. message.info(result.msg);
  174. hidden();
  175. emits("onSuccess", result);
  176. });
  177. };
  178. const handleOk = (e: MouseEvent) => {
  179. console.log("handleOK", e);
  180. formRef.value?.validate().then(
  181. () => {
  182. console.log("11");
  183. save();
  184. },
  185. () => {
  186. console.log("22");
  187. }
  188. );
  189. };
  190. const show = () => {
  191. visible.value = true;
  192. };
  193. const hidden = () => {
  194. visible.value = false;
  195. };
  196. const add = () => {
  197. isAdd.value = true;
  198. resetProperties(formState);
  199. formRef.value?.clearValidate();
  200. show();
  201. };
  202. const update = (record: any) => {
  203. isAdd.value = false;
  204. record.id = record.deviceId;
  205. Object.assign(formState, record);
  206. formRef.value?.clearValidate();
  207. show();
  208. };
  209. // 声明周期
  210. onMounted(() => {
  211. console.log("onMounted");
  212. options.splice(0);
  213. post(
  214. {
  215. url: "/product/search",
  216. data: {
  217. size: 20,
  218. page: 1,
  219. sort: "createtime",
  220. order: "desc",
  221. },
  222. },
  223. (result: any) => {
  224. console.log(result);
  225. result.data.forEach((item: any) => {
  226. const option = {
  227. value: item.code,
  228. label: item.name,
  229. };
  230. options.push(option);
  231. });
  232. },
  233. (failed: any) => {
  234. console.log(failed);
  235. }
  236. );
  237. });
  238. onUnmounted(() => {
  239. console.log("onUnmounted");
  240. });
  241. defineExpose({
  242. add,
  243. update,
  244. });
  245. //拖拽
  246. const startX = ref<number>(0);
  247. const startY = ref<number>(0);
  248. const startedDrag = ref(false);
  249. const transformX = ref(0);
  250. const transformY = ref(0);
  251. const preTransformX = ref(0);
  252. const preTransformY = ref(0);
  253. const dragRect = ref({ left: 0, right: 0, top: 0, bottom: 0 });
  254. watch([x, y], () => {
  255. if (!startedDrag.value) {
  256. startX.value = x.value;
  257. startY.value = y.value;
  258. const bodyRect = document.body.getBoundingClientRect();
  259. const titleRect = modalTitleRef.value.getBoundingClientRect();
  260. dragRect.value.right = bodyRect.width - titleRect.width;
  261. dragRect.value.bottom = bodyRect.height - titleRect.height;
  262. preTransformX.value = transformX.value;
  263. preTransformY.value = transformY.value;
  264. }
  265. startedDrag.value = true;
  266. });
  267. watch(isDragging, () => {
  268. if (!isDragging) {
  269. startedDrag.value = false;
  270. }
  271. });
  272. watchEffect(() => {
  273. if (startedDrag.value) {
  274. transformX.value =
  275. preTransformX.value +
  276. Math.min(Math.max(dragRect.value.left, x.value), dragRect.value.right) -
  277. startX.value;
  278. transformY.value =
  279. preTransformY.value +
  280. Math.min(Math.max(dragRect.value.top, y.value), dragRect.value.bottom) -
  281. startY.value;
  282. }
  283. });
  284. const transformStyle = computed<CSSProperties>(() => {
  285. return {
  286. transform: `translate(${transformX.value}px, ${transformY.value}px)`,
  287. };
  288. });
  289. </script>
  290. <style scoped></style>