Casper Dai 3 vuotta sitten
vanhempi
sitoutus
d55f7d1212

+ 1 - 1
src/components/tree/DeviceGroupTree/index.vue

@@ -104,7 +104,7 @@
                   :class="{ sub: !onlyOneGroup }"
                   @click="onDeviceToggle(group, device)"
                 >
-                  <span class="c-tree__label">{{ device.name }} {{ isGroupTab ? device.resolutionRatio : '' }}</span>
+                  <span class="c-tree__label u-ellipsis">{{ device.name }} {{ isGroupTab ? device.resolutionRatio : '' }}</span>
                   <el-checkbox
                     :value="device.checked"
                     class="l-flex__none c-tree__checkbox"

+ 186 - 0
src/components/tree/DeviceTreeSingle/index.vue

@@ -0,0 +1,186 @@
+<template>
+  <div
+    v-loading="loading"
+    class="l-flex--col c-tree"
+    :class="size"
+  >
+    <warning
+      v-if="error"
+      @click="getDevices"
+    />
+    <template v-else>
+      <div
+        v-if="isEmpty"
+        class="c-tree__empty"
+      >
+        暂无设备
+      </div>
+      <template v-else>
+        <div class="l-flex__none l-flex--row has-bottom-padding">
+          <div class="l-flex__auto" />
+          <search-input
+            v-model.trim="deviceName"
+            class="l-flex__none c-sibling-item"
+            placeholder="设备名称"
+            @search="onSearch"
+          />
+          <button
+            class="l-flex__none c-sibling-item o-button"
+            @click="onSearch"
+          >
+            搜索
+          </button>
+        </div>
+        <div
+          v-if="isEmptySeach"
+          class="c-tree__empty"
+        >
+          暂无设备
+        </div>
+        <template v-else>
+          <div class="l-flex__auto l-flex--col u-overflow-y--auto">
+            <div
+              v-for="group in groups"
+              :key="group.id"
+              class="l-flex__none"
+            >
+              <div
+                v-if="!onlyOneGroup"
+                class="c-tree__content u-pointer"
+                @click="onGroupToggle(group)"
+              >
+                <i
+                  class="c-tree__expand el-icon-arrow-right"
+                  :class="{ expand: group.expand }"
+                />
+                <span class="c-tree__label">{{ group.name }}</span>
+              </div>
+              <div v-show="onlyOneGroup || group.expand">
+                <div
+                  v-if="group.empty"
+                  class="c-tree__empty--content"
+                >
+                  暂无设备
+                </div>
+                <div
+                  v-for="device in group.list"
+                  :key="device.id"
+                  class="c-tree__content u-ellipsis u-pointer"
+                  :class="{ sub: !onlyOneGroup, selected: device.id === deviceId }"
+                  @click="onDeviceToggle(device)"
+                >
+                  <span class="l-flex__fill">{{ device.name }}</span>
+                </div>
+              </div>
+            </div>
+          </div>
+        </template>
+      </template>
+    </template>
+  </div>
+</template>
+
+<script>
+import { getDeviceTree } from '@/api/device'
+
+export default {
+  name: 'DeviceTreeSingle',
+  props: {
+    size: {
+      type: String,
+      default: ''
+    }
+  },
+  data () {
+    return {
+      loading: false,
+      error: false,
+      deviceName: '',
+      isEmpty: true,
+      groups: [],
+      selectedDevice: null
+    }
+  },
+  computed: {
+    isEmptySeach () {
+      return !this.groups.some(({ empty }) => !empty)
+    },
+    onlyOneGroup () {
+      return this.groups.length < 2
+    },
+    deviceId () {
+      return this.selectedDevice?.id
+    }
+  },
+  watch: {
+    active: {
+      handler () {
+        this.getDevices()
+      },
+      immediate: true
+    }
+  },
+  methods: {
+    onGroupToggle (group) {
+      group.expand = !group.expand
+    },
+    onDeviceToggle (device) {
+      if (!this.selectedDevice || this.selectedDevice.id !== device.id) {
+        this.selectedDevice = device
+        this.$emit('change', this.deviceId)
+      }
+    },
+    getDevices () {
+      this.loading = true
+      this.error = false
+      this.getDevicesByActive().then(
+        data => {
+          this.$groups = data
+          const { length } = data
+          if (length === 0 || !data.some(({ list }) => list.length)) {
+            this.isEmpty = true
+          } else {
+            this.isEmpty = false
+            this.onSearch()
+          }
+        },
+        () => {
+          this.error = true
+        }
+      ).finally(() => {
+        this.loading = false
+      })
+    },
+    getDevicesByActive () {
+      if (this.$groupCache) {
+        return Promise.resolve(this.$groupCache)
+      }
+      return getDeviceTree().then(({ data }) => {
+        this.$groupCache = data
+        return this.getDevicesByActive()
+      })
+    },
+    onSearch () {
+      const regx = this.deviceName ? new RegExp(this.deviceName) : null
+      this.groups = this.$groups.map(({ name, list }) => {
+        if (regx) {
+          list = list.filter(({ name }) => regx.test(name))
+        }
+        const empty = list.length === 0
+        return {
+          name,
+          expand: !!(regx && !empty),
+          empty,
+          list: list.map(({ id, name }) => {
+            return { id, name }
+          })
+        }
+      })
+    },
+    reset () {
+      this.deviceName = ''
+      this.onSearch()
+    }
+  }
+}
+</script>

+ 12 - 0
src/router/index.js

@@ -351,6 +351,18 @@ export const asyncRoutes = [
         path: 'order/history',
         component: () => import('@/views/ad/history/index'),
         meta: { title: '订单历史' }
+      },
+      {
+        name: 'ad-order-task',
+        path: 'order/task',
+        component: () => import('@/views/ad/task/index'),
+        meta: { title: '上播管理' }
+      },
+      {
+        name: 'ad-order-scheduling',
+        path: 'order/scheduling',
+        component: () => import('@/views/ad/scheduling/index'),
+        meta: { title: '一键排单' }
       }
     ]
   },

+ 16 - 3
src/scss/bem/_component.scss

@@ -512,6 +512,14 @@
   color: $black;
   font-size: 16px;
 
+  &.small {
+    font-size: 14px;
+  }
+
+  &.mini {
+    font-size: 12px;
+  }
+
   &__title {
     margin: 0 0 12px;
     color: $black;
@@ -522,15 +530,20 @@
   &__content {
     display: flex;
     align-items: center;
-    padding: 6px 6px 6px 0;
+    padding: 6px;
 
     &.sub {
-      padding-left: 30px;
+      padding-left: 36px;
     }
 
     &:hover {
       background-color: $blue--light;
     }
+
+    &.selected {
+      color: #fff;
+      background-color: $blue;
+    }
   }
 
   &__expand {
@@ -547,7 +560,7 @@
   }
 
   &__label {
-    flex: auto;
+    flex: 1 0 0;
     padding-right: 10px;
   }
 

+ 17 - 2
src/views/ad/api.js

@@ -68,12 +68,27 @@ export function rejectAsset ({ keyName }, reason) {
   })
 }
 
-export function getOrdersByDeviceAndDate (deviceId, options) {
+export function getOrdersByDevice (query, options) {
+  const { pageNum: pageIndex, pageSize, ...params } = query
   return request({
     url: '/ad/tenant/order/device/range',
     method: 'GET',
     params: {
-      deviceId,
+      pageIndex, pageSize,
+      ...params,
+      ...options
+    }
+  })
+}
+
+export function getDeviceSchedulings (query, options) {
+  const { pageNum: pageIndex, pageSize, ...params } = query
+  return request({
+    url: '/ad/tenant/order/scheduling/list',
+    method: 'GET',
+    params: {
+      pageIndex, pageSize,
+      ...params,
       ...options
     }
   })

+ 63 - 0
src/views/ad/scheduling/index.vue

@@ -0,0 +1,63 @@
+<template>
+  <wrapper
+    :vertical="false"
+    fill
+    margin
+    padding
+    background
+  >
+    <device-tree-single
+      class="l-flex__none c-device-tree"
+      size="mini"
+      @change="onChange"
+    />
+    <schema-table
+      v-if="deviceId"
+      ref="table"
+      row-key="id"
+      :schema="schema"
+    />
+  </wrapper>
+</template>
+
+<script>
+import { getDeviceSchedulings } from '../api'
+
+export default {
+  name: 'AdScheduling',
+  data () {
+    return {
+      deviceId: ''
+    }
+  },
+  computed: {
+    schema () {
+      return {
+        buttons: [
+          { label: '一键排单', on: this.onScheduling }
+        ],
+        condition: { deviceId: this.deviceId },
+        list: getDeviceSchedulings,
+        cols: [{ prop: 'name', label: '名称', align: 'center' }]
+      }
+    }
+  },
+  methods: {
+    onChange (deviceId) {
+      this.deviceId = deviceId
+    },
+    onScheduling (val) {
+      console.log(val)
+    }
+  }
+}
+</script>
+
+<style lang="scss" scoped>
+.c-device-tree {
+  width: 294px;
+  padding-right: $spacing;
+  margin-right: $spacing;
+  border-right: 1px solid $gray--light;
+}
+</style>

+ 57 - 0
src/views/ad/task/index.vue

@@ -0,0 +1,57 @@
+<template>
+  <wrapper
+    :vertical="false"
+    fill
+    margin
+    padding
+    background
+  >
+    <device-tree-single
+      class="l-flex__none c-device-tree"
+      size="mini"
+      @change="onChange"
+    />
+    <schema-table
+      v-if="deviceId"
+      ref="table"
+      row-key="id"
+      :schema="schema"
+    />
+  </wrapper>
+</template>
+
+<script>
+import { getOrdersByDevice } from '../api'
+
+export default {
+  name: 'AdOrderTask',
+  data () {
+    return {
+      deviceId: ''
+    }
+  },
+  computed: {
+    schema () {
+      return {
+        condition: { deviceId: this.deviceId },
+        list: getOrdersByDevice,
+        cols: [{ prop: 'name', label: '名称', align: 'center' }]
+      }
+    }
+  },
+  methods: {
+    onChange (deviceId) {
+      this.deviceId = deviceId
+    }
+  }
+}
+</script>
+
+<style lang="scss" scoped>
+.c-device-tree {
+  width: 294px;
+  padding-right: $spacing;
+  margin-right: $spacing;
+  border-right: 1px solid $gray--light;
+}
+</style>