diff --git a/app/Http/Controllers/Api/DialogController.php b/app/Http/Controllers/Api/DialogController.php
index 86d7e8061..40bb53689 100755
--- a/app/Http/Controllers/Api/DialogController.php
+++ b/app/Http/Controllers/Api/DialogController.php
@@ -1348,6 +1348,55 @@ class DialogController extends AbstractController
}
}
+ /**
+ * @api {post} api/dialog/msg/convertrecord 25. 录音转文字
+ *
+ * @apiDescription 需要token身份
+ * @apiVersion 1.0.0
+ * @apiGroup dialog
+ * @apiName msg__convertrecord
+ *
+ * @apiParam {Number} dialog_id 对话ID
+ * @apiParam {String} base64 语音base64
+ * @apiParam {Number} duration 语音时长(毫秒)
+ *
+ * @apiSuccess {Number} ret 返回状态码(1正确、0错误)
+ * @apiSuccess {String} msg 返回信息(错误描述)
+ * @apiSuccess {Object} data 返回数据
+ */
+ public function msg__convertrecord()
+ {
+ $user = User::auth();
+ $user->checkChatInformation();
+ //
+ $dialog_id = intval(Request::input('dialog_id'));
+ //
+ WebSocketDialog::checkDialog($dialog_id);
+ //
+ $path = "uploads/tmp/chat/" . date("Ym") . "/" . $dialog_id . "/";
+ $base64 = Request::input('base64');
+ $duration = intval(Request::input('duration'));
+ if ($duration < 600) {
+ return Base::retError('说话时间太短');
+ }
+ $data = Base::record64save([
+ "base64" => $base64,
+ "path" => $path,
+ ]);
+ if (Base::isError($data)) {
+ return Base::retError($data['msg']);
+ }
+ $recordData = $data['data'];
+ $res = Extranet::openAItranscriptions($recordData['file']);
+ if (Base::isError($res)) {
+ return $res;
+ }
+ if (strlen($res['data']) < 1) {
+ return Base::retError('转文字失败');
+ }
+ return $res;
+ }
+
/**
* @api {post} api/dialog/msg/sendfile 26. 文件上传
*
diff --git a/resources/assets/js/pages/manage/components/ChatInput/index.vue b/resources/assets/js/pages/manage/components/ChatInput/index.vue
index 069436a21..c9b82675d 100755
--- a/resources/assets/js/pages/manage/components/ChatInput/index.vue
+++ b/resources/assets/js/pages/manage/components/ChatInput/index.vue
@@ -188,15 +188,53 @@
v-transfer-dom
:data-transfer="true"
class="chat-input-record-transfer"
- :class="{cancel: touchLimitY}"
+ :class="recordClassName"
:style="recordTransferStyle"
@click="stopRecord">
{{recordFormatDuration}}
- {{$L(touchLimitY ? '松开取消' : '向上滑动取消')}}
+ {{$L(recordFormatTip)}}
+
+
+
+
+
+
0 ? (this.cacheDialogs.find(({id}) => id == this.dialogId) || {}) : {};
},
@@ -1140,7 +1202,7 @@ export default {
if (this.showMenu) {
return;
}
- if (this.stopRecord(this.touchLimitY)) {
+ if (this.stopRecord(this.touchLimitY, this.touchLimitX)) {
return;
}
if (this.touchLimitY || this.touchLimitX) {
@@ -1222,7 +1284,7 @@ export default {
}
},
- stopRecord(isCancel) {
+ stopRecord(isCancel, isConvert = false) {
switch (this.recordState) {
case "ing":
this.recordState = "stop";
@@ -1235,7 +1297,12 @@ export default {
$A.messageWarning("说话时间太短") // 小于 600ms 不发送
} else {
this.recordBlob = blob;
- this.uploadRecord(duration);
+ this.recordDuration = duration;
+ if (isConvert === true) {
+ this.convertRecord();
+ } else {
+ this.uploadRecord();
+ }
}
}, (msg) => {
this.recordRec.close();
@@ -1270,7 +1337,54 @@ export default {
})
},
- uploadRecord(duration) {
+ convertRecord() {
+ if (this.recordBlob === null) {
+ this.recordConvertIng = false
+ return;
+ }
+ this.recordConvertResult = ''
+ this.recordConvertStatus = 0
+ this.recordConvertIng = true
+ //
+ const reader = new FileReader();
+ reader.onloadend = () => {
+ this.$store.dispatch("call", {
+ url: 'dialog/msg/convertrecord',
+ data: {
+ dialog_id: this.dialogId,
+ base64: reader.result,
+ duration: this.recordDuration,
+ },
+ method: 'post',
+ }).then(({data}) => {
+ this.recordConvertStatus = data ? 1 : 2
+ this.recordConvertResult = data || this.$L('转文字失败')
+ }).catch(({msg}) => {
+ this.recordConvertStatus = 2
+ this.recordConvertResult = msg
+ });
+ };
+ reader.readAsDataURL(this.recordBlob);
+ },
+
+ convertSend(type) {
+ if (!this.recordConvertIng) {
+ return;
+ }
+ if (type === 'voice') {
+ this.uploadRecord();
+ this.recordConvertIng = false
+ } else {
+ if (this.recordConvertStatus === 1) {
+ this.$emit('on-send', this.recordConvertResult)
+ this.recordConvertIng = false
+ } else if (this.recordConvertStatus === 2) {
+ this.convertRecord()
+ }
+ }
+ },
+
+ uploadRecord() {
if (this.recordBlob === null) {
return;
}
@@ -1279,7 +1393,7 @@ export default {
this.$emit('on-record', {
type: this.recordBlob.type,
base64: reader.result,
- duration,
+ duration: this.recordDuration,
})
};
reader.readAsDataURL(this.recordBlob);
diff --git a/resources/assets/sass/dark.scss b/resources/assets/sass/dark.scss
index f1f3206bd..b9e9e9ab2 100644
--- a/resources/assets/sass/dark.scss
+++ b/resources/assets/sass/dark.scss
@@ -571,6 +571,7 @@ body.dark-mode-reverse {
}
.chat-input-record-transfer {
+ &.convert,
&.cancel {
color: #000000;
}
diff --git a/resources/assets/sass/pages/components/chat-input.scss b/resources/assets/sass/pages/components/chat-input.scss
index a069e988f..1e715d42d 100755
--- a/resources/assets/sass/pages/components/chat-input.scss
+++ b/resources/assets/sass/pages/components/chat-input.scss
@@ -723,12 +723,122 @@
margin-top: 6px;
opacity: 0.6;
}
+ &.convert {
+ background-color: #2db7f5;
+ color: #ffffff;
+ }
&.cancel {
background-color: #ff6565;
color: #ffffff;
}
}
+.chat-input-convert-transfer {
+ position: fixed;
+ top: 0;
+ left: 0;
+ right: 0;
+ bottom: 0;
+ z-index: 9999;
+ display: flex;
+ align-items: center;
+ justify-content: flex-end;
+ flex-direction: column;
+ background-color: rgba(255, 255, 255, 0.8);
+ .convert-box {
+ width: 100%;
+ max-width: 500px;
+ height: 50%;
+ display: flex;
+ flex-direction: column;
+ justify-content: space-between;
+ align-items: center;
+ .convert-content {
+ position: relative;
+ background-color: $primary-color;
+ color: #000000;
+ width: 88%;
+ padding: 18px;
+ border-radius: 14px;
+ transform: translateY(-50%);
+ &:before {
+ content: "";
+ position: absolute;
+ bottom: -15px;
+ right: 12%;
+ transform: translateX(-50%);
+ border-width: 8px;
+ border-style: solid;
+ border-color: $primary-color transparent transparent transparent;
+ }
+ .convert-result {
+ .ivu-input {
+ font-size: 18px;
+ border: 0;
+ box-shadow: none;
+ background: transparent;
+ color: #000000;
+ border-radius: 0;
+ outline: none;
+ resize: none;
+ &::placeholder {
+ color: rgba(0, 0, 0, 0.7);
+ }
+ }
+ }
+ }
+ .convert-footer {
+ width: 88%;
+ display: flex;
+ justify-content: space-around;
+ margin-bottom: 64px;
+ > li {
+ flex-grow: 0;
+ flex-shrink: 0;
+ width: 76px;
+ height: 76px;
+ list-style: none;
+ display: flex;
+ flex-direction: column;
+ justify-content: center;
+ align-items: center;
+ > i {
+ font-size: 18px;
+ &.voice {
+ transform: rotate(180deg);
+ }
+ &.send,
+ &.error {
+ font-size: 22px;
+ width: 100%;
+ height: 100%;
+ border-radius: 50%;
+ display: flex;
+ justify-content: center;
+ align-items: center;
+ color: #0a7600;
+ background: #000000;
+ font-weight: 600;
+ .common-loading {
+ width: 26px;
+ height: 26px;
+ }
+ }
+ &.error {
+ color: #ff0000;
+ font-size: 30px;
+ font-weight: 500;
+ }
+ }
+ > span {
+ font-size: 12px;
+ margin-top: 4px;
+ }
+ }
+ }
+ }
+}
+
.chat-input-full-input {
.ivu-modal {
.ivu-modal-content {