videoPolingForm.vue 6.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249
  1. <template>
  2. <ele-modal
  3. :visible.sync="visible"
  4. :title="title"
  5. width="800px"
  6. append-to-body
  7. @close="cancel"
  8. :maxable="true"
  9. >
  10. <el-form
  11. ref="form"
  12. :model="form"
  13. :rules="rules"
  14. label-width="100px"
  15. class="create-form"
  16. >
  17. <el-row :gutter="15">
  18. <el-col :span="12">
  19. <el-form-item label="规则编码:" prop="ruleCode">
  20. <el-input
  21. v-model="form.ruleCode"
  22. maxlength="50"
  23. placeholder="请输入"
  24. :disabled="type == 'update'"
  25. />
  26. </el-form-item>
  27. </el-col>
  28. <el-col :span="12">
  29. <el-form-item label="规则名称:" prop="ruleName">
  30. <el-input
  31. v-model="form.ruleName"
  32. maxlength="50"
  33. placeholder="请输入"
  34. />
  35. </el-form-item>
  36. </el-col>
  37. <el-col :span="12">
  38. <el-form-item label="时间间隔:" prop="forInterval">
  39. <el-input-number
  40. v-model="form.forInterval"
  41. :min="1"
  42. :max="100"
  43. controls-position="right"
  44. class="w-full"
  45. />
  46. </el-form-item>
  47. </el-col>
  48. <el-col :span="12">
  49. <el-form-item label="是否重复:" prop="repeated">
  50. <el-radio-group v-model="form.repeated">
  51. <el-radio :label="true">是</el-radio>
  52. <el-radio :label="false">否</el-radio>
  53. </el-radio-group>
  54. </el-form-item>
  55. </el-col>
  56. <el-col :span="12">
  57. <el-form-item label="排序号:" prop="indexNo">
  58. <el-input-number
  59. v-model="form.indexNo"
  60. :min="1"
  61. :max="99999"
  62. controls-position="right"
  63. class="w-full"
  64. />
  65. </el-form-item>
  66. </el-col>
  67. <el-col :span="24">
  68. <el-form-item label="摄像头:" prop="devices" class="!mb-0">
  69. <Draggable
  70. :devices="form.devices"
  71. :camera-list="cameraList"
  72. ref="draggable"
  73. />
  74. </el-form-item>
  75. </el-col>
  76. </el-row>
  77. </el-form>
  78. <template #footer>
  79. <el-button @click="cancel">取消</el-button>
  80. <el-button
  81. type="primary"
  82. @click="save"
  83. :loading="loading"
  84. >
  85. 保存
  86. </el-button>
  87. </template>
  88. </ele-modal>
  89. </template>
  90. <script>
  91. import * as VideoPollingApi from '@/api/config/videoPolling'
  92. import Draggable from './draggable.vue'
  93. const defForm = {
  94. id: undefined,
  95. ruleCode: '',
  96. ruleName: '',
  97. forInterval: 10,
  98. repeated: true,
  99. indexNo: 100,
  100. devices: [{ deviceCode: undefined }]
  101. }
  102. export default {
  103. name: 'VideoPolingForm',
  104. components: {
  105. Draggable
  106. },
  107. data() {
  108. return {
  109. visible: false,
  110. title: '',
  111. type: '',
  112. loading: false,
  113. form: { ...defForm },
  114. cameraList: [],
  115. rules: {
  116. ruleCode: [{ required: true, message: '规则编码不能为空', trigger: 'blur' }],
  117. ruleName: [{ required: true, message: '规则名称不能为空', trigger: 'blur' }],
  118. forInterval: [{ required: true, message: '时间间隔不能为空', trigger: 'blur' }],
  119. repeated: [{ required: true, message: '请选择是否重复', trigger: 'change' }],
  120. indexNo: [{ required: true, message: '排序号不能为空', trigger: 'blur' }]
  121. }
  122. }
  123. },
  124. created() {
  125. // 初始化时获取摄像头列表
  126. this.getCameraList()
  127. },
  128. methods: {
  129. /** 获取摄像头列表 */
  130. async getCameraList() {
  131. try {
  132. const res = await VideoPollingApi.listByType()
  133. this.cameraList = res || []
  134. } catch (e) {
  135. console.error(e)
  136. }
  137. },
  138. /** devices 更新回调 */
  139. // handleDevicesUpdate(val) {
  140. // this.form.devices = val
  141. // console.log('form.devices:', this.form.devices)
  142. // },
  143. /** 打开弹窗 */
  144. openForm(type, id) {
  145. this.visible = true
  146. this.type = type
  147. this.title = type === 'create' ? '新增轮询规则' : '编辑轮询规则'
  148. // 重置表单
  149. this.form = { ...defForm }
  150. // 修改时,加载数据
  151. if (id) {
  152. this.loading = true
  153. VideoPollingApi.getVideoRule(id)
  154. .then((res) => {
  155. // 解析 devices 字符串为数组
  156. let devices = JSON.parse(res.devices || '[]')
  157. res.devices = devices.length ? devices : [{ deviceCode: undefined }]
  158. this.form = res
  159. console.log('res:', res)
  160. })
  161. .finally(() => {
  162. this.loading = false
  163. })
  164. }
  165. },
  166. /** 取消 */
  167. cancel() {
  168. this.form = { ...defForm }
  169. this.visible = false
  170. },
  171. /** 保存 */
  172. save() {
  173. this.$refs.form.validate((valid) => {
  174. if (valid) {
  175. console.log('form:', this.form)
  176. const devices = this.$refs.draggable.localDevices
  177. console.log('devices:', devices)
  178. // 验证摄像头选择
  179. const hasEmptyCamera = devices.some(item => !item.deviceCode)
  180. if (hasEmptyCamera) {
  181. this.$message.warning('请选择摄像头')
  182. return
  183. }
  184. this.loading = true
  185. const formData = { ...this.form }
  186. const array = []
  187. // 处理摄像头数据:直接使用 deviceCode 数组
  188. devices.forEach((item) => {
  189. this.cameraList.forEach((camera) => {
  190. if (item.deviceCode == camera.deviceCode) {
  191. array.push(camera)
  192. }
  193. })
  194. })
  195. console.log('array:', array)
  196. formData.devices = JSON.stringify(array)
  197. const action = this.type === 'create'
  198. ? VideoPollingApi.createVideoRule(formData)
  199. : VideoPollingApi.updateVideoRule(formData)
  200. action
  201. .then(() => {
  202. this.$message.success('操作成功')
  203. this.cancel()
  204. this.$emit('success')
  205. })
  206. .catch((e) => {
  207. console.error(e)
  208. })
  209. .finally(() => {
  210. this.loading = false
  211. })
  212. }
  213. })
  214. },
  215. /** 新增摄像头 */
  216. addCamera() {
  217. this.form.devices.push({ deviceCode: undefined })
  218. // 强制刷新 Draggable
  219. // this.$nextTick(() => {
  220. // this.$refs.draggable && this.$refs.draggable.refresh()
  221. // })
  222. }
  223. }
  224. }
  225. </script>
  226. <style lang="scss" scoped>
  227. .w-full {
  228. width: 100%
  229. }
  230. </style>