فهرست منبع

动态表单组件coding...

刘洋 1 سال پیش
والد
کامیت
12312848fa

+ 2 - 0
src/api/sop.js

@@ -3,3 +3,5 @@ import { http } from '@/service/request.js'
 export const getSopList = (data) => http.post('/api/admin/sop/list', data, { custom: { loading: true } })
 export const getSopList = (data) => http.post('/api/admin/sop/list', data, { custom: { loading: true } })
 //流程详细信息接口
 //流程详细信息接口
 export const getSopFlowView = (params) => http.post('/api/admin/flow/view', {}, { params, custom: { loading: true } })
 export const getSopFlowView = (params) => http.post('/api/admin/flow/view', {}, { params, custom: { loading: true } })
+export const deviceCanOut = (params) => http.post('/api/admin/device/in/out/can_out_info', {}, { params })
+export const deviceCanIn = (params) => http.post('/api/admin/device/in/out/can_in_info', {}, { params })

+ 1 - 1
src/api/user.js

@@ -4,7 +4,7 @@ import { getBase64 } from '@/utils/crypto'
 export const pcLogin = () =>
 export const pcLogin = () =>
   http.post(
   http.post(
     '/api/admin/common/login',
     '/api/admin/common/login',
-    { loginName: 'admin1', password: getBase64('123456'), type: 'ACCOUNT' },
+    { loginName: 'liuyang', password: getBase64('123456'), type: 'ACCOUNT' },
     {
     {
       custom: { noAuth: true }
       custom: { noAuth: true }
     }
     }

+ 33 - 0
src/components/low-code/CHECKBOX.vue

@@ -0,0 +1,33 @@
+<template>
+  <u-checkbox-group @change="change" :disabled="config.writable">
+    <u-checkbox v-for="(item, index) in options" v-model="list[index]" :key="item.value" :name="item.value">{{ item.label }}</u-checkbox>
+  </u-checkbox-group>
+</template>
+
+<script>
+  export default {
+    name: 'CHECKBOX',
+    props: ['config', 'onChange'],
+    data() {
+      return {
+        options: [],
+        show: false,
+        list: []
+      }
+    },
+    created() {
+      this.value = this.config.value || []
+      this.options = this.config.options || []
+      this.list = new Array(this.options.length).map((item, index) => {
+        return this.value.includes(this.options[index].value)
+      })
+    },
+    methods: {
+      change(val) {
+        this.onChange({ prop: this.config.formName, value: val })
+      }
+    }
+  }
+</script>
+
+<style></style>

+ 3 - 4
src/components/low-code/DATE.vue

@@ -1,6 +1,6 @@
 <template>
 <template>
   <view>
   <view>
-    <u-input v-model="valueStr" type="select" :border="true" :disabled="!config.writable" @click="show = true" />
+    <u-input v-model="value" type="select" :border="true" :disabled="!config.writable" @click="show = true" />
     <!-- <u-select v-model="show" :list="options" @confirm="confirm"></u-select> -->
     <!-- <u-select v-model="show" :list="options" @confirm="confirm"></u-select> -->
     <u-calendar v-model="show" mode="date" @change="change"></u-calendar>
     <u-calendar v-model="show" mode="date" @change="change"></u-calendar>
   </view>
   </view>
@@ -13,7 +13,6 @@
     data() {
     data() {
       return {
       return {
         value: '',
         value: '',
-        valueStr: '',
         show: false
         show: false
       }
       }
     },
     },
@@ -22,8 +21,8 @@
     },
     },
     methods: {
     methods: {
       change(obj) {
       change(obj) {
-        this.valueStr = obj.result
-        this.value = new Date(obj.result).getTime()
+        this.value = obj.result
+        // this.value = new Date(obj.result).getTime()
       }
       }
     }
     }
   }
   }

+ 106 - 0
src/components/low-code/DEVICE_IN_TABLE.vue

@@ -0,0 +1,106 @@
+<template>
+  <view class="device-in-table">
+    <view class="head flex justify-between items-center">
+      <view class="title">设备入库时间</view>
+    </view>
+    <u-input v-model="inOutTime" type="select" :border="true" placeholder="请选择入库时间" @click="show = true" />
+
+    <u-calendar v-model="show" mode="date" @change="change"></u-calendar>
+    <view class="head flex justify-between items-center m-t-24rpx">
+      <view class="title">设备入库登记</view>
+      <u-button type="primary" plain @click="open" size="mini">新增</u-button>
+    </view>
+
+    <u-popup v-model="showPopup" mode="bottom" :mask-close-able="false" :closeable="true" :border-radius="28">
+      <view class="form-box">
+        <view class="f-item">
+          <view class="label">
+            <text class="red">*</text>
+            <text class="text">设备编号</text>
+            <u-input v-model="deviceStr" type="select" :border="true" placeholder="请选择设备" @click="showSelect1 = true" />
+
+            <u-select v-model="showSelect1" :list="deviceList" @confirm="confirm"></u-select>
+          </view>
+        </view>
+      </view>
+    </u-popup>
+  </view>
+</template>
+
+<script>
+  import { deviceCanIn } from '@/api/sop'
+  export default {
+    name: 'DEVICEINTABLE',
+    computed: {
+      deviceStr() {
+        return this.deviceList.find((item) => item.value == this.deviceItemInfo.deviceNo)?.label || ''
+      }
+    },
+    data() {
+      return {
+        inOutTime: '',
+        list: [],
+        show: false,
+        showPopup: false,
+        showSelect1: false,
+        deviceList: [],
+        deviceItemInfo: {
+          deviceNo: '', //设备编号
+          supplierName: '', //供应商
+          deviceStatus: '', //运行状态
+          scanCount: '', //总扫描量
+          location: '', //当前所在地
+          address: '', //发往地
+          basePhotoPath: '' //拍照
+        }
+      }
+    },
+    mounted() {
+      deviceCanIn().then((res) => {
+        res = [{ deviceNo: 1, supplierName: '似懂非懂', deviceStatus: 'NORMAL', scanCount: 20, location: '武汉', address: '北京', basePhotoPath: '' }]
+        this.deviceList = res.map((item) => {
+          item.value = item.deviceNo
+          item.label = item.deviceModel
+          return item
+        })
+      })
+    },
+    methods: {
+      open() {
+        this.showPopup = true
+      },
+      add() {
+        // this.list.push({
+        //   deviceNo: '', //设备编号
+        //   supplierName: '', //供应商
+        //   deviceStatus: '', //运行状态
+        //   scanCount: '', //总扫描量
+        //   location: '', //当前所在地
+        //   address: '', //发往地
+        //   basePhotoPath: '' //拍照
+        // })
+      },
+      change(obj) {
+        this.inOutTime = obj.result
+      },
+      confirm(arr) {
+        this.deviceItemInfo.deviceNo = arr[0].value
+      }
+    }
+  }
+</script>
+
+<style lang="scss" scoped>
+  .device-in-table {
+    .form-box {
+      padding: 24rpx;
+    }
+    .head {
+      .title {
+        color: #595959;
+        font-size: 28rpx;
+        height: 60rpx;
+      }
+    }
+  }
+</style>

+ 0 - 0
src/components/low-code/DEVICE_OUT_TABLE.vue


+ 1 - 2
src/components/low-code/RADIO.vue

@@ -13,8 +13,7 @@
     data() {
     data() {
       return {
       return {
         value: '',
         value: '',
-        options: [],
-        show: false
+        options: []
       }
       }
     },
     },
     created() {
     created() {

+ 36 - 0
src/components/low-code/RADIO_WITH_INPUT.vue

@@ -0,0 +1,36 @@
+<template>
+  <view>
+    <u-radio-group v-model="valueData" @change="change" :disabled="!config.writable">
+      <u-radio v-for="(item, index) in options" :key="index" :name="item.value" :disabled="item.disabled">
+        {{ item.label }}
+      </u-radio>
+    </u-radio-group>
+    <u-input v-model="inputData" type="text" :border="true" />
+  </view>
+</template>
+
+<script>
+  export default {
+    name: 'RADIOWITHINPUT',
+    props: ['config', 'onChange'],
+    data() {
+      return {
+        valueData: '',
+        inputData: '',
+        options: []
+      }
+    },
+    created() {
+      this.valueData = this.config.value || ''
+      this.options = this.config.options || []
+    },
+    methods: {
+      change(val) {
+        console.log('va', val)
+        this.onChange({ prop: this.config.formName, value: val })
+      }
+    }
+  }
+</script>
+
+<style></style>

+ 2 - 2
src/components/low-code/TEXT.vue

@@ -1,11 +1,11 @@
 <template>
 <template>
-  <u-input v-model="value" type="text" :border="true" @input="onInput" placeholder="请输入" :disabled="!config.writable" />
+  <u-input v-model="value" :type="type || 'text'" :border="true" @input="onInput" placeholder="请输入" :disabled="!config.writable" />
 </template>
 </template>
 
 
 <script>
 <script>
   export default {
   export default {
     name: 'TEXT',
     name: 'TEXT',
-    props: ['config', 'onChange'],
+    props: ['config', 'onChange', 'type'],
     data() {
     data() {
       return {
       return {
         value: ''
         value: ''

+ 114 - 0
src/components/low-code/UPLOAD_IMAGE.vue

@@ -0,0 +1,114 @@
+<template>
+  <view class="upload-image">
+    <u-upload
+      ref="uUpload"
+      :file-list="fileList"
+      :max-size="20 * 1024 * 1024"
+      :max-count="config.length || 3"
+      :before-upload="beforeUpload"
+      :action="action"
+      :header="header"
+      :form-data="{ type: 'FILE' }"
+      @on-list-change="change"
+    ></u-upload>
+    <view class="tip">最多只能上传 {{ config.length || 3 }}张图片</view>
+  </view>
+</template>
+
+<script>
+  import SparkMD5 from 'spark-md5'
+  import { getAuthorization, DEVICE_ID } from '@/utils/crypto'
+  export default {
+    props: ['config', 'onChange'],
+    data() {
+      return {
+        fileList: [],
+        action: process.env.VUE_APP_BASE_API + '/api/admin/common/file/upload',
+        md5: '',
+        header: {
+          'Content-Type': 'multipart/form-data',
+          md5: '92eeda52d99adc1e4640520e20bda65f',
+          deviceId: DEVICE_ID,
+          platform: 'WEB',
+          Authorization: '',
+          time: ''
+        }
+      }
+    },
+    created() {
+      this.fileList = this.config.value || []
+    },
+
+    methods: {
+      //   ab2str(buffer, decodeType = 'utf-8') {
+      //     // 默认是uft-8格式
+      //     let decoder = new TextDecoder(decodeType)
+      //     return decoder.decode(buffer)
+      //   },
+
+      change(lists) {
+        //非常蛋疼,这个change事件里的回调里提供的参数lists里,并不会立刻包含response属性,会有延迟!于是使用了一个定时器!
+        setTimeout(() => {
+          let responseList = lists.map((item) => {
+            return item.response.data
+          })
+          //该组件兼容动态表单使用和常规业务使用,通过config参数里是否有formName来区分
+          if (this.config.formName) {
+            this.onChange({
+              prop: this.config.formName,
+              value: responseList
+            })
+          } else {
+            this.$emit('getLists', responseList)
+          }
+        }, 200)
+      },
+      beforeUpload(index, list) {
+        console.log('beforeUpload:')
+        const _this = this
+        const path = list[index].file.path
+        let user = uni.getStorageSync('user')
+        let timestamp = Date.now()
+        const authorization = getAuthorization(
+          {
+            method: 'post',
+            uri: '/api/admin/common/file/upload',
+            timestamp,
+            sessionId: user.sessionId,
+            token: user.accessToken
+          },
+          'token'
+        )
+        this.header.Authorization = authorization
+        this.header.time = timestamp
+        this.header = { ...this.header }
+
+        return new Promise((resolve, reject) => {
+          wx.getFileSystemManager().readFile({
+            filePath: path,
+            encoding: 'binary',
+            success: (res) => {
+              let spark = new SparkMD5()
+              spark.appendBinary(res.data)
+              var md5 = spark.end()
+              _this.header.md5 = md5
+              setTimeout(() => {
+                resolve()
+              }, 0)
+            }
+          })
+        })
+      }
+    }
+  }
+</script>
+
+<style lang="scss" scoped>
+  .upload-image {
+    .tip {
+      color: #999;
+      font-size: 24rpx;
+      line-height: 40rpx;
+    }
+  }
+</style>

+ 15 - 4
src/components/low-code/my-form-item.vue

@@ -4,11 +4,17 @@
       <view class="top-label flex items-center" :class="{ 'm-t-40rpx m-b-30rpx': isBigTitle }">
       <view class="top-label flex items-center" :class="{ 'm-t-40rpx m-b-30rpx': isBigTitle }">
         <text>{{ config.title }}</text>
         <text>{{ config.title }}</text>
       </view>
       </view>
-      <!-- <TEXT :config="config" :onChange="onChange"></TEXT> -->
+      <!-- <TEXT :config="config" :onChange="onChange" type="text"></TEXT> -->
       <!-- <SELECT :config="config" :onChange="onChange"></SELECT> -->
       <!-- <SELECT :config="config" :onChange="onChange"></SELECT> -->
       <!-- <MULTIPLESELECT :config="config" :onChange="onChange"></MULTIPLESELECT> -->
       <!-- <MULTIPLESELECT :config="config" :onChange="onChange"></MULTIPLESELECT> -->
       <!-- <DATE :config="config" :onChange="onChange"></DATE> -->
       <!-- <DATE :config="config" :onChange="onChange"></DATE> -->
-      <RADIO :config="config" :onChange="onChange"></RADIO>
+      <!-- <RADIO :config="config" :onChange="onChange"></RADIO> -->
+      <!-- <CHECKBOX :config="config" :onChange="onChange"></CHECKBOX> -->
+      <!-- <TEXT :config="config" :onChange="onChange" type="textarea"></TEXT> -->
+      <!-- <TEXT :config="config" :onChange="onChange" type="number"></TEXT> -->
+      <!-- <UPLOADIMAGE :config="config" :onChange="onChange"></UPLOADIMAGE> -->
+      <!-- <RADIOWITHINPUT :config="config" :onChange="onChange"></RADIOWITHINPUT> -->
+      <DEVICEINTABLE :config="config" :onChange="onChange"></DEVICEINTABLE>
     </view>
     </view>
   </u-form-item>
   </u-form-item>
 </template>
 </template>
@@ -19,10 +25,14 @@
   import MULTIPLESELECT from './MULTIPLE_SELECT.vue'
   import MULTIPLESELECT from './MULTIPLE_SELECT.vue'
   import DATE from './DATE.vue'
   import DATE from './DATE.vue'
   import RADIO from './RADIO.vue'
   import RADIO from './RADIO.vue'
+  import CHECKBOX from './CHECKBOX.vue'
+  import UPLOADIMAGE from './UPLOAD_IMAGE.vue'
+  import RADIOWITHINPUT from './RADIO_WITH_INPUT.vue'
+  import DEVICEINTABLE from './DEVICE_IN_TABLE.vue'
   export default {
   export default {
     name: 'MyFormItem',
     name: 'MyFormItem',
     props: ['config'],
     props: ['config'],
-    components: { TEXT, SELECT, MULTIPLESELECT, DATE, RADIO },
+    components: { TEXT, SELECT, MULTIPLESELECT, DATE, RADIO, CHECKBOX, UPLOADIMAGE, RADIOWITHINPUT, DEVICEINTABLE },
     computed: {
     computed: {
       isBigTitle() {
       isBigTitle() {
         return this.bigTitles.includes(this.config.code)
         return this.bigTitles.includes(this.config.code)
@@ -44,9 +54,10 @@
 <style lang="scss" scoped>
 <style lang="scss" scoped>
   .my-form-item {
   .my-form-item {
     .top-label {
     .top-label {
-      color: #595959;
+      color: #262626;
       font-size: 28rpx;
       font-size: 28rpx;
       line-height: 60rpx;
       line-height: 60rpx;
+      font-weight: bold;
     }
     }
   }
   }
 </style>
 </style>

+ 1 - 0
src/pages.json

@@ -19,6 +19,7 @@
     ]
     ]
   },
   },
   "pages": [
   "pages": [
+
     {
     {
       "path": "pages/index/index",
       "path": "pages/index/index",
       "style": {
       "style": {

+ 0 - 1
src/pages/sop-step/sop-step.vue

@@ -167,7 +167,6 @@
       height: calc(100% - 88rpx);
       height: calc(100% - 88rpx);
       .main {
       .main {
         padding: 24rpx;
         padding: 24rpx;
-        padding-top: 40rpx;
         .form-wrap {
         .form-wrap {
           background-color: #fff;
           background-color: #fff;
           border-radius: 12rpx;
           border-radius: 12rpx;

+ 22 - 17
src/pages/sop-step/test.js

@@ -27,24 +27,29 @@ export default {
     setup: 10,
     setup: 10,
     formKey: 'XXX',
     formKey: 'XXX',
     formProperty: [
     formProperty: [
-      {
-        code: 'RADIO',
-        title: '设备出入库',
-        options: [
-          { value: '1', label: '出库' },
-          { value: '2', label: '入库' }
-        ],
-        disabled: true
-      },
-      {
-        code: 'DATE',
-        title: '设备出入库时间'
-      },
       {
       {
         code: 'DEVICE_IN_TABLE',
         code: 'DEVICE_IN_TABLE',
         title: '设备入库登记',
         title: '设备入库登记',
-        api: '/api/******' //获取表格整体数据的api
+        span: 12
       }
       }
+      // {
+      //   code: 'RADIO',
+      //   title: '设备出入库',
+      //   options: [
+      //     { value: '1', label: '出库' },
+      //     { value: '2', label: '入库' }
+      //   ],
+      //   disabled: true
+      // },
+      // {
+      //   code: 'DATE',
+      //   title: '设备出入库时间'
+      // },
+      // {
+      //   code: 'DEVICE_IN_TABLE',
+      //   title: '设备入库登记',
+      //   api: '/api/******' //获取表格整体数据的api
+      // }
     ]
     ]
   },
   },
   flowTaskHistoryList: [
   flowTaskHistoryList: [
@@ -297,7 +302,7 @@ export default {
         {
         {
           code: 'FILE',
           code: 'FILE',
           title: '上传项目关键信息表(纸质)拍照',
           title: '上传项目关键信息表(纸质)拍照',
-          limit: 3
+          length: 3
         }
         }
       ]
       ]
     },
     },
@@ -590,7 +595,7 @@ export default {
         {
         {
           code: 'FILE',
           code: 'FILE',
           title: '上传学校未上传考生沟通确认截图',
           title: '上传学校未上传考生沟通确认截图',
-          limit: 1
+          length: 1
         },
         },
         {
         {
           code: 'FORM_GROUP_TITLE',
           code: 'FORM_GROUP_TITLE',
@@ -718,7 +723,7 @@ export default {
         {
         {
           code: 'FILE',
           code: 'FILE',
           title: '上传验收报告(纸质)拍照',
           title: '上传验收报告(纸质)拍照',
-          limit: 5
+          length: 5
         }
         }
       ]
       ]
     }
     }

+ 0 - 0
src/pages/sop/delay-warning.vue


+ 0 - 0
src/pages/sop/plan-change.vue


+ 0 - 0
src/pages/sop/violation-registration.vue