• NVIDIA 7th SkyHackathon(八)使用 Flask 与 Vue 开发 Web


    1.页面效果

    Web 采用 flask+vue 开发,效果图如下
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述

    2.后端

    import sys
    import subprocess
    import os
    from PIL import Image
    from datetime import datetime
    from ASR_metrics import utils as metrics
    
    from werkzeug.wrappers import Request, Response
    from flask import Flask, render_template, request, jsonify
    
    sys.path.append('/home/nvidia/7th_CV')
    sys.path.append('/home/nvidia/7th_ASR')
    
    # ASR 路径
    pathASR = "/home/nvidia/7th_ASR"
    
    # 项目路径
    pathSky = '/home/nvidia'
    
    app = Flask(__name__, static_folder='')
    
    # 上传路径
    uploadPath = 'uploads/'
    try_model_1 = None
    
    # 主页
    @app.route('/')
    def index():
        return render_template('sky7.html', template_folder='templates')
    
    # ------------------ASR------------------
    # ASR 模型加载
    @app.route('/asr/load')
    def asrLoad():
        global try_model_1
        if try_model_1 == None:
            import nemo.collections.asr as nemo_asr
            print('Loading Nemo')
            # 加载模型
            try_model_1 = nemo_asr.models.EncDecCTCModel.restore_from("/home/nvidia/7th_ASR/7th_asr_model.nemo")
            print('Done loading Nemo')
        return 'ok'
    
    # POST 请求上传音频
    @app.route('/asr/upload', methods=['POST'])
    def asrUpload():
        if request.method == 'POST':
            f = request.files['file']
            if(f.headers.get('Content-Type') != 'audio/wav'):
                return '音频格式有错误', 400
            else:
                fileName = f'{uploadPath}audio.wav'
                f.save(fileName)
                dt = datetime.now()
                ts = str(int(datetime.timestamp(dt)))
                return jsonify(f'/{uploadPath}audio.wav?t={ts}')
    
    # 识别上传的音频
    @app.route('/asr/identify', methods=['GET', 'POST'])
    def asrIdentify():
        global try_model_1
        if try_model_1 == None:
            return '模型无效,请重新加载', 500
        try:
            asr_result = try_model_1.transcribe(paths2audio_files=["uploads/audio.wav"])
            s1 = request.form.get('defaultText')
            s2 = " ".join(asr_result)#识别结果
            result = {
                "asr_result": asr_result,
                "word_error_rate": metrics.calculate_cer(s1,s2),
                "word_accuracy_rate":1-metrics.calculate_cer(s1,s2)
            }
            return jsonify(result)
        except Exception as e:
            return '无法识别', 400
    
    # ------------------CV------------------
    
    # POST 请求上传图片
    @app.route("/cv/upload", methods=['POST'])
    def cvUpload():
        if request.method == 'POST':
            f = request.files['file']
            print('image', f, f.filename)
    
            if not 'image' in f.headers.get('Content-Type'):
                return '图片有错误', 400
    
            original = f'{uploadPath}original.jpg'
    
            try:
                # Convert image to jpeg
                im = Image.open(f)
                rgb_im = im.convert('RGB')
                rgb_im.save(original)
    
                # Add timestamp
                dt = datetime.now()
                ts = str(int(datetime.timestamp(dt)))
                return jsonify(original+'?t='+ts)
    
            except Exception as e:
                return '有错误', 400
    
    # 检测图片
    @app.route("/api/detect/image")
    def detectImage():
        cv_results = subprocess.Popen('python3 /home/nvidia/7th_CV/detection_image.py /home/nvidia/uploads/original.jpg', shell = True, stdout = subprocess.PIPE, stderr = subprocess.PIPE)
        print('code', cv_results.returncode)
        cv_results = str(cv_results.stdout.read()).split('\\n')[-2]
        dt = datetime.now()
        ts = str(int(datetime.timestamp(dt)))
        result = {
            "detection_result_image_path": f'/uploads/result.jpg?t={ts}'
        }
        return jsonify(result)
    
    # 获取 FPS,以 Json 格式返回前端
    @app.route("/api/detect/fps")
    def detectFPS():
        # Code here
        fps_results = subprocess.Popen('python3 /home/nvidia/7th_CV/cv_fps.py', shell = True, stdout = subprocess.PIPE, stderr = subprocess.STDOUT)
        fps_results = str(fps_results.stdout.read()).split('\\n')[-2]
        fps_results = fps_results.split(" ")[-1]
        result = {
            "detection_FPS": fps_results,
        }
        return jsonify(result)
    
    # 获取 mAP
    @app.route("/api/detect/map")
    def detectMAP():
        # Code here
        map_results = subprocess.Popen('python3 /home/nvidia/7th_CV/cv_map.py', shell = True, stdout = subprocess.PIPE, stderr = subprocess.STDOUT)
        map_results = str(map_results.stdout.read())
        bytes(map_results, encoding="utf-8").decode()
        map_results = map_results[-9:-3]
        result = {
            "detection_mAP": map_results,
        }
        return jsonify(result)
    
    if __name__ == "__main__":
        app.run(debug=True)
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72
    • 73
    • 74
    • 75
    • 76
    • 77
    • 78
    • 79
    • 80
    • 81
    • 82
    • 83
    • 84
    • 85
    • 86
    • 87
    • 88
    • 89
    • 90
    • 91
    • 92
    • 93
    • 94
    • 95
    • 96
    • 97
    • 98
    • 99
    • 100
    • 101
    • 102
    • 103
    • 104
    • 105
    • 106
    • 107
    • 108
    • 109
    • 110
    • 111
    • 112
    • 113
    • 114
    • 115
    • 116
    • 117
    • 118
    • 119
    • 120
    • 121
    • 122
    • 123
    • 124
    • 125
    • 126
    • 127
    • 128
    • 129
    • 130
    • 131
    • 132
    • 133
    • 134
    • 135
    • 136
    • 137
    • 138
    • 139
    • 140
    • 141
    • 142
    • 143
    • 144

    3.前端

    3.1 html

    <html>
        <meta http-equiv="content-type" content="text/html; charset=UTF-8">
    
        <head>
            <script src="https://unpkg.com/vue@3">script>
            <script src="https://unpkg.com/axios/dist/axios.min.js">script>
            <link rel="stylesheet" href="//unpkg.com/layui@2.6.8/dist/css/layui.css">
            <script src="//unpkg.com/layui@2.6.8/dist/layui.js">script>
            <link rel="stylesheet" type="text/css" href="/style.css">
        head>
    
        <body id="app">
            
            <div class="loading" v-if="loading!=''">
                <div class="pad">%%loading%%div>
            div>
            <h1>7th Sky Hackathonh1>
            <h5>team:早八睡不醒h5>
            <div class="content">
    
                <div class="layui-tab layui-tab-brief" lay-filter="docDemoTabBrief">
    
                    <ul class="layui-tab-title">
                        <li class="layui-this"><i class="layui-icon panel-title layui-icon"> ASRi>li>
                        <li><i class="layui-icon panel-title layui-icon"> CVi>li>
                    ul>
                    <div class="layui-tab-content">
                        
                        <div class="layui-tab-item layui-show">
                            <div class="layui-anim layui-anim-up">
                                <fieldset class="asr">
                                    <legend><span class="panel-title">ASRspan>legend>
    
                                    <div class="layui-container">
    
                                        
                                        <div class="layui-row">
                                            <div class="layui-col-md4">
                                                1.请加载语音识别模型
                                            div>
                                            <div class="layui-col-md4">
                                                <button class="layui-btn" @click="loadModel()" v-if="!modelLoaded"><i
                                                        class="layui-icon"> 加载i>button>
                                                <div v-if="modelLoaded" class="modelLoaded">模型加载成功div>
                                            div>
                                        div>
                                        
    
                                        
                                        <div class="field file">
                                            <div class="newFileUpload">
                                                
                                                <div class="layui-row">
                                                    <div class="layui-col-md4">
                                                        <label for="file">2.请选择音频文件label>
                                                        <div class="note">   仅支持 .wav 和单声道格式div>
                                                    div>
                                                    <div class="layui-col-md4">
                                                        <div class="userdefined-file">
                                                            <input type="text" name="userdefinedFile"
                                                                id="userdefinedFileAudio" value="未选择任何文件" />
                                                            <button type="button">选择button>
                                                        div>
                                                        <input type="file" name="file" id="fileAudio"
                                                            @change="handleFileUploadAudio($event)" />
                                                    div>
                                                div>
                                                
                                            div>
    
                                            
                                            <div class="layui-row">
                                                <div class="layui-col-md4"> 3.请上传音频文件div>
                                                <div class="layui-col-md4">
                                                    <button class="layui-btn" @click="submitFile('asr')"><i
                                                            class="layui-icon"> 上传i>button>
                                                div>
                                            div>
                                            
                                        div>
                                        
    
                                        
                                        <div class="layui-row">
                                            <div class="field">
                                                <div class="layui-col-md4">
                                                    <label>4.请试听上传语音并输入正确答案label>
                                                div>
                                                <div class="layui-col-md4">
                                                    <input id="answer" type="text" name="defaultText"
                                                        v-model="defaultText" />
                                                div>
                                            div>
                                        div>
                                        
    
    
                                        <div class="field" v-if="asrStatus=='uploaded' || asrStatus=='identified'">
                                            
                                            <div class="layui-row">
                                                <div class="audio">
                                                    <div class="layui-col-md4">    试听 div>
                                                    <div class="layui-col-md4">
                                                        <audio controls :src="audioOriginal">audio>
                                                    div>
                                                div>
                                            div>
                                            
    
                                            
                                            <div class="layui-row">
                                                <div class="layui-col-md4">5.识别语音div>
                                                <div class="layui-col-md4">
                                                    <div class="action">
                                                        <button class="layui-btn" @click="identifyAudio()"><i
                                                                class="layui-icon"> 识别i>button>
                                                    div>
                                                div>
                                            div>
                                            
                                        div>
    
                                        
                                        <div class="layui-row">
                                            <div class="field result asr" v-if="asrStatus=='identified'">
                                                <div class="layui-col-md4">6.指标div>
                                                <div class="layui-col-md4">
                                                    <ul>
                                                        <li v-for="(value, key) in asrResult">%%key%%: %%value%%li>
                                                    ul>
                                                div>
                                            div>
                                        div>
                                        
                                    div>
    
                                fieldset>
                            div>
                        div>
                        
    
                        
                        <div class="layui-tab-item">
                            <div class="layui-anim layui-anim-up">
                                <fieldset class="cv">
                                    <legend><span class="panel-title">CVspan>legend>
    
                                    <div class="layui-container">
    
                                        
                                        <div class="field">
                                            <div class="layui-row">
                                                <div class="layui-col-md4">
                                                    <p>1. 获取 FPSp>
                                                    <div class="item result">    FPS: %%cvFps%%div>
                                                div>
                                                <div class="layui-col-md4">
                                                    <div class="item action">
                                                        <button @click="getFps()" class="inline layui-btn"><i
                                                                class="layui-icon"> 获取i>button>
                                                    div>
                                                div>
                                            div>
                                        div>
                                        
    
                                        
                                        <div class="field">
                                            <div class="layui-row">
                                                <div class="layui-col-md4">
                                                    <p>2. 获取 mAPp>
                                                    <div class="item result">    mAP: %%cvMap%%div>
                                                div>
                                                <div class="layui-col-md4">
                                                    <div class="item">
                                                        <button @click="getMap()" class="inline layui-btn"><i
                                                                class="layui-icon"> 获取i>button>
                                                    div>
                                                div>
                                            div>
                                        div>
                                        
    
                                        
                                        <div class="field file">
                                            
                                            <div class="newFileUpload">
                                                <div class="layui-row">
                                                    <div class="layui-col-md4">
                                                        <label for="file">3.请选择图像文件 label>
                                                        <div class="note"> div>
                                                    div>
                                                    <div class="layui-col-md4">
                                                        <div class="userdefined-file">
                                                            <input type="text" name="userdefinedFile"
                                                                id="userdefinedFileImage" value="未选择任何文件" />
                                                            <button type="button">选择button>
                                                        div>
    
                                                        <input type="file" name="file" ref="file" id="fileImage"
                                                            @change="handleFileUploadImage($event)" />
                                                    div>
                                                div>
                                            div>
                                            
    
                                            
                                            <div class="layui-row">
                                                <div class="layui-col-md4">4.请上传图像文件 div>
                                                <div class="layui-col-md4">
                                                    <button @click="submitFile('cv')" class="layui-btn"><i
                                                            class="layui-icon"> 上传i>button>
                                                div>
                                            div>
                                            
                                        div>
                                        
    
                                        <div class="action" v-if="imageOriginal!=''">
                                            <div class="layui-row">
                                                <div class="layui-col-md4">5.识别图片div>
                                                <div class="layui-col-md4">
                                                    <button class="layui-btn" @click="identifyImage()"><i
                                                            class="layui-icon"> 识别i>button><br>
                                                div>
                                            div>
                                        div>
    
                                        <div class="field">
                                            <div class="layui-row">
                                                <div class="image original" v-if="imageOriginal!=''">
                                                    <div class="layui-col-md1">
                                                        <div class="label">原图div>
                                                    div>
                                                    <div class="layui-col-md3">
                                                        <image :src="imageOriginal" />
                                                    div>
                                                div>
    
                                                <div class="image result cv" v-if="imageResult!=''">
                                                    <div class="layui-col-md1">
                                                        <div class="label">结果图div>
                                                    div>
                                                    <div class="layui-col-md3">
                                                        <image :src="imageResult" />
                                                    div>
                                                div>
                                            div>
                                        div>
    
                                    div>
                                fieldset>
                            div>
                        div>
                        
                    div>
                div>
            div>
        body>
        <script>
            const {
                createApp
            } = Vue
            createApp({
                data() {
                    return {
                        file: '',
                        defaultText: '请检测出纸箱、瓶子和果皮',
                        modelLoaded: false,
                        imageOriginal: '',
                        imageResult: '',
                        audioOriginal: '',
                        error: '',
                        asrResult: {},
                        cvMap: '',
                        cvFps: '',
                        loading: '',
                        asrStatus: 'pending',
                        cvStatus: 'pending'
                    }
                },
                // Avoid conflict with Flask delimiters
                compilerOptions: {
                    delimiters: ["%%", "%%"]
                },
                methods: {
                    async loadModel() {
                        if (this.loading != '') return showError('在运行中,无法执行')
                        this.loading = '加载模型中,请耐心等待...'
                        this.modelLoaded = false
                        try {
                            var {
                                data,
                                status
                            } = await axios.get('/asr/load')
                            if (status == 200) {
                                this.modelLoaded = true
                            }
                        } catch (err) {
                            showError(err.response.data)
                        }
                        this.loading = ''
                    },
                    async submitFile(fileType) {
                        let formData = new FormData()
                        formData.append('file', this.file)
                        if (this.file == "") {
                            showError("请选择文件");
                            return false;
                        }
    
                        statusType = fileType + 'Status'
                        this.loading = '上传中...'
                        try {
                            var {
                                data,
                                status
                            } = await axios.post('/' + fileType + '/upload', formData, {
                                headers: {
                                    'Content-Type': 'multipart/form-data'
                                }
                            })
                            if (status == 200) {
                                this[statusType] = 'uploaded'
                                if (fileType == 'cv') {
                                    this.imageOriginal = data
                                } else {
                                    this.audioOriginal = data
                                }
                            }
                        } catch (err) {
                            showError(err.response.data)
                        }
                        this.loading = ''
                    },
                    handleFileUploadAudio(event) {
                        document.getElementById("userdefinedFileAudio").value = document.getElementById("fileAudio")
                            .value;
                        this.file = event.target.files[0];
                    },
                    handleFileUploadImage(event) {
                        document.getElementById("userdefinedFileImage").value = document.getElementById("fileImage")
                            .value;
                        this.file = event.target.files[0];
                    },
                    async identifyAudio(event) {
                        // if (this.loading != '') return showError('在运行中,无法执行')
                        this.loading = '识别中...'
                        try {
                            let formData = new FormData()
                            formData.append('defaultText', this.defaultText)
                            console.log('t', this.defaultText)
                            var result = await axios.post('/asr/identify', formData)
                            this['asrStatus'] = 'identified'
                            this.asrResult = result.data
                        } catch (err) {
                            if (err.response.status == 500) this.modelLoaded = false
                            showError(err.response.data)
                        }
                        this.loading = ''
                    },
                    async identifyImage(event) {
                        if (this.loading != '') return showError('在运行中,无法执行')
                        this.loading = '识别中...'
                        this.cvStatus = 'pending'
                        try {
                            var {
                                data
                            } = await axios.get('/api/detect/image')
                            this.imageResult = data['detection_result_image_path']
                        } catch (err) {
                            showError(err.response.data)
                        }
                        this.loading = ''
                    },
                    async getFps(event) {
                        if (this.loading != '') return showError('在运行中,无法执行')
                        this.loading = '获取 FPS...'
                        try {
                            var {
                                data
                            } = await axios.get('/api/detect/fps')
                            this.cvFps = data['detection_FPS']
                        } catch (err) {
                            showError(err.response.data)
                        }
                        this.loading = ''
                    },
                    async getMap(event) {
                        // 接口路径: /api/detect/map
                        // 方式: GET
                        if (this.loading != '') return showError('在运行中,无法执行')
                        this.loading = '获取 mAP...'
                        try {
                            var {
                                data
                            } = await axios.get('/api/detect/map')
                            this.cvMap = data['detection_mAP']
                        } catch (err) {
                            showError(err.response.data)
                        }
                        this.loading = ''
                    }
                }
            }).mount('#app')
    
            function showError(msg) {
                layer.msg(msg || '错误')
            }
        script>
    html>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72
    • 73
    • 74
    • 75
    • 76
    • 77
    • 78
    • 79
    • 80
    • 81
    • 82
    • 83
    • 84
    • 85
    • 86
    • 87
    • 88
    • 89
    • 90
    • 91
    • 92
    • 93
    • 94
    • 95
    • 96
    • 97
    • 98
    • 99
    • 100
    • 101
    • 102
    • 103
    • 104
    • 105
    • 106
    • 107
    • 108
    • 109
    • 110
    • 111
    • 112
    • 113
    • 114
    • 115
    • 116
    • 117
    • 118
    • 119
    • 120
    • 121
    • 122
    • 123
    • 124
    • 125
    • 126
    • 127
    • 128
    • 129
    • 130
    • 131
    • 132
    • 133
    • 134
    • 135
    • 136
    • 137
    • 138
    • 139
    • 140
    • 141
    • 142
    • 143
    • 144
    • 145
    • 146
    • 147
    • 148
    • 149
    • 150
    • 151
    • 152
    • 153
    • 154
    • 155
    • 156
    • 157
    • 158
    • 159
    • 160
    • 161
    • 162
    • 163
    • 164
    • 165
    • 166
    • 167
    • 168
    • 169
    • 170
    • 171
    • 172
    • 173
    • 174
    • 175
    • 176
    • 177
    • 178
    • 179
    • 180
    • 181
    • 182
    • 183
    • 184
    • 185
    • 186
    • 187
    • 188
    • 189
    • 190
    • 191
    • 192
    • 193
    • 194
    • 195
    • 196
    • 197
    • 198
    • 199
    • 200
    • 201
    • 202
    • 203
    • 204
    • 205
    • 206
    • 207
    • 208
    • 209
    • 210
    • 211
    • 212
    • 213
    • 214
    • 215
    • 216
    • 217
    • 218
    • 219
    • 220
    • 221
    • 222
    • 223
    • 224
    • 225
    • 226
    • 227
    • 228
    • 229
    • 230
    • 231
    • 232
    • 233
    • 234
    • 235
    • 236
    • 237
    • 238
    • 239
    • 240
    • 241
    • 242
    • 243
    • 244
    • 245
    • 246
    • 247
    • 248
    • 249
    • 250
    • 251
    • 252
    • 253
    • 254
    • 255
    • 256
    • 257
    • 258
    • 259
    • 260
    • 261
    • 262
    • 263
    • 264
    • 265
    • 266
    • 267
    • 268
    • 269
    • 270
    • 271
    • 272
    • 273
    • 274
    • 275
    • 276
    • 277
    • 278
    • 279
    • 280
    • 281
    • 282
    • 283
    • 284
    • 285
    • 286
    • 287
    • 288
    • 289
    • 290
    • 291
    • 292
    • 293
    • 294
    • 295
    • 296
    • 297
    • 298
    • 299
    • 300
    • 301
    • 302
    • 303
    • 304
    • 305
    • 306
    • 307
    • 308
    • 309
    • 310
    • 311
    • 312
    • 313
    • 314
    • 315
    • 316
    • 317
    • 318
    • 319
    • 320
    • 321
    • 322
    • 323
    • 324
    • 325
    • 326
    • 327
    • 328
    • 329
    • 330
    • 331
    • 332
    • 333
    • 334
    • 335
    • 336
    • 337
    • 338
    • 339
    • 340
    • 341
    • 342
    • 343
    • 344
    • 345
    • 346
    • 347
    • 348
    • 349
    • 350
    • 351
    • 352
    • 353
    • 354
    • 355
    • 356
    • 357
    • 358
    • 359
    • 360
    • 361
    • 362
    • 363
    • 364
    • 365
    • 366
    • 367
    • 368
    • 369
    • 370
    • 371
    • 372
    • 373
    • 374
    • 375
    • 376
    • 377
    • 378
    • 379
    • 380
    • 381
    • 382
    • 383
    • 384
    • 385
    • 386
    • 387
    • 388
    • 389
    • 390
    • 391
    • 392
    • 393
    • 394
    • 395
    • 396
    • 397
    • 398
    • 399
    • 400
    • 401
    • 402
    • 403
    • 404
    • 405
    • 406
    • 407
    • 408
    • 409
    • 410
    • 411

    3.2 CSS

    body {
    	font-size: 20px;
    	margin: 0;
    }
    
    .content {
    	padding: 10px;
    	margin: 40px;
    }
    
    fieldset {
    	border: 1px solid #ccc;
    	padding: 10px;
    }
    
    .modelLoaded {
    	color: green;
    }
    
    .note {
    	color: #999;
    	margin: 5px 0;
    	font-size: 12px;
    }
    
    .field {
    	margin: 10px 0;
    }
    
    .action {
    	margin-top: 10px;
    }
    
    .loading {
    	position: fixed;
    	top: 0;
    	background: #E8F9D9;
    	text-align: center;
    	width: 100%;
    }
    
    .pad {
    	padding: 5px;
    }
    
    .inline {
    	display: inline-block;
    }
    
    .field .item {
    	margin: 5px 0;
    }
    
    .image {
    	display: inline-block;
    	margin-right: 10px;
    }
    
    .image img {
    	max-height: 600px;
    }
    
    /* 标题 */
    h1,
    h5 {
    	margin: 40px;
    }
    
    /* 队名 */
    h5 {
    	margin-left: 210px;
    }
    
    /* 面板title */
    .panel-title {
    	font-size: 25px;
    }
    
    /* 答案输入框 */
    #answer {
    	height: 40px;
    	width: 200px;
    	font-size: 14px;
    	display: inline-block;
    	vertical-align: middle;
    	padding-right: 14px;
    	padding-left: 14px;
    }
    
    /* 音频文件选择 */
    .newFileUpload {
    	position: relative;
    	height: 40px;
    	line-height: 40px;
    }
    
    .newFileUpload label {
    	display: inline-block;
    }
    
    .userdefined-file {
    	position: absolute;
    	top: 0;
    	/* left: 200px; */
    	z-index: 2;
    	width: 300px;
    	height: 40px;
    	line-height: 40px;
    	font-size: 0;
    	/*应对子元素为 inline-block 引起的外边距*/
    }
    
    .userdefined-file input[type="text"] {
    	display: inline-block;
    	vertical-align: middle;
    	padding-right: 14px;
    	padding-left: 14px;
    	width: 220px;
    	box-sizing: border-box;
    	border: 1px solid #ccc;
    	height: 40px;
    	line-height: 40px;
    	font-size: 14px;
    	overflow: hidden;
    	text-overflow: ellipsis;
    	white-space: nowrap;
    }
    
    .userdefined-file button {
    	display: inline-block;
    	vertical-align: middle;
    	width: 80px;
    	text-align: center;
    	height: 40px;
    	line-height: 40px;
    	font-size: 14px;
    	background-color: #009688;
    	/* background-color: #f54; */
    	border: none;
    	color: #fff;
    	cursor: pointer;
    }
    
    .newFileUpload input[type="file"] {
    	position: absolute;
    	top: 0;
    	/* left: 200px; */
    	z-index: 3;
    	opacity: 0;
    	width: 300px;
    	height: 40px;
    	line-height: 40px;
    	cursor: pointer;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72
    • 73
    • 74
    • 75
    • 76
    • 77
    • 78
    • 79
    • 80
    • 81
    • 82
    • 83
    • 84
    • 85
    • 86
    • 87
    • 88
    • 89
    • 90
    • 91
    • 92
    • 93
    • 94
    • 95
    • 96
    • 97
    • 98
    • 99
    • 100
    • 101
    • 102
    • 103
    • 104
    • 105
    • 106
    • 107
    • 108
    • 109
    • 110
    • 111
    • 112
    • 113
    • 114
    • 115
    • 116
    • 117
    • 118
    • 119
    • 120
    • 121
    • 122
    • 123
    • 124
    • 125
    • 126
    • 127
    • 128
    • 129
    • 130
    • 131
    • 132
    • 133
    • 134
    • 135
    • 136
    • 137
    • 138
    • 139
    • 140
    • 141
    • 142
    • 143
    • 144
    • 145
    • 146
    • 147
    • 148
    • 149
    • 150
    • 151
    • 152
    • 153
    • 154
  • 相关阅读:
    草莓熊python turtle绘图代码
    工业智能网关BL110详解之1:实现三菱 PLC FX1S 接入Modbus TCP Server云平台
    Vue2项目知识点总结-尚品汇
    Spring中事务的传播行为有哪些
    asyncawait和promise的区别
    没有实施APS软件的工厂,常常面临的问题
    Linux常用命令:htop(交互式进程查看器)【后台运行及查看状态命令】【top命令的升级版】
    Properties类
    Java—修饰符
    【hadoop运维】running beyond physical memory limits:正确配置yarn中的mapreduce内存
  • 原文地址:https://blog.csdn.net/u011815404/article/details/128114268