Casper Dai 3 жил өмнө
parent
commit
862147ee3b

+ 7 - 0
src/router/index.js

@@ -257,6 +257,13 @@ export const asyncRoutes = [
         component: () => import('@/views/realm/assign/index'),
         access: [Access.MANAGE_TENANTS, Access.MANAGE_TENANT],
         meta: { title: '设备分配' }
+      },
+      {
+        name: 'stock',
+        path: 'stock',
+        component: () => import('@/views/realm/ai-stock/index'),
+        access: Access.MANAGE_TENANTS,
+        meta: { title: 'AI审核库存' }
       }
     ]
   },

+ 4 - 0
src/scss/bem/_utility.scss

@@ -89,3 +89,7 @@
   background-size: contain;
   background-repeat: no-repeat;
 }
+
+.u-width--auto {
+  width: auto !important;
+}

+ 254 - 0
src/views/realm/ai-stock/Assign.vue

@@ -0,0 +1,254 @@
+<template>
+  <div class="l-flex">
+    <template v-if="groups">
+      <div class="c-tree-sidebar u-overflow-y--auto">
+        <el-tree
+          ref="groupTree"
+          :data="groups"
+          class="c-tree-sidebar__main"
+          node-key="path"
+          highlight-current
+          @node-click="onGroupTreeClick"
+        />
+      </div>
+      <schema-table
+        ref="table"
+        :schema="schema"
+      >
+        <table-dialog
+          ref="stockDialog"
+          title="总库存"
+          :schema="stockSchema"
+          @choosen="onChoosen"
+        />
+        <confirm-dialog
+          ref="addDialog"
+          title="分配"
+          @confirm="onSave"
+        >
+          <div class="c-grid-form u-align-self--center">
+            <span class="c-grid-form__label">类型:</span>
+            <schema-select
+              v-model="credit.auditType"
+              :schema="auditTypeSchema"
+              disabled
+            />
+            <span class="c-grid-form__label">次数:</span>
+            <div class="l-flex--row">
+              <el-input-number
+                v-model="credit.initialAmount"
+                class="c-sibling-item"
+                :min="1"
+                :max="remaining"
+                step-strictly
+              />
+              <span class="c-sibling-item u-color--info light">1 ~ {{ remaining }}</span>
+            </div>
+            <span class="c-grid-form__label required">有效期:</span>
+            <el-date-picker
+              v-model="credit.date"
+              class="u-width--auto"
+              type="daterange"
+              range-separator="至"
+              start-placeholder="开始日期"
+              end-placeholder="结束日期"
+              value-format="yyyy-MM-dd"
+              :picker-options="pickerOptions"
+            />
+          </div>
+        </confirm-dialog>
+      </schema-table>
+    </template>
+    <template v-else>
+      <div
+        v-loading="loading"
+        class="l-flex__auto l-flex--row center"
+      >
+        <template v-if="!loading">
+          <warning
+            v-if="error"
+            @click="getTreeData"
+          />
+          <div
+            v-else
+            class="u-bold"
+          >
+            暂无租户,请先添加租户
+          </div>
+        </template>
+      </div>
+    </template>
+  </div>
+</template>
+
+<script>
+import { getTopGroups } from '@/api/user'
+import {
+  getCredits,
+  getTenantCredits,
+  addCredit,
+  deleteCredit
+} from './api'
+
+export default {
+  name: 'StockAssign',
+  data () {
+    const auditTypeOptions = [
+      { value: 1, label: '图片' },
+      { value: 2, label: '视频' }
+    ]
+
+    return {
+      loading: true,
+      error: false,
+      groups: null,
+      group: null,
+      auditTypeSchema: {
+        options: auditTypeOptions
+      },
+      schema: {
+        condition: { auditType: void 0 },
+        list: this.getTenantCredits,
+        buttons: [
+          { type: 'add', label: '分配', on: this.onAdd }
+        ],
+        filters: [
+          { key: 'auditType', type: 'select', placeholder: '全部类型', options: auditTypeOptions }
+        ],
+        cols: [
+          { label: '审核类型', render: this.transformAuditType },
+          { prop: 'effectiveDate', label: '生效日期' },
+          { prop: 'expiryDate', label: '结束日期' },
+          { prop: 'initialAmount', label: '总次数' },
+          { prop: 'remaining', label: '剩余次数' },
+          { type: 'invoke', render: [
+            { label: '删除', on: this.onDel }
+          ] }
+        ]
+      },
+      stockSchema: {
+        condition: { auditType: void 0 },
+        list: getCredits,
+        filters: [
+          { key: 'auditType', type: 'select', placeholder: '全部类型', options: auditTypeOptions }
+        ],
+        cols: [
+          { label: '审核类型', render: this.transformAuditType },
+          { prop: 'effectiveDate', label: '生效日期' },
+          { prop: 'expiryDate', label: '结束日期' },
+          { label: '可分配', render ({ initialAmount, allocatedAmount }) {
+            return initialAmount - allocatedAmount
+          } }
+        ]
+      },
+      fromCredit: {},
+      credit: {},
+      pickerOptions: {
+        disabledDate: this.disabledDate
+      }
+    }
+  },
+  computed: {
+    remaining () {
+      return this.fromCredit
+        ? this.fromCredit.initialAmount - this.fromCredit.allocatedAmount
+        : 0
+    }
+  },
+  created () {
+    this.getTreeData()
+  },
+  methods: {
+    disabledDate (date) {
+      if (this.fromCredit) {
+        const { effectiveDate, expiryDate } = this.fromCredit
+        return date < new Date(`${effectiveDate} 00:00:00`) || date > new Date(`${expiryDate} 00:00:00`)
+      }
+      return false
+    },
+    transformAuditType (data) {
+      return ['', '图片', '视频'][data.auditType]
+    },
+    getTreeData () {
+      this.loading = true
+      this.error = false
+      getTopGroups().then(
+        ({ data }) => {
+          if (data.length) {
+            this.groups = data
+            this.group = this.groups[0]
+            this.$nextTick(() => {
+              this.$refs.groupTree.setCurrentKey(this.group.path)
+            })
+          }
+        },
+        () => {
+          this.error = true
+        }
+      ).finally(() => {
+        this.loading = false
+      })
+    },
+    onGroupTreeClick (group) {
+      if (!this.group || this.group.id !== group.id) {
+        this.group = group
+        this.$refs.table.pageTo(1)
+      }
+    },
+    getTenantCredits (params) {
+      return getTenantCredits({
+        tenant: this.group.path,
+        ...params
+      })
+    },
+    onAdd () {
+      this.$refs.stockDialog.show()
+    },
+    onChoosen ({ value, done }) {
+      const { auditType, initialAmount, allocatedAmount } = value
+      if (initialAmount - allocatedAmount < 1) {
+        this.$message({
+          type: 'warning',
+          message: '可分配次数不足,请重新选择'
+        })
+        return
+      }
+      this.fromCredit = value
+      this.credit = {
+        auditType,
+        initialAmount: 1,
+        date: ''
+      }
+      done()
+      this.$refs.addDialog.show()
+    },
+    onSave (done) {
+      const { auditType, initialAmount, date } = this.credit
+      if (!date) {
+        this.$message({
+          type: 'warning',
+          message: '请选择有效期'
+        })
+        return
+      }
+      addCredit({
+        admin: 0,
+        fromCredit: this.fromCredit.id,
+        tenant: this.group.path,
+        auditType,
+        initialAmount,
+        effectiveDate: date[0],
+        expiryDate: date[1]
+      }).then(() => {
+        done()
+        this.$refs.table.pageTo(1)
+      })
+    },
+    onDel (credit) {
+      deleteCredit(credit).then(() => {
+        this.$refs.table.decrease(1)
+      })
+    }
+  }
+}
+</script>

+ 123 - 0
src/views/realm/ai-stock/Stock.vue

@@ -0,0 +1,123 @@
+<template>
+  <schema-table
+    ref="table"
+    :schema="schema"
+  >
+    <confirm-dialog
+      ref="addDialog"
+      title="新增库存"
+      @confirm="onSave"
+    >
+      <div class="c-grid-form u-align-self--center">
+        <span class="c-grid-form__label">类型:</span>
+        <schema-select
+          v-model="credit.auditType"
+          :schema="auditTypeSchema"
+        />
+        <span class="c-grid-form__label">次数:</span>
+        <el-input-number
+          v-model="credit.initialAmount"
+          :min="1"
+          :max="999999"
+          step-strictly
+        />
+        <span class="c-grid-form__label required">有效期:</span>
+        <el-date-picker
+          v-model="credit.date"
+          class="u-width--auto"
+          type="daterange"
+          range-separator="至"
+          start-placeholder="开始日期"
+          end-placeholder="结束日期"
+          value-format="yyyy-MM-dd"
+        />
+      </div>
+    </confirm-dialog>
+  </schema-table>
+</template>
+
+<script>
+import {
+  getCredits,
+  addCredit,
+  deleteCredit
+} from './api'
+
+export default {
+  name: 'AIStock',
+  data () {
+    const auditTypeOptions = [
+      { value: 1, label: '图片' },
+      { value: 2, label: '视频' }
+    ]
+
+    return {
+      auditTypeSchema: {
+        options: auditTypeOptions
+      },
+      schema: {
+        condition: { auditType: void 0 },
+        list: getCredits,
+        buttons: [
+          { type: 'add', on: this.onAdd }
+        ],
+        filters: [
+          { key: 'auditType', type: 'select', placeholder: '全部类型', options: auditTypeOptions }
+        ],
+        cols: [
+          { label: '审核类型', render (data) {
+            return ['', '图片', '视频'][data.auditType]
+          } },
+          { prop: 'effectiveDate', label: '生效日期' },
+          { prop: 'expiryDate', label: '结束日期' },
+          { prop: 'initialAmount', label: '总次数' },
+          { prop: 'remaining', label: '剩余次数' },
+          { prop: 'allocatedAmount', label: '已分配' },
+          { label: '可分配', render ({ initialAmount, allocatedAmount }) {
+            return initialAmount - allocatedAmount
+          } },
+          { type: 'invoke', render: [
+            { label: '删除', on: this.onDel }
+          ] }
+        ]
+      },
+      credit: {}
+    }
+  },
+  methods: {
+    onAdd () {
+      this.credit = {
+        auditType: 1,
+        initialAmount: 1,
+        date: ''
+      }
+      this.$refs.addDialog.show()
+    },
+    onSave (done) {
+      const { auditType, initialAmount, date } = this.credit
+      if (!date) {
+        this.$message({
+          type: 'warning',
+          message: '请选择有效期'
+        })
+        return
+      }
+      addCredit({
+        admin: 1,
+        auditType,
+        initialAmount,
+        effectiveDate: date[0],
+        expiryDate: date[1]
+      }).then(() => {
+        done()
+        this.$refs.table.pageTo(1)
+      })
+    },
+    onDel (credit) {
+      deleteCredit(credit).then(() => {
+        this.$refs.table.decrease(1)
+      })
+    }
+  }
+}
+</script>

+ 46 - 0
src/views/realm/ai-stock/api.js

@@ -0,0 +1,46 @@
+import request from '@/utils/request'
+import {
+  add,
+  del
+} from '@/api/base'
+
+export function getCredits (query) {
+  const { pageNum: pageIndex, pageSize, ...params } = query
+  return request({
+    url: '/minio-data/ai/credit/listByPage',
+    method: 'GET',
+    params: {
+      admin: 1,
+      pageIndex, pageSize,
+      ...params
+    }
+  })
+}
+
+export function getTenantCredits (query) {
+  const { pageNum: pageIndex, pageSize, ...params } = query
+  return request({
+    url: '/minio-data/ai/credit/listByPage',
+    method: 'GET',
+    params: {
+      admin: 0,
+      pageIndex, pageSize,
+      ...params
+    }
+  })
+}
+
+export function addCredit (data) {
+  return add({
+    url: '/minio-data/ai/credit/deposit',
+    method: 'POST',
+    data
+  })
+}
+
+export function deleteCredit ({ id, auditType }) {
+  return del({
+    url: `/minio-data/ai/credit/${id}`,
+    method: 'DELETE'
+  }, ['库存', '图片库存', '视频库存'][auditType])
+}

+ 44 - 0
src/views/realm/ai-stock/index.vue

@@ -0,0 +1,44 @@
+<template>
+  <wrapper
+    fill
+    margin
+    padding
+    background
+  >
+    <el-tabs
+      v-model="active"
+      class="c-tabs has-bottom-padding"
+    >
+      <el-tab-pane
+        label="库存管理"
+        name="Stock"
+      />
+      <el-tab-pane
+        label="库存分配"
+        name="StockAssign"
+      />
+    </el-tabs>
+    <component
+      :is="active"
+      class="l-flex__auto"
+    />
+  </wrapper>
+</template>
+
+<script>
+import Stock from './Stock'
+import StockAssign from './Assign'
+
+export default {
+  name: 'AIStock',
+  components: {
+    Stock,
+    StockAssign
+  },
+  data () {
+    return {
+      active: 'Stock'
+    }
+  }
+}
+</script>

+ 3 - 4
src/views/realm/assign/index.vue

@@ -8,7 +8,7 @@
     <template v-if="tenants">
       <el-tabs
         v-model="active"
-        class="c-tabs"
+        class="c-tabs has-bottom-padding"
       >
         <el-tab-pane
           label="设备到部门"
@@ -23,7 +23,7 @@
         <template v-if="groups">
           <div
             v-if="isSuperAdmin"
-            class="c-tree-sidebar has-top-padding u-overflow-y--auto"
+            class="c-tree-sidebar u-overflow-y--auto"
           >
             <el-tree
               ref="tenantTree"
@@ -36,7 +36,7 @@
             />
           </div>
           <div
-            class="c-tree-sidebar has-top-padding u-overflow-y--auto"
+            class="c-tree-sidebar u-overflow-y--auto"
             :class="{ large: !isSuperAdmin }"
           >
             <component
@@ -48,7 +48,6 @@
           </div>
           <device
             v-if="value"
-            class="has-top-padding"
             :is-group="isGroup"
             :tenant="tenant"
             :value="value"