IotDeviceForm.vue 31 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885
  1. <template>
  2. <ContentWrap v-loading="formLoading">
  3. <el-form
  4. ref="formRef"
  5. :model="formData"
  6. :rules="formRules"
  7. style="margin-right: 4em; margin-left: 0.5em"
  8. label-width="130px"
  9. >
  10. <div class="title-div">
  11. <el-button @click="baseInfoClick" class="title-button">
  12. <Icon color="black" icon="ep:set-up" :size="18" class="cursor-pointer first-icon" />
  13. <span class="cursor-pointer">{{ t('deviceForm.basic') }}</span>
  14. <Icon
  15. color="black"
  16. :icon="baseIsExpanded ? 'fa-solid:angle-double-down' : 'fa-solid:angle-double-right'"
  17. :size="18"
  18. class="cursor-pointer"
  19. />
  20. </el-button>
  21. </div>
  22. <div class="base-expandable-content" :class="{ 'is-expanded': baseIsExpanded }">
  23. <el-row>
  24. <el-col :span="8">
  25. <el-form-item :label="t('iotDevice.yfClass')" prop="yfClass">
  26. <el-cascader
  27. :disabled="formType === 'update' && formData.yfDeviceCode"
  28. style="width: 100%"
  29. v-model="formData.yfClass"
  30. :options="yfclasses"
  31. :props="{ expandTrigger: 'hover' }"
  32. clearable
  33. filterable
  34. @change="handleYfClassChange"
  35. />
  36. </el-form-item>
  37. </el-col>
  38. <el-col :span="8">
  39. <el-form-item :label="t('iotDevice.yfCode')" prop="yfDeviceCode">
  40. <el-input
  41. v-model="formData.yfDeviceCode"
  42. :disabled="formData.yfDeviceCode"
  43. placeholder="请输入油服设备编码"
  44. />
  45. </el-form-item>
  46. </el-col>
  47. <el-col :span="8">
  48. <el-form-item :label="t('iotDevice.code')" prop="deviceCode">
  49. <el-input
  50. v-model="formData.deviceCode"
  51. :disabled="formType === 'update'"
  52. placeholder="请输入设备编码"
  53. />
  54. </el-form-item>
  55. </el-col>
  56. <el-col :span="8">
  57. <el-form-item :label="t('iotDevice.name')" prop="deviceName">
  58. <lang-input v-model="formData.deviceName" placeholder="请输入设备名称" />
  59. </el-form-item>
  60. </el-col>
  61. <el-col :span="8">
  62. <el-form-item :label="t('iotDevice.dept')" prop="deptId">
  63. <el-tree-select
  64. :disabled="formType === 'update'"
  65. v-model="formData.deptId"
  66. :data="deptList"
  67. :props="defaultProps"
  68. check-strictly
  69. node-key="id"
  70. filterable
  71. placeholder="请选择所在部门"
  72. />
  73. <!-- <el-tree-select-->
  74. <!-- v-model="formData.deptId"-->
  75. <!-- :data="deptList"-->
  76. <!-- :props="defaultProps"-->
  77. <!-- check-strictly-->
  78. <!-- node-key="id"-->
  79. <!-- placeholder="请选择归属部门"-->
  80. <!-- />-->
  81. </el-form-item>
  82. </el-col>
  83. <el-col :span="8">
  84. <el-form-item :label="t('deviceForm.category')" prop="assetClass">
  85. <el-tree-select
  86. :disabled="formType === 'update' && username !== '超级管理员'"
  87. v-model="formData.assetClass"
  88. :data="productClassifyList"
  89. :props="defaultProps"
  90. check-strictly
  91. node-key="id"
  92. :placeholder="t('deviceForm.categoryHolder')"
  93. @change="assetclasschange"
  94. filterable
  95. />
  96. </el-form-item>
  97. </el-col>
  98. <el-col :span="8">
  99. <el-form-item :label="t('iotDevice.status')" prop="deviceStatus">
  100. <el-select
  101. v-model="formData.deviceStatus"
  102. :placeholder="t('deviceForm.choose')"
  103. :disabled="formType === 'update'"
  104. clearable
  105. >
  106. <el-option
  107. v-for="dict in getStrDictOptions(DICT_TYPE.PMS_DEVICE_STATUS)"
  108. :key="dict.label"
  109. :label="dict.label"
  110. :value="dict.value"
  111. />
  112. </el-select>
  113. </el-form-item>
  114. </el-col>
  115. <el-col :span="8">
  116. <el-form-item :label="t('iotDevice.assets')" prop="assetProperty">
  117. <el-select v-model="formData.assetProperty" placeholder="请选择" clearable>
  118. <el-option
  119. v-for="dict in getStrDictOptions(DICT_TYPE.PMS_ASSET_PROPERTY)"
  120. :key="dict.id"
  121. :label="dict.label"
  122. :value="dict.value"
  123. />
  124. </el-select>
  125. </el-form-item>
  126. </el-col>
  127. <el-col :span="8">
  128. <el-form-item :label="t('iotDevice.brand')" prop="brandName">
  129. <el-select
  130. clearable
  131. v-model="formData.brandName"
  132. @clear="brandClear"
  133. :placeholder="t('iotDevice.brandHolder')"
  134. @click="openForm"
  135. />
  136. </el-form-item>
  137. </el-col>
  138. <el-col :span="8">
  139. <el-form-item label="车牌号" prop="carNo">
  140. <el-input clearable v-model="formData.carNo" placeholder="请输入车牌号" />
  141. </el-form-item>
  142. </el-col>
  143. <el-col :span="8">
  144. <el-form-item label="设备号" prop="deviceNo">
  145. <el-input clearable v-model="formData.deviceNo" placeholder="请输入设备号" />
  146. </el-form-item>
  147. </el-col>
  148. <el-col :span="8">
  149. <div style="display: flex; flex-direction: row">
  150. <el-form-item :label="t('deviceForm.model')" prop="model" style="width: 86%">
  151. <el-input
  152. clearable
  153. v-model="formData.model"
  154. :placeholder="t('deviceForm.modelHolder')"
  155. />
  156. </el-form-item>
  157. <el-button type="info" @click="openModelForm">请选择</el-button>
  158. </div>
  159. </el-col>
  160. <el-col :span="8">
  161. <el-form-item :label="t('deviceForm.useProject')" prop="useProject">
  162. <el-input v-model="formData.useProject" :disabled="isDetail" height="60px" />
  163. </el-form-item>
  164. </el-col>
  165. <el-col :span="8">
  166. <el-form-item :label="t('deviceForm.assetOwner')" prop="assetOwnership">
  167. <el-input v-model="formData.assetOwnership" :disabled="isDetail" height="60px" />
  168. </el-form-item>
  169. </el-col>
  170. <el-col :span="8">
  171. <el-form-item :label="t('deviceForm.picture')" prop="picUrl">
  172. <UploadImg v-model="formData.picUrl" :disabled="isDetail" height="60px" />
  173. </el-form-item>
  174. </el-col>
  175. <el-col :span="8">
  176. <el-form-item :label="t('deviceForm.remark')" prop="remark">
  177. <el-input
  178. v-model="formData.remark"
  179. type="textarea"
  180. :placeholder="t('deviceForm.remarkHolder')"
  181. />
  182. </el-form-item>
  183. </el-col>
  184. </el-row>
  185. </div>
  186. <div class="title-div">
  187. <el-button @click="zzInfoClick" class="title-button">
  188. <Icon color="black" icon="ep:set-up" :size="18" class="cursor-pointer first-icon" />
  189. <span class="cursor-pointer">{{ t('deviceForm.make') }}</span>
  190. <Icon
  191. color="black"
  192. :icon="zzIsExpanded ? 'fa-solid:angle-double-down' : 'fa-solid:angle-double-right'"
  193. :size="18"
  194. class="cursor-pointer"
  195. />
  196. </el-button>
  197. </div>
  198. <div class="zz-expandable-content" :class="{ 'is-expanded': zzIsExpanded }">
  199. <el-row>
  200. <el-col :span="8">
  201. <el-form-item :label="t('deviceForm.mfg')" prop="manufacturerId">
  202. <el-select
  203. clearable
  204. @clear="zzClear"
  205. v-model="formData.manufacturerName"
  206. :placeholder="t('deviceForm.mfgHolder')"
  207. @click="openCustomerZz"
  208. />
  209. </el-form-item>
  210. </el-col>
  211. <el-col :span="8">
  212. <el-form-item :label="t('deviceForm.pd')" prop="manDate">
  213. <el-date-picker
  214. style="width: 150%"
  215. v-model="formData.manDate"
  216. type="date"
  217. value-format="x"
  218. :placeholder="t('deviceForm.pdHolder')"
  219. />
  220. </el-form-item>
  221. </el-col>
  222. <el-col :span="8">
  223. <el-form-item :label="t('deviceForm.supplier')" prop="supplierId">
  224. <el-select
  225. clearable
  226. @clear="supplierClear"
  227. v-model="formData.supplierName"
  228. :placeholder="t('deviceForm.suppHolder')"
  229. @click="openCustomerSupplier"
  230. />
  231. </el-form-item>
  232. </el-col>
  233. <el-col :span="8">
  234. <el-form-item :label="t('deviceForm.warranty')" prop="expires">
  235. <el-date-picker
  236. style="width: 150%"
  237. v-model="formData.expires"
  238. type="date"
  239. value-format="x"
  240. :placeholder="t('deviceForm.warrHolder')"
  241. />
  242. </el-form-item>
  243. </el-col>
  244. <el-col :span="8">
  245. <el-form-item :label="t('deviceForm.enable')" prop="enableDate">
  246. <el-date-picker
  247. style="width: 150%"
  248. v-model="formData.enableDate"
  249. type="date"
  250. value-format="x"
  251. :placeholder="t('deviceForm.enableHolder')"
  252. />
  253. </el-form-item>
  254. </el-col>
  255. <el-col :span="8">
  256. <el-form-item :label="t('deviceForm.ni')" prop="nameplate">
  257. <el-input
  258. v-model="formData.nameplate"
  259. type="textarea"
  260. :placeholder="t('deviceForm.niHolder')"
  261. />
  262. </el-form-item>
  263. </el-col>
  264. </el-row>
  265. </div>
  266. <div class="title-div">
  267. <el-button @click="cwInfoClick" class="title-button">
  268. <Icon color="black" icon="ep:set-up" :size="18" class="cursor-pointer first-icon" />
  269. <span class="cursor-pointer">{{ t('deviceForm.finance') }}</span>
  270. <Icon
  271. color="black"
  272. :icon="cwIsExpanded ? 'fa-solid:angle-double-down' : 'fa-solid:angle-double-right'"
  273. :size="18"
  274. class="cursor-pointer"
  275. />
  276. </el-button>
  277. </div>
  278. <div class="cw-expandable-content" :class="{ 'is-expanded': cwIsExpanded }">
  279. <el-row>
  280. <el-col :span="8">
  281. <el-form-item
  282. :label="formData.assetProperty === 'zy' ? '采购价格' : '租赁价格'"
  283. prop="plPrice"
  284. >
  285. <el-input
  286. v-model="formData.plPrice"
  287. @input="handleInput(formData.plPrice, 'plPrice')"
  288. :placeholder="formData.assetProperty === 'zy' ? '请输入采购价格' : '请输入租赁价格'"
  289. />
  290. </el-form-item>
  291. </el-col>
  292. <el-col :span="8">
  293. <el-form-item
  294. :label="formData.assetProperty === 'zy' ? '采购日期' : '租赁日期'"
  295. prop="plDate"
  296. >
  297. <el-date-picker
  298. style="width: 150%"
  299. v-model="formData.plDate"
  300. type="date"
  301. value-format="x"
  302. :placeholder="formData.assetProperty === 'zy' ? '请输入采购日期' : '请输入租赁日期'"
  303. />
  304. </el-form-item>
  305. </el-col>
  306. <el-col :span="8">
  307. <el-form-item
  308. :label="formData.assetProperty === 'zy' ? '折旧年限' : '租赁年限'"
  309. prop="plYear"
  310. >
  311. <el-input
  312. v-model="formData.plYear"
  313. type="number"
  314. :placeholder="formData.assetProperty === 'zy' ? '请输入折旧年限' : '请输入租赁年限'"
  315. />
  316. </el-form-item>
  317. </el-col>
  318. <el-col :span="8">
  319. <el-form-item
  320. :label="formData.assetProperty === 'zy' ? '折旧开始日期' : '租赁开始日期'"
  321. prop="plStartDate"
  322. >
  323. <el-date-picker
  324. style="width: 150%"
  325. v-model="formData.plStartDate"
  326. type="date"
  327. value-format="x"
  328. :placeholder="
  329. formData.assetProperty === 'zy' ? '请选择折旧开始日期' : '请选择租赁开始日期'
  330. "
  331. />
  332. </el-form-item>
  333. </el-col>
  334. <el-col :span="8">
  335. <el-form-item
  336. :label="formData.assetProperty === 'zy' ? '已提折旧月数' : '已租赁月数'"
  337. prop="plMonthed"
  338. >
  339. <el-input
  340. v-model="formData.plMonthed"
  341. type="number"
  342. :placeholder="
  343. formData.assetProperty === 'zy' ? '请输入已提折旧月数' : '请输入已租赁月数'
  344. "
  345. />
  346. </el-form-item>
  347. </el-col>
  348. <el-col :span="8">
  349. <el-form-item
  350. :label="formData.assetProperty === 'zy' ? '已提折旧金额' : '已租赁金额'"
  351. prop="plAmounted"
  352. >
  353. <el-input
  354. v-model="formData.plAmounted"
  355. @input="handleInput(formData.plAmounted, 'plAmounted')"
  356. :placeholder="formData.assetProperty === 'zy' ? '请输入已提折旧金额' : '已租赁金额'"
  357. />
  358. </el-form-item>
  359. </el-col>
  360. <el-col :span="8">
  361. <el-form-item label="剩余金额" prop="remainAmount">
  362. <el-input
  363. v-model="formData.remainAmount"
  364. @input="handleInput(formData.remainAmount, 'remainAmount')"
  365. placeholder="请输入剩余金额"
  366. />
  367. </el-form-item>
  368. </el-col>
  369. </el-row>
  370. </div>
  371. <div class="title-div">
  372. <el-button @click="qtInfoClick" class="title-button">
  373. <Icon color="black" icon="ep:set-up" :size="18" class="cursor-pointer first-icon" />
  374. <span class="cursor-pointer">{{ t('deviceForm.other') }}</span>
  375. <Icon
  376. color="black"
  377. :icon="qtIsExpanded ? 'fa-solid:angle-double-down' : 'fa-solid:angle-double-right'"
  378. :size="18"
  379. class="cursor-pointer"
  380. />
  381. </el-button>
  382. </div>
  383. <div class="qt-expandable-content" :class="{ 'is-expanded': qtIsExpanded }">
  384. <el-row>
  385. <el-col v-for="field in list" :key="field.sort" :span="8">
  386. <el-form-item
  387. label-width="180px"
  388. :label="field.name"
  389. :prop="field.code"
  390. :rules="field.rules"
  391. >
  392. <!-- 文本输入 -->
  393. <el-input
  394. v-if="field.type === 'text'"
  395. v-model="formData[field.code]"
  396. :placeholder="'请输入' + field.name"
  397. :type="field.type || 'text'"
  398. />
  399. <el-select
  400. v-else-if="field.type === 'enum'"
  401. v-model="formData[field.code]"
  402. :placeholder="'请输入' + field.name"
  403. clearable
  404. filterable
  405. >
  406. <el-option
  407. v-for="item in field.selectOptions.dataSpecsList"
  408. :key="item.name"
  409. :label="item.name"
  410. :value="item.name"
  411. />
  412. </el-select>
  413. <!-- 数字输入 -->
  414. <el-input
  415. v-else-if="field.type === 'int'"
  416. type="number"
  417. v-model="formData[field.code]"
  418. style="width: 150%"
  419. />
  420. <el-input
  421. v-else-if="field.type === 'double'"
  422. v-model="formData[field.code]"
  423. @input="handleInput(formData[field.code], field.code)"
  424. style="width: 150%"
  425. />
  426. <!-- 日期选择 -->
  427. <el-date-picker
  428. v-else-if="field.type === 'date'"
  429. v-model="formData[field.code]"
  430. :type="field.type || 'date'"
  431. :placeholder="'请输入' + field.name"
  432. value-format="YYYY-MM-DD"
  433. style="width: 150%"
  434. />
  435. </el-form-item>
  436. </el-col>
  437. </el-row>
  438. </div>
  439. </el-form>
  440. <el-form>
  441. <el-form-item style="float: right">
  442. <el-button type="success" @click="allzhankai">{{ t('deviceForm.expand') }}</el-button>
  443. <el-button type="info" @click="allshouqi">{{ t('deviceForm.close') }}</el-button>
  444. <el-button v-if="!isDetail" :loading="formLoading" type="warning" @click="submitForm">
  445. {{ t('deviceForm.save') }}
  446. </el-button>
  447. <el-button @click="close" type="primary">{{ t('deviceForm.return') }}</el-button>
  448. </el-form-item>
  449. </el-form>
  450. </ContentWrap>
  451. <BrandList ref="brandFormRef" @choose="brandChoose" />
  452. <ModelList ref="modelFormRef" @choose="modelChoose" :brand="formData.brand" />
  453. <CustomerList ref="customerZzFormRef" @choose="customerZzChoose" />
  454. <CustomerList ref="customerSupplierFormRef" @choose="customerSupplierChoose" />
  455. </template>
  456. <script setup lang="ts">
  457. import { IotDeviceApi, IotDeviceVO } from '@/api/pms/device'
  458. import BrandList from '@/views/pms/device/BrandList.vue'
  459. import ModelList from '@/views/pms/device/ModelList.vue'
  460. import CustomerList from '@/views/pms/device/CustomerList.vue'
  461. import { defaultProps, handleTree } from '@/utils/tree'
  462. import * as DeptApi from '@/api/system/dept'
  463. import * as ProductClassifyApi from '@/api/pms/productclassify'
  464. import { DICT_TYPE, getStrDictOptions } from '@/utils/dict'
  465. import { useTagsViewStore } from '@/store/modules/tagsView'
  466. import { DeviceAttrModelApi } from '@/api/pms/deviceattrmodel'
  467. import { CACHE_KEY, useCache } from '@/hooks/web/useCache'
  468. import { IotYfClassifyApi } from '@/api/pms/yfclass'
  469. import { useRefreshStore } from '@/store/modules/pms/refreshStore'
  470. import { watch } from 'vue'
  471. /** 设备台账 表单 */
  472. defineOptions({ name: 'DeviceDetailAdd' })
  473. const baseIsExpanded = ref(true) // 控制表单是否展开的变量
  474. const zzIsExpanded = ref(true) // 控制表单是否展开的变量
  475. const cwIsExpanded = ref(true) // 控制表单是否展开的变量
  476. const qtIsExpanded = ref(true) // 控制表单是否展开的变量
  477. const username = ref('')
  478. const deptList = ref<Tree[]>([]) // 树形结构
  479. const productClassifyList = ref<Tree[]>([]) // 树形结构
  480. const { delView } = useTagsViewStore() // 视图操作
  481. const { params, name, query } = useRoute() // 查询参数
  482. const { currentRoute, push } = useRouter()
  483. const { wsCache } = useCache()
  484. const id = params.id
  485. const type = params.type
  486. const deptId = params.deptId
  487. const isDetail = params.isDetail
  488. const { t } = useI18n() // 国际化
  489. const message = useMessage() // 消息弹窗
  490. const dialogVisible = ref(false) // 弹窗的是否展示
  491. const dialogTitle = ref('') // 弹窗的标题
  492. const formLoading = ref(false) // 表单的加载中:1)修改时的数据加载;2)提交的按钮禁用
  493. const formType = ref('') // 表单的类型:create - 新增;update - 修改
  494. const brandLabel = ref('') // 表单的类型:create - 新增;update - 修改
  495. const zzLabel = ref('') // 表单的类型:create - 新增;update - 修改
  496. const supplierLabel = ref('') // 表单的类型:create - 新增;update - 修改
  497. const yfclasses = ref([])
  498. const refreshStore = useRefreshStore()
  499. const formData = ref({
  500. id: undefined,
  501. yfClass: undefined,
  502. yfDeviceCode: undefined,
  503. enableDate: undefined,
  504. deviceCode: undefined,
  505. deviceName: undefined,
  506. brand: undefined,
  507. brandName: undefined,
  508. model: undefined,
  509. deptId: undefined,
  510. deviceStatus: undefined,
  511. assetProperty: undefined,
  512. picUrl: undefined,
  513. assetOwnership: undefined,
  514. remark: undefined,
  515. useProject: undefined,
  516. manufacturerId: undefined,
  517. manufacturerName: undefined,
  518. supplierId: undefined,
  519. supplierName: undefined,
  520. manDate: undefined,
  521. nameplate: undefined,
  522. expires: undefined,
  523. plPrice: undefined,
  524. plDate: undefined,
  525. plYear: undefined,
  526. plStartDate: undefined,
  527. plMonthed: undefined,
  528. plAmounted: undefined,
  529. remainAmount: undefined,
  530. infoId: undefined,
  531. infoType: undefined,
  532. infoName: undefined,
  533. infoRemark: undefined,
  534. infoUrl: undefined,
  535. templateJson: undefined,
  536. assetClass: undefined,
  537. carNo: undefined,
  538. deviceNo: undefined
  539. })
  540. const formRules = reactive({
  541. yfClass: [
  542. {
  543. validator: (rule, value, callback) => {
  544. // 当资产性质为租赁('zl')时,yfClass非必填;否则必填
  545. if (formData.value.assetProperty === 'zl' || value) {
  546. callback() // 租赁资产或有值时通过验证
  547. } else {
  548. callback(new Error('编码类别不能为空')) // 非租赁资产且无值时失败
  549. }
  550. },
  551. trigger: 'blur'
  552. }
  553. ],
  554. yfDeviceCode: [{ required: true, message: '油服编码不能为空', trigger: 'blur' }],
  555. assetClass: [{ required: true, message: '资产类别不能为空', trigger: 'blur' }],
  556. deviceCode: [{ required: true, message: '设备编码不能为空', trigger: 'blur' }],
  557. deviceName: [{ required: true, message: '设备名称不能为空', trigger: 'blur' }],
  558. brandName: [{ required: true, message: '品牌不能为空', trigger: 'blur' }],
  559. deptId: [{ required: true, message: '所在部门不能为空', trigger: 'blur' }],
  560. deviceStatus: [{ required: true, message: '设备状态不能为空', trigger: 'blur' }],
  561. assetProperty: [{ required: true, message: '资产性质不能为空', trigger: 'blur' }],
  562. manufacturerId: [{ required: true, message: '制造商id不能为空', trigger: 'blur' }],
  563. manDate: [{ required: true, message: '生产日期不能为空', trigger: 'blur' }]
  564. })
  565. const list = ref([])
  566. const handleYfClassChange = async (value) => {
  567. console.log(value)
  568. const prefix = value.join('')
  569. const last = await IotDeviceApi.getMaxCode(prefix)
  570. formData.value.yfDeviceCode = prefix + last
  571. }
  572. const assetclasschange = () => {
  573. const assetClass = formData.value.assetClass
  574. DeviceAttrModelApi.getDeviceAttrModelListByDeviceCategoryId(assetClass).then((res) => {
  575. if (res) {
  576. res.forEach((item) => {
  577. if (item.requiredFlag) {
  578. const rule = { required: true, message: item.name + '不能为空', trigger: 'blur' }
  579. item.rules = []
  580. item.rules.push(rule)
  581. }
  582. })
  583. list.value = res
  584. } else {
  585. list.value = []
  586. }
  587. })
  588. }
  589. watch(
  590. () => formData.value.assetProperty,
  591. (newVal) => {
  592. nextTick(() => {
  593. if (formRef.value) {
  594. // 重新验证 yfClass 和 yfCode 字段
  595. formRef.value.validateField('yfClass')
  596. }
  597. })
  598. },
  599. { immediate: true }
  600. )
  601. const brandChoose = (row) => {
  602. formData.value.brand = row.id
  603. // brandLabel.value = row.value
  604. formData.value.brandName = row.label
  605. }
  606. const brandClear = () => {
  607. formData.value.brand = undefined
  608. formData.value.brandName = undefined
  609. }
  610. const modelChoose = (row) => {
  611. formData.value.model = row.name
  612. }
  613. const customerSupplierChoose = (row) => {
  614. formData.value.supplierId = row.id
  615. formData.value.supplierName = row.name
  616. // supplierLabel.value = row.name
  617. }
  618. const supplierClear = (row) => {
  619. formData.value.supplierId = undefined
  620. formData.value.supplierName = undefined
  621. }
  622. const customerZzChoose = (row) => {
  623. formData.value.manufacturerId = row.id
  624. // zzLabel.value = row.name
  625. formData.value.manufacturerName = row.name
  626. }
  627. const zzClear = () => {
  628. formData.value.manufacturerId = undefined
  629. formData.value.manufacturerName = undefined
  630. }
  631. /** 添加/修改操作 */
  632. const brandFormRef = ref()
  633. const openForm = () => {
  634. brandFormRef.value.open()
  635. }
  636. const modelFormRef = ref()
  637. const openModelForm = () => {
  638. modelFormRef.value.open()
  639. }
  640. const customerSupplierFormRef = ref()
  641. const openCustomerSupplier = () => {
  642. customerSupplierFormRef.value.open()
  643. }
  644. const customerZzFormRef = ref()
  645. const openCustomerZz = () => {
  646. customerZzFormRef.value.open()
  647. }
  648. const allshouqi = () => {
  649. baseIsExpanded.value = false
  650. zzIsExpanded.value = false
  651. cwIsExpanded.value = false
  652. qtIsExpanded.value = false
  653. }
  654. const allzhankai = () => {
  655. baseIsExpanded.value = true
  656. zzIsExpanded.value = true
  657. cwIsExpanded.value = true
  658. qtIsExpanded.value = true
  659. }
  660. const handleInput = (value, obj) => {
  661. // 1. 过滤非法字符(只允许数字和小数点)
  662. let filtered = value.replace(/[^\d.]/g, '')
  663. // 2. 处理多个小数点的情况
  664. filtered = filtered.replace(/\.{2,}/g, '.')
  665. // 3. 限制小数点后最多两位
  666. let decimalParts = filtered.split('.')
  667. if (decimalParts.length > 1) {
  668. decimalParts = decimalParts.slice(0, 2)
  669. filtered = decimalParts.join('.')
  670. }
  671. // 4. 处理以小数点开头的情况(自动补0)
  672. if (filtered.startsWith('.')) {
  673. filtered = '0' + filtered
  674. }
  675. // 5. 更新绑定值(同时处理连续输入多个0的情况)
  676. formData.value[obj] = filtered.replace(/^0+(?=\d)/, '')
  677. }
  678. const close = () => {
  679. delView(unref(currentRoute))
  680. push({ name: 'IotDevicePms', params: {} })
  681. // delView(unref(currentRoute))
  682. // push({
  683. // name: 'IotDevicePms',
  684. // query: {
  685. // date: new Date().getTime()
  686. // }
  687. // })
  688. }
  689. const baseInfoClick = () => {
  690. baseIsExpanded.value = !baseIsExpanded.value // 切换展开状态
  691. }
  692. const zzInfoClick = () => {
  693. zzIsExpanded.value = !zzIsExpanded.value // 切换展开状态
  694. }
  695. const cwInfoClick = () => {
  696. cwIsExpanded.value = !cwIsExpanded.value // 切换展开状态
  697. }
  698. const qtInfoClick = () => {
  699. qtIsExpanded.value = !qtIsExpanded.value // 切换展开状态
  700. }
  701. /** 提交表单 */
  702. const emit = defineEmits(['success']) // 定义 success 事件,用于操作成功后的回调
  703. const formRef = ref()
  704. const submitForm = async () => {
  705. // 校验表单
  706. await formRef.value.validate()
  707. // 提交请求
  708. formLoading.value = true
  709. try {
  710. if (list.value) {
  711. list.value = list.value.map((item) => ({
  712. ...item,
  713. value: formData.value[item.code] // 自定义属性生成逻辑
  714. }))
  715. formData.value.templateJson = JSON.stringify(list.value)
  716. }
  717. formData.value.yfClass = formData.value.yfClass.join(',')
  718. const data = formData.value as unknown as IotDeviceVO
  719. if (formType.value === 'create') {
  720. await IotDeviceApi.createIotDevice(data)
  721. message.success(t('common.createSuccess'))
  722. } else {
  723. await IotDeviceApi.updateIotDevice(data)
  724. message.success(t('common.updateSuccess'))
  725. }
  726. dialogVisible.value = false
  727. // 发送操作成功的事件
  728. //emit('success')
  729. const sourcePage = query.source as string
  730. // 如果有来源页面标识,触发原页面的刷新
  731. if (sourcePage) {
  732. refreshStore.triggerRefresh(sourcePage)
  733. }
  734. close()
  735. } finally {
  736. formLoading.value = false
  737. }
  738. }
  739. onMounted(async () => {
  740. const userInfo = wsCache.get(CACHE_KEY.USER)
  741. // NOTE: 是否需要像`setUserInfoAction`一样判断`userInfo != null`
  742. username.value = userInfo.user.nickname
  743. deptList.value = handleTree(await DeptApi.getSimpleDeptList())
  744. productClassifyList.value = handleTree(
  745. await ProductClassifyApi.IotProductClassifyApi.getSimpleProductClassifyList()
  746. )
  747. formData.value.assetProperty = 'zy'
  748. // 修改时,设置数据
  749. if (id) {
  750. formType.value = 'update'
  751. formLoading.value = true
  752. try {
  753. const iotDevice = await IotDeviceApi.getIotDevice(id)
  754. formData.value = iotDevice
  755. formData.value.brandName = iotDevice.brandName
  756. formData.value.manufacturerName = iotDevice.zzName
  757. formData.value.supplierName = iotDevice.supplierName
  758. formData.value.carNo = iotDevice.carNo
  759. formData.value.deviceNo = iotDevice.deviceNo
  760. if (iotDevice.yfClass) {
  761. formData.value.yfClass = iotDevice.yfClass.split(',')
  762. }
  763. list.value = JSON.parse(iotDevice.templateJson)
  764. list.value.forEach((item) => {
  765. formData.value[item.code] = item.value
  766. })
  767. } finally {
  768. formLoading.value = false
  769. }
  770. } else {
  771. if (deptId) {
  772. formData.value.deptId = Number(deptId)
  773. }
  774. formType.value = 'create'
  775. }
  776. await IotYfClassifyApi.getChildrenList().then((res) => {
  777. yfclasses.value = res
  778. })
  779. })
  780. /** 重置表单 */
  781. const resetForm = () => {
  782. formData.value = {
  783. id: undefined,
  784. deviceCode: undefined,
  785. deviceName: undefined,
  786. brand: undefined,
  787. model: undefined,
  788. deptId: undefined,
  789. deviceStatus: undefined,
  790. assetProperty: undefined,
  791. picUrl: undefined,
  792. remark: undefined,
  793. manufacturerId: undefined,
  794. supplierId: undefined,
  795. manDate: undefined,
  796. nameplate: undefined,
  797. expires: undefined,
  798. plPrice: undefined,
  799. plDate: undefined,
  800. plYear: undefined,
  801. plStartDate: undefined,
  802. plMonthed: undefined,
  803. plAmounted: undefined,
  804. remainAmount: undefined,
  805. infoId: undefined,
  806. infoType: undefined,
  807. infoName: undefined,
  808. infoRemark: undefined,
  809. infoUrl: undefined,
  810. templateJson: undefined,
  811. assetClass: undefined
  812. }
  813. formRef.value?.resetFields()
  814. }
  815. </script>
  816. <style scoped lang="scss">
  817. .base-expandable-content {
  818. max-height: 0; /* 初始高度为0 */
  819. overflow: hidden; /* 隐藏溢出的内容 */
  820. transition: max-height 0.3s ease; /* 平滑过渡效果 */
  821. }
  822. .base-expandable-content.is-expanded {
  823. min-height: 260px; /* 或者根据内容设定一个合适的最大高度 */
  824. }
  825. .zz-expandable-content {
  826. max-height: 0; /* 初始高度为0 */
  827. overflow: hidden; /* 隐藏溢出的内容 */
  828. transition: max-height 0.3s ease; /* 平滑过渡效果 */
  829. }
  830. .zz-expandable-content.is-expanded {
  831. min-height: 130px; /* 或者根据内容设定一个合适的最大高度 */
  832. }
  833. .cw-expandable-content {
  834. max-height: 0; /* 初始高度为0 */
  835. overflow: hidden; /* 隐藏溢出的内容 */
  836. transition: max-height 0.3s ease; /* 平滑过渡效果 */
  837. }
  838. .cw-expandable-content.is-expanded {
  839. max-height: 200px; /* 或者根据内容设定一个合适的最大高度 */
  840. }
  841. .qt-expandable-content {
  842. max-height: 0; /* 初始高度为0 */
  843. overflow: hidden; /* 隐藏溢出的内容 */
  844. transition: max-height 0.3s ease; /* 平滑过渡效果 */
  845. }
  846. .qt-expandable-content.is-expanded {
  847. max-height: 1200px; /* 或者根据内容设定一个合适的最大高度 */
  848. }
  849. .title-button {
  850. font-size: 18px;
  851. border: none;
  852. }
  853. .title-div {
  854. margin-bottom: 20px;
  855. margin-top: 10px;
  856. }
  857. .cursor-pointer {
  858. vertical-align: middle;
  859. }
  860. .first-icon {
  861. margin-bottom: 2px;
  862. }
  863. </style>