index.vue 8.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297
  1. <template>
  2. <el-form class="search" inline>
  3. <el-form-item>
  4. <el-select v-model="organizationIds" placeholder="请选择企业" style="width: 200px" filterable remote
  5. :remote-method="businessRemote" remote-show-suffix>
  6. <el-option v-for="item in businessData.options" :key="item.id" :value="item.id" :label="item.name" />
  7. </el-select>
  8. </el-form-item>
  9. <el-form-item>
  10. <el-select v-model="storeId" placeholder="请选择门店" style="width: 200px" filterable remote
  11. :remote-method="storeRemote" remote-show-suffix>
  12. <el-option v-for="item in storeData.options" :key="item.id" :value="item.id" :label="item.name" />
  13. </el-select>
  14. </el-form-item>
  15. <el-form-item style="float:right">
  16. <el-button type="primary" icon="Plus" @click="getDetail()">新增预设</el-button>
  17. </el-form-item>
  18. </el-form>
  19. <div class="timer">
  20. <div class="item" v-for="(item, index) in data.timeList" :key="item">
  21. <div class="value">
  22. <span>{{ item.time[0].slice(0, 5) }}</span>
  23. <span class="solid"></span>
  24. </div>
  25. <draggable class="label_box" v-model="item.list" group="componentGroup" :item-key="index.toString()"
  26. :move="onMove" @end="onEnd">
  27. <template #item="{ element, index }">
  28. <div @mousedown.stop style="width: 100%">
  29. <el-popover placement="bottom" trigger="click" width="300px" popper-class="popper"
  30. :popper-style="popperStyle" :hide-after="0">
  31. <div class="title">
  32. <h2>{{ element.takeName }}</h2>
  33. <div style="display:flex; justify-content: space-between;">
  34. <span>{{ element.listDate.startTime }} - {{ element.listDate.endTime }}</span>
  35. <div style="display:flex; align-items: center">
  36. <el-icon style="margin-right: 10px" @click="getDetail(element)">
  37. <Edit />
  38. </el-icon>
  39. <el-icon @click="getDelete(element)">
  40. <Delete />
  41. </el-icon>
  42. </div>
  43. </div>
  44. </div>
  45. <div class="main">
  46. <span>当前门店:{{ storeData.options.find(i => i.id === element.storeId).name }}</span>
  47. <span>当前设备:{{ element.deviceIds }}</span>
  48. <span>当前状态:{{ proxy.selectDictLabel(sys_change_status, element.status) }}</span>
  49. </div>
  50. <template #reference>
  51. <span class="label">{{ element.takeName }}</span>
  52. </template>
  53. </el-popover>
  54. </div>
  55. </template>
  56. </draggable>
  57. </div>
  58. </div>
  59. </template>
  60. <script setup>
  61. import { timeList, removeScene } from '@/api/content/scene'
  62. import { useBusinessSelect, useStoreSelect } from '@/hooks/index'
  63. const { storeData, getStore, storeRemote } = useStoreSelect()
  64. const { businessData, getBusiness, businessRemote } = useBusinessSelect(true)
  65. getBusiness()
  66. const { proxy } = getCurrentInstance();
  67. const { sys_change_status } = proxy.useDict("sys_change_status");
  68. const props = defineProps({
  69. path: {
  70. type: String,
  71. default: null
  72. }
  73. })
  74. const data = reactive({
  75. timeList: [
  76. { time: ['00:00:00', '01:00:00'], list: [] },
  77. { time: ['01:00:00', '02:00:00'], list: [] },
  78. { time: ['02:00:00', '03:00:00'], list: [] },
  79. { time: ['03:00:00', '04:00:00'], list: [] },
  80. { time: ['04:00:00', '05:00:00'], list: [] },
  81. { time: ['05:00:00', '06:00:00'], list: [] },
  82. { time: ['06:00:00', '07:00:00'], list: [] },
  83. { time: ['07:00:00', '08:00:00'], list: [] },
  84. { time: ['08:00:00', '09:00:00'], list: [] },
  85. { time: ['09:00:00', '10:00:00'], list: [] },
  86. { time: ['10:00:00', '11:00:00'], list: [] },
  87. { time: ['11:00:00', '12:00:00'], list: [] },
  88. { time: ['12:00:00', '13:00:00'], list: [] },
  89. { time: ['13:00:00', '14:00:00'], list: [] },
  90. { time: ['14:00:00', '15:00:00'], list: [] },
  91. { time: ['15:00:00', '16:00:00'], list: [] },
  92. { time: ['16:00:00', '17:00:00'], list: [] },
  93. { time: ['17:00:00', '18:00:00'], list: [] },
  94. { time: ['18:00:00', '19:00:00'], list: [] },
  95. { time: ['19:00:00', '20:00:00'], list: [] },
  96. { time: ['20:00:00', '21:00:00'], list: [] },
  97. { time: ['21:00:00', '22:00:00'], list: [] },
  98. { time: ['22:00:00', '23:00:00'], list: [] },
  99. { time: ['23:00:00', '00:00:00'], list: [] },
  100. { time: ['00:00:00', '01:00:00'], list: [] }
  101. ],
  102. })
  103. // 时间轴表单
  104. const organizationIds = ref(null)
  105. const storeId = ref(null)
  106. // 时间段
  107. function getTime() {
  108. for (let i = 0; i <= data.timeList.length - 1; i++) {
  109. data.timeList[i].timer = []
  110. data.timeList[i].timer[0] = proxy.hoursToSeconds(data.timeList[i].time[0])
  111. data.timeList[i].timer[1] = proxy.hoursToSeconds(data.timeList[i].time[1])
  112. }
  113. }
  114. getTime()
  115. const popperStyle = ref({
  116. padding: 0,
  117. borderRadius: '10px'
  118. })
  119. // 时间轴
  120. function getTimeList() {
  121. timeList({ storeId: storeId.value }).then(res => {
  122. for (let i = 0; i < res.data.length; i++) {
  123. for (let j = 0; j < res.data[i].listDate.length; j++) {
  124. let start = proxy.hoursToSeconds(res.data[i].listDate[j].startTime)
  125. let end = proxy.hoursToSeconds(res.data[i].listDate[j].endTime)
  126. const index1 = data.timeList.findIndex(e => {
  127. let st = e.timer[0]
  128. let en = e.timer[1]
  129. return st <= start && start <= en || st <= end && end <= en
  130. })
  131. data.timeList[index1].list.push({ ...res.data[i], listDate: res.data[i].listDate[j] })
  132. const index2 = data.timeList.findIndex(e => {
  133. let st = e.timer[0]
  134. let en = e.timer[1]
  135. return st >= start && en <= end || st >= end && en <= start
  136. })
  137. data.timeList[index2].list.push({ ...res.data[i], listDate: res.data[i].listDate[j] })
  138. }
  139. }
  140. })
  141. }
  142. // 拖拽内容
  143. function onMove(params) {
  144. if (params.to.childElementCount < 1) {
  145. return true
  146. } else {
  147. return false
  148. }
  149. }
  150. // 拖拽结束
  151. function onEnd(params) {
  152. if (params.from.className === 'contentList' &&
  153. params.to.className === 'label_box' ||
  154. params.from.className === 'label_box' &&
  155. params.from.__draggable_component__.itemKey !== params.to.__draggable_component__.itemKey) {
  156. let query = {
  157. value: params.item._underlying_vm_.value,
  158. label: params.item._underlying_vm_.label
  159. }
  160. getDetail(query)
  161. }
  162. }
  163. // 删除
  164. const getDelete = (row) => {
  165. proxy.$modal.confirm(`是否删除预设名称为:${row.takeName}的数据?`).then(() => {
  166. removeScene({ id: row.id }).then(res => {
  167. if (res.code === 0) {
  168. proxy.$modal.msgSuccess('删除成功!')
  169. getTimeList()
  170. }
  171. })
  172. }).catch(() => { })
  173. }
  174. watch(() => businessData.options, (val) => {
  175. if (val) {
  176. organizationIds.value = val[0].id
  177. }
  178. })
  179. watch(organizationIds, (val) => {
  180. if (val) {
  181. storeData.form.tenantId = val
  182. getStore()
  183. }
  184. })
  185. watch(() => storeData.storeId, (val) => {
  186. data.timeList.map(i => i.list = [])
  187. storeId.value = val
  188. if (val) {
  189. getTimeList()
  190. }
  191. })
  192. // 新增预设
  193. function getDetail(query) {
  194. proxy.$router.push({
  195. path: props.path,
  196. query
  197. })
  198. }
  199. </script>
  200. <style lang="scss" scoped>
  201. .timer {
  202. display: flex;
  203. flex-direction: column;
  204. width: calc(100% - 50px);
  205. margin-left: 50px;
  206. overflow-y: auto;
  207. padding: 20px 20px 20px 50px;
  208. .item {
  209. width: 100%;
  210. height: 100px;
  211. line-height: 100px;
  212. position: relative;
  213. border-left: 1px solid #e3e3e3;
  214. display: flex;
  215. align-items: center;
  216. .value {
  217. width: 100px;
  218. margin-left: -50px;
  219. .solid {
  220. border-top: 1px solid #e3e3e3;
  221. width: 100%;
  222. position: absolute;
  223. top: 50px;
  224. left: 0;
  225. }
  226. }
  227. .label_box {
  228. display: flex;
  229. width: 100%;
  230. z-index: 99;
  231. position: absolute;
  232. top: 70px;
  233. .label {
  234. background-color: #ebf1fe;
  235. color: #3979F9;
  236. height: 60px;
  237. display: flex;
  238. justify-content: center;
  239. align-items: center;
  240. border-left: 4px solid #3979F9;
  241. border-radius: 4px;
  242. margin-right: 10px;
  243. font-size: 12px;
  244. padding: 0 20px;
  245. flex: 1;
  246. }
  247. }
  248. }
  249. }
  250. .popper {
  251. .title,
  252. .main {
  253. line-height: 35px;
  254. padding: 20px;
  255. }
  256. .title {
  257. background-color: #337ecc;
  258. color: #FFF;
  259. border-radius: 10px 10px 0 0;
  260. font-size: 16px;
  261. }
  262. .main {
  263. display: flex;
  264. flex-direction: column;
  265. }
  266. }
  267. .search {
  268. padding-left: 70px;
  269. }
  270. </style>