소스 검색

会议转写

xyg 3 년 전
부모
커밋
05ccab57d0

+ 116 - 0
spring-cloud/commons/src/main/java/com/jd/entity/basic/MeetingTranscription.java

@@ -0,0 +1,116 @@
+package com.jd.entity.basic;
+
+import java.io.Serializable;
+import java.util.Date;
+
+/**
+ * 会议转写
+ * @author Admin
+ */
+public class MeetingTranscription implements Serializable {
+
+    /**
+     * 记录ID,主键
+     */
+    private Integer recordId;
+
+    /**
+     * 会议名称
+     */
+    private String meetingName;
+
+    /**
+     * 会议开始时间
+     */
+    private Date startTime;
+
+    /**
+     * 会议转写内容
+     */
+    private String meetingContent;
+
+    /**
+     * 状态(0:删除,1:可用)
+     */
+    private Integer status;
+
+    /**
+     * 创建用户Id
+     */
+    private Integer userId;
+
+    /**
+     * 创建时间
+     */
+    private Date createTime;
+
+    /**
+     * 编辑时间
+     */
+    private Date updateTime;
+
+    public Integer getRecordId() {
+        return recordId;
+    }
+
+    public void setRecordId(Integer recordId) {
+        this.recordId = recordId;
+    }
+
+    public String getMeetingName() {
+        return meetingName;
+    }
+
+    public void setMeetingName(String meetingName) {
+        this.meetingName = meetingName;
+    }
+
+    public Date getStartTime() {
+        return startTime;
+    }
+
+    public void setStartTime(Date startTime) {
+        this.startTime = startTime;
+    }
+
+    public String getMeetingContent() {
+        return meetingContent;
+    }
+
+    public void setMeetingContent(String meetingContent) {
+        this.meetingContent = meetingContent;
+    }
+
+    public Integer getStatus() {
+        return status;
+    }
+
+    public void setStatus(Integer status) {
+        this.status = status;
+    }
+
+    public Integer getUserId() {
+        return userId;
+    }
+
+    public void setUserId(Integer userId) {
+        this.userId = userId;
+    }
+
+    public Date getCreateTime() {
+        return createTime;
+    }
+
+    public void setCreateTime(Date createTime) {
+        this.createTime = createTime;
+    }
+
+    public Date getUpdateTime() {
+        return updateTime;
+    }
+
+    public void setUpdateTime(Date updateTime) {
+        this.updateTime = updateTime;
+    }
+
+}

+ 120 - 0
spring-cloud/server-basic/src/main/java/com/jd/controller/MeetingTranscriptionController.java

@@ -0,0 +1,120 @@
+package com.jd.controller;
+
+import cn.hutool.core.convert.Convert;
+import com.jd.code.ConstString;
+import com.jd.entity.basic.MeetingTranscription;
+import com.jd.service.MeetingTranscriptionService;
+import com.jd.util.Blank;
+import com.jd.util.SendUtil;
+import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiOperation;
+import io.swagger.models.auth.In;
+import org.apache.commons.io.IOUtils;
+import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.PostMapping;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RestController;
+
+import javax.servlet.ServletOutputStream;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+import java.io.ByteArrayInputStream;
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.IOException;
+import java.nio.charset.StandardCharsets;
+import java.util.Map;
+
+/**
+ * 会议转写
+ * @author Admin
+ */
+@RestController
+@RequestMapping("meetingTranscription")
+@Api(value = "会议转写", tags = {"会议转写"})
+public class MeetingTranscriptionController {
+
+    private final MeetingTranscriptionService meetingTranscriptionService;
+
+    public MeetingTranscriptionController(MeetingTranscriptionService meetingTranscriptionService) {
+        this.meetingTranscriptionService = meetingTranscriptionService;
+    }
+
+    /**
+     * 分页查询会议转写列表
+     * @param page
+     * @param limit
+     * @param queryVal
+     * @return
+     */
+    @GetMapping("getMeetingTranscriptionListByPage")
+    @ApiOperation(value = "分页查询会议转写列表")
+    public Map<String, Object> getMeetingTranscriptionListByPage(Integer page, Integer limit, String queryVal) {
+        if (Blank.isEmpty(page, limit)) {
+            return SendUtil.send(false, ConstString.REQUEST_WRONGPARAMS);
+        }
+        return meetingTranscriptionService.getMeetingTranscriptionListByPage(page, limit, queryVal);
+    }
+
+    /**
+     * 新增会议转写
+     * @param meetingTranscription
+     * @return
+     */
+    @PostMapping("insertMeetingTranscription")
+    @ApiOperation(value = "新增会议转写")
+    public Map<String, Object> insertMeetingTranscription(MeetingTranscription meetingTranscription) {
+        String[] keys = {"meetingName", "meetingContent"};
+        if (!Blank.checkObjectParamNotNull(meetingTranscription, keys)) {
+            return SendUtil.send(false, ConstString.REQUEST_WRONGPARAMS);
+        }
+        return meetingTranscriptionService.insertMeetingTranscription(meetingTranscription);
+
+    }
+
+    /**
+     * 编辑会议转写
+     * @param meetingTranscription
+     * @return
+     */
+    @PostMapping("updateMeetingTranscription")
+    @ApiOperation(value = "编辑会议转写")
+    public Map<String, Object> updateMeetingTranscription(MeetingTranscription meetingTranscription) {
+        String[] keys = {"recordId", "meetingName", "meetingContent"};
+        if (!Blank.checkObjectParamNotNull(meetingTranscription, keys)) {
+            return SendUtil.send(false, ConstString.REQUEST_WRONGPARAMS);
+        }
+        return meetingTranscriptionService.updateMeetingTranscription(meetingTranscription);
+
+    }
+
+    /**
+     * 根据ID删除会议转写记录
+     * @param recordId
+     * @return
+     */
+    @PostMapping("deleteMeetingTranscription")
+    @ApiOperation(value = "删除会议转写")
+    public Map<String, Object> deleteMeetingTranscription(Integer recordId) {
+        if (Blank.isEmpty(recordId)) {
+            return SendUtil.send(false, ConstString.REQUEST_WRONGPARAMS);
+        }
+        return meetingTranscriptionService.deleteMeetingTranscription(recordId);
+
+    }
+
+    /**
+     * 根据ID查询会议转写记录详情
+     * @param recordId
+     * @return
+     */
+    @GetMapping("getMeetingTranscriptionById")
+    @ApiOperation(value = "删除会议转写")
+    public Map<String, Object> getMeetingTranscriptionById(Integer recordId) {
+        if (Blank.isEmpty(recordId)) {
+            return SendUtil.send(false, ConstString.REQUEST_WRONGPARAMS);
+        }
+        return meetingTranscriptionService.getMeetingTranscriptionById(recordId);
+    }
+
+}

+ 57 - 0
spring-cloud/server-basic/src/main/java/com/jd/mapper/MeetingTranscriptionMapper.java

@@ -0,0 +1,57 @@
+package com.jd.mapper;
+
+import com.jd.entity.basic.MeetingTranscription;
+import org.apache.ibatis.annotations.Param;
+
+import java.util.List;
+import java.util.Map;
+
+/**
+ * @author Admin
+ */
+public interface MeetingTranscriptionMapper {
+
+    /**
+     * 查询会议转写列表数量
+     * @param param
+     * @return
+     */
+    Integer getMeetingTranscriptionCount(Map<String, Object> param);
+
+
+    /**
+     * 分页查询会议转写列表
+     * @param param
+     * @return
+     */
+    List<Map<String, Object>> getMeetingTranscriptionListByPage(Map<String, Object> param);
+
+    /**
+     * 新增会议转写
+     * @param meetingTranscription
+     * @return
+     */
+    boolean insertMeetingTranscription(MeetingTranscription meetingTranscription);
+
+    /**
+     * 编辑会议转写
+     * @param meetingTranscription
+     * @return
+     */
+    boolean updateMeetingTranscription(MeetingTranscription meetingTranscription);
+
+    /**
+     * 根据ID删除会议转写记录
+     * @param recordId
+     * @return
+     */
+    boolean deleteMeetingTranscription(@Param("recordId") Integer recordId);
+
+    /**
+     * 根据ID查询会议转写记录详情
+     * @param recordId
+     * @return
+     */
+    Map<String, Object> getMeetingTranscriptionById(@Param("recordId") Integer recordId);
+
+}

+ 50 - 0
spring-cloud/server-basic/src/main/java/com/jd/service/MeetingTranscriptionService.java

@@ -0,0 +1,50 @@
+package com.jd.service;
+
+import com.jd.entity.basic.MeetingTranscription;
+
+import java.util.Map;
+
+/**
+ * 会议转写
+ * @author Admin
+ */
+public interface MeetingTranscriptionService {
+
+    /**
+     * 分页查询会议转写列表
+     * @param page
+     * @param limit
+     * @param queryVal
+     * @return
+     */
+    Map<String, Object> getMeetingTranscriptionListByPage(Integer page, Integer limit, String queryVal);
+
+    /**
+     * 新增会议转写
+     * @param meetingTranscription
+     * @return
+     */
+    Map<String, Object> insertMeetingTranscription(MeetingTranscription meetingTranscription);
+
+    /**
+     * 编辑会议转写
+     * @param meetingTranscription
+     * @return
+     */
+    Map<String, Object> updateMeetingTranscription(MeetingTranscription meetingTranscription);
+
+    /**
+     * 根据ID删除会议转写记录
+     * @param recordId
+     * @return
+     */
+    Map<String, Object> deleteMeetingTranscription(Integer recordId);
+
+    /**
+     * 根据ID查询会议转写记录详情
+     * @param recordId
+     * @return
+     */
+    Map<String, Object> getMeetingTranscriptionById(Integer recordId);
+
+}

+ 67 - 0
spring-cloud/server-basic/src/main/java/com/jd/service/impl/MeetingTranscriptionServiceImpl.java

@@ -0,0 +1,67 @@
+package com.jd.service.impl;
+
+import com.jd.code.ConstString;
+import com.jd.entity.basic.MeetingTranscription;
+import com.jd.mapper.MeetingTranscriptionMapper;
+import com.jd.service.MeetingTranscriptionService;
+import com.jd.util.Blank;
+import com.jd.util.SendUtil;
+import org.springframework.stereotype.Service;
+
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+/**
+ * @author Admin
+ */
+@Service
+public class MeetingTranscriptionServiceImpl implements MeetingTranscriptionService {
+
+    private final MeetingTranscriptionMapper meetingTranscriptionMapper;
+
+    public MeetingTranscriptionServiceImpl(MeetingTranscriptionMapper meetingTranscriptionMapper) {
+        this.meetingTranscriptionMapper = meetingTranscriptionMapper;
+    }
+
+    @Override
+    public Map<String, Object> getMeetingTranscriptionListByPage(Integer page, Integer limit, String queryVal) {
+        Map<String, Object> param = new HashMap<>();
+        param.put("queryVal", queryVal);
+        param.put("limit", limit);
+        param.put("start", (page - 1) * limit);
+
+        // 查询菜单列表数量
+        Integer count = meetingTranscriptionMapper.getMeetingTranscriptionCount(param);
+        if (Blank.isEmpty(count) || count < 1) {
+            return SendUtil.layuiTable(0, null);
+        }
+        List<Map<String, Object>> list = meetingTranscriptionMapper.getMeetingTranscriptionListByPage(param);
+        return SendUtil.layuiTable(count, list);
+    }
+
+    @Override
+    public Map<String, Object> insertMeetingTranscription(MeetingTranscription meetingTranscription) {
+        boolean flag = meetingTranscriptionMapper.insertMeetingTranscription(meetingTranscription);
+        return SendUtil.send(flag);
+    }
+
+    @Override
+    public Map<String, Object> updateMeetingTranscription(MeetingTranscription meetingTranscription) {
+        boolean flag = meetingTranscriptionMapper.updateMeetingTranscription(meetingTranscription);
+        return SendUtil.send(flag);
+    }
+
+    @Override
+    public Map<String, Object> deleteMeetingTranscription(Integer recordId) {
+        boolean flag = meetingTranscriptionMapper.deleteMeetingTranscription(recordId);
+        return SendUtil.send(flag);
+    }
+
+    @Override
+    public Map<String, Object> getMeetingTranscriptionById(Integer recordId) {
+        Map<String, Object> map = meetingTranscriptionMapper.getMeetingTranscriptionById(recordId);
+        return SendUtil.send(true, ConstString.RESULT_SUCCESS, map);
+    }
+
+}

+ 97 - 0
spring-cloud/server-basic/src/main/resources/mapper/MeetingTranscriptionMapper.xml

@@ -0,0 +1,97 @@
+<?xml version="1.0" encoding="UTF-8" ?>
+<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd" >
+<mapper namespace="com.jd.mapper.MeetingTranscriptionMapper">
+
+    <!-- 查询会议转写列表数量 -->
+    <select id="getMeetingTranscriptionCount" resultType="java.lang.Integer">
+        SELECT
+            COUNT(*)
+        FROM
+            t_meeting_transcription
+        <where>
+            <if test="queryVal != null and queryVal != ''">
+                AND meeting_name LIKE CONCAT('%', #{queryVal},'%')
+            </if>
+        </where>
+    </select>
+
+    <!-- 分页查询会议转写列表 -->
+    <select id="getMeetingTranscriptionListByPage" resultType="java.util.Map">
+        SELECT
+            record_id,
+            meeting_name,
+            start_time,
+            meeting_content,
+            status,
+            user_id,
+            create_time,
+            update_time
+        FROM
+            t_meeting_transcription
+        <where>
+            <if test="queryVal != null and queryVal != ''">
+                AND meeting_name LIKE CONCAT('%', #{queryVal},'%')
+            </if>
+        </where>
+        ORDER BY
+            create_time DESC
+        LIMIT #{start}, #{limit}
+    </select>
+
+    <!-- 新增会议转写 -->
+    <insert id="insertMeetingTranscription" useGeneratedKeys="true" keyProperty="recordId">
+        INSERT INTO t_meeting_transcription (
+            meeting_name,
+            start_time,
+            meeting_content,
+            user_id,
+            create_time
+        )
+        VALUES (
+            #{meetingName},
+            #{startTime},
+            #{meetingContent},
+            #{userId},
+            NOW()
+        )
+    </insert>
+
+    <!-- 编辑会议转写 -->
+    <update id="updateMeetingTranscription">
+        UPDATE t_meeting_transcription
+        <set>
+            meeting_name = #{meetingName},
+            start_time = #{startTime},
+            meeting_content = #{meetingContent},
+            update_time = NOW()
+        </set>
+        WHERE
+            record_id = #{recordId}
+    </update>
+
+    <!-- 根据ID删除会议转写记录 -->
+    <delete id="deleteMeetingTranscription">
+        DELETE
+        FROM t_meeting_transcription
+        WHERE record_id = #{recordId}
+    </delete>
+
+    <!-- 根据ID查询会议转写记录详情 -->
+    <select id="getMeetingTranscriptionById" resultType="java.util.Map">
+        SELECT
+            record_id,
+            meeting_name,
+            start_time,
+            meeting_content,
+            status,
+            user_id,
+            create_time,
+            update_time
+        FROM
+            t_meeting_transcription
+        WHERE
+            record_id = #{recordId}
+        LIMIT 1
+    </select>
+
+</mapper>

+ 243 - 0
spring-cloud/server-page/src/main/resources/static/page/js/base64.js

@@ -0,0 +1,243 @@
+/**
+ * Created by SLICE_30_K on 2017/5/22.
+ *
+ * 支持一般Base64的编码和解码
+ * 支持符合RFC_4648标准中"URL and Filename Safe Alphabet"的URL安全Base64编解码
+ * 支持中文字符的编解码(Unicode编码)
+ */
+;(function (root, factory) {
+    if (typeof exports === "object") {
+        // CommonJS
+        module.exports = exports = factory();
+    }
+    else if (typeof define === "function" && define.amd) {
+        // AMD
+        define(factory);
+    }
+    else {
+        // Global (browser)
+        window.BASE64 = factory();
+    }
+}(this, function () {
+    var BASE64_MAPPING = [
+        'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H',
+        'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P',
+        'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X',
+        'Y', 'Z', 'a', 'b', 'c', 'd', 'e', 'f',
+        'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n',
+        'o', 'p', 'q', 'r', 's', 't', 'u', 'v',
+        'w', 'x', 'y', 'z', '0', '1', '2', '3',
+        '4', '5', '6', '7', '8', '9', '+', '/'
+    ];
+    var URLSAFE_BASE64_MAPPING = [
+        'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H',
+        'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P',
+        'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X',
+        'Y', 'Z', 'a', 'b', 'c', 'd', 'e', 'f',
+        'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n',
+        'o', 'p', 'q', 'r', 's', 't', 'u', 'v',
+        'w', 'x', 'y', 'z', '0', '1', '2', '3',
+        '4', '5', '6', '7', '8', '9', '-', '_'
+    ];
+
+    var _toBinary = function (ascii) {
+        var binary = [];
+        while (ascii > 0) {
+            var b = ascii % 2;
+            ascii = Math.floor(ascii / 2);
+            binary.push(b);
+        }
+        binary.reverse();
+        return binary;
+    };
+
+    var _toDecimal = function (binary) {
+        var dec = 0;
+        var p = 0;
+        for (var i = binary.length - 1; i >= 0; --i) {
+            var b = binary[i];
+            if (b == 1) {
+                dec += Math.pow(2, p);
+            }
+            ++p;
+        }
+        return dec;
+    };
+
+    var _toUTF8Binary = function (c, binaryArray) {
+        var mustLen = (8 - (c + 1)) + ((c - 1) * 6);
+        var fatLen = binaryArray.length;
+        var diff = mustLen - fatLen;
+        while (--diff >= 0) {
+            binaryArray.unshift(0);
+        }
+        var binary = [];
+        var _c = c;
+        while (--_c >= 0) {
+            binary.push(1);
+        }
+        binary.push(0);
+        var i = 0, len = 8 - (c + 1);
+        for (; i < len; ++i) {
+            binary.push(binaryArray[i]);
+        }
+
+        for (var j = 0; j < c - 1; ++j) {
+            binary.push(1);
+            binary.push(0);
+            var sum = 6;
+            while (--sum >= 0) {
+                binary.push(binaryArray[i++]);
+            }
+        }
+        return binary;
+    };
+
+    var _toBinaryArray = function (str) {
+        var binaryArray = [];
+        for (var i = 0, len = str.length; i < len; ++i) {
+            var unicode = str.charCodeAt(i);
+            var _tmpBinary = _toBinary(unicode);
+            if (unicode < 0x80) {
+                var _tmpdiff = 8 - _tmpBinary.length;
+                while (--_tmpdiff >= 0) {
+                    _tmpBinary.unshift(0);
+                }
+                binaryArray = binaryArray.concat(_tmpBinary);
+            } else if (unicode >= 0x80 && unicode <= 0x7FF) {
+                binaryArray = binaryArray.concat(_toUTF8Binary(2, _tmpBinary));
+            } else if (unicode >= 0x800 && unicode <= 0xFFFF) {//UTF-8 3byte
+                binaryArray = binaryArray.concat(_toUTF8Binary(3, _tmpBinary));
+            } else if (unicode >= 0x10000 && unicode <= 0x1FFFFF) {//UTF-8 4byte
+                binaryArray = binaryArray.concat(_toUTF8Binary(4, _tmpBinary));
+            } else if (unicode >= 0x200000 && unicode <= 0x3FFFFFF) {//UTF-8 5byte
+                binaryArray = binaryArray.concat(_toUTF8Binary(5, _tmpBinary));
+            } else if (unicode >= 4000000 && unicode <= 0x7FFFFFFF) {//UTF-8 6byte
+                binaryArray = binaryArray.concat(_toUTF8Binary(6, _tmpBinary));
+            }
+        }
+        return binaryArray;
+    };
+
+    var _toUnicodeStr = function (binaryArray) {
+        var unicode;
+        var unicodeBinary = [];
+        var str = "";
+        for (var i = 0, len = binaryArray.length; i < len;) {
+            if (binaryArray[i] == 0) {
+                unicode = _toDecimal(binaryArray.slice(i, i + 8));
+                str += String.fromCharCode(unicode);
+                i += 8;
+            } else {
+                var sum = 0;
+                while (i < len) {
+                    if (binaryArray[i] == 1) {
+                        ++sum;
+                    } else {
+                        break;
+                    }
+                    ++i;
+                }
+                unicodeBinary = unicodeBinary.concat(binaryArray.slice(i + 1, i + 8 - sum));
+                i += 8 - sum;
+                while (sum > 1) {
+                    unicodeBinary = unicodeBinary.concat(binaryArray.slice(i + 2, i + 8));
+                    i += 8;
+                    --sum;
+                }
+                unicode = _toDecimal(unicodeBinary);
+                str += String.fromCharCode(unicode);
+                unicodeBinary = [];
+            }
+        }
+        return str;
+    };
+
+    var _encode = function (str, url_safe) {
+        var base64_Index = [];
+        var binaryArray = _toBinaryArray(str);
+        var dictionary = url_safe ? URLSAFE_BASE64_MAPPING : BASE64_MAPPING;
+
+        var extra_Zero_Count = 0;
+        for (var i = 0, len = binaryArray.length; i < len; i += 6) {
+            var diff = (i + 6) - len;
+            if (diff == 2) {
+                extra_Zero_Count = 2;
+            } else if (diff == 4) {
+                extra_Zero_Count = 4;
+            }
+            var _tmpExtra_Zero_Count = extra_Zero_Count;
+            while (--_tmpExtra_Zero_Count >= 0) {
+                binaryArray.push(0);
+            }
+            base64_Index.push(_toDecimal(binaryArray.slice(i, i + 6)));
+        }
+
+        var base64 = '';
+        for (var i = 0, len = base64_Index.length; i < len; ++i) {
+            base64 += dictionary[base64_Index[i]];
+        }
+
+        for (var i = 0, len = extra_Zero_Count / 2; i < len; ++i) {
+            base64 += '=';
+        }
+        return base64;
+    };
+
+    var _decode = function (_base64Str, url_safe) {
+        var _len = _base64Str.length;
+        var extra_Zero_Count = 0;
+        var dictionary = url_safe ? URLSAFE_BASE64_MAPPING : BASE64_MAPPING;
+
+        if (_base64Str.charAt(_len - 1) == '=') {
+            if (_base64Str.charAt(_len - 2) == '=') {//两个等号说明补了4个0
+                extra_Zero_Count = 4;
+                _base64Str = _base64Str.substring(0, _len - 2);
+            } else {//一个等号说明补了2个0
+                extra_Zero_Count = 2;
+                _base64Str = _base64Str.substring(0, _len - 1);
+            }
+        }
+
+        var binaryArray = [];
+        for (var i = 0, len = _base64Str.length; i < len; ++i) {
+            var c = _base64Str.charAt(i);
+            for (var j = 0, size = dictionary.length; j < size; ++j) {
+                if (c == dictionary[j]) {
+                    var _tmp = _toBinary(j);
+                    /*不足6位的补0*/
+                    var _tmpLen = _tmp.length;
+                    if (6 - _tmpLen > 0) {
+                        for (var k = 6 - _tmpLen; k > 0; --k) {
+                            _tmp.unshift(0);
+                        }
+                    }
+                    binaryArray = binaryArray.concat(_tmp);
+                    break;
+                }
+            }
+        }
+        if (extra_Zero_Count > 0) {
+            binaryArray = binaryArray.slice(0, binaryArray.length - extra_Zero_Count);
+        }
+        var str = _toUnicodeStr(binaryArray);
+        return str;
+    };
+
+    var __BASE64 = {
+        encode: function (str) {
+            return _encode(str, false);
+        },
+        decode: function (base64Str) {
+            return _decode(base64Str, false);
+        },
+        urlsafe_encode: function (str) {
+            return _encode(str, true);
+        },
+        urlsafe_decode: function (base64Str) {
+            return _decode(base64Str, true);
+        }
+    };
+
+    return __BASE64;
+}));

+ 432 - 0
spring-cloud/server-page/src/main/resources/static/page/js/basic/meetingTranscription.js

@@ -0,0 +1,432 @@
+var form, table;
+layui.config({
+    base: 'js/encryption/'
+}).use(['layer', 'form', 'jquery', 'table', 'laydate', 'upload', 'ajax'], function () {
+    layer = layui.layer;
+    laydate = layui.laydate;
+    upload = layui.upload;
+    table = layui.table;
+    form = layui.form;
+    $ = layui.jquery;
+    ly = layui.ajax;
+
+    // 主要表格
+    table.render({
+        elem: '#transcriptionTable',
+        url: PAGE_BASIC + '/meetingTranscription/getMeetingTranscriptionListByPage',
+        toolbar: '#transcriptionTable_toolbar', //开启头部工具栏,并为其绑定左侧模板
+        page: true,
+        cols: [
+            [{
+                type: 'numbers',
+                title: '序号'
+            }, {
+                field: 'meeting_name',
+                title: '会议名称',
+            }, {
+                field: 'start_time',
+                title: '开始时间',
+            }, {
+                field: 'create_time',
+                title: '创建时间'
+            }, {
+                fixed: 'right',
+                title: '操作',
+                toolbar: '#transcriptionTable_bar',
+                width: 250
+            }]
+        ]
+    });
+
+    //头工具栏事件(主要表格)
+    table.on('toolbar(transcriptionTable)', function (obj) {
+        var checkStatus = table.checkStatus(obj.config.id);
+        switch (obj.event) {
+            case 'add': //新增
+                $(".main").addClass("layui-hide").removeClass("layui-show");
+                $(".add").addClass("layui-show").removeClass("layui-hide");
+                $('#submit').attr('submitType', 'insert');
+                $(".add .header_title span").html("新增");
+                $('.planCode').addClass("layui-show").removeClass("layui-hide");
+                $('#transcriptionInfo')[0].reset();
+                $('#uploadBtn').removeClass('layui-hide');
+                break;
+        }
+    });
+
+    //监听行工具事件(主要表格)
+    table.on('tool(transcriptionTable)', function (obj) {
+        var data = obj.data;
+        //console.log(obj)
+        if (obj.event === 'del') {
+            layer.confirm('是否确认删除', function (index) {
+                deletePlan(data.id);
+                layer.close(index);
+            });
+        } else if (obj.event === 'edit') {
+            $(".main").addClass("layui-hide").removeClass("layui-show");
+            $(".add").addClass("layui-show").removeClass("layui-hide");
+            $(".add .header_title span").html("编辑");
+            $('#submit').attr('submitType', 'update');
+            $('#transcriptionInfo')[0].reset();
+            $('#meetingContent').attr('readonly', false);
+            $('#uploadBtn').addClass('layui-hide');
+            // 数据初始化
+            initPlan(data.record_id);
+        } else if (obj.event === 'download') {
+            downloadFile(data.record_id);
+        }
+    });
+
+    var uploadInst = upload.render({
+        elem: '#uploadBtn', //绑定元素
+        // url: PAGE_BASIC + '/awaken/transfer', //上传接口
+        url: 'http://192.168.0.223:8093/awaken/transfer',
+        accept: 'file',
+        before: function (obj) {
+            layer.load(2); //上传loading
+        },
+        done: function (res) {
+            layer.closeAll('loading');
+            //上传完毕回调
+            console.info(res)
+            if (res.data) {
+                var index = layer.load(2);
+                let timer = setInterval(() => {
+                    $.ajax({
+                        type: 'POST',
+                        // url: PAGE_BASIC + '/plan/switchDefaultPlan',
+                        url: 'http://192.168.0.223:8093/awaken/getResult',
+                        dataType: 'json',
+                        data: {taskId: res.data},
+                        success: function (json) {
+                            console.info(json);
+                            if (json.code == 0 && json.data.data) {
+                                clearInterval(timer);
+                                layer.close(index);
+                                var datas = JSON.parse(json.data.data);
+                                console.info(datas);
+                                var arr = [];
+                                for (var k in datas) {
+                                    let str = '[' + timeFormat(datas[k].bg) + '-' + timeFormat(datas[k].ed) + ']' + datas[k].onebest;
+                                    arr.push(str);
+                                }
+                                var content = arr.join('\r\n');
+                                $('#meetingContent').val(content);
+                                $('#meetingContent').attr('readonly', false);
+                            }
+                        },
+                        error: function (msg) {
+                            layer.close(index);
+                            console.error(msg);
+                        }
+                    });
+                }, 10000);
+            }
+        },
+        error: function (err) {
+            //请求异常回调
+            console.error(err)
+            layer.closeAll('loading');
+        }
+    });
+
+    //日期时间选择器
+    laydate.render({
+        elem: '#startTime',
+        type: 'datetime'
+    });
+
+    // 验证表单
+    form.verify({
+        meetingName: function (value, item) {
+            if (!value.trim()) {
+                return '会议名称不能为空';
+            }
+        },
+        startTime: function (value, item) {
+            if (!value.trim()) {
+                return '请选择会议开始时间';
+            }
+        },
+        meetingContent: function (value, item) {
+            if (!value.trim()) {
+                return '请上传会议文件进行转写';
+            }
+        }
+    });
+
+    // 监听提交按钮
+    form.on('submit(submit)', function (data) {
+        var submitType = data.elem.getAttribute("submitType");
+        // 新增
+        if (submitType == 'insert') {
+            addPlan();
+            return false;
+        } else if (submitType == 'update') {
+            updatePlan();
+            return false;
+        }
+    });
+
+    // 查询
+    $(".search_btn").click(function () {
+        var queryValue = $.trim($("#queryValue").val());
+        table.reload('transcriptionTable', {
+            where: {
+                "queryVal": queryValue
+            },
+            page: {
+                curr: 1 //重新从第 1 页开始
+            }
+        }); //只重载数据
+    });
+
+    //基础数据搜索回车事件
+    $('#queryValue').bind('keypress', function (event) {
+        if (event.keyCode == "13") {
+            var queryValue = $.trim($("#queryValue").val());
+            table.reload('transcriptionTable', {
+                where: {
+                    "queryVal": queryValue
+                },
+                page: {
+                    curr: 1 //重新从第 1 页开始
+                }
+            }); //只重载数据
+        }
+    });
+
+    // 返回
+    $(".back").click(function () {
+        $(".main").addClass("layui-show").removeClass("layui-hide");
+        $(".add").addClass("layui-hide").removeClass("layui-show");
+    })
+
+});
+
+/**
+ * 新增会议转写
+ */
+function addPlan() {
+    var postData = form.val('transcriptionInfo');
+    var index = layer.load(2);
+    ly.ajax({
+        type: 'POST',
+        url: PAGE_BASIC + '/meetingTranscription/insertMeetingTranscription',
+        dataType: 'json',
+        data: postData,
+        success: function (json) {
+            if (json.result) {
+                layer.msg("新增成功");
+                $(".main").addClass("layui-show").removeClass("layui-hide");
+                $(".add").addClass("layui-hide").removeClass("layui-show");
+                reloadTable();
+            } else {
+                layer.msg("新增失败");
+            }
+            layer.close(index);
+        },
+        error: function (msg) {
+            layer.close(index);
+        }
+    });
+}
+
+/**
+ * 编辑会议转写
+ */
+function updatePlan() {
+    var postData = form.val('transcriptionInfo');
+    var index = layer.load(2);
+    ly.ajax({
+        type: 'POST',
+        url: PAGE_BASIC + '/meetingTranscription/updateMeetingTranscription',
+        dataType: 'json',
+        data: postData,
+        success: function (json) {
+            if (json.result) {
+                layer.msg("编辑成功");
+                $(".main").addClass("layui-show").removeClass("layui-hide");
+                $(".add").addClass("layui-hide").removeClass("layui-show");
+                reloadTable();
+            } else {
+                layer.msg("编辑失败");
+            }
+            layer.close(index);
+        },
+        error: function (msg) {
+            layer.close(index);
+        }
+    });
+}
+
+/**
+ * 回显会议转写详情
+ * @param recordId
+ */
+function initPlan(recordId) {
+    var index = layer.load(2);
+    ly.ajax({
+        type: 'GET',
+        url: PAGE_BASIC + '/meetingTranscription/getMeetingTranscriptionById',
+        dataType: 'json',
+        data: {
+            "recordId": recordId,
+        },
+        success: function (json) {
+            if (json.result) {
+                $('#recordId').empty().val(recordId);
+                $('#meetingName').empty().val(json.data.meeting_name);
+                $('#startTime').empty().val(json.data.start_time);
+                $('#meetingContent').val(json.data.meeting_content);
+                form.render();
+            } else {
+                layer.msg("数据获取失败");
+            }
+            layer.close(index);
+        },
+        error: function (msg) {
+            layer.close(index);
+        }
+    });
+}
+
+/**
+ * 删除会议转写
+ * @param recordId
+ */
+function deletePlan(recordId) {
+    var index = layer.load(2);
+    ly.ajax({
+        type: 'POST',
+        url: PAGE_BASIC + '/meetingTranscription/deleteMeetingTranscription',
+        dataType: 'json',
+        data: {
+            "recordId": recordId,
+        },
+        success: function (json) {
+            if (json.result) {
+                layer.msg("删除成功");
+                reloadTable();
+            } else {
+                layer.msg("删除失败");
+            }
+            layer.close(index);
+        },
+        error: function (msg) {
+            layer.close(index);
+        }
+    });
+}
+
+/**
+ * 重载数据表格
+ */
+function reloadTable() {
+    table.reload('transcriptionTable', {
+        page: {
+            curr: 1 //重新从第 1 页开始
+        }
+    }); //只重载数据
+}
+
+/**
+ * 自定义时间格式化
+ * @param timestamp
+ * @returns {string|*}
+ */
+function timeFormat(timestamp) {
+    if (!timestamp) {
+        return timestamp;
+    }
+    let ss = parseInt(Number(timestamp) / 1000);
+    let s = parseInt(ss % 60);
+    let mm = parseInt(ss / 60);
+    if (mm == 0) {
+        return '00:' + (s < 10 ? '0' + s : s);
+    } else {
+        let m = parseInt(mm % 60);
+        let h = parseInt(mm / 60);
+        if (h == 0) {
+            return (m < 10 ? '0' + m : m) + ':' + (s < 10 ? '0' + s : s);
+        } else {
+            return (h < 10 ? '0' + h : h) + ':' + (m < 10 ? '0' + m : m) + ':' + (s < 10 ? '0' + s : s);
+        }
+    }
+}
+
+/**
+ * 下载会议转写内容
+ * @param recordId
+ */
+function downloadFile(recordId) {
+    var index = layer.load(2);
+    ly.ajax({
+        type: 'GET',
+        url: PAGE_BASIC + '/meetingTranscription/getMeetingTranscriptionById',
+        dataType: 'json',
+        data: {
+            "recordId": recordId,
+        },
+        responseType: 'blob',
+        success: function (json) {
+            layer.close(index);
+            if (json.result) {
+                let fileName = json.data.meeting_name + '.txt';
+                let content = json.data.meeting_content;
+                let base64 = BASE64.encode(content);
+                let blob = getBlob(base64, {type: "application/vnd.ms-excel"});
+                let url = downloadBlob(fileName, blob, true);
+            } else {
+                layer.msg("数据获取失败");
+            }
+        },
+        error: function (msg) {
+            layer.close(index);
+        }
+    });
+
+}
+
+/**
+ * 获取Blob
+ * @param base64 base64字符串
+ * @param contentType 导出格式 MIME 类型
+ * @param sliceSize 分割大小
+ * @returns {Blob}
+ */
+function getBlob(base64, contentType, sliceSize) {
+    contentType = contentType || '';
+    sliceSize = sliceSize || 1024;
+    let byteCharacters = window.atob(base64);
+    let byteArrays = [];
+    for (let offset = 0; offset < byteCharacters.length; offset += sliceSize) {
+        let slice = byteCharacters.slice(offset, offset + sliceSize);
+        let byteNumbers = new Array(slice.length);
+        for (let i = 0; i < slice.length; i++) {
+            byteNumbers[i] = slice.charCodeAt(i);
+        }
+        let byteArray = new Uint8Array(byteNumbers);
+        byteArrays.push(byteArray);
+    }
+    return new Blob(byteArrays, {type: contentType});
+}
+
+function downloadBlob(fileName, blob, isDown) {
+    //默认不下载,返回url
+    //判断是直接下载还是返回对应的URL
+    let url = URL.createObjectURL(blob);
+    if (isDown) {
+        //如果是直接下载,利用a标签来实现下载
+        let docEle = document;
+        let link = docEle.createElement("a");
+        link.innerHTML = fileName;
+        link.download = fileName;
+        link.href = url;
+        docEle.getElementsByTagName("body")[0].appendChild(link);
+        link.click();
+        $(link).remove();
+    }
+    return url;
+}

+ 106 - 0
spring-cloud/server-page/src/main/resources/static/page/meetingTranscription.html

@@ -0,0 +1,106 @@
+<!DOCTYPE html>
+<html>
+
+<head>
+    <meta charset="UTF-8">
+    <meta name="renderer" content="webkit">
+    <meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
+    <meta name="viewport" content="width=device-width,initial-scale=1,minimum-scale=1,maximum-scale=1,user-scalable=no"/>
+    <title>会议转写</title>
+    <link rel="stylesheet" type="text/css" href="layui/css/layui.css"/>
+    <link rel="stylesheet" type="text/css" href="css/admin.css"/>
+    <link rel="stylesheet" type="text/css" href="css/common.css"/>
+    <link rel="stylesheet" type="text/css" href="css/animate.css"/>
+</head>
+<style>
+    .layui-form-item .layui-input-inline {
+        width: 60%;
+    }
+
+    .layui-textarea {
+        resize: none;
+        height: 300px;
+    }
+</style>
+<body>
+<!-- 主要内容 -->
+<div class="main fadeIn animated">
+    <div class="header_title"><span>会议转写</span></div>
+    <div class="main_content">
+        <table class="layui-hide" id="transcriptionTable" lay-filter="transcriptionTable"></table>
+
+        <script type="text/html" id="transcriptionTable_toolbar">
+            {{# if (sessionStorage.getItem("menuid-" + sessionStorage.MENU_ID + "-add")  == 'add') { }}
+            <div class="layui-btn-container">
+                <button class="layui-btn layui-btn-sm main_head_btn" lay-event="add"><span class="iconfont">&#xe607;</span>新增</button>
+            </div>
+            {{# } }}
+        </script>
+
+        <script type="text/html" id="transcriptionTable_bar">
+            <a class="main_tab_btn" lay-event="download" style="color: #5FB878;" title="下载会议转写内容"><span class="iconfont">&#xe63e;</span>下载</a>
+            {{# if (sessionStorage.getItem("menuid-" + sessionStorage.MENU_ID + "-update") == 'update') { }}
+            <a class="main_tab_btn" lay-event="edit" style="color: #64ADF9;"><span class="iconfont">&#xe637;</span>编辑</a>
+            {{# } }}
+            {{# if (sessionStorage.getItem("menuid-" + sessionStorage.MENU_ID + "-delete") == 'delete') { }}
+            <a class="main_tab_btn" lay-event="del" style="color: #FC7D8C;"><span class="iconfont">&#xe78d;</span>删除</a>
+            {{# } }}
+        </script>
+
+        <div class="search_box">
+            <div class="layui-input-inline">
+                <input type="text" name="queryValue" id="queryValue" autocomplete="off" class="layui-input" placeholder="请输会议名称查询"/>
+            </div>
+            <button type="button" class="layui-btn layui-btn-sm search_btn">搜 索</button>
+        </div>
+    </div>
+</div>
+
+<!-- 新增 -->
+<div class="add layui-hide fadeIn animated">
+    <div class="header_title"><span>新增</span></div>
+    <div class="main_content">
+        <form class="layui-form" action="" id="transcriptionInfo" lay-filter="transcriptionInfo">
+            <input type="hidden" class="layui-hide" id="recordId" name="recordId" readonly=""/>
+            <div class="layui-form-item">
+                <label class="layui-form-label"><span class="font-red">*</span>会议名称:</label>
+                <div class="layui-input-inline">
+                    <input type="text" name="meetingName" id="meetingName" maxlength="50" lay-verify="meetingName" autocomplete="off" placeholder="请输入会议名称" class="layui-input"/>
+                </div>
+            </div>
+            <div class="layui-form-item">
+                <label class="layui-form-label"><span class="font-red">*</span>开始时间:</label>
+                <div class="layui-input-inline">
+                    <input type="text" name="startTime" id="startTime" maxlength="50" lay-verify="startTime" autocomplete="off" placeholder="请输开始时间" class="layui-input" readonly/>
+                </div>
+            </div>
+            <div class="layui-form-item">
+                <label class="layui-form-label">
+                    <button type="button" class="layui-btn" id="uploadBtn">
+                        <i class="layui-icon">&#xe67c;</i>上传文件
+                    </button>
+                </label>
+                <div class="layui-input-inline"></div>
+            </div>
+            <div class="layui-form-item">
+                <label class="layui-form-label"><span class="font-red">*</span>会议内容:</label>
+                <div class="layui-input-inline">
+                    <textarea class="layui-textarea" id="meetingContent" name="meetingContent" lay-verify="meetingContent" placeholder="请上传会议音频进行转写" autocomplete="off" readonly></textarea>
+                </div>
+            </div>
+            <button type="submit" id="submit" class="layui-btn submit_btn" lay-submit="" lay-filter="submit" submitType="" style="margin-left: 50px;margin-top: 30px;">提交</button>
+            <button type="button" class="layui-btn layui-btn-primary back back_btn" style="margin-top: 30px;">返回</button>
+        </form>
+    </div>
+</div>
+
+<script src="layui/layui.js" type="text/javascript" charset="utf-8"></script>
+<script src="js/common.js" type="text/javascript" charset="utf-8"></script>
+<script src="js/constants.js" type="text/javascript" charset="utf-8"></script>
+<script src="js/js-util.js" type="text/javascript" charset="utf-8"></script>
+<script src="js/base64.js" type="text/javascript" charset="utf-8"></script>
+<script src="js/basic/meetingTranscription.js" type="text/javascript" charset="utf-8"></script>
+
+</body>
+
+</html>