Purpose 9 months ago
parent
commit
29c977746a

+ 37 - 4
src/components/DialogTagPurchase.vue

@@ -26,7 +26,24 @@
             </el-row>
 
             <template v-if="operatorTypeId === 1">
-
+              <el-row
+                v-for="(info, index) in data.infos"
+                :key="index"
+                :gutter="$$Constant.LAYOUT_GAP"
+              >
+                <el-col :span="12">
+                  <el-form-item label="标签类型">
+                    <el-input v-model="info.tagTypeName" readonly />
+                  </el-form-item>
+                </el-col>
+                <el-col :span="12">
+                  <el-form-item label="标签数量" :prop="`infos[${index}].number`" :rules="[{
+                    validator: tagNumberValidator
+                  }]">
+                    <integer-input v-model="info.number" placeholder="输入标签数量"></integer-input>
+                  </el-form-item>
+                </el-col>
+              </el-row>
             </template>
             <el-row v-else :gutter="$$Constant.LAYOUT_GAP">
               <el-col :span="12">
@@ -39,8 +56,11 @@
               </el-col>
 
               <el-col :span="12">
-                <el-form-item label="标签数量" prop="number">
-                  <el-input v-model="data.number" type="number" />
+                <el-form-item label="标签数量" prop="number" :rules="[{
+                  required: true,
+                  message: '请输入标签数量'
+                }]">
+                  <integer-input v-model="data.number" placeholder="输入标签数量"></integer-input>
                 </el-form-item>
               </el-col>
             </el-row>
@@ -52,7 +72,6 @@
     <template #footer>
       <div class="flex center dialog-footer">
         <el-button @click="onCloseBtnClick">取消</el-button>
-
         <el-button type="primary" @click="onSaveBtnClick">确定</el-button>
       </div>
     </template>
@@ -71,6 +90,20 @@ export default {
       required: true,
       type: Object
     }
+  },
+  methods: {
+    tagNumberValidator (rule, value, callback) {
+      value = parseFloat(value)
+      if (value <= 0) {
+        return callback(new Error('标签数量不能<=0'))
+      }
+
+      if (this.data.infos.every(info => !Number.isFinite(parseInt(info.number)))) {
+        return callback(new Error('请至少输入一种标签类型的数量'))
+      }
+
+      return callback()
+    }
   }
 }
 </script>

+ 35 - 0
src/components/IntegerInput.vue

@@ -0,0 +1,35 @@
+<template>
+  <el-input v-model="integerNumber" type="number" :placeholder="placeholder" />
+</template>
+
+<script>
+export default {
+  name: 'IntegerInput',
+  props: {
+    value: {
+      required: true
+    },
+    placeholder: {
+      type: String
+    },
+    readonly: {
+      type: Boolean
+    },
+    disabled: {
+      type: Boolean
+    }
+  },
+  computed: {
+    integerNumber: {
+      get () {
+        return this.value
+      },
+      set (number) {
+        this.$emit('input', (number || '').replace(/\D/g, ''))
+      }
+    }
+  }
+}
+</script>
+
+<style lang="scss"></style>

+ 5 - 1
src/components/MySelect.vue

@@ -4,6 +4,7 @@
     :filterable="filterable"
     :clearable="clearable"
     :placeholder="placeholder"
+    :disabled="disabled"
     style="width:100%"
     @change="change"
   >
@@ -34,7 +35,10 @@ export default {
     clearable: {
       type: Boolean
     },
-    placeholder: {}
+    placeholder: {},
+    disabled: {
+      type: Boolean
+    }
   },
   computed: {
     selectValue: {

+ 6 - 8
src/entries/TagPurchase.js

@@ -68,14 +68,12 @@ export default class TagPurchase extends BaseCurdEntry {
     }
 
     const tagTypeConfig = optionGroup.TagType
-    // const infos = []
-    this.infos = [{
-      tagTypeId: ''
-    }]
-    const [ tagType ] = tagTypeConfig.list
-    if (tagType) {
-      this.tagTypeId = tagType[tagTypeConfig.Target.$$idProp]
-    }
+    const tagTypeTarget = tagTypeConfig.Target
+    this.infos = tagTypeConfig.list.map(tagType => ({
+      tagTypeId: tagType[tagTypeTarget.$$idProp],
+      tagTypeName: tagType[tagTypeTarget.$$nameProp],
+      number: null
+    }))
   }
 
   static get $$api () {

+ 17 - 0
src/mock/index.js

@@ -70,6 +70,7 @@ Mock.mock(/\/tag\/purchase\/page/, 'post', {
     'count|10-40': 1,
     'list|1-20': [{
       'id|1-20': 1,
+      'providerId|1-3': 1,
       dataTime: '2024/01/01 00:00:00',
       orderNo: '123456',
       'tagTypeId|1': [1, 2, 3],
@@ -82,4 +83,20 @@ Mock.mock(/\/tag\/purchase\/page/, 'post', {
   }
 })
 
+Mock.mock(/\/tag\/purchase\/.+/, 'get', {
+  type: 'success',
+  data: {
+    'id|1-20': 1,
+    'providerId|1-3': 1,
+    dataTime: '2024/01/01 00:00:00',
+    orderNo: '123456',
+    'tagTypeId|1': [1, 2, 3],
+    number: 123,
+    'amount|1-100.1-2': 30,
+    buyerName: '采购者',
+    receiveDate: '2024/01/02 00:00:00',
+    'tagPurchaseStateId|1-2': 1
+  }
+})
+
 export default Mock

+ 2 - 73
src/utils/api.js

@@ -1,75 +1,4 @@
-import axios from 'axios'
+import apiCreator from './apiCreator'
 import Constant from './Constant'
 
-export class AjaxError extends Error {
-  code = 0
-
-  constructor (msg, code) {
-    super(msg || '未知错误')
-    this.code = code
-  }
-}
-
-const CancelToken = axios.CancelToken
-
-const link = document.createElement('a')
-
-// const RESPONSE_ERROR = 'ResponseError'
-const REQUEST_CANCEL = 'RequestCancel'
-
-const request = axios.create({
-  baseURL: Constant.REQUEST_PREFIX,
-  timeout: 300000
-})
-
-request.interceptors.request.use(config => {
-  return config
-}, error => new Promise((resolve, reject) => reject(error)))
-
-request.interceptors.response.use(response => new Promise((resolve, reject) => {
-  const { config, data } = response
-  if (/^(blob)$/i.test(config.responseType)) {
-    if (data instanceof Blob) {
-      const match = /filename=([^;]+)/.exec(response.headers['content-disposition'])
-      if (match) {
-        let filename = decodeURIComponent(match).split(',')
-        link.href = URL.createObjectURL(data)
-        link.download = filename ? filename[filename.length - 1] : ''
-        link.click()
-        URL.revokeObjectURL(link.href)
-      }
-      return resolve(response)
-    }
-
-    return resolve(data)
-  }
-
-  if (typeof data !== 'object' || data === null) {
-    return reject(new AjaxError('数据格式不正确', 30000))
-  }
-
-  const { type } = data
-  if (type === 'success') {
-    return resolve(data.data)
-  }
-
-  return reject(new AjaxError(data.msg, 500))
-}), error => {
-  if (error.message === REQUEST_CANCEL) {
-    return
-  }
-
-  if (!(error instanceof AjaxError)) {
-    error = new AjaxError('服务器正忙', 500)
-  }
-
-  return Promise.reject(error)
-})
-
-export const api = (config) => {
-  const source = CancelToken.source()
-  config = Object.assign({ cancelToken: source.token }, config)
-  const promise = request(config)
-  promise.abort = () => source.cancel(REQUEST_CANCEL)
-  return promise
-}
+export const api = apiCreator(Constant.REQUEST_PREFIX)

+ 76 - 0
src/utils/apiCreator.js

@@ -0,0 +1,76 @@
+import axios from 'axios'
+
+const CancelToken = axios.CancelToken
+
+export class AjaxError extends Error {
+  code = 0
+
+  constructor (msg, code) {
+    super(msg || '未知错误')
+    this.code = code
+  }
+}
+
+// const RESPONSE_ERROR = 'ResponseError'
+const REQUEST_CANCEL = 'RequestCancel'
+
+export default (baseApiPath) => {
+  const link = document.createElement('a')
+
+  const request = axios.create({
+    baseURL: baseApiPath,
+    timeout: 300000
+  })
+
+  request.interceptors.request.use(config => {
+    return config
+  }, error => new Promise((resolve, reject) => reject(error)))
+
+  request.interceptors.response.use(response => new Promise((resolve, reject) => {
+    const { config, data } = response
+    if (/^(blob)$/i.test(config.responseType)) {
+      if (data instanceof Blob) {
+        const match = /filename=([^;]+)/.exec(response.headers['content-disposition'])
+        if (match) {
+          let filename = decodeURIComponent(match).split(',')
+          link.href = URL.createObjectURL(data)
+          link.download = filename ? filename[filename.length - 1] : ''
+          link.click()
+          URL.revokeObjectURL(link.href)
+        }
+        return resolve(response)
+      }
+
+      return resolve(data)
+    }
+
+    if (typeof data !== 'object' || data === null) {
+      return reject(new AjaxError('数据格式不正确', 30000))
+    }
+
+    const { type } = data
+    if (type === 'success') {
+      return resolve(data.data)
+    }
+
+    return reject(new AjaxError(data.msg, 500))
+  }), error => {
+    if (error.message === REQUEST_CANCEL) {
+      return
+    }
+
+    if (!(error instanceof AjaxError)) {
+      error = new AjaxError('服务器正忙', 500)
+    }
+
+    return Promise.reject(error)
+  })
+
+  return (config) => {
+    const source = CancelToken.source()
+    config = Object.assign({ cancelToken: source.token }, config)
+    const promise = request(config)
+    promise.abort = () => source.cancel(REQUEST_CANCEL)
+    return promise
+  }
+}