index.vue 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488
  1. <template>
  2. <div class="mainContentBox">
  3. <avue-crud
  4. ref="crudRef"
  5. v-model:search="search"
  6. v-model="form"
  7. :data="data"
  8. :option="option"
  9. v-model:page="page"
  10. @row-save="createRow"
  11. @row-update="updateRow"
  12. @row-del="deleteRow"
  13. @search-change="searchChange"
  14. @search-reset="resetChange"
  15. @size-change="dataList"
  16. @current-change="dataList"
  17. @selection-change="selectionChange"
  18. >
  19. <!-- <template #collect="scope">
  20. <el-switch
  21. active-value="1"
  22. inactive-value="0"
  23. inline-prompt
  24. active-text="是"
  25. inactive-text="否"
  26. v-model="scope.row.collect"
  27. @click="changeItem($event,scope.row)"
  28. class="ml-2"
  29. style="&#45;&#45;el-switch-on-color: #13ce66; &#45;&#45;el-switch-off-color: #ff4949"
  30. />
  31. </template>-->
  32. <template #menu="{ size, row, index }">
  33. <el-button
  34. v-hasPerm="[buttonPermission.DEVICE.BTNS.maintenance_edit]"
  35. type="primary"
  36. link
  37. size="small"
  38. @click="showParamsPage(row)"
  39. >模型
  40. <template #icon>
  41. <svg-icon icon-class="moxing" />
  42. </template>
  43. </el-button>
  44. </template>
  45. <template #menu-left="{ size }">
  46. <el-button
  47. :disabled="toDeleteIds.length < 1"
  48. type="danger"
  49. icon="el-icon-delete"
  50. :size="size"
  51. @click="multipleDelete"
  52. >删除</el-button
  53. >
  54. </template>
  55. <template #menu-right="{}">
  56. <el-dropdown split-button
  57. >导入
  58. <template #dropdown>
  59. <el-dropdown-menu>
  60. <el-dropdown-item
  61. @click="downloadTemplate('/api/v1/device/template')"
  62. >
  63. <i-ep-download />下载模板
  64. </el-dropdown-item>
  65. <el-dropdown-item @click="importExcelData">
  66. <i-ep-top />导入数据
  67. </el-dropdown-item>
  68. </el-dropdown-menu>
  69. </template>
  70. </el-dropdown>
  71. <el-button class="ml-3" @click="exportData('/api/v1/device/export')">
  72. <template #icon> <i-ep-download /> </template>导出
  73. </el-button>
  74. </template>
  75. </avue-crud>
  76. <el-dialog
  77. v-model="dialog.visible"
  78. :title="dialog.title"
  79. width="30%"
  80. @close="dialog.visible = false"
  81. >
  82. <el-button
  83. type="primary"
  84. @click="addItem"
  85. icon="el-icon-plus"
  86. style="margin-left: 15px; width: 25px; height: 25px"
  87. circle
  88. />
  89. <el-table
  90. v-loading="loading"
  91. ref="ruleListRef"
  92. :data="pageData"
  93. style="height: 280px"
  94. >
  95. <el-table-column label="参数" prop="fieldCode">
  96. <template #default="{ row }">
  97. <el-input v-model="row.fieldCode" />
  98. </template>
  99. </el-table-column>
  100. <el-table-column label="参数名称" prop="fieldLabel">
  101. <template #default="{ row }">
  102. <el-input v-model="row.fieldLabel" />
  103. </template>
  104. </el-table-column>
  105. <el-table-column label="参数值" prop="fieldValue">
  106. <template #default="{ row }">
  107. <el-input v-model="row.fieldValue" />
  108. </template>
  109. </el-table-column>
  110. <el-table-column label="操作" align="center">
  111. <template #default="{ row }">
  112. <el-button
  113. type="danger"
  114. @click="minusItem(row)"
  115. icon="el-icon-minus"
  116. style="margin-left: 15px; width: 25px; height: 25px"
  117. circle
  118. />
  119. </template>
  120. </el-table-column>
  121. </el-table>
  122. <div class="dialog-footer" style="margin-top: 20px" align="center">
  123. <el-button type="primary" @click="handleSubmit">保 存</el-button>
  124. <el-button @click="dialog.visible = false">取消</el-button>
  125. </div>
  126. </el-dialog>
  127. <el-dialog
  128. v-model="dialog2.visible"
  129. :title="dialog2.title"
  130. width="70%"
  131. @close="dialog2.visible = false"
  132. >
  133. <choice-workshop-page @work-shop-info="workShopInfo" />
  134. </el-dialog>
  135. <el-dialog
  136. v-model="dialog3.visible"
  137. :title="dialog3.title"
  138. width="70%"
  139. @close="dialog3.visible = false"
  140. >
  141. <choice-station-page @station-info="stationInfo" />
  142. </el-dialog>
  143. <ExcelUpload ref="uploadRef" @finished="uploadFinished" />
  144. </div>
  145. </template>
  146. <script setup>
  147. import { ref, getCurrentInstance } from "vue";
  148. import { useCrud } from "@/hooks/userCrud";
  149. import buttonPermission from "@/common/configs/buttonPermission";
  150. import { configSave, configList, deviceUpdateCollect } from "@/api/device";
  151. import { useCommonStoreHook } from "@/store";
  152. import ChoiceWorkshopPage from "../../plan/workOrder/components/choice-workshop-page.vue";
  153. import ChoiceStationPage from "./components/choice-station-page.vue";
  154. import dictDataUtil from "@/common/configs/dictDataUtil";
  155. const { isShowTable, tableType } = toRefs(useCommonStoreHook());
  156. const test = () => {
  157. isShowTable.value = true;
  158. tableType.value = tableType.value == 1 ? 2 : 1;
  159. };
  160. const pageData = ref([]);
  161. const loading = ref(false); // 加载状态
  162. const addItem = () => {
  163. pageData.value.push({
  164. deviceType: clickRow.value.deviceType,
  165. deviceNo: clickRow.value.deviceNo,
  166. type: 1,
  167. });
  168. };
  169. const minusItem = (row) => {
  170. pageData.value = pageData.value.filter(
  171. (item) => item.fieldCode !== row.fieldCode
  172. );
  173. };
  174. const changeItem = (obj, row) => {
  175. deviceUpdateCollect({
  176. id: row.id,
  177. collect: row.collect,
  178. deviceNo: row.deviceNo,
  179. }).then((data) => {
  180. if (data.code === "200") {
  181. ElMessage.success(data.msg);
  182. } else {
  183. ElMessage.error(data.msg);
  184. }
  185. });
  186. };
  187. const clickRow = ref(null);
  188. const showParamsPage = (row) => {
  189. clickRow.value = row;
  190. configList({ deviceNo: row.deviceNo }).then((data) => {
  191. pageData.value = data.data;
  192. dialog.visible = true;
  193. });
  194. };
  195. const dialog = reactive({
  196. title: "模型设置",
  197. visible: false,
  198. });
  199. const handleSubmit = () => {
  200. //判断参数
  201. let errorData = pageData.value.filter((item) => !item.fieldCode);
  202. if (errorData.length > 0) {
  203. ElMessage.warning("请填写参数");
  204. return;
  205. }
  206. errorData = pageData.value.filter((item) => !item.fieldLabel);
  207. if (errorData.length > 0) {
  208. ElMessage.warning("请填写参数名");
  209. return;
  210. }
  211. errorData = pageData.value.filter((item) => !item.fieldValue);
  212. if (errorData.length > 0) {
  213. ElMessage.warning("请填写参数值");
  214. return;
  215. }
  216. configSave(pageData.value).then((data) => {
  217. if (data.code === "200") {
  218. ElMessage.success(data.msg);
  219. } else {
  220. ElMessage.error(data.msg);
  221. }
  222. });
  223. };
  224. // 传入一个url,后面不带/
  225. const { form, data, option, search, page, toDeleteIds, Methords, Utils } =
  226. useCrud({
  227. src: "/api/v1/device",
  228. });
  229. const { dataList, createRow, updateRow, deleteRow, searchChange, resetChange } =
  230. Methords; //增删改查
  231. const { selectionChange, multipleDelete } = Methords; //选中和批量删除事件
  232. const { checkBtnPerm, downloadTemplate, exportData } = Utils; //按钮权限等工具
  233. const crudRef = ref(null); //crudRef.value 获取avue-crud对象
  234. const workShopInfo = (value) => {
  235. form.value.workshop = value.name;
  236. dialog2.visible = false;
  237. };
  238. const stationInfo = (value) => {
  239. form.value.station = value.name;
  240. dialog3.visible = false;
  241. };
  242. const dialog2 = reactive({
  243. title: "车间选择",
  244. visible: false,
  245. });
  246. const dialog3 = reactive({
  247. title: "工位选择",
  248. visible: false,
  249. });
  250. // 设置表格列或者其他自定义的option
  251. option.value = Object.assign(option.value, {
  252. delBtn: false,
  253. selection: true,
  254. labelWidth: 120,
  255. column: [
  256. {
  257. label: "设备编号",
  258. prop: "deviceNo",
  259. search: true,
  260. editDisabled: true,
  261. width: 160,
  262. overHidden: true,
  263. rules: [
  264. {
  265. required: true,
  266. message: "设备编号不能为空",
  267. trigger: "trigger",
  268. },
  269. ],
  270. },
  271. {
  272. label: "设备名称",
  273. prop: "deviceName",
  274. search: true,
  275. width: 160,
  276. overHidden: true,
  277. rules: [
  278. {
  279. required: true,
  280. message: "设备名称不能为空",
  281. trigger: "trigger",
  282. },
  283. ],
  284. },
  285. {
  286. label: "设备类型",
  287. prop: "deviceType",
  288. type: "select",
  289. width: 130,
  290. overHidden: true,
  291. search: true,
  292. dicUrl: dictDataUtil.request_url + dictDataUtil.TYPE_CODE.device_type,
  293. props: {
  294. label: "dictLabel",
  295. value: "dictValue",
  296. },
  297. rules: [
  298. {
  299. required: true,
  300. message: "设备类型不能为空",
  301. trigger: "trigger",
  302. },
  303. ],
  304. },
  305. {
  306. label: "设备状态",
  307. prop: "state",
  308. type: "select",
  309. width: 120,
  310. overHidden: true,
  311. search: true,
  312. dicUrl: dictDataUtil.request_url + dictDataUtil.TYPE_CODE.device_status,
  313. props: {
  314. label: "dictLabel",
  315. value: "dictValue",
  316. },
  317. rules: [
  318. {
  319. required: true,
  320. message: "设备状态不能为空",
  321. trigger: "trigger",
  322. },
  323. ],
  324. },
  325. {
  326. label: "在线状态",
  327. prop: "onlineState",
  328. width: 100,
  329. display: false,
  330. html: true,
  331. formatter: (val) => {
  332. if (val.onlineState === "1") {
  333. return '<b class="el-tag el-tag--success el-tag--light">在线</b>';
  334. } else {
  335. return '<b class="el-tag el-tag--warning el-tag--light">离线</b>';
  336. }
  337. },
  338. },
  339. {
  340. label: "连接状态",
  341. prop: "collectState",
  342. width: 100,
  343. display: false,
  344. html: true,
  345. formatter: (val) => {
  346. if (val.onlineState === "1") {
  347. return '<b class="el-tag el-tag--success el-tag--light">已连接</b>';
  348. } else {
  349. return '<b class="el-tag el-tag--warning el-tag--light">未连接</b>';
  350. }
  351. },
  352. },
  353. {
  354. label: "负责人",
  355. prop: "head",
  356. width: 120,
  357. overHidden: true,
  358. rules: [
  359. {
  360. required: true,
  361. message: "负责人不能为空",
  362. trigger: "trigger",
  363. },
  364. ],
  365. },
  366. {
  367. label: "计量有效期",
  368. prop: "meteringDate",
  369. type: "date",
  370. width: 160,
  371. format: "YYYY-MM-DD",
  372. valueFormat: "YYYY-MM-DD",
  373. overHidden: true,
  374. rules: [
  375. {
  376. required: true,
  377. message: "计量有效期不能为空",
  378. trigger: "trigger",
  379. },
  380. ],
  381. },
  382. {
  383. label: "所属PAC",
  384. prop: "terminal",
  385. type: "select",
  386. width: 120,
  387. overHidden: true,
  388. search: true,
  389. dicUrl: import.meta.env.VITE_APP_BASE_API + "/api/v1/device/pacList",
  390. props: {
  391. label: "deviceName",
  392. value: "deviceNo",
  393. },
  394. },
  395. /*{
  396. label: "是否采集",
  397. prop: "collect",
  398. editDisplay: false,
  399. addDisplay: false,
  400. slot: true,
  401. width: 100,
  402. },*/
  403. {
  404. label: "供应厂商",
  405. prop: "manufacturer",
  406. width: 160,
  407. overHidden: true,
  408. },
  409. {
  410. label: "所属部门",
  411. prop: "deptId",
  412. width: 160,
  413. overHidden: true,
  414. type: "tree",
  415. dicUrl: dictDataUtil.dept_tree_url,
  416. props: {
  417. label: "deptName",
  418. value: "id",
  419. },
  420. },
  421. {
  422. label: "所在车间",
  423. prop: "workshop",
  424. width: 160,
  425. overHidden: true,
  426. click: ({ value, column }) => {
  427. if (column.boxType) {
  428. dialog2.visible = true;
  429. }
  430. },
  431. },
  432. {
  433. label: "所在工位",
  434. prop: "station",
  435. width: 160,
  436. overHidden: true,
  437. click: ({ value, column }) => {
  438. if (column.boxType) {
  439. /*if(!form.value.workshop){
  440. ElMessage({
  441. message: "请先选择车间",
  442. type: "warning",
  443. });
  444. return;
  445. }*/
  446. dialog3.visible = true;
  447. }
  448. },
  449. },
  450. {
  451. label: "设备位置",
  452. prop: "devicePosition",
  453. width: 160,
  454. overHidden: true,
  455. },
  456. {
  457. label: "规格",
  458. prop: "specifications",
  459. width: 160,
  460. overHidden: true,
  461. },
  462. {
  463. label: "品牌",
  464. width: 160,
  465. overHidden: true,
  466. prop: "brand",
  467. },
  468. ],
  469. });
  470. onMounted(() => {
  471. dataList();
  472. });
  473. /**
  474. * 上传excel相关
  475. */
  476. const uploadRef = ref(null);
  477. const uploadFinished = () => {
  478. // 上传完成后的刷新操作
  479. page.currentPage = 1;
  480. dataList();
  481. };
  482. const importExcelData = () => {
  483. if (uploadRef.value) {
  484. uploadRef.value.show("/api/v1/device/import");
  485. }
  486. };
  487. </script>