From 1969ccdad1e5135a4d6fba46826dc916a9e40a42 Mon Sep 17 00:00:00 2001
From: haoxuan <haoxuan>
Date: 星期二, 12 九月 2023 15:08:17 +0800
Subject: [PATCH] 应用中心 2023-9-12
---
src/pages/ai/FileUpload/uploader.vue | 189 +
src/pages/ai/FileUpload/common/mixins.js | 14
src/pages/ai/FileUpload/file.vue | 469 +++
src/pages/desktop/index/components/ToolsEntry.vue | 2
src/pages/ai/FileUpload/common/uploader-simple.js | 1612 +++++++++++++
src/pages/ai/FileUpload/unsupport.vue | 30
src/pages/ai/FileUpload/list.vue | 43
public/apps.json | 27
src/pages/ai/FileUpload/index.vue | 306 ++
src/pages/ai/FileUpload/common/utils.js | 28
src/pages/ai/FileUpload/files.vue | 42
src/pages/ai/index/App.vue | 3180 ++++++++-----------------
src/pages/ai/index/detail.vue | 1117 +++++++++
/dev/null | 0
src/pages/ai/FileUpload/btn.vue | 69
src/pages/ai/FileUpload/drop.vue | 64
public/images/app-mid/knowledge.png | 0
src/pages/ai/FileUpload/common/file-events.js | 3
src/pages/ai/index/api.ts | 8
19 files changed, 5,074 insertions(+), 2,129 deletions(-)
diff --git a/public/apps.json b/public/apps.json
index c35a2d7..276db05 100644
--- a/public/apps.json
+++ b/public/apps.json
@@ -8,8 +8,8 @@
"type": "2",
"url": "/view/ai/",
"title": "搴旂敤涓績",
- "width": 1243,
- "height": 670,
+ "width": 1036,
+ "height": 742,
"iconBlob": "",
"icon": "../../images/app-mid/algorithm-store.png",
"version": "1.0.0",
@@ -209,6 +209,29 @@
"progressMsg": ""
},
{
+ "id": "fa5674ee-70cf-4e22-8a06-c17429fb777",
+ "name": "涓撳鐭ヨ瘑搴�",
+ "package": "knowledge",
+ "type": "2",
+ "url": "/view/knowledge/",
+ "title": "涓撳鐭ヨ瘑搴�",
+ "width": 1500,
+ "height": 750,
+ "iconBlob": "",
+ "icon": "../../images/app-mid/knowledge.png",
+ "version": "1.0.0",
+ "create_time": "2020-10-09 14:00:08",
+ "create_by": "",
+ "update_time": "",
+ "update_by": "",
+ "isDelete": 0,
+ "isDefault": false,
+ "remoteVersion": "",
+ "installed": true,
+ "isUpgrade": false,
+ "progressMsg": ""
+ },
+ {
"id": "1e51abbf-a4dd-4cf9-9eee-2149102d6d43",
"name": "绯荤粺鐩戞帶",
"package": "systemMonitor",
diff --git a/public/images/app-mid/knowledge.png b/public/images/app-mid/knowledge.png
new file mode 100644
index 0000000..5c188f4
--- /dev/null
+++ b/public/images/app-mid/knowledge.png
Binary files differ
diff --git a/src/pages/ai/FileUpload/btn.vue b/src/pages/ai/FileUpload/btn.vue
new file mode 100644
index 0000000..c72b67c
--- /dev/null
+++ b/src/pages/ai/FileUpload/btn.vue
@@ -0,0 +1,69 @@
+<template>
+ <label class="uploader-btn" ref="btn" v-show="support">
+ <slot></slot>
+ </label>
+</template>
+
+<script>
+import { uploaderMixin, supportMixin } from './common/mixins'
+
+const COMPONENT_NAME = 'uploader-btn'
+
+export default {
+ name: COMPONENT_NAME,
+ mixins: [uploaderMixin, supportMixin],
+ props: {
+ directory: {
+ type: Boolean,
+ default: false
+ },
+ single: {
+ type: Boolean,
+ default: false
+ },
+ attrs: {
+ type: Object,
+ default() {
+ return {}
+ }
+ },
+ sourceType: {
+ type: Number,
+ }
+ },
+
+ mounted() {
+ this.uploader.uploader.assignBrowse(this.$refs.btn, this.directory, this.single, this.attrs)
+ this.$nextTick(() => {
+ let props = {accept:''};
+ if(this.sourceType == 1){
+ props.accept = '.mp4';
+ }else if(this.sourceType == 2){
+ props.accept = '.jpg,.jpeg,.png';
+ }else if(this.sourceType == 3){
+ props.accept = '.tar,.tar.gz,.gz';
+ }
+ this.uploader.uploader.assignBrowse(this.$refs.btn, this.directory, this.single, this.attrs)
+ })
+ }
+}
+</script>
+
+<style>
+.uploader-btn {
+ display: inline-block;
+ position: relative;
+ padding: 4px 8px;
+ font-size: 100%;
+ line-height: 1.4;
+ color: #666;
+ border: 1px solid #666;
+ cursor: pointer;
+ border-radius: 2px;
+ background: none;
+ outline: none;
+}
+.uploader-btn:hover {
+ /* background-color: rgba(0, 0, 0, 0.08); */
+}
+</style>
diff --git a/src/pages/ai/FileUpload/common/file-events.js b/src/pages/ai/FileUpload/common/file-events.js
new file mode 100644
index 0000000..2aba807
--- /dev/null
+++ b/src/pages/ai/FileUpload/common/file-events.js
@@ -0,0 +1,3 @@
+const events = ['fileProgress', 'fileSuccess', 'fileComplete', 'fileError']
+
+export default events
diff --git a/src/pages/ai/FileUpload/common/mixins.js b/src/pages/ai/FileUpload/common/mixins.js
new file mode 100644
index 0000000..efab3b0
--- /dev/null
+++ b/src/pages/ai/FileUpload/common/mixins.js
@@ -0,0 +1,14 @@
+export const uploaderMixin = {
+ inject: ['uploader']
+}
+
+export const supportMixin = {
+ data () {
+ return {
+ support: true
+ }
+ },
+ mounted () {
+ this.support = this.uploader.uploader.support
+ }
+}
diff --git a/src/pages/ai/FileUpload/common/uploader-simple.js b/src/pages/ai/FileUpload/common/uploader-simple.js
new file mode 100644
index 0000000..b0a0d16
--- /dev/null
+++ b/src/pages/ai/FileUpload/common/uploader-simple.js
@@ -0,0 +1,1612 @@
+/*!
+ * Uploader - Uploader library implements html5 file upload and provides multiple simultaneous, stable, fault tolerant and resumable uploads
+ * @version v0.5.4
+ * @author dolymood <dolymood@gmail.com>
+ * @link https://github.com/simple-uploader/Uploader
+ * @license MIT
+ */
+!function(e){if("object"==typeof exports)module.exports=e();else if("function"==typeof define&&define.amd)define(e);else{var f;"undefined"!=typeof window?f=window:"undefined"!=typeof global?f=global:"undefined"!=typeof self&&(f=self),f.Uploader=e()}}(function(){var define,module,exports;return (function e(t,n,r){function s(o,u){if(!n[o]){if(!t[o]){var a=typeof require=="function"&&require;if(!u&&a)return a(o,!0);if(i)return i(o,!0);throw new Error("Cannot find module '"+o+"'")}var f=n[o]={exports:{}};t[o][0].call(f.exports,function(e){var n=t[o][1][e];return s(n?n:e)},f,f.exports,e,t,n,r)}return n[o].exports}var i=typeof require=="function"&&require;for(var o=0;o<r.length;o++)s(r[o]);return s})({1:[function(_dereq_,module,exports){
+ var utils = _dereq_('./utils')
+
+ function Chunk (uploader, file, offset) {
+ utils.defineNonEnumerable(this, 'uploader', uploader)
+ utils.defineNonEnumerable(this, 'file', file)
+ utils.defineNonEnumerable(this, 'bytes', null)
+ this.offset = offset
+ this.tested = false
+ this.retries = 0
+ this.pendingRetry = false
+ this.preprocessState = 0
+ this.readState = 0
+ this.loaded = 0
+ this.total = 0
+ this.chunkSize = this.uploader.opts.chunkSize
+ this.startByte = this.offset * this.chunkSize
+ this.endByte = this.computeEndByte()
+ this.xhr = null
+ }
+
+ var STATUS = Chunk.STATUS = {
+ PENDING: 'pending',
+ UPLOADING: 'uploading',
+ READING: 'reading',
+ SUCCESS: 'success',
+ ERROR: 'error',
+ COMPLETE: 'complete',
+ PROGRESS: 'progress',
+ RETRY: 'retry'
+ }
+
+ utils.extend(Chunk.prototype, {
+
+ _event: function (evt, args) {
+ args = utils.toArray(arguments)
+ args.unshift(this)
+ this.file._chunkEvent.apply(this.file, args)
+ },
+
+ computeEndByte: function () {
+ var endByte = Math.min(this.file.size, (this.offset + 1) * this.chunkSize)
+ if (this.file.size - endByte < this.chunkSize && !this.uploader.opts.forceChunkSize) {
+ // The last chunk will be bigger than the chunk size,
+ // but less than 2 * this.chunkSize
+ endByte = this.file.size
+ }
+ return endByte
+ },
+
+ getParams: function () {
+ return {
+ chunkNumber: this.offset + 1,
+ chunkSize: this.uploader.opts.chunkSize,
+ currentChunkSize: this.endByte - this.startByte,
+ totalSize: this.file.size,
+ identifier: this.file.uniqueIdentifier,
+ filename: this.file.name,
+ relativePath: this.file.relativePath,
+ totalChunks: this.file.chunks.length
+ }
+ },
+
+ getTarget: function (target, params) {
+ if (!params.length) {
+ return target
+ }
+ if (target.indexOf('?') < 0) {
+ target += '?'
+ } else {
+ target += '&'
+ }
+ return target + params.join('&')
+ },
+
+ test: function () {
+ this.xhr = new XMLHttpRequest()
+ this.xhr.addEventListener('load', testHandler, false)
+ this.xhr.addEventListener('error', testHandler, false)
+ var testMethod = utils.evalOpts(this.uploader.opts.testMethod, this.file, this)
+ var data = this.prepareXhrRequest(testMethod, true)
+ this.xhr.send(data)
+
+ var $ = this
+ function testHandler (event) {
+ var status = $.status(true)
+ if (status === STATUS.ERROR) {
+ $._event(status, $.message())
+ $.uploader.uploadNextChunk()
+ } else if (status === STATUS.SUCCESS) {
+ $._event(status, $.message())
+ $.tested = true
+ } else if (!$.file.paused) {
+ // Error might be caused by file pause method
+ // Chunks does not exist on the server side
+ $.tested = true
+ $.send()
+ }
+ }
+ },
+
+ preprocessFinished: function () {
+ // Compute the endByte after the preprocess function to allow an
+ // implementer of preprocess to set the fileObj size
+ this.endByte = this.computeEndByte()
+ this.preprocessState = 2
+ this.send()
+ },
+
+ readFinished: function (bytes) {
+ this.readState = 2
+ this.bytes = bytes
+ this.send()
+ },
+
+ send: function () {
+ var preprocess = this.uploader.opts.preprocess
+ var read = this.uploader.opts.readFileFn
+ if (utils.isFunction(preprocess)) {
+ switch (this.preprocessState) {
+ case 0:
+ this.preprocessState = 1
+ preprocess(this)
+ return
+ case 1:
+ return
+ }
+ }
+ switch (this.readState) {
+ case 0:
+ this.readState = 1
+ read(this.file, this.file.fileType, this.startByte, this.endByte, this)
+ return
+ case 1:
+ return
+ }
+ if (this.uploader.opts.testChunks && !this.tested) {
+ this.test()
+ return
+ }
+
+ this.loaded = 0
+ this.total = 0
+ this.pendingRetry = false
+
+ // Set up request and listen for event
+ this.xhr = new XMLHttpRequest()
+ this.xhr.upload.addEventListener('progress', progressHandler, false)
+ this.xhr.addEventListener('load', doneHandler, false)
+ this.xhr.addEventListener('error', doneHandler, false)
+
+ var uploadMethod = utils.evalOpts(this.uploader.opts.uploadMethod, this.file, this)
+ var data = this.prepareXhrRequest(uploadMethod, false, this.uploader.opts.method, this.bytes)
+ this.xhr.send(data)
+
+ var $ = this
+ function progressHandler (event) {
+ if (event.lengthComputable) {
+ $.loaded = event.loaded
+ $.total = event.total
+ }
+ $._event(STATUS.PROGRESS, event)
+ }
+
+ function doneHandler (event) {
+ var msg = $.message()
+ $.processingResponse = true
+ $.uploader.opts.processResponse(msg, function (err, res) {
+ $.processingResponse = false
+ if (!$.xhr) {
+ return
+ }
+ $.processedState = {
+ err: err,
+ res: res
+ }
+ var status = $.status()
+ if (status === STATUS.SUCCESS || status === STATUS.ERROR) {
+ delete this.data
+ $._event(status, res)
+ status === STATUS.ERROR && $.uploader.uploadNextChunk()
+ } else {
+ $._event(STATUS.RETRY, res)
+ $.pendingRetry = true
+ $.abort()
+ $.retries++
+ var retryInterval = $.uploader.opts.chunkRetryInterval
+ if (retryInterval !== null) {
+ setTimeout(function () {
+ $.send()
+ }, retryInterval)
+ } else {
+ $.send()
+ }
+ }
+ }, $.file, $)
+ }
+ },
+
+ abort: function () {
+ var xhr = this.xhr
+ this.xhr = null
+ this.processingResponse = false
+ this.processedState = null
+ if (xhr) {
+ xhr.abort()
+ }
+ },
+
+ status: function (isTest) {
+ if (this.readState === 1) {
+ return STATUS.READING
+ } else if (this.pendingRetry || this.preprocessState === 1) {
+ // if pending retry then that's effectively the same as actively uploading,
+ // there might just be a slight delay before the retry starts
+ return STATUS.UPLOADING
+ } else if (!this.xhr) {
+ return STATUS.PENDING
+ } else if (this.xhr.readyState < 4 || this.processingResponse) {
+ // Status is really 'OPENED', 'HEADERS_RECEIVED'
+ // or 'LOADING' - meaning that stuff is happening
+ return STATUS.UPLOADING
+ } else {
+ var _status
+ if (this.uploader.opts.successStatuses.indexOf(this.xhr.status) > -1) {
+ // HTTP 200, perfect
+ // HTTP 202 Accepted - The request has been accepted for processing, but the processing has not been completed.
+ _status = STATUS.SUCCESS
+ } else if (this.uploader.opts.permanentErrors.indexOf(this.xhr.status) > -1 ||
+ !isTest && this.retries >= this.uploader.opts.maxChunkRetries) {
+ // HTTP 415/500/501, permanent error
+ _status = STATUS.ERROR
+ } else {
+ // this should never happen, but we'll reset and queue a retry
+ // a likely case for this would be 503 service unavailable
+ this.abort()
+ _status = STATUS.PENDING
+ }
+ var processedState = this.processedState
+ if (processedState && processedState.err) {
+ _status = STATUS.ERROR
+ }
+ return _status
+ }
+ },
+
+ message: function () {
+ return this.xhr ? this.xhr.responseText : ''
+ },
+
+ progress: function () {
+ if (this.pendingRetry) {
+ return 0
+ }
+ var s = this.status()
+ if (s === STATUS.SUCCESS || s === STATUS.ERROR) {
+ return 1
+ } else if (s === STATUS.PENDING) {
+ return 0
+ } else {
+ return this.total > 0 ? this.loaded / this.total : 0
+ }
+ },
+
+ sizeUploaded: function () {
+ var size = this.endByte - this.startByte
+ // can't return only chunk.loaded value, because it is bigger than chunk size
+ if (this.status() !== STATUS.SUCCESS) {
+ size = this.progress() * size
+ }
+ return size
+ },
+
+ prepareXhrRequest: function (method, isTest, paramsMethod, blob) {
+ // Add data from the query options
+ var query = utils.evalOpts(this.uploader.opts.query, this.file, this, isTest)
+ query = utils.extend(this.getParams(), query)
+
+ // processParams
+ query = this.uploader.opts.processParams(query, this.file, this, isTest)
+
+ var target = utils.evalOpts(this.uploader.opts.target, this.file, this, isTest)
+ var data = null
+ if (method === 'GET' || paramsMethod === 'octet') {
+ // Add data from the query options
+ var params = []
+ utils.each(query, function (v, k) {
+ params.push([encodeURIComponent(k), encodeURIComponent(v)].join('='))
+ })
+ target = this.getTarget(target, params)
+ data = blob || null
+ } else {
+ // Add data from the query options
+ data = new FormData()
+ utils.each(query, function (v, k) {
+ data.append(k, v)
+ })
+ if (typeof blob !== 'undefined') {
+ data.append(this.uploader.opts.fileParameterName, blob, this.file.name)
+ }
+ }
+
+ this.xhr.open(method, target, true)
+ this.xhr.withCredentials = this.uploader.opts.withCredentials
+
+ // Add data from header options
+ utils.each(utils.evalOpts(this.uploader.opts.headers, this.file, this, isTest), function (v, k) {
+ this.xhr.setRequestHeader(k, v)
+ }, this)
+
+ return data
+ }
+
+ })
+
+ module.exports = Chunk
+
+ },{"./utils":5}],2:[function(_dereq_,module,exports){
+ var each = _dereq_('./utils').each
+
+ var event = {
+
+ _eventData: null,
+
+ on: function (name, func) {
+ if (!this._eventData) this._eventData = {}
+ if (!this._eventData[name]) this._eventData[name] = []
+ var listened = false
+ each(this._eventData[name], function (fuc) {
+ if (fuc === func) {
+ listened = true
+ return false
+ }
+ })
+ if (!listened) {
+ this._eventData[name].push(func)
+ }
+ },
+
+ off: function (name, func) {
+ if (!this._eventData) this._eventData = {}
+ if (!this._eventData[name] || !this._eventData[name].length) return
+ if (func) {
+ each(this._eventData[name], function (fuc, i) {
+ if (fuc === func) {
+ this._eventData[name].splice(i, 1)
+ return false
+ }
+ }, this)
+ } else {
+ this._eventData[name] = []
+ }
+ },
+
+ trigger: function (name) {
+ if (!this._eventData) this._eventData = {}
+ if (!this._eventData[name]) return true
+ var args = this._eventData[name].slice.call(arguments, 1)
+ var preventDefault = false
+ each(this._eventData[name], function (fuc) {
+ preventDefault = fuc.apply(this, args) === false || preventDefault
+ }, this)
+ return !preventDefault
+ }
+ }
+
+ module.exports = event
+
+ },{"./utils":5}],3:[function(_dereq_,module,exports){
+ var utils = _dereq_('./utils')
+ var event = _dereq_('./event')
+ var File = _dereq_('./file')
+ var Chunk = _dereq_('./chunk')
+
+ var version = '0.5.4'
+
+ var isServer = typeof window === 'undefined'
+
+ // ie10+
+ var ie10plus = isServer ? false : window.navigator.msPointerEnabled
+ var support = (function () {
+ if (isServer) {
+ return false
+ }
+ var sliceName = 'slice'
+ var _support = utils.isDefined(window.File) && utils.isDefined(window.Blob) &&
+ utils.isDefined(window.FileList)
+ var bproto = null
+ if (_support) {
+ bproto = window.Blob.prototype
+ utils.each(['slice', 'webkitSlice', 'mozSlice'], function (n) {
+ if (bproto[n]) {
+ sliceName = n
+ return false
+ }
+ })
+ _support = !!bproto[sliceName]
+ }
+ if (_support) Uploader.sliceName = sliceName
+ bproto = null
+ return _support
+ })()
+
+ var supportDirectory = (function () {
+ if (isServer) {
+ return false
+ }
+ var input = window.document.createElement('input')
+ input.type = 'file'
+ var sd = 'webkitdirectory' in input || 'directory' in input
+ input = null
+ return sd
+ })()
+
+ function Uploader (opts) {
+ this.support = support
+ /* istanbul ignore if */
+ if (!this.support) {
+ return
+ }
+ this.supportDirectory = supportDirectory
+ utils.defineNonEnumerable(this, 'filePaths', {})
+ this.opts = utils.extend({}, Uploader.defaults, opts || {})
+
+ this.preventEvent = utils.bind(this._preventEvent, this)
+
+ File.call(this, this)
+ }
+
+ /**
+ * Default read function using the webAPI
+ *
+ * @function webAPIFileRead(fileObj, fileType, startByte, endByte, chunk)
+ *
+ */
+ var webAPIFileRead = function (fileObj, fileType, startByte, endByte, chunk) {
+ chunk.readFinished(fileObj.file[Uploader.sliceName](startByte, endByte, fileType))
+ }
+
+ Uploader.version = version
+
+ Uploader.defaults = {
+ chunkSize: 1024 * 1024,
+ forceChunkSize: false,
+ simultaneousUploads: 3,
+ singleFile: false,
+ fileParameterName: 'file',
+ progressCallbacksInterval: 500,
+ speedSmoothingFactor: 0.1,
+ query: {},
+ headers: {},
+ withCredentials: false,
+ preprocess: null,
+ method: 'multipart',
+ testMethod: 'GET',
+ uploadMethod: 'POST',
+ prioritizeFirstAndLastChunk: false,
+ allowDuplicateUploads: false,
+ target: '/',
+ testChunks: true,
+ generateUniqueIdentifier: null,
+ maxChunkRetries: 0,
+ chunkRetryInterval: null,
+ permanentErrors: [404, 415, 500, 501],
+ successStatuses: [200, 201, 202],
+ onDropStopPropagation: false,
+ initFileFn: null,
+ readFileFn: webAPIFileRead,
+ checkChunkUploadedByResponse: null,
+ initialPaused: false,
+ processResponse: function (response, cb) {
+ cb(null, response)
+ },
+ processParams: function (params) {
+ return params
+ }
+ }
+
+ Uploader.utils = utils
+ Uploader.event = event
+ Uploader.File = File
+ Uploader.Chunk = Chunk
+
+ // inherit file
+ Uploader.prototype = utils.extend({}, File.prototype)
+ // inherit event
+ utils.extend(Uploader.prototype, event)
+ utils.extend(Uploader.prototype, {
+
+ constructor: Uploader,
+
+ _trigger: function (name) {
+ var args = utils.toArray(arguments)
+ var preventDefault = !this.trigger.apply(this, arguments)
+ if (name !== 'catchAll') {
+ args.unshift('catchAll')
+ preventDefault = !this.trigger.apply(this, args) || preventDefault
+ }
+ return !preventDefault
+ },
+
+ _triggerAsync: function () {
+ var args = arguments
+ utils.nextTick(function () {
+ this._trigger.apply(this, args)
+ }, this)
+ },
+
+ addFiles: function (files, evt) {
+ var _files = []
+ var oldFileListLen = this.fileList.length
+ utils.each(files, function (file) {
+ // Uploading empty file IE10/IE11 hangs indefinitely
+ // Directories have size `0` and name `.`
+ // Ignore already added files if opts.allowDuplicateUploads is set to false
+ if ((!ie10plus || ie10plus && file.size > 0) && !(file.size % 4096 === 0 && (file.name === '.' || file.fileName === '.'))) {
+ var uniqueIdentifier = this.generateUniqueIdentifier(file)
+ if (this.opts.allowDuplicateUploads || !this.getFromUniqueIdentifier(uniqueIdentifier)) {
+ var _file = new File(this, file, this)
+ _file.uniqueIdentifier = uniqueIdentifier
+ if (this._trigger('fileAdded', _file, evt)) {
+ _files.push(_file)
+ } else {
+ File.prototype.removeFile.call(this, _file)
+ }
+ }
+ }
+ }, this)
+ // get new fileList
+ var newFileList = this.fileList.slice(oldFileListLen)
+ if (this._trigger('filesAdded', _files, newFileList, evt)) {
+ utils.each(_files, function (file) {
+ if (this.opts.singleFile && this.files.length > 0) {
+ this.removeFile(this.files[0])
+ }
+ this.files.push(file)
+ }, this)
+ this._trigger('filesSubmitted', _files, newFileList, evt)
+ } else {
+ utils.each(newFileList, function (file) {
+ File.prototype.removeFile.call(this, file)
+ }, this)
+ }
+ },
+
+ addFile: function (file, evt) {
+ this.addFiles([file], evt)
+ },
+
+ cancel: function () {
+ for (var i = this.fileList.length - 1; i >= 0; i--) {
+ this.fileList[i].cancel()
+ }
+ },
+
+ removeFile: function (file) {
+ File.prototype.removeFile.call(this, file)
+ this._trigger('fileRemoved', file)
+ },
+
+ generateUniqueIdentifier: function (file) {
+ var custom = this.opts.generateUniqueIdentifier
+ if (utils.isFunction(custom)) {
+ return custom(file)
+ }
+ /* istanbul ignore next */
+ // Some confusion in different versions of Firefox
+ var relativePath = file.relativePath || file.webkitRelativePath || file.fileName || file.name
+ /* istanbul ignore next */
+ return file.size + '-' + relativePath.replace(/[^0-9a-zA-Z_-]/img, '')
+ },
+
+ getFromUniqueIdentifier: function (uniqueIdentifier) {
+ var ret = false
+ utils.each(this.files, function (file) {
+ if (file.uniqueIdentifier === uniqueIdentifier) {
+ ret = file
+ return false
+ }
+ })
+ return ret
+ },
+
+ uploadNextChunk: function (preventEvents) {
+ var found = false
+ var pendingStatus = Chunk.STATUS.PENDING
+ var checkChunkUploaded = this.uploader.opts.checkChunkUploadedByResponse
+ if (this.opts.prioritizeFirstAndLastChunk) {
+ utils.each(this.files, function (file) {
+ if (file.paused) {
+ return
+ }
+ if (checkChunkUploaded && !file._firstResponse && file.isUploading()) {
+ // waiting for current file's first chunk response
+ return
+ }
+ if (file.chunks.length && file.chunks[0].status() === pendingStatus) {
+ file.chunks[0].send()
+ found = true
+ return false
+ }
+ if (file.chunks.length > 1 && file.chunks[file.chunks.length - 1].status() === pendingStatus) {
+ file.chunks[file.chunks.length - 1].send()
+ found = true
+ return false
+ }
+ })
+ if (found) {
+ return found
+ }
+ }
+
+ // Now, simply look for the next, best thing to upload
+ utils.each(this.files, function (file) {
+ if (!file.paused) {
+ if (checkChunkUploaded && !file._firstResponse && file.isUploading()) {
+ // waiting for current file's first chunk response
+ return
+ }
+ utils.each(file.chunks, function (chunk) {
+ if (chunk.status() === pendingStatus) {
+ chunk.send()
+ found = true
+ return false
+ }
+ })
+ }
+ if (found) {
+ return false
+ }
+ })
+ if (found) {
+ return true
+ }
+
+ // The are no more outstanding chunks to upload, check is everything is done
+ var outstanding = false
+ utils.each(this.files, function (file) {
+ if (!file.isComplete()) {
+ outstanding = true
+ return false
+ }
+ })
+ // should check files now
+ // if now files in list
+ // should not trigger complete event
+ if (!outstanding && !preventEvents && this.files.length) {
+ // All chunks have been uploaded, complete
+ this._triggerAsync('complete')
+ }
+ return outstanding
+ },
+
+ upload: function (preventEvents) {
+ // Make sure we don't start too many uploads at once
+ var ret = this._shouldUploadNext()
+ if (ret === false) {
+ return
+ }
+ !preventEvents && this._trigger('uploadStart')
+ var started = false
+ for (var num = 1; num <= this.opts.simultaneousUploads - ret; num++) {
+ started = this.uploadNextChunk(!preventEvents) || started
+ if (!started && preventEvents) {
+ // completed
+ break
+ }
+ }
+ if (!started && !preventEvents) {
+ this._triggerAsync('complete')
+ }
+ },
+
+ /**
+ * should upload next chunk
+ * @function
+ * @returns {Boolean|Number}
+ */
+ _shouldUploadNext: function () {
+ var num = 0
+ var should = true
+ var simultaneousUploads = this.opts.simultaneousUploads
+ var uploadingStatus = Chunk.STATUS.UPLOADING
+ utils.each(this.files, function (file) {
+ utils.each(file.chunks, function (chunk) {
+ if (chunk.status() === uploadingStatus) {
+ num++
+ if (num >= simultaneousUploads) {
+ should = false
+ return false
+ }
+ }
+ })
+ return should
+ })
+ // if should is true then return uploading chunks's length
+ return should && num
+ },
+
+ /**
+ * Assign a browse action to one or more DOM nodes.
+ * @function
+ * @param {Element|Array.<Element>} domNodes
+ * @param {boolean} isDirectory Pass in true to allow directories to
+ * @param {boolean} singleFile prevent multi file upload
+ * @param {Object} attributes set custom attributes:
+ * http://www.w3.org/TR/html-markup/input.file.html#input.file-attributes
+ * eg: accept: 'image/*'
+ * be selected (Chrome only).
+ */
+ assignBrowse: function (domNodes, isDirectory, singleFile, attributes) {
+ if (typeof domNodes.length === 'undefined') {
+ domNodes = [domNodes]
+ }
+
+ utils.each(domNodes, function (domNode) {
+ var input
+ if (domNode.tagName === 'INPUT' && domNode.type === 'file') {
+ input = domNode
+ } else {
+ input = document.createElement('input')
+ input.setAttribute('type', 'file')
+ // display:none - not working in opera 12
+ utils.extend(input.style, {
+ visibility: 'hidden',
+ position: 'absolute',
+ width: '1px',
+ height: '1px'
+ })
+ // for opera 12 browser, input must be assigned to a document
+ Array.from(domNode.children).forEach(function(child){
+ if(child.type=='file'){
+ console.log(child)
+ domNode.removeChild(child)
+ }
+ })
+ domNode.appendChild(input)
+ // https://developer.mozilla.org/en/using_files_from_web_applications)
+ // event listener is executed two times
+ // first one - original mouse click event
+ // second - input.click(), input is inside domNode
+ domNode.addEventListener('click', function (e) {
+ if (domNode.tagName.toLowerCase() === 'label') {
+ return
+ }
+ input.click()
+ }, false)
+ }
+ if (!this.opts.singleFile && !singleFile) {
+ input.setAttribute('multiple', 'multiple')
+ }
+ if (isDirectory) {
+ input.setAttribute('webkitdirectory', 'webkitdirectory')
+ }
+ attributes && utils.each(attributes, function (value, key) {
+ input.setAttribute(key, value)
+ })
+ // When new files are added, simply append them to the overall list
+ var that = this
+ input.addEventListener('change', function (e) {
+ that._trigger(e.type, e)
+ if (e.target.value) {
+ that.addFiles(e.target.files, e)
+ e.target.value = ''
+ }
+ }, false)
+ }, this)
+ },
+
+ onDrop: function (evt) {
+ this._trigger(evt.type, evt)
+ if (this.opts.onDropStopPropagation) {
+ evt.stopPropagation()
+ }
+ evt.preventDefault()
+ this._parseDataTransfer(evt.dataTransfer, evt)
+ },
+
+ _parseDataTransfer: function (dataTransfer, evt) {
+ if (dataTransfer.items && dataTransfer.items[0] &&
+ dataTransfer.items[0].webkitGetAsEntry) {
+ this.webkitReadDataTransfer(dataTransfer, evt)
+ } else {
+ this.addFiles(dataTransfer.files, evt)
+ }
+ },
+
+ webkitReadDataTransfer: function (dataTransfer, evt) {
+ var self = this
+ var queue = dataTransfer.items.length
+ var files = []
+ utils.each(dataTransfer.items, function (item) {
+ var entry = item.webkitGetAsEntry()
+ if (!entry) {
+ decrement()
+ return
+ }
+ if (entry.isFile) {
+ // due to a bug in Chrome's File System API impl - #149735
+ fileReadSuccess(item.getAsFile(), entry.fullPath)
+ } else {
+ readDirectory(entry.createReader())
+ }
+ })
+ function readDirectory (reader) {
+ reader.readEntries(function (entries) {
+ if (entries.length) {
+ queue += entries.length
+ utils.each(entries, function (entry) {
+ if (entry.isFile) {
+ var fullPath = entry.fullPath
+ entry.file(function (file) {
+ fileReadSuccess(file, fullPath)
+ }, readError)
+ } else if (entry.isDirectory) {
+ readDirectory(entry.createReader())
+ }
+ })
+ readDirectory(reader)
+ } else {
+ decrement()
+ }
+ }, readError)
+ }
+ function fileReadSuccess (file, fullPath) {
+ // relative path should not start with "/"
+ file.relativePath = fullPath.substring(1)
+ files.push(file)
+ decrement()
+ }
+ function readError (fileError) {
+ throw fileError
+ }
+ function decrement () {
+ if (--queue === 0) {
+ self.addFiles(files, evt)
+ }
+ }
+ },
+
+ _assignHelper: function (domNodes, handles, remove) {
+ if (typeof domNodes.length === 'undefined') {
+ domNodes = [domNodes]
+ }
+ var evtMethod = remove ? 'removeEventListener' : 'addEventListener'
+ utils.each(domNodes, function (domNode) {
+ utils.each(handles, function (handler, name) {
+ domNode[evtMethod](name, handler, false)
+ }, this)
+ }, this)
+ },
+
+ _preventEvent: function (e) {
+ utils.preventEvent(e)
+ this._trigger(e.type, e)
+ },
+
+ /**
+ * Assign one or more DOM nodes as a drop target.
+ * @function
+ * @param {Element|Array.<Element>} domNodes
+ */
+ assignDrop: function (domNodes) {
+ this._onDrop = utils.bind(this.onDrop, this)
+ this._assignHelper(domNodes, {
+ dragover: this.preventEvent,
+ dragenter: this.preventEvent,
+ dragleave: this.preventEvent,
+ drop: this._onDrop
+ })
+ },
+
+ /**
+ * Un-assign drop event from DOM nodes
+ * @function
+ * @param domNodes
+ */
+ unAssignDrop: function (domNodes) {
+ this._assignHelper(domNodes, {
+ dragover: this.preventEvent,
+ dragenter: this.preventEvent,
+ dragleave: this.preventEvent,
+ drop: this._onDrop
+ }, true)
+ this._onDrop = null
+ }
+ })
+
+ module.exports = Uploader
+
+ },{"./chunk":1,"./event":2,"./file":4,"./utils":5}],4:[function(_dereq_,module,exports){
+ var utils = _dereq_('./utils')
+ var Chunk = _dereq_('./chunk')
+
+ function File (uploader, file, parent) {
+ utils.defineNonEnumerable(this, 'uploader', uploader)
+ this.isRoot = this.isFolder = uploader === this
+ utils.defineNonEnumerable(this, 'parent', parent || null)
+ utils.defineNonEnumerable(this, 'files', [])
+ utils.defineNonEnumerable(this, 'fileList', [])
+ utils.defineNonEnumerable(this, 'chunks', [])
+ utils.defineNonEnumerable(this, '_errorFiles', [])
+ utils.defineNonEnumerable(this, 'file', null)
+ this.id = utils.uid()
+
+ if (this.isRoot || !file) {
+ this.file = null
+ } else {
+ if (utils.isString(file)) {
+ // folder
+ this.isFolder = true
+ this.file = null
+ this.path = file
+ if (this.parent.path) {
+ file = file.substr(this.parent.path.length)
+ }
+ this.name = file.charAt(file.length - 1) === '/' ? file.substr(0, file.length - 1) : file
+ } else {
+ this.file = file
+ this.fileType = this.file.type
+ this.name = file.fileName || file.name
+ this.size = file.size
+ this.relativePath = file.relativePath || file.webkitRelativePath || this.name
+ this._parseFile()
+ }
+ }
+
+ this.paused = uploader.opts.initialPaused
+ this.error = false
+ this.allError = false
+ this.aborted = false
+ this.completed = false
+ this.averageSpeed = 0
+ this.currentSpeed = 0
+ this._lastProgressCallback = Date.now()
+ this._prevUploadedSize = 0
+ this._prevProgress = 0
+
+ this.bootstrap()
+ }
+
+ utils.extend(File.prototype, {
+
+ _parseFile: function () {
+ var ppaths = parsePaths(this.relativePath)
+ if (ppaths.length) {
+ var filePaths = this.uploader.filePaths
+ utils.each(ppaths, function (path, i) {
+ var folderFile = filePaths[path]
+ if (!folderFile) {
+ folderFile = new File(this.uploader, path, this.parent)
+ filePaths[path] = folderFile
+ this._updateParentFileList(folderFile)
+ }
+ this.parent = folderFile
+ folderFile.files.push(this)
+ if (!ppaths[i + 1]) {
+ folderFile.fileList.push(this)
+ }
+ }, this)
+ } else {
+ this._updateParentFileList()
+ }
+ },
+
+ _updateParentFileList: function (file) {
+ if (!file) {
+ file = this
+ }
+ var p = this.parent
+ if (p) {
+ p.fileList.push(file)
+ }
+ },
+
+ _eachAccess: function (eachFn, fileFn) {
+ if (this.isFolder) {
+ utils.each(this.files, function (f, i) {
+ return eachFn.call(this, f, i)
+ }, this)
+ return
+ }
+ fileFn.call(this, this)
+ },
+
+ bootstrap: function () {
+ if (this.isFolder) return
+ var opts = this.uploader.opts
+ if (utils.isFunction(opts.initFileFn)) {
+ opts.initFileFn.call(this, this)
+ }
+
+ this.abort(true)
+ this._resetError()
+ // Rebuild stack of chunks from file
+ this._prevProgress = 0
+ var round = opts.forceChunkSize ? Math.ceil : Math.floor
+ var chunks = Math.max(round(this.size / opts.chunkSize), 1)
+ for (var offset = 0; offset < chunks; offset++) {
+ this.chunks.push(new Chunk(this.uploader, this, offset))
+ }
+ },
+
+ _measureSpeed: function () {
+ var smoothingFactor = this.uploader.opts.speedSmoothingFactor
+ var timeSpan = Date.now() - this._lastProgressCallback
+ if (!timeSpan) {
+ return
+ }
+ var uploaded = this.sizeUploaded()
+ // Prevent negative upload speed after file upload resume
+ this.currentSpeed = Math.max((uploaded - this._prevUploadedSize) / timeSpan * 1000, 0)
+ this.averageSpeed = smoothingFactor * this.currentSpeed + (1 - smoothingFactor) * this.averageSpeed
+ this._prevUploadedSize = uploaded
+ if (this.parent && this.parent._checkProgress()) {
+ this.parent._measureSpeed()
+ }
+ },
+
+ _checkProgress: function (file) {
+ return Date.now() - this._lastProgressCallback >= this.uploader.opts.progressCallbacksInterval
+ },
+
+ _chunkEvent: function (chunk, evt, message) {
+ var uploader = this.uploader
+ var STATUS = Chunk.STATUS
+ var that = this
+ var rootFile = this.getRoot()
+ var triggerProgress = function () {
+ that._measureSpeed()
+ uploader._trigger('fileProgress', rootFile, that, chunk)
+ that._lastProgressCallback = Date.now()
+ }
+ switch (evt) {
+ case STATUS.PROGRESS:
+ if (this._checkProgress()) {
+ triggerProgress()
+ }
+ break
+ case STATUS.ERROR:
+ this._error()
+ this.abort(true)
+ uploader._trigger('fileError', rootFile, this, message, chunk)
+ break
+ case STATUS.SUCCESS:
+ this._updateUploadedChunks(message, chunk)
+ if (this.error) {
+ return
+ }
+ clearTimeout(this._progeressId)
+ this._progeressId = 0
+ var timeDiff = Date.now() - this._lastProgressCallback
+ if (timeDiff < uploader.opts.progressCallbacksInterval) {
+ this._progeressId = setTimeout(triggerProgress, uploader.opts.progressCallbacksInterval - timeDiff)
+ }
+ if (this.isComplete()) {
+ clearTimeout(this._progeressId)
+ triggerProgress()
+ this.currentSpeed = 0
+ this.averageSpeed = 0
+ uploader._trigger('fileSuccess', rootFile, this, message, chunk)
+ if (rootFile.isComplete()) {
+ uploader._trigger('fileComplete', rootFile, this)
+ }
+ } else if (!this._progeressId) {
+ triggerProgress()
+ }
+ break
+ case STATUS.RETRY:
+ uploader._trigger('fileRetry', rootFile, this, chunk)
+ break
+ }
+ },
+
+ _updateUploadedChunks: function (message, chunk) {
+ var checkChunkUploaded = this.uploader.opts.checkChunkUploadedByResponse
+ if (checkChunkUploaded) {
+ var xhr = chunk.xhr
+ utils.each(this.chunks, function (_chunk) {
+ if (!_chunk.tested) {
+ var uploaded = checkChunkUploaded.call(this, _chunk, message)
+ if (_chunk === chunk && !uploaded) {
+ // fix the first chunk xhr status
+ // treated as success but checkChunkUploaded is false
+ // so the current chunk should be uploaded again
+ _chunk.xhr = null
+ }
+ if (uploaded) {
+ // first success and other chunks are uploaded
+ // then set xhr, so the uploaded chunks
+ // will be treated as success too
+ _chunk.xhr = xhr
+ }
+ _chunk.tested = true
+ }
+ }, this)
+ if (!this._firstResponse) {
+ this._firstResponse = true
+ this.uploader.upload(true)
+ } else {
+ this.uploader.uploadNextChunk()
+ }
+ } else {
+ this.uploader.uploadNextChunk()
+ }
+ },
+
+ _error: function () {
+ this.error = this.allError = true
+ var parent = this.parent
+ while (parent && parent !== this.uploader) {
+ parent._errorFiles.push(this)
+ parent.error = true
+ if (parent._errorFiles.length === parent.files.length) {
+ parent.allError = true
+ }
+ parent = parent.parent
+ }
+ },
+
+ _resetError: function () {
+ this.error = this.allError = false
+ var parent = this.parent
+ var index = -1
+ while (parent && parent !== this.uploader) {
+ index = parent._errorFiles.indexOf(this)
+ parent._errorFiles.splice(index, 1)
+ parent.allError = false
+ if (!parent._errorFiles.length) {
+ parent.error = false
+ }
+ parent = parent.parent
+ }
+ },
+
+ isComplete: function () {
+ if (!this.completed) {
+ var outstanding = false
+ this._eachAccess(function (file) {
+ if (!file.isComplete()) {
+ outstanding = true
+ return false
+ }
+ }, function () {
+ var STATUS = Chunk.STATUS
+ utils.each(this.chunks, function (chunk) {
+ var status = chunk.status()
+ if (status === STATUS.PENDING || status === STATUS.UPLOADING || status === STATUS.READING || chunk.preprocessState === 1 || chunk.readState === 1) {
+ outstanding = true
+ return false
+ }
+ })
+ })
+ this.completed = !outstanding
+ }
+ return this.completed
+ },
+
+ isUploading: function () {
+ var uploading = false
+ this._eachAccess(function (file) {
+ if (file.isUploading()) {
+ uploading = true
+ return false
+ }
+ }, function () {
+ var uploadingStatus = Chunk.STATUS.UPLOADING
+ utils.each(this.chunks, function (chunk) {
+ if (chunk.status() === uploadingStatus) {
+ uploading = true
+ return false
+ }
+ })
+ })
+ return uploading
+ },
+
+ resume: function () {
+ this._eachAccess(function (f) {
+ f.resume()
+ }, function () {
+ this.paused = false
+ this.aborted = false
+ this.uploader.upload()
+ })
+ this.paused = false
+ this.aborted = false
+ },
+
+ pause: function () {
+ this._eachAccess(function (f) {
+ f.pause()
+ }, function () {
+ this.paused = true
+ this.abort()
+ })
+ this.paused = true
+ },
+
+ cancel: function () {
+ this.uploader.removeFile(this)
+ },
+
+ retry: function (file) {
+ var fileRetry = function (file) {
+ if (file.error) {
+ file.bootstrap()
+ }
+ }
+ if (file) {
+ file.bootstrap()
+ } else {
+ this._eachAccess(fileRetry, function () {
+ this.bootstrap()
+ })
+ }
+ this.uploader.upload()
+ },
+
+ abort: function (reset) {
+ if (this.aborted) {
+ return
+ }
+ this.currentSpeed = 0
+ this.averageSpeed = 0
+ this.aborted = !reset
+ var chunks = this.chunks
+ if (reset) {
+ this.chunks = []
+ }
+ var uploadingStatus = Chunk.STATUS.UPLOADING
+ utils.each(chunks, function (c) {
+ if (c.status() === uploadingStatus) {
+ c.abort()
+ this.uploader.uploadNextChunk()
+ }
+ }, this)
+ },
+
+ progress: function () {
+ var totalDone = 0
+ var totalSize = 0
+ var ret = 0
+ this._eachAccess(function (file, index) {
+ totalDone += file.progress() * file.size
+ totalSize += file.size
+ if (index === this.files.length - 1) {
+ ret = totalSize > 0 ? totalDone / totalSize : this.isComplete() ? 1 : 0
+ }
+ }, function () {
+ if (this.error) {
+ ret = 1
+ return
+ }
+ if (this.chunks.length === 1) {
+ this._prevProgress = Math.max(this._prevProgress, this.chunks[0].progress())
+ ret = this._prevProgress
+ return
+ }
+ // Sum up progress across everything
+ var bytesLoaded = 0
+ utils.each(this.chunks, function (c) {
+ // get chunk progress relative to entire file
+ bytesLoaded += c.progress() * (c.endByte - c.startByte)
+ })
+ var percent = bytesLoaded / this.size
+ // We don't want to lose percentages when an upload is paused
+ this._prevProgress = Math.max(this._prevProgress, percent > 0.9999 ? 1 : percent)
+ ret = this._prevProgress
+ })
+ return ret
+ },
+
+ getSize: function () {
+ var size = 0
+ this._eachAccess(function (file) {
+ size += file.size
+ }, function () {
+ size += this.size
+ })
+ return size
+ },
+
+ getFormatSize: function () {
+ var size = this.getSize()
+ return utils.formatSize(size)
+ },
+
+ getRoot: function () {
+ if (this.isRoot) {
+ return this
+ }
+ var parent = this.parent
+ while (parent) {
+ if (parent.parent === this.uploader) {
+ // find it
+ return parent
+ }
+ parent = parent.parent
+ }
+ return this
+ },
+
+ sizeUploaded: function () {
+ var size = 0
+ this._eachAccess(function (file) {
+ size += file.sizeUploaded()
+ }, function () {
+ utils.each(this.chunks, function (chunk) {
+ size += chunk.sizeUploaded()
+ })
+ })
+ return size
+ },
+
+ timeRemaining: function () {
+ var ret = 0
+ var sizeDelta = 0
+ var averageSpeed = 0
+ this._eachAccess(function (file, i) {
+ if (!file.paused && !file.error) {
+ sizeDelta += file.size - file.sizeUploaded()
+ averageSpeed += file.averageSpeed
+ }
+ if (i === this.files.length - 1) {
+ ret = calRet(sizeDelta, averageSpeed)
+ }
+ }, function () {
+ if (this.paused || this.error) {
+ ret = 0
+ return
+ }
+ var delta = this.size - this.sizeUploaded()
+ ret = calRet(delta, this.averageSpeed)
+ })
+ return ret
+ function calRet (delta, averageSpeed) {
+ if (delta && !averageSpeed) {
+ return Number.POSITIVE_INFINITY
+ }
+ if (!delta && !averageSpeed) {
+ return 0
+ }
+ return Math.floor(delta / averageSpeed)
+ }
+ },
+
+ removeFile: function (file) {
+ if (file.isFolder) {
+ while (file.files.length) {
+ var f = file.files[file.files.length - 1]
+ this._removeFile(f)
+ }
+ }
+ this._removeFile(file)
+ },
+
+ _delFilePath: function (file) {
+ if (file.path && this.filePaths) {
+ delete this.filePaths[file.path]
+ }
+ utils.each(file.fileList, function (file) {
+ this._delFilePath(file)
+ }, this)
+ },
+
+ _removeFile: function (file) {
+ if (!file.isFolder) {
+ utils.each(this.files, function (f, i) {
+ if (f === file) {
+ this.files.splice(i, 1)
+ return false
+ }
+ }, this)
+ file.abort()
+ var parent = file.parent
+ var newParent
+ while (parent && parent !== this) {
+ newParent = parent.parent
+ parent._removeFile(file)
+ parent = newParent
+ }
+ }
+ file.parent === this && utils.each(this.fileList, function (f, i) {
+ if (f === file) {
+ this.fileList.splice(i, 1)
+ return false
+ }
+ }, this)
+ if (!this.isRoot && this.isFolder && !this.files.length) {
+ this.parent._removeFile(this)
+ this.uploader._delFilePath(this)
+ }
+ file.parent = null
+ },
+
+ getType: function () {
+ if (this.isFolder) {
+ return 'folder'
+ }
+ return this.file.type && this.file.type.split('/')[1]
+ },
+
+ getExtension: function () {
+ if (this.isFolder) {
+ return ''
+ }
+ return this.name.substr((~-this.name.lastIndexOf('.') >>> 0) + 2).toLowerCase()
+ }
+
+ })
+
+ module.exports = File
+
+ function parsePaths (path) {
+ var ret = []
+ var paths = path.split('/')
+ var len = paths.length
+ var i = 1
+ paths.splice(len - 1, 1)
+ len--
+ if (paths.length) {
+ while (i <= len) {
+ ret.push(paths.slice(0, i++).join('/') + '/')
+ }
+ }
+ return ret
+ }
+
+ },{"./chunk":1,"./utils":5}],5:[function(_dereq_,module,exports){
+ var oproto = Object.prototype
+ var aproto = Array.prototype
+ var serialize = oproto.toString
+
+ var isFunction = function (fn) {
+ return serialize.call(fn) === '[object Function]'
+ }
+
+ var isArray = Array.isArray || /* istanbul ignore next */ function (ary) {
+ return serialize.call(ary) === '[object Array]'
+ }
+
+ var isPlainObject = function (obj) {
+ return serialize.call(obj) === '[object Object]' && Object.getPrototypeOf(obj) === oproto
+ }
+
+ var i = 0
+ var utils = {
+ uid: function () {
+ return ++i
+ },
+ noop: function () {},
+ bind: function (fn, context) {
+ return function () {
+ return fn.apply(context, arguments)
+ }
+ },
+ preventEvent: function (evt) {
+ evt.preventDefault()
+ },
+ stop: function (evt) {
+ evt.preventDefault()
+ evt.stopPropagation()
+ },
+ nextTick: function (fn, context) {
+ setTimeout(utils.bind(fn, context), 0)
+ },
+ toArray: function (ary, start, end) {
+ if (start === undefined) start = 0
+ if (end === undefined) end = ary.length
+ return aproto.slice.call(ary, start, end)
+ },
+
+ isPlainObject: isPlainObject,
+ isFunction: isFunction,
+ isArray: isArray,
+ isObject: function (obj) {
+ return Object(obj) === obj
+ },
+ isString: function (s) {
+ return typeof s === 'string'
+ },
+ isUndefined: function (a) {
+ return typeof a === 'undefined'
+ },
+ isDefined: function (a) {
+ return typeof a !== 'undefined'
+ },
+
+ each: function (ary, func, context) {
+ if (utils.isDefined(ary.length)) {
+ for (var i = 0, len = ary.length; i < len; i++) {
+ if (func.call(context, ary[i], i, ary) === false) {
+ break
+ }
+ }
+ } else {
+ for (var k in ary) {
+ if (func.call(context, ary[k], k, ary) === false) {
+ break
+ }
+ }
+ }
+ },
+
+ /**
+ * If option is a function, evaluate it with given params
+ * @param {*} data
+ * @param {...} args arguments of a callback
+ * @returns {*}
+ */
+ evalOpts: function (data, args) {
+ if (utils.isFunction(data)) {
+ // `arguments` is an object, not array, in FF, so:
+ args = utils.toArray(arguments)
+ data = data.apply(null, args.slice(1))
+ }
+ return data
+ },
+
+ extend: function () {
+ var options
+ var name
+ var src
+ var copy
+ var copyIsArray
+ var clone
+ var target = arguments[0] || {}
+ var i = 1
+ var length = arguments.length
+ var force = false
+
+ // 濡傛灉绗竴涓弬鏁颁负甯冨皵,鍒ゅ畾鏄惁娣辨嫹璐�
+ if (typeof target === 'boolean') {
+ force = target
+ target = arguments[1] || {}
+ i++
+ }
+
+ // 纭繚鎺ュ彈鏂逛负涓�涓鏉傜殑鏁版嵁绫诲瀷
+ if (typeof target !== 'object' && !isFunction(target)) {
+ target = {}
+ }
+
+ // 濡傛灉鍙湁涓�涓弬鏁帮紝閭d箞鏂版垚鍛樻坊鍔犱簬 extend 鎵�鍦ㄧ殑瀵硅薄涓�
+ if (i === length) {
+ target = this
+ i--
+ }
+
+ for (; i < length; i++) {
+ // 鍙鐞嗛潪绌哄弬鏁�
+ if ((options = arguments[i]) != null) {
+ for (name in options) {
+ src = target[name]
+ copy = options[name]
+
+ // 闃叉鐜紩鐢�
+ if (target === copy) {
+ continue
+ }
+ if (force && copy && (isPlainObject(copy) || (copyIsArray = isArray(copy)))) {
+ if (copyIsArray) {
+ copyIsArray = false
+ clone = src && isArray(src) ? src : []
+ } else {
+ clone = src && isPlainObject(src) ? src : {}
+ }
+ target[name] = utils.extend(force, clone, copy)
+ } else if (copy !== undefined) {
+ target[name] = copy
+ }
+ }
+ }
+ }
+ return target
+ },
+
+ formatSize: function (size) {
+ if (size < 1024) {
+ return size.toFixed(0) + ' bytes'
+ } else if (size < 1024 * 1024) {
+ return (size / 1024.0).toFixed(0) + ' KB'
+ } else if (size < 1024 * 1024 * 1024) {
+ return (size / 1024.0 / 1024.0).toFixed(1) + ' MB'
+ } else {
+ return (size / 1024.0 / 1024.0 / 1024.0).toFixed(1) + ' GB'
+ }
+ },
+
+ defineNonEnumerable: function (target, key, value) {
+ Object.defineProperty(target, key, {
+ enumerable: false,
+ configurable: true,
+ writable: true,
+ value: value
+ })
+ }
+ }
+
+ module.exports = utils
+
+ },{}]},{},[3])
+ (3)
+ });
\ No newline at end of file
diff --git a/src/pages/ai/FileUpload/common/utils.js b/src/pages/ai/FileUpload/common/utils.js
new file mode 100644
index 0000000..92c775a
--- /dev/null
+++ b/src/pages/ai/FileUpload/common/utils.js
@@ -0,0 +1,28 @@
+export function secondsToStr(temp) {
+ const years = Math.floor(temp / 31536000)
+ if (years) {
+ return years + ' 骞�' + numberEnding(years)
+ }
+ const days = Math.floor((temp %= 31536000) / 86400)
+ if (days) {
+ return days + ' 澶�' + numberEnding(days)
+ }
+ const hours = Math.floor((temp %= 86400) / 3600)
+ if (hours) {
+ return hours + ' 灏忔椂' + numberEnding(hours)
+ }
+ const minutes = Math.floor((temp %= 3600) / 60)
+ if (minutes) {
+ return minutes + ' 鍒�' + numberEnding(minutes)
+ }
+ const seconds = temp % 60
+ return seconds + ' 绉�' + numberEnding(seconds)
+ function numberEnding(number) {
+ // return (number > 1) ? 's' : ''
+ return ''
+ }
+}
+
+export function kebabCase(s) {
+ return s.replace(/[A-Z]/g, (m) => `-${m.toLowerCase()}`)
+}
diff --git a/src/pages/ai/FileUpload/drop.vue b/src/pages/ai/FileUpload/drop.vue
new file mode 100644
index 0000000..9c88666
--- /dev/null
+++ b/src/pages/ai/FileUpload/drop.vue
@@ -0,0 +1,64 @@
+<template>
+ <div class="uploader-drop" :class="dropClass" ref="drop" v-show="support">
+ <slot></slot>
+ </div>
+</template>
+
+<script>
+import { uploaderMixin, supportMixin } from './common/mixins'
+
+const COMPONENT_NAME = 'uploader-drop'
+
+export default {
+ name: COMPONENT_NAME,
+ mixins: [uploaderMixin, supportMixin],
+ data() {
+ return {
+ dropClass: ''
+ }
+ },
+ methods: {
+ onDragEnter() {
+ this.dropClass = 'uploader-dragover'
+ },
+ onDragLeave() {
+ this.dropClass = ''
+ },
+ onDrop() {
+ this.dropClass = 'uploader-droped'
+ }
+ },
+ mounted() {
+ this.$nextTick(() => {
+ const dropEle = this.$refs.drop
+ const uploader = this.uploader.uploader
+ uploader.assignDrop(dropEle)
+ uploader.on('dragenter', this.onDragEnter)
+ uploader.on('dragleave', this.onDragLeave)
+ uploader.on('drop', this.onDrop)
+ })
+ },
+ beforeDestroy() {
+ const dropEle = this.$refs.drop
+ const uploader = this.uploader.uploader
+ uploader.off('dragenter', this.onDragEnter)
+ uploader.off('dragleave', this.onDragLeave)
+ uploader.off('drop', this.onDrop)
+ uploader.unAssignDrop(dropEle)
+ }
+}
+</script>
+
+<style>
+.uploader-drop {
+ position: relative;
+ padding: 10px;
+ overflow: hidden;
+ border: 1px dashed #ccc;
+ background-color: #f5f5f5;
+}
+.uploader-dragover {
+ border-color: #999;
+ background-color: #f7f7f7;
+}
+</style>
diff --git a/src/pages/ai/FileUpload/file.vue b/src/pages/ai/FileUpload/file.vue
new file mode 100644
index 0000000..ddd30c8
--- /dev/null
+++ b/src/pages/ai/FileUpload/file.vue
@@ -0,0 +1,469 @@
+<template>
+ <div class="uploader-file" :status="status">
+ <slot
+ :file="file"
+ :list="list"
+ :status="status"
+ :paused="paused"
+ :error="error"
+ :response="response"
+ :average-speed="averageSpeed"
+ :formated-average-speed="formatedAverageSpeed"
+ :current-speed="currentSpeed"
+ :is-complete="isComplete"
+ :is-uploading="isUploading"
+ :size="size"
+ :formated-size="formatedSize"
+ :uploaded-size="uploadedSize"
+ :progress="progress"
+ :progress-style="progressStyle"
+ :progressing-class="progressingClass"
+ :time-remaining="timeRemaining"
+ :formated-time-remaining="formatedTimeRemaining"
+ :type="type"
+ :extension="extension"
+ :file-category="fileCategory"
+ >
+ <div
+ class="uploader-file-progress"
+ :class="progressingClass"
+ :style="progressStyle"
+ ></div>
+ <div class="uploader-file-info">
+ <div class="uploader-file-name">
+ <i class="uploader-file-icon" :icon="fileCategory"></i>
+ {{ file.name }}
+ </div>
+ <div class="uploader-file-size">{{ formatedSize }}</div>
+ <div class="uploader-file-meta"></div>
+ <div class="uploader-file-status">
+ <span v-show="status !== 'uploading'">{{ statusText }}</span>
+ <span v-show="status === 'uploading'">
+ <span>{{ progressStyle.progress }}</span>
+ <em>{{ formatedAverageSpeed }}</em>
+
+ <i> {{ formatedTimeRemaining }}</i>
+ </span>
+ </div>
+ <div class="uploader-file-actions">
+ <span class="uploader-file-pause" @click="pause"></span>
+ <span class="uploader-file-resume" @click="resume">锔�</span>
+ <span class="uploader-file-retry" @click="retry"></span>
+ <span class="uploader-file-remove" @click="remove"></span>
+ </div>
+ </div>
+ </slot>
+ </div>
+</template>
+
+<script>
+import Uploader from "simple-uploader.js";
+import events from "./common/file-events";
+import { secondsToStr } from "./common/utils";
+
+const COMPONENT_NAME = "uploader-file";
+
+export default {
+ name: COMPONENT_NAME,
+ props: {
+ file: {
+ type: Object,
+ default() {
+ return {};
+ },
+ },
+ list: {
+ type: Boolean,
+ default: false,
+ },
+ },
+ data() {
+ return {
+ response: null,
+ paused: false,
+ error: false,
+ averageSpeed: 0,
+ currentSpeed: 0,
+ isComplete: false,
+ isUploading: false,
+ size: 0,
+ formatedSize: "",
+ uploadedSize: 0,
+ progress: 0,
+ timeRemaining: 0,
+ type: "",
+ extension: "",
+ progressingClass: "",
+ };
+ },
+ computed: {
+ fileCategory() {
+ const extension = this.extension;
+ const isFolder = this.file.isFolder;
+ let type = isFolder ? "folder" : "unknown";
+ const categoryMap = this.file.uploader.opts.categoryMap;
+ const typeMap = categoryMap || {
+ image: ["gif", "jpg", "jpeg", "png", "bmp", "webp"],
+ video: ["mp4", "m3u8", "rmvb", "avi", "swf", "3gp", "mkv", "flv"],
+ audio: ["mp3", "wav", "wma", "ogg", "aac", "flac"],
+ document: [
+ "doc",
+ "txt",
+ "docx",
+ "pages",
+ "epub",
+ "pdf",
+ "numbers",
+ "csv",
+ "xls",
+ "xlsx",
+ "keynote",
+ "ppt",
+ "pptx",
+ ],
+ };
+ Object.keys(typeMap).forEach((_type) => {
+ const extensions = typeMap[_type];
+ if (extensions.indexOf(extension) > -1) {
+ type = _type;
+ }
+ });
+ return type;
+ },
+ progressStyle() {
+ const progress = Math.floor(this.progress * 100);
+ const style = `translateX(${Math.floor(progress - 100)}%)`;
+ return {
+ progress: `${progress}%`,
+ webkitTransform: style,
+ mozTransform: style,
+ msTransform: style,
+ transform: style,
+ };
+ },
+ formatedAverageSpeed() {
+ return `${Uploader.utils.formatSize(this.averageSpeed)} / s`;
+ },
+ status() {
+ const isUploading = this.isUploading;
+ const isComplete = this.isComplete;
+ const isError = this.error;
+ const paused = this.paused;
+ if (isComplete) {
+ return "success";
+ } else if (isError) {
+ return "error";
+ } else if (isUploading) {
+ return "uploading";
+ } else if (paused) {
+ return "paused";
+ } else {
+ return "waiting";
+ }
+ },
+ statusText() {
+ const status = this.status;
+ const fileStatusText = this.file.uploader.fileStatusText;
+ let txt = status;
+ if (typeof fileStatusText === "function") {
+ txt = fileStatusText(status, this.response);
+ } else {
+ txt = fileStatusText[status];
+ }
+ return txt || status;
+ },
+ formatedTimeRemaining() {
+ const timeRemaining = this.timeRemaining;
+ const file = this.file;
+ if (timeRemaining === Number.POSITIVE_INFINITY || timeRemaining === 0) {
+ return "";
+ }
+ let parsedTimeRemaining = secondsToStr(timeRemaining);
+ const parseTimeRemaining = file.uploader.opts.parseTimeRemaining;
+ if (parseTimeRemaining) {
+ parsedTimeRemaining = parseTimeRemaining(
+ timeRemaining,
+ parsedTimeRemaining
+ );
+ }
+ return parsedTimeRemaining;
+ },
+ },
+ watch: {
+ status(newStatus, oldStatus) {
+ if (oldStatus && newStatus === "uploading" && oldStatus !== "uploading") {
+ this.tid = setTimeout(() => {
+ this.progressingClass = "uploader-file-progressing";
+ }, 200);
+ } else {
+ clearTimeout(this.tid);
+ this.progressingClass = "";
+ }
+ },
+ },
+ methods: {
+ _actionCheck() {
+ this.paused = this.file.paused;
+ this.error = this.file.error;
+ this.isUploading = this.file.isUploading();
+ },
+ pause() {
+ this.file.pause();
+ this._actionCheck();
+ this._fileProgress();
+ },
+ resume() {
+ this.file.resume();
+ this._actionCheck();
+ },
+ remove() {
+ this.file.cancel();
+ },
+ retry() {
+ this.file.retry();
+ this._actionCheck();
+ },
+ processResponse(message) {
+ let res = message;
+ try {
+ res = JSON.parse(message);
+ } catch (e) {}
+ this.response = res;
+ },
+ fileEventsHandler(event, args) {
+ const rootFile = args[0];
+ const file = args[1];
+ const target = this.list ? rootFile : file;
+ if (this.file === target) {
+ if (this.list && event === "fileSuccess") {
+ this.processResponse(args[2]);
+ return;
+ }
+ this[`_${event}`].apply(this, args);
+ }
+ },
+ _fileProgress() {
+ this.progress = this.file.progress();
+ this.averageSpeed = this.file.averageSpeed;
+ this.currentSpeed = this.file.currentSpeed;
+ this.timeRemaining = this.file.timeRemaining();
+ this.uploadedSize = this.file.sizeUploaded();
+ this._actionCheck();
+ },
+ _fileSuccess(rootFile, file, message) {
+ if (rootFile) {
+ this.processResponse(message);
+ }
+ this._fileProgress();
+ this.error = false;
+ this.isComplete = true;
+ this.isUploading = false;
+ },
+ _fileComplete() {
+ this._fileSuccess();
+ },
+ _fileError(rootFile, file, message) {
+ this._fileProgress();
+ this.processResponse(message);
+ this.error = true;
+ this.isComplete = false;
+ this.isUploading = false;
+ },
+ },
+ mounted() {
+ const staticProps = ["paused", "error", "averageSpeed", "currentSpeed"];
+ const fnProps = [
+ "isComplete",
+ "isUploading",
+ {
+ key: "size",
+ fn: "getSize",
+ },
+ {
+ key: "formatedSize",
+ fn: "getFormatSize",
+ },
+ {
+ key: "uploadedSize",
+ fn: "sizeUploaded",
+ },
+ "progress",
+ "timeRemaining",
+ {
+ key: "type",
+ fn: "getType",
+ },
+ {
+ key: "extension",
+ fn: "getExtension",
+ },
+ ];
+ staticProps.forEach((prop) => {
+ this[prop] = this.file[prop];
+ });
+ fnProps.forEach((fnProp) => {
+ if (typeof fnProp === "string") {
+ this[fnProp] = this.file[fnProp]();
+ } else {
+ this[fnProp.key] = this.file[fnProp.fn]();
+ }
+ });
+
+ const handlers = (this._handlers = {});
+ const eventHandler = (event) => {
+ handlers[event] = (...args) => {
+ this.fileEventsHandler(event, args);
+ };
+ return handlers[event];
+ };
+ events.forEach((event) => {
+ this.file.uploader.on(event, eventHandler(event));
+ });
+ },
+ destroyed() {
+ events.forEach((event) => {
+ this.file.uploader.off(event, this._handlers[event]);
+ });
+ this._handlers = null;
+ },
+};
+</script>
+
+<style>
+.uploader-file {
+ position: relative;
+ height: 49px;
+ line-height: 49px;
+ overflow: hidden;
+}
+.uploader-file[status="waiting"] .uploader-file-pause,
+.uploader-file[status="uploading"] .uploader-file-pause {
+ display: block;
+}
+.uploader-file[status="paused"] .uploader-file-resume {
+ display: block;
+}
+.uploader-file[status="error"] .uploader-file-retry {
+ display: block;
+}
+.uploader-file[status="success"] .uploader-file-remove {
+ display: none;
+}
+.uploader-file[status="error"] .uploader-file-progress {
+ background: #ffe0e0;
+}
+.uploader-file-progress {
+ position: absolute;
+ width: 100%;
+ height: 4px;
+ border-radius: 4px;
+ background: #1dd4ec;
+ transform: translateX(-100%);
+}
+.uploader-file-progressing {
+ transition: all 0.4s linear;
+}
+.uploader-file-info {
+ position: relative;
+ z-index: 1;
+ height: 100%;
+ overflow: hidden;
+ font-size: 13px;
+}
+.uploader-file-info:hover {
+ background-color: rgba(240, 240, 240, 0.2);
+}
+.uploader-file-info i,
+.uploader-file-info em {
+ font-style: normal;
+}
+.uploader-file-name,
+.uploader-file-size,
+.uploader-file-meta,
+.uploader-file-status,
+.uploader-file-actions {
+ float: left;
+ position: relative;
+ height: 100%;
+}
+.uploader-file-name {
+ width: 50%;
+ overflow: hidden;
+ white-space: nowrap;
+ text-overflow: ellipsis;
+ text-indent: 14px;
+ text-align: left;
+}
+.uploader-file-icon {
+ width: 24px;
+ height: 24px;
+ display: inline-block;
+ vertical-align: top;
+ margin-top: 13px;
+ margin-right: 8px;
+}
+.uploader-file-icon::before {
+ content: "馃搵";
+ display: block;
+ /* height: 49px; */
+ font-size: 18px;
+ line-height: 26px;
+ text-indent: 0;
+}
+.uploader-file-icon[icon="folder"]::before {
+ content: "馃搨";
+}
+.uploader-file-icon[icon="image"]::before {
+ content: "馃寙";
+}
+.uploader-file-icon[icon="video"]::before {
+ content: "馃幀";
+}
+.uploader-file-icon[icon="audio"]::before {
+ content: "馃幍";
+}
+.uploader-file-icon[icon="document"]::before {
+ content: "馃搵";
+}
+.uploader-file-size {
+ width: 11%;
+ text-indent: 10px;
+}
+.uploader-file-meta {
+ width: 8%;
+}
+.uploader-file-status {
+ width: 24%;
+ text-indent: 20px;
+}
+.uploader-file-actions {
+ width: 6%;
+}
+.uploader-file-actions > span {
+ display: none;
+ float: left;
+ width: 16px;
+ height: 16px;
+ margin-top: 16px;
+ margin-right: 10px;
+ cursor: pointer;
+ background: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACgAAABkCAYAAAD0ZHJ6AAAAIGNIUk0AAHolAACAgwAA+f8AAIDpAAB1MAAA6mAAADqYAAAXb5JfxUYAAAAJcEhZcwAACxMAAAsTAQCanBgAAARkSURBVGje7ZnfS1NRHMAH4ptPkvQSuAdBkCxD8FUQJMEULUgzy1KyyPVQ4JMiiP4Bvg6EwUQQfMmwhwRDshwaKUjDVCgoSdDNHkzTJZ6+Z37Purve8+PeTb2TM/ggu+ew89l33x8H9BBCPG7GowXTJej3+wnDvEm0JuLC04+EYWftVAUv+fiCvDUdQR1BHUEdQR3BTIygvixoQS14XgTtthLVdpNWwXRLqvQ724LplFRtyrYF0yVpFLQrKRVMh6RZ0I6kkmCqklaCqpKZH0FX56Crq9jVfdDVk0RfFrSgFsxkQVmLcdKCVrKySCrryhPEyYShhzOcrFtG0EoilfHHk1CRU5rF6ZjNZhlVOW6RnMSVyyilKies4pO41diVy8wIujoHXV3FGdMHXTtJKLFYTLhZtq4vC1rwXApCZTIqgR6g1PBMCO9DL3bMMSqBHqDU8EyISDAHiGKvWwcCQG2KgjlAFCDAOhAAap0K5gKLphk8mqJgLrCIgoxRJ4J5wKpJ7gAoMkn5EBXBPGDVJHcAFJmkfIhQcAql1oBpTvTol9gG9pm4RHAKpdaAaU706JfYBvaZuJVgPQrt4sFlnOh5MC/p3lmJYD0K7eLBZZzoeTAv6d5ZnuAYHjpgEOnk5F0ufhG6v1ggOIaHDhhEOjl5l4tfhO4vthLcwAMrFNvLJO5vEwhu4IEViu1lEve3WQmyoihQFBzG/V0CQVYUBYqCw7i/SxTBcpsRbFeIYLnNCLZbCY5b5KAnxRwct8hBj9McZFVMW0ihRNBuFdMWUigRlFaxuQ9WWYjRMTiIe5z0wSoLMToGB3GPsA9aTZIJoB+nRgBnM1tzOkkmgH6cGgGczWzNpzqLx3n/aULJJgezeNw07oxQySbVywKjBOgFRnDs+VEsx8FlgVEC9AIjOPb8KJYjvSzoG7UW1IJaUAtqQS14toLNM5fN5APdwBJA8G83Pk/aK/rgzVvXzeQD3cASQPBvNz5P2ssTzAaGUIrHEO6zI5gNDKEUjyHcxxWkh4Ylcowwk1QQpIeGJXKMMJO0EgwqyjGCioJBJvDrxRMSuVOTJEXfbz1/bHwWtBL0yoQehK6RucgE+bGzanzulQh6E3IgQV+xpc8kcrfuSO7eTfJ3ZYmQw0Oy9azVKOk1C/bJ5D5F38YPeLfx0rjWJxHsS0SqsSYuxySjj5qO5Oj7xQWy2VBtFOwzCy6ryH3YfE3uh64Y1xckgstJPydEjkkeHv07Iy4Xaao15+KCWTBx6M/db+T9xivSErqaJDdzXI6yLRE8Vgg0coex/SPJvT0SbWu0KpZtbgSpCH3NRt7I5OxHkObc6heU+/M/J5vrpBFM5GBLqCQux14COXs5CNXK5OjPGm1tSMrJSOMNYQ4mVTGV/L6zTL7+DovkbFUxbSW0Wo05l8hJWsU+cRWfSh+Mt5Lb1ck/J1TvVsdDaR/MiEni+llsdZuZp62EViu+96bpNjNPWwmtVnzvFd5m9IVVC54x/wA7gNvqFG9vXQAAAABJRU5ErkJggg==")
+ no-repeat 0 0;
+}
+.uploader-file-actions > span:hover {
+ background-position-x: -21px;
+}
+.uploader-file-actions .uploader-file-pause {
+ background-position-y: 0;
+}
+.uploader-file-actions .uploader-file-resume {
+ background-position-y: -17px;
+}
+.uploader-file-actions .uploader-file-retry {
+ background-position-y: -53px;
+}
+.uploader-file-actions .uploader-file-remove {
+ display: block;
+ background-position-y: -34px;
+}
+</style>
diff --git a/src/pages/ai/FileUpload/files.vue b/src/pages/ai/FileUpload/files.vue
new file mode 100644
index 0000000..1380ba9
--- /dev/null
+++ b/src/pages/ai/FileUpload/files.vue
@@ -0,0 +1,42 @@
+<template>
+ <div class="uploader-files">
+ <slot :files="files">
+ <ul>
+ <li v-for="file in files" :key="file.id">
+ <uploader-file :file="file"></uploader-file>
+ </li>
+ </ul>
+ </slot>
+ </div>
+</template>
+
+<script>
+import { uploaderMixin } from './common/mixins'
+import UploaderFile from './file.vue'
+
+const COMPONENT_NAME = 'uploader-files'
+
+export default {
+ name: COMPONENT_NAME,
+ mixins: [uploaderMixin],
+ computed: {
+ files() {
+ return this.uploader.files
+ }
+ },
+ components: {
+ UploaderFile
+ }
+}
+</script>
+
+<style>
+.uploader-files {
+ position: relative;
+}
+.uploader-files > ul {
+ list-style: none;
+ margin: 0;
+ padding: 0;
+}
+</style>
diff --git a/src/pages/ai/FileUpload/index.vue b/src/pages/ai/FileUpload/index.vue
new file mode 100644
index 0000000..a7b8311
--- /dev/null
+++ b/src/pages/ai/FileUpload/index.vue
@@ -0,0 +1,306 @@
+<template>
+ <div class="file-uploader">
+ <uploader
+ v-if="single"
+ ref="uploader"
+ :options="options"
+ :file-status-text="statusText"
+ class="uploader-single"
+ :sourceType="sourceType"
+ @file-added="onFileAdded"
+ @complete="onComplete"
+ >
+ <div class="up-bar" v-if="isDrag == true">
+ <div class="name">{{ fileName || uploadPlaceholder }}</div>
+ <uploader-btn slot="suffix" :attrs="attrs">
+ <el-tooltip :content="tipWords" placement="top" v-if="tip">
+ <div class="open-file-btn">
+ <span class="icon iconfont"></span>
+ </div>
+ </el-tooltip>
+ </uploader-btn>
+ </div>
+ <el-input
+ :placeholder="uploadPlaceholder"
+ v-if="isDrag == false"
+ size="small"
+ :readonly="true"
+ v-model="fileName"
+ >
+ <uploader-btn slot="suffix" :attrs="attrs">
+ <el-tooltip :content="tipWords" placement="top" v-if="tip">
+ <i
+ class="el-icon-upload2"
+ style="font-size: 18px; color: #0088ff"
+ ></i>
+ </el-tooltip>
+ <i
+ v-else
+ class="el-icon-upload2"
+ style="font-size: 18px; color: #0088ff"
+ ></i>
+ </uploader-btn>
+ </el-input>
+ <uploader-list />
+ </uploader>
+
+ <uploader
+ v-else
+ ref="uploader"
+ :options="options"
+ :file-status-text="statusText"
+ class="uploader-example"
+ @file-added="onFileAdded"
+ @file-complete="fileComplete"
+ @complete="onComplete"
+ @close="closeHandle"
+ >
+ <uploader-btn ref="button" :sourceType="sourceType">
+ <i class="el-icon-upload2" style="font-size: 18px; color: #0088ff"></i>
+ 涓婁紶
+ </uploader-btn>
+ <uploader-list />
+ </uploader>
+ </div>
+</template>
+
+<script>
+import uploader from "./uploader";
+import SparkMD5 from "spark-md5";
+import UploaderBtn from "./btn";
+import UploaderList from "./list";
+import UploaderDrop from "./drop";
+
+export default {
+ components: {
+ uploader,
+ UploaderBtn,
+ UploaderList,
+ UploaderDrop,
+ },
+ props: {
+ sourceType: {
+ type: Number,
+ },
+ tip: {
+ type: Boolean,
+ default: false,
+ },
+ tipWords: {
+ type: String,
+ default: "",
+ },
+ single: {
+ type: Boolean,
+ default: false,
+ },
+ uploadPlaceholder: {
+ type: String,
+ default: "",
+ },
+ isDrag: {
+ type: Boolean,
+ default: false,
+ },
+ url: {
+ type: String,
+ default: "/data/api-f/file/upload",
+ },
+ attrs: {
+ type: Object,
+ default() {
+ return {};
+ },
+ },
+ },
+ data() {
+ return {
+ fileName: "",shouldStop:false,
+ fileMd5: "",
+ statusText: {
+ success: "涓婁紶鎴愬姛",
+ error: "涓婁紶澶辫触",
+ uploading: "涓婁紶涓�",
+ paused: "鏆傚仠涓�",
+ waiting: "绛夊緟涓�",
+ },
+ };
+ },
+ computed: {
+ uploader() {
+ return this.$refs.uploader.uploader;
+ },
+ options() {
+ return {
+ target: this.url,
+ testChunks: true,
+ headers: {
+ Authorization:
+ sessionStorage.getItem("loginedInfo") &&
+ JSON.parse(sessionStorage.getItem("loginedInfo")).access_token,
+ },
+ };
+ },
+ },
+ methods: {
+ onFileAdded(file) {
+ // if (this.sourceType == 3) {
+ // if (
+ // !file.name.endsWith(".tar") ||
+ // !file.name.endsWith(".gz") ||
+ // !file.name.endsWith(".tar.gz")
+ // ) {
+ // this.shouldStop = true
+ // this.$notify.warning("浠呮敮鎸�.tar/.gz/.tar.gz涓夌鏍煎紡鏂囦欢");
+ // return
+ // }
+ // }
+ if (this.single) {
+ this.uploader.fileList = this.uploader.fileList.slice([-1]);
+ this.$emit("file-added");
+ }
+ this.computeMD5(file);
+ },
+ computeMD5(file) {
+ let fileReader = new FileReader();
+ let time = new Date().getTime();
+ let blobSlice =
+ File.prototype.slice ||
+ File.prototype.mozSlice ||
+ File.prototype.webkitSlice;
+ let currentChunk = 0;
+ const chunkSize = 10 * 1024 * 1000;
+ let chunks = Math.ceil(file.size / chunkSize);
+ let spark = new SparkMD5.ArrayBuffer();
+ // 鏂囦欢鐘舵�佽涓�"璁$畻MD5"
+ this.statusText.paused = "鍑嗗涓婁紶,姝e湪妫�鏌ユ枃浠�";
+ file.pause();
+ loadNext();
+ fileReader.onload = (e) => {
+ spark.append(e.target.result);
+ if (currentChunk < chunks) {
+ currentChunk++;
+ loadNext();
+ } else {
+ let md5 = spark.end();
+ this.computeMD5Success(md5, file);
+ this.fileName = file.name;
+ this.fileMd5 = md5;
+ }
+ };
+ fileReader.onerror = function () {
+ this.error(`鏂囦欢${file.name}璇诲彇鍑洪敊锛岃妫�鏌ヨ鏂囦欢`);
+ file.cancel();
+ };
+ function loadNext() {
+ let start = currentChunk * chunkSize;
+ let end =
+ start + chunkSize >= file.size ? file.size : start + chunkSize;
+ fileReader.readAsArrayBuffer(blobSlice.call(file.file, start, end));
+ }
+ },
+ computeMD5Success(md5, file) {
+ //灏嗚嚜瀹氫箟鍙傛暟鐩存帴鍔犺浇uploader瀹炰緥鐨刼pts涓�
+ if (location.href.indexOf("dataStack") >= 0) {
+ Object.assign(this.uploader.opts, {
+ query: {
+ stackId: this.DataStackPool.selectedDir.id,
+ // ...this.params,
+ },
+ });
+ }
+ file.uniqueIdentifier = md5;
+ file.resume();
+ this.statusText.paused = "鏆傚仠涓�";
+ },
+ onComplete() {
+ if (this.shouldStop) {
+ return
+ }
+ this.$emit("complete", {
+ filename: this.fileName,
+ identifier: this.fileMd5,
+ });
+ },
+ fileComplete() {},
+ closeHandle() {
+ this.$emit("close");
+ },
+ },
+ mounted() {
+ this.isDrag;
+ this.$nextTick(() => {
+ window.uploader = this.$refs.uploader.uploader;
+ });
+ },
+};
+</script>
+
+<style lang="scss">
+.file-uploader {
+ .el-input__suffix,
+ .el-input__suffix-inner {
+ outline: none !important;
+ }
+ .el-tooltip.focusing {
+ outline: none;
+ }
+ .uploader-example {
+ width: 99%;
+ // padding: 15px;
+ // margin: 40px auto 0;
+ font-size: 12px;
+ // box-shadow: 0 0 10px rgba(0, 0, 0, 0.4);
+ background-color: #fff;
+ }
+ .uploader-example .uploader-btn {
+ position: relative;
+ display: none;
+ // float: right;
+ // top: -45px;
+ }
+ .uploader-example .uploader-list {
+ max-height: 440px;
+ overflow: auto;
+ overflow-x: hidden;
+ overflow-y: auto;
+ }
+ .uploader-single {
+ position: unset;
+ .close {
+ display: none;
+ }
+ .uploader-btn {
+ border: 0px;
+ }
+ .uploader-file {
+ // height: 2px;
+ .uploader-file-progress {
+ // background: #3d68e1;
+ }
+ .uploader-file-info {
+ // display: none;
+ }
+ }
+
+ .up-bar {
+ height: 30px;
+ background: #f2f2f7;
+ border-radius: 2px;
+ display: flex;
+ align-items: center;
+ justify-content: space-between;
+ box-sizing: border-box;
+ padding: 0 20px;
+ .iconfont {
+ font-size: 16px;
+ color: #333;
+ }
+ .name {
+ color: #bdbdbd;
+ font-size: 14px;
+ }
+ }
+ }
+}
+</style>>
diff --git a/src/pages/ai/FileUpload/list.vue b/src/pages/ai/FileUpload/list.vue
new file mode 100644
index 0000000..9951595
--- /dev/null
+++ b/src/pages/ai/FileUpload/list.vue
@@ -0,0 +1,43 @@
+<template>
+ <div class="uploader-list">
+ <slot :file-list="fileList">
+ <ul>
+ <li v-for="file in fileList" :key="file.id">
+ <uploader-file :file="file" :list="true"></uploader-file>
+ </li>
+ </ul>
+ </slot>
+ </div>
+</template>
+
+<script>
+import { uploaderMixin } from './common/mixins'
+import UploaderFile from './file.vue'
+
+const COMPONENT_NAME = 'uploader-list'
+
+export default {
+ name: COMPONENT_NAME,
+ mixins: [uploaderMixin],
+ computed: {
+ fileList() {
+ return this.uploader.fileList
+ }
+ },
+ components: {
+ UploaderFile
+ }
+}
+</script>
+
+<style>
+.uploader-list {
+ position: relative; margin-top: 12px;
+
+}
+.uploader-list > ul {
+ list-style: none;
+ margin: 0;
+ padding: 0;
+}
+</style>
diff --git a/src/pages/ai/FileUpload/unsupport.vue b/src/pages/ai/FileUpload/unsupport.vue
new file mode 100644
index 0000000..59626ee
--- /dev/null
+++ b/src/pages/ai/FileUpload/unsupport.vue
@@ -0,0 +1,30 @@
+<template>
+ <div class="uploader-unsupport" v-show="!support">
+ <slot>
+ <p>
+ Your browser, unfortunately, is not supported by Uploader.js. The library requires support for
+ <a href="http://www.w3.org/TR/FileAPI/">the HTML5 File API</a> along with
+ <a href="http://www.w3.org/TR/FileAPI/#normalization-of-params">file slicing</a>.
+ </p>
+ </slot>
+ </div>
+</template>
+
+<script>
+import { uploaderMixin, supportMixin } from './common/mixins'
+
+const COMPONENT_NAME = 'uploader-unsupport'
+
+export default {
+ name: COMPONENT_NAME,
+ mixins: [uploaderMixin, supportMixin]
+}
+</script>
+
+<style>
+.uploader-unsupport {
+ position: relative;
+ z-index: 10;
+ overflow: hidden;
+}
+</style>
diff --git a/src/pages/ai/FileUpload/uploader.vue b/src/pages/ai/FileUpload/uploader.vue
new file mode 100644
index 0000000..69705de
--- /dev/null
+++ b/src/pages/ai/FileUpload/uploader.vue
@@ -0,0 +1,189 @@
+<template>
+ <div class="uploader">
+ <!-- <div class="close" @click="closeHandle">x</div> -->
+ <slot :files="files" :file-list="fileList" :started="started">
+ <uploader-unsupport></uploader-unsupport>
+ <UploaderDrop>
+ <p>鎷栧姩鏂囦欢鍒拌鍖哄煙涓婁紶</p>
+
+ <uploader-btn >閫夋嫨鏂囦欢</uploader-btn>
+ <uploader-btn :directory="true" >閫夋嫨鏂囦欢澶�</uploader-btn>
+ </UploaderDrop>
+ <uploader-list></uploader-list>
+ </slot>
+ </div>
+</template>
+
+<script>
+import Uploader from 'simple-uploader.js'
+import { kebabCase } from './common/utils'
+import UploaderBtn from './btn.vue'
+import UploaderDrop from './drop.vue'
+import UploaderUnsupport from './unsupport.vue'
+import UploaderList from './list.vue'
+
+const COMPONENT_NAME = 'uploader'
+const FILE_ADDED_EVENT = 'fileAdded'
+const FILES_ADDED_EVENT = 'filesAdded'
+const UPLOAD_START_EVENT = 'uploadStart'
+
+export default {
+ name: COMPONENT_NAME,
+ provide() {
+ return {
+ uploader: this
+ }
+ },
+ props: {
+ attrs: {
+ type: Object,
+ default() {
+ return {}
+ }
+ },
+ sourceType: {
+ type: Number,
+ },
+ options: {
+ type: Object,
+ default() {
+ return {}
+ }
+ },
+ autoStart: {
+ type: Boolean,
+ default: true
+ },
+ fileStatusText: {
+ type: [Object, Function],
+ default() {
+ return {
+ success: 'success',
+ error: 'error',
+ uploading: 'uploading',
+ paused: 'paused',
+ waiting: 'waiting'
+ }
+ }
+ }
+ },
+ data() {
+ return {
+ started: false,
+ files: [],
+ fileList: []
+ }
+ },
+ methods: {
+ uploadStart() {
+ this.started = true
+ },
+ fileAdded(file) {
+ this.$emit(kebabCase(FILE_ADDED_EVENT), file)
+ if (file.ignored) {
+ // is ignored, filter it
+ return false
+ }
+ },
+ filesAdded(files, fileList) {
+ if (this.sourceType == 3 && files[0]) {
+ if (
+ !files[0].name.endsWith(".tar") ||
+ !files[0].name.endsWith(".gz") ||
+ !files[0].name.endsWith(".tar.gz")
+ ) {
+ this.shouldStop = true
+ return
+ }
+ }
+ this.$emit(kebabCase(FILES_ADDED_EVENT), files, fileList)
+ if (files.ignored || fileList.ignored) {
+ // is ignored, filter it
+ return false
+ }
+ },
+ fileRemoved(file) {
+ this.files = this.uploader.files
+ this.fileList = this.uploader.fileList
+ },
+ filesSubmitted(files, fileList) {
+ if (this.sourceType == 3&& files[0]) {
+ if (
+ !files[0].name.endsWith(".tar") ||
+ !files[0].name.endsWith(".gz") ||
+ !files[0].name.endsWith(".tar.gz")
+ ) {
+ this.shouldStop = true
+ return
+ }
+ }
+ this.files = this.uploader.files
+ this.fileList = this.uploader.fileList
+ if (this.autoStart) {
+ this.uploader.upload()
+ }
+ },
+ allEvent(...args) {
+ const name = args[0]
+ const EVENTSMAP = {
+ [FILE_ADDED_EVENT]: true,
+ [FILES_ADDED_EVENT]: true,
+ [UPLOAD_START_EVENT]: 'uploadStart'
+ }
+ const handler = EVENTSMAP[name]
+ if (handler) {
+ if (handler === true) {
+ return
+ }
+ this[handler].apply(this, args.slice(1))
+ }
+ args[0] = kebabCase(name)
+ this.$emit.apply(this, args)
+ },
+ closeHandle() {
+ this.$emit("close")
+ }
+ },
+ created() {
+ // this.bindUploader();
+ this.options.initialPaused = !this.autoStart
+ const uploader = new Uploader(this.options)
+ this.uploader = uploader
+ this.uploader.fileStatusText = this.fileStatusText
+ uploader.on('catchAll', this.allEvent)
+ uploader.on(FILE_ADDED_EVENT, this.fileAdded)
+ uploader.on(FILES_ADDED_EVENT, this.filesAdded)
+ uploader.on('fileRemoved', this.fileRemoved)
+ uploader.on('filesSubmitted', this.filesSubmitted)
+ },
+ mounted() {
+ },
+ destroyed() {
+ const uploader = this.uploader
+ uploader.off('catchAll', this.allEvent)
+ uploader.off(FILE_ADDED_EVENT, this.fileAdded)
+ uploader.off(FILES_ADDED_EVENT, this.filesAdded)
+ uploader.off('fileRemoved', this.fileRemoved)
+ uploader.off('filesSubmitted', this.filesSubmitted)
+ this.uploader = null
+ },
+ components: {
+ UploaderBtn,
+ UploaderDrop,
+ UploaderUnsupport,
+ UploaderList
+ }
+}
+</script>
+
+<style lang="scss">
+.uploader {
+ .close {
+ position: absolute;
+ right: 5px;
+ top: 3px;
+ cursor: pointer;
+ }
+}
+
+</style>
diff --git a/src/pages/ai/index/App.vue b/src/pages/ai/index/App.vue
index 13549e1..68b8825 100644
--- a/src/pages/ai/index/App.vue
+++ b/src/pages/ai/index/App.vue
@@ -7,568 +7,390 @@
<div class="inner-bar"></div>
</div>
</div>
- <!-- 瓒呯骇绠$悊鍛樺彲瑙� -->
<div class="super">
- <div class="left-box">
- <!-- <div class="title">
- <label>绠楁硶搴�</label>
- </div>-->
- <el-tabs
- v-model="activeName"
- type="border-card"
- @tab-click="handleTabClick"
- style="height: calc(100% - 20px)"
- >
- <el-tab-pane label="宸叉縺娲�" name="myAlgorithm">
- <div class="width-new-line task-list" v-show="activeName === 'myAlgorithm'">
- <p class="src-title">绠楁硶杞欢</p>
- <div class="flex-list">
- <div class="wrap-box" v-for="item in installedList" :key="item.id">
- <div class="list-choose-item-left">
- <div class="list-complete-item-handle">
- <div
- class="svg-wrap"
- :class="{ willUpGrade: item.isUpgrade }"
- v-loading="item.upgradeLoading"
- :element-loading-text="item.progressMsg"
- element-loading-background="rgba(0,0,0,.8)"
- >
- <!-- <i class="iconfont iconupdate" v-if="item.isUpgrade"></i> -->
- <img class="update-icon" v-if="item.isUpgrade" src="../../../assets/img/鏇存柊鎻愮ず.png" alt="">
- <div class="mask" v-if="!item.isDefault || item.isUpgrade">
- <div class="left-top">
- <div>褰撳墠鐗堟湰:{{ item.version }}</div>
- <div v-if="item.remoteVersion">鏈�鏂扮増鏈�:{{ item.remoteVersion }}</div>
- </div>
- <div class="info-onmask" @click="checkDetail(item, 'active')">鏌ョ湅璇︽儏</div>
- <div class="mask-btn">
- <el-button
- @click="unLoadSdk(item)"
- type="primary"
- size="small"
- class="bot-btn"
- >鍗歌浇</el-button>
- <el-button
- v-if="item.isUpgrade"
- @click="donwload(item, 0)"
- type="warning"
- size="small"
- class="bot-btn"
- >鍗囩骇</el-button>
- </div>
- </div>
- <img
- v-if="item.iconBlob"
- class="baseImg"
- :src="
- item.iconBlob.indexOf(',') > 0
- ? item.iconBlob
- : `data:image/png;base64,${item.iconBlob}`
- "
- alt
- />
- <img v-else class="baseImg" :src="item.icon" alt />
- </div>
- <div class="alg-name">
- <div style="padding: 0px 10px 0px 10px">
- <span v-if="!item.isEdit">
- {{
- item.sdk_name
- }}
- </span>
-
- <el-input
- size="small"
- v-model="item.sdk_name"
- v-if="item.isEdit"
- v-focus
- :maxlength="15"
- @blur="inputBlur(item)"
- ></el-input>
- </div>
- </div>
- </div>
- </div>
- </div>
- <div class="wrap-box" v-for="item in notInstalledList" :key="item.id">
- <div
- class="list-choose-item-left list-choose-item-left-uninstal"
- v-loading="downloading && downloadItem == item.id"
- >
- <div class="mask">
- <div class="left-top">
- <div v-if="item.installed">褰撳墠鐗堟湰:{{ item.version }}</div>
- <div v-if="item.remoteVersion">鏈�鏂扮増鏈�:{{ item.remoteVersion }}</div>
- </div>
- <div
- class="info-onmask"
- @click="checkDetail(item, 'activeNotInstall')"
- >鏌ョ湅璇︽儏</div>
- <div class="mask-btn">
- <el-button @click="donwload(item,1)" type="primary" class="bot-btn">瀹夎</el-button>
- </div>
- </div>
- <div class="click-download" title="涓嬭浇">
- <span class="iconfont iconxiazai1"></span>
- </div>
- <div class="list-complete-item-handle">
- <div
- class="svg-wrap"
- v-loading="
- item.installLoading || item.upgradeLoading
- "
- :element-loading-text="item.progressMsg"
- element-loading-background="rgba(0,0,0,.8)"
- >
- <img
- v-if="item.iconBlob"
- class="baseImg"
- :src="
- item.iconBlob.indexOf(',') > 0
- ? item.iconBlob
- : `data:image/png;base64,${item.iconBlob}`
- "
- alt
- />
- <img v-else class="baseImg" :src="item.icon" alt />
- </div>
- <div class="alg-name">
- <div style="padding: 0px 10px 0px 10px">
- <span class="list-choose-item-left-uninstal">
- {{
- item.sdk_name
- }}
- </span>
- </div>
- </div>
- </div>
- </div>
- </div>
- </div>
- <p class="src-title">搴旂敤杞欢</p>
- <div class="flex-list">
- <div class="wrap-box" v-for="item in installedApps" :key="item.id">
- <div class="list-choose-item-left">
- <div class="list-complete-item-handle">
- <div
- class="svg-wrap"
- :class="{ willUpGrade: item.isUpgrade }"
- v-loading="
- item.unloadLoading || item.upgradeLoading
- "
- :element-loading-text="item.progressMsg"
- element-loading-background="rgba(0,0,0,.8)"
- >
- <!-- <i class="iconfont iconupdate" v-if="item.isUpgrade"></i> -->
- <img class="update-icon" v-if="item.isUpgrade" src="../../../assets/img/鏇存柊鎻愮ず.png" alt="">
-
- <div class="mask">
- <div class="left-top">
- <div>褰撳墠鐗堟湰:{{ item.version }}</div>
- <div v-if="item.remoteVersion">鏈�鏂扮増鏈�:{{ item.remoteVersion }}</div>
- </div>
- <!-- v-if="!item.isDefault" -->
- <div class="info-onmask" @click="checkDetail(item,'active')">鏌ョ湅璇︽儏</div>
- <div class="mask-btn">
- <el-button
- v-show="!item.isDefault"
- @click="unLoad(item)"
- type="primary"
- size="small"
- class="bot-btn"
- >鍗歌浇</el-button>
- <el-button
- v-if="item.isUpgrade"
- @click="downloadApp(item, 'upgrade')"
- type="warning"
- size="small"
- class="bot-btn"
- >鍗囩骇</el-button>
- </div>
- </div>
- <img
- v-if="item.iconBlob"
- class="baseImg"
- :src="
- item.iconBlob.indexOf(',') > 0
- ? item.iconBlob
- : `data:image/png;base64,${item.iconBlob}`
- "
- alt
- />
- <img v-else class="baseImg" :src="item.icon" alt />
- </div>
- <div class="alg-name" style="color:grey;">
- <div style="padding: 0px 10px 0px 10px">
- <span v-if="!item.isEdit">{{ item.name }}</span>
- <el-input
- size="small"
- v-model="item.sdk_name"
- v-if="item.isEdit"
- v-focus
- :maxlength="15"
- @blur="inputBlur(item)"
- ></el-input>
- </div>
- </div>
- </div>
- </div>
- </div>
- <div class="wrap-box" v-for="item in storeApps" :key="item.id">
- <div class="list-choose-item-left">
- <div class="list-complete-item-handle uninstall">
- <div
- class="svg-wrap"
- v-loading="
- item.installLoading || item.upgradeLoading
- "
- :element-loading-text="item.progressMsg"
- element-loading-background="rgba(0,0,0,.8)"
- >
- <div class="mask">
- <div class="left-top">
- <div v-if="item.remoteVersion">鏈�鏂扮増鏈�:{{ item.remoteVersion }}</div>
- </div>
- <!-- v-if="!item.isDefault" -->
- <div class="info-onmask" @click="checkDetail(item,'activeNotInstall')">鏌ョ湅璇︽儏</div>
- <div class="mask-btn">
- <el-button
- @click="downloadApp(item)"
- type="primary"
- size="small"
- class="bot-btn"
- >瀹夎</el-button>
- </div>
- </div>
- <img
- v-if="item.iconBlob"
- class="baseImg"
- :src="
- item.iconBlob.indexOf(',') > 0
- ? item.iconBlob
- : `data:image/png;base64,${item.iconBlob}`
- "
- alt
- />
- <img v-else class="baseImg" :src="item.icon" alt />
- </div>
- <div class="alg-name">
- <div style="padding: 0px 10px 0px 10px">
- <span v-if="!item.isEdit">{{ item.name }}</span>
- <el-input
- size="small"
- v-model="item.name"
- v-if="item.isEdit"
- v-focus
- :maxlength="15"
- @blur="inputBlur(item)"
- ></el-input>
- </div>
- </div>
- </div>
- </div>
- </div>
- </div>
+ <div class="left-box" v-if="!inDetail">
+ <div class="nav-box">
+ <div class="nav-box-menu">
+ <div
+ v-for="(name, index) in menuArr"
+ :key="index"
+ class="menu-item"
+ :class="activeName == name ? 'menu-item-actiove' : ''"
+ @click="pickMenu(name)"
+ >
+ {{ name }}
+ <sup v-if="index == 3 && updateNum != 0">{{ updateNum }}</sup>
</div>
- </el-tab-pane>
+ </div>
+ <div class="nav-box-search">
+ <span class="icon iconfont all-scene"></span>
+ <el-input
+ placeholder="鎼滅储"
+ v-model="inputText"
+ @change="searchAll"
+ class="input-with-select"
+ >
+ <i class="el-icon-search" slot="prepend"></i>
+ <el-select
+ v-model="select"
+ slot="append"
+ placeholder="閫夋嫨鍦烘櫙"
+ :popper-append-to-body="false"
+ >
+ <el-option label="閾佽矾鍦烘櫙" value="1">
+ <span class="icon iconfont"></span>
+ <span>閾佽矾鍦烘櫙</span>
+ </el-option>
+ <el-option label="瀹夊叏鍦烘櫙" value="2">
+ <span class="icon iconfont"></span>
+ <span>瀹夊叏鍦烘櫙</span>
+ </el-option>
+ <el-option label="閫氱敤鍦烘櫙" value="3">
+ <span class="icon iconfont"></span>
+ <span>閫氱敤鍦烘櫙</span>
+ </el-option>
+ <el-option label="鏍″洯鍥尯" value="4">
+ <span class="icon iconfont"></span>
+ <span>鏍″洯鍥尯</span>
+ </el-option>
+ </el-select>
+ </el-input>
+ </div>
- <el-tab-pane
- label="绂荤嚎鍗囩骇/瀹夎"
- name="upgradeOrInstallation"
- v-if="isShow('algorithmManage:insOffLine')"
- >
- <div class="tab-content">
- <div class="action-bar">
- <file-uploader
- single
- tip
- tipWords="涓婁紶绠楁硶"
- uploadPlaceholder="涓婁紶瀹夎杞欢"
- url="/data/api-v/sdk/upload"
- @complete="onFileUpload"
- @file-added="onFileAdded"
+ <div class="bg-img-wrap">
+ <img src="/images/appCenter/Group-112.png" alt="" />
+ </div>
+ </div>
+ <div class="quick-path" v-if="showQuickPath">
+ <div class="left-items">
+ <div
+ class="quick-item"
+ v-for="(item, index) in recomandUpdateList"
+ :key="index"
+ @click="checkDetail(item, 'inactive', item.sdk_name)"
+ >
+ <div class="icon-img">
+ <span class="icon iconfont" v-if="item.isUpgrade"
+ ></span
+ >
+ <img
+ v-if="item.iconBlob"
+ :src="
+ item.iconBlob.indexOf(',') > 0
+ ? item.iconBlob
+ : `data:image/png;base64,${item.iconBlob}`
+ "
+ alt
/>
+ <img v-else :src="item.icon" alt />
+ </div>
+ <div class="desc">
+ <el-tooltip
+ :content="item.sdk_name || item.name"
+ effect="light"
+ >
+ <div class="desc-1">{{ item.sdk_name || item.name }}</div>
+ </el-tooltip>
+ <div class="desc-2">鐗堟湰 {{ item.version }}</div>
+ </div>
+ <div class="right-icon">
+ <el-tooltip effect="dark" content="涓嬭浇" placement="bottom">
+ <span class="icon iconfont"></span>
+ </el-tooltip>
</div>
</div>
- </el-tab-pane>
- <el-tab-pane label="搴旂敤涓績" name="algorithmMall" v-if="isShow('algorithmManage:buy')">
- <div class="tab-content">
- <div class="flex-title">
- <p class="src-title">绠楁硶杞欢</p>
- </div>
- <div class="store-list flex-list">
- <div class="wrap-box" v-for="item in unActivedSDKList" :key="item.id">
- <div class="list-choose-item-left">
- <div class="list-complete-item-handle">
- <div class="alg-icon svg-wrap">
- <!-- <div class="mask" @click="actSdkOrApp(item.id)">
- <span
- class="iconfont iconyunxiazai"
- style="
- color: #ff6a00;
- font-size: 20px;
- position: absolute;
- top: 45%;
- left: 45%;
- "
- ></span>
- </div>-->
- <div class="mask" v-if="!item.isDefault || item.isUpgrade">
- <div class="left-top">
- <div>褰撳墠鐗堟湰:{{ item.version }}</div>
- <div v-if="item.remoteVersion">鏈�鏂扮増鏈�:{{ item.remoteVersion }}</div>
- </div>
- <div class="info-onmask" @click="actSdkOrApp(item)">鏌ョ湅璇︽儏</div>
- <div class="mask-btn">
- <el-button
- @click="actSdkOrApp(item)"
- type="primary"
- size="small"
- class="bot-btn"
- >婵�娲�</el-button>
- </div>
- </div>
- <img
- v-if="item.iconBlob"
- class="baseImg"
- :src="
- item.iconBlob.indexOf(',') > 0
- ? item.iconBlob
- : `data:image/png;base64,${item.iconBlob}`
- "
- alt
- />
- <img v-else class="baseImg" :src="item.icon" alt />
- </div>
- <div class="alg-name">
- <div style="padding: 0px 10px 0px 10px">
- <span v-if="!item.isEdit">
- {{
- item.sdk_name
- }}
- </span>
- <el-input
- size="small"
- v-model="item.sdk_name"
- v-if="item.isEdit"
- v-focus
- :maxlength="15"
- @blur="inputBlur(item)"
- ></el-input>
- </div>
- </div>
- </div>
- </div>
- </div>
- </div>
- <p class="src-title">搴旂敤杞欢</p>
- <div class="app-list flex-list">
- <div v-if="!unActivedAppList.length" class="empty-tip">鏆傛棤鏁版嵁</div>
- <div class="wrap-box" v-for="item in unActivedAppList" :key="item.id">
- <div class="list-choose-item-left">
- <div class="list-complete-item-handle">
- <div class="alg-icon svg-wrap">
- <div class="mask" v-if="!item.isDefault || item.isUpgrade">
- <div class="left-top">
- <div>褰撳墠鐗堟湰:{{ item.version }}</div>
- <div v-if="item.remoteVersion">鏈�鏂扮増鏈�:{{ item.remoteVersion }}</div>
- </div>
- <div class="info-onmask" @click="actSdkOrApp(item,'app')">鏌ョ湅璇︽儏</div>
- <div class="mask-btn">
- <el-button
- @click="actSdkOrApp(item, 'app')"
- type="primary"
- size="small"
- class="bot-btn"
- >婵�娲�</el-button>
- </div>
- </div>
- <img
- v-if="item.iconBlob"
- class="baseImg"
- :src="
- item.iconBlob.indexOf(',') > 0
- ? item.iconBlob
- : `data:image/png;base64,${item.iconBlob}`
- "
- alt
- />
- <img v-else class="baseImg" :src="item.icon" alt />
- </div>
- <div class="alg-name">
- <div style="padding: 0px 10px 0px 10px">
- <span v-if="!item.isEdit">{{ item.name }}</span>
- <el-input
- size="small"
- v-model="item.name"
- v-if="item.isEdit"
- v-focus
- :maxlength="15"
- @blur="inputBlur(item)"
- ></el-input>
- </div>
- </div>
- </div>
- </div>
- </div>
- </div>
- </div>
- <!-- -->
- </el-tab-pane>
- <el-tab-pane name="update">
- <span slot="label">
- <el-badge class="update-badge" :value="updateNum" :hidden="updateNum==0">鏇存柊</el-badge>
- </span>
- <div class="task-list">
- <div class="flex-title">
- <p class="src-title">绠楁硶杞欢</p>
- <el-button @click="batchUpdate('sdk')" size="mini" type="primary">鏇存柊鍏ㄩ儴</el-button>
- </div>
- <div class="flex-list">
- <div
- v-if="hasNewVersionSdk.length==0"
- class="empty-tip"
- >{{errMsg?errMsg:"鏆傛棤鏁版嵁"}}</div>
- <div class="wrap-box" v-for="item in hasNewVersionSdk" :key="item.id">
- <div class="list-choose-item-left">
- <div class="list-complete-item-handle">
- <div
- class="svg-wrap"
- :class="{ willUpGrade: item.isUpgrade }"
- v-loading="item.upgradeLoading"
- :element-loading-text="item.progressMsg"
- element-loading-background="rgba(0,0,0,.8)"
- >
- <!-- <i class="iconfont iconupdate" v-if="item.isUpgrade"></i> -->
- <img class="update-icon" v-if="item.isUpgrade" src="../../../assets/img/鏇存柊鎻愮ず.png" alt="">
+ </div>
- <div class="mask" v-if="!item.isDefault || item.isUpgrade">
- <div class="left-top">
- <div>褰撳墠鐗堟湰:{{ item.version }}</div>
- <div v-if="item.remoteVersion">鏈�鏂扮増鏈�:{{ item.remoteVersion }}</div>
- </div>
- <div class="info-onmask" @click="checkDetail(item,'active')">鏌ョ湅璇︽儏</div>
- <div class="mask-btn">
- <el-button
- @click="unLoadSdk(item)"
- type="primary"
- size="small"
- class="bot-btn"
- >鍗歌浇</el-button>
- <el-button
- v-if="item.isUpgrade"
- @click="donwload(item, 0)"
- type="warning"
- size="small"
- class="bot-btn"
- >鍗囩骇</el-button>
- </div>
- </div>
- <img
- v-if="item.iconBlob"
- class="baseImg"
- :src="
- item.iconBlob.indexOf(',') > 0
- ? item.iconBlob
- : `data:image/png;base64,${item.iconBlob}`
- "
- alt
- />
- <img v-else class="baseImg" :src="item.icon" alt />
- </div>
- <div class="alg-name">
- <div style="padding: 0px 10px 0px 10px">
- <span v-if="!item.isEdit">
- {{
- item.sdk_name
- }}
- </span>
- </div>
- </div>
- </div>
- </div>
- </div>
- </div>
- <div class="flex-title">
- <p class="src-title">搴旂敤杞欢</p>
- <el-button @click="batchUpdate('app')" type="primary" size="mini">鏇存柊鍏ㄩ儴</el-button>
- </div>
- <div class="flex-list">
- <div v-if="!hasNewVersionApp.length" class="empty-tip">鏆傛棤鏁版嵁</div>
- <div class="wrap-box" v-for="item in hasNewVersionApp" :key="item.id">
- <div class="list-choose-item-left">
- <div class="list-complete-item-handle">
- <div
- class="svg-wrap"
- :class="{ willUpGrade: item.isUpgrade }"
- v-loading="
- item.unloadLoading || item.upgradeLoading
- "
- :element-loading-text="item.progressMsg"
- element-loading-background="rgba(0,0,0,.8)"
- >
- <!-- <i class="iconfont iconupdate" v-if="item.isUpgrade"></i> -->
- <img class="update-icon" v-if="item.isUpgrade" src="../../../assets/img/鏇存柊鎻愮ず.png" alt="">
+ <!-- <div class="down-all-btn">
+ <el-button plain size="small" @click="batchUpdate('both')" round
+ >鍏ㄩ儴鏇存柊</el-button
+ >
+ </div> -->
+ </div>
- <div class="mask">
- <div class="left-top">
- <div>褰撳墠鐗堟湰:{{ item.version }}</div>
- <div v-if="item.remoteVersion">鏈�鏂扮増鏈�:{{ item.remoteVersion }}</div>
- </div>
- <div class="info-onmask" @click="checkDetail(item,'active')">鏌ョ湅璇︽儏</div>
- <div class="mask-btn">
- <el-button
- v-if="!item.isDefault"
- @click="unLoad(item)"
- type="primary"
- size="small"
- class="bot-btn"
- >鍗歌浇</el-button>
- <el-button
- v-if="item.isUpgrade"
- @click="downloadApp(item, 'upgrade')"
- type="warning"
- size="small"
- class="bot-btn"
- >鍗囩骇</el-button>
- </div>
- </div>
- <img
- v-if="item.iconBlob"
- class="baseImg"
- :src="
- item.iconBlob.indexOf(',') > 0
- ? item.iconBlob
- : `data:image/png;base64,${item.iconBlob}`
- "
- alt
- />
- <img v-else class="baseImg" :src="item.icon" alt />
- </div>
- <div class="alg-name">
- <div style="padding: 0px 10px 0px 10px">
- <span v-if="!item.isEdit">{{ item.name }}</span>
- <el-input
- size="small"
- v-model="item.sdk_name"
- v-if="item.isEdit"
- v-focus
- :maxlength="15"
- @blur="inputBlur(item)"
- ></el-input>
- </div>
- </div>
- </div>
- </div>
+ <div class="main-content">
+ <!-- <div class="main-title">搴旂敤涓績</div> -->
+ <div class="tab-btns" v-if="activeName != '绂荤嚎鍗囩骇/瀹夎'">
+ <div class="group-left">
+ <div
+ class="tab"
+ @click="pickTab('sdk')"
+ :class="activeTab == 'sdk' ? 'tab-active' : ''"
+ >
+ 绠楁硶杞欢
+ </div>
+ <div
+ class="tab"
+ @click="pickTab('app')"
+ :class="activeTab == 'app' ? 'tab-active' : ''"
+ >
+ 搴旂敤杞欢
+ </div>
+ </div>
+
+ <div
+ class="batch-update"
+ v-if="activeName == '鏇存柊' && tempList.length"
+ >
+ <el-button
+ size="small"
+ type="primary"
+ round
+ @click="batchUpdate"
+ >鍏ㄩ儴鏇存柊</el-button
+ >
+ </div>
+ </div>
+ <div
+ class="front-page-items"
+ v-if="activeName != '绂荤嚎鍗囩骇/瀹夎'"
+ >
+ <div
+ class="front-page-item"
+ v-for="(item, index) in tempList"
+ :key="index"
+ @click="checkDetail(item, null, item.sdk_name)"
+ :class="{
+ disabled: activeName == '搴旂敤涓績' && !item.canUpOrIns,
+ }"
+ >
+ <div class="icon-img">
+ <span class="icon iconfont" v-if="item.isUpgrade"
+ ></span
+ >
+ <img
+ v-if="item.iconBlob"
+ :src="
+ item.iconBlob.indexOf(',') > 0
+ ? item.iconBlob
+ : `data:image/png;base64,${item.iconBlob}`
+ "
+ alt
+ />
+ <img v-else :src="item.icon" alt />
+ </div>
+ <div class="desc">
+ <el-tooltip
+ :content="item.sdk_name || item.name"
+ effect="light"
+ >
+ <div class="desc-1">{{ item.sdk_name || item.name }}</div>
+ </el-tooltip>
+ <div class="desc-2">鐗堟湰 {{ item.version }}</div>
+ </div>
+ <div class="right-btn">
+ <el-button
+ size="small"
+ type="primary"
+ class="other-btn"
+ round
+ @click="checkDetail(item, null, item.sdk_name)"
+ v-if="activeName == '搴旂敤涓績' && item.price > 0"
+ >婵�娲�</el-button
+ >
+ <el-button
+ size="small"
+ type="primary"
+ class="update-btn"
+ round
+ @click.stop="actived(item)"
+ v-if="activeName == '搴旂敤涓績' && item.price == 0"
+ >瀹夎</el-button
+ >
+ <el-button
+ size="small"
+ type="primary"
+ class="check-btn"
+ round
+ v-if="
+ activeName == '宸叉縺娲�' &&
+ ((activeTab == 'sdk' && !item.isUpgrade) ||
+ (activeTab == 'app' &&
+ !item.isUpgrade &&
+ !item.isDefault))
+ "
+ >鏌ョ湅</el-button
+ >
+ <el-button
+ size="small"
+ type="primary"
+ class="check-btn"
+ round
+ v-if="
+ activeName == '宸叉縺娲�' &&
+ activeTab == 'app' &&
+ item.isDefault &&
+ !item.isUpgrade
+ "
+ >鏌ョ湅</el-button
+ >
+ <el-button
+ size="small"
+ type="primary"
+ class="other-btn"
+ round
+ v-if="
+ activeName == '宸叉縺娲�' &&
+ activeTab == 'app' &&
+ item.isDefault &&
+ item.isUpgrade
+ "
+ >鍗囩骇</el-button
+ >
+ <el-button
+ size="small"
+ type="primary"
+ class="update-btn"
+ round
+ @click.stop="donwloadSDK(item)"
+ v-if="
+ (activeName == '鏇存柊' || activeName == '宸叉縺娲�') &&
+ activeTab == 'sdk' &&
+ item.isUpgrade &&
+ !item.upgradeLoading
+ "
+ >鏇存柊</el-button
+ >
+ <span
+ class="icon iconfont rocket-icon"
+ v-if="
+ activeName == '鏇存柊' &&
+ item.isUpgrade &&
+ item.upgradeLoading &&
+ rocketIf
+ "
+ ></span
+ >
+ <span
+ class="icon iconfont rocket-icon"
+ v-if="
+ activeName == '鏇存柊' &&
+ item.isUpgrade &&
+ item.upgradeLoading &&
+ !rocketIf
+ "
+ ></span
+ >
+ <el-button
+ size="small"
+ type="primary"
+ class="update-btn"
+ round
+ @click.stop="downloadApp(item, 'upgrade')"
+ v-if="
+ (activeName == '鏇存柊' || activeName == '宸叉縺娲�') &&
+ activeTab == 'app' &&
+ item.isUpgrade &&
+ !item.upgradeLoading
+ "
+ >鏇存柊</el-button
+ >
+
+ <div class="status">
+ {{ item.progressMsg }}
</div>
</div>
</div>
- </el-tab-pane>
- </el-tabs>
+
+ <div
+ class="front-page-item item-dimmed"
+ v-for="(item, index) in tempDarkList"
+ :key="index"
+ @click="checkDetail(item, 'activeNotInstall', item.sdk_name)"
+ >
+ <div class="icon-img">
+ <img
+ v-if="item.iconBlob"
+ :src="
+ item.iconBlob.indexOf(',') > 0
+ ? item.iconBlob
+ : `data:image/png;base64,${item.iconBlob}`
+ "
+ alt
+ />
+ <img v-else :src="item.icon" alt />
+ </div>
+ <div class="desc">
+ <el-tooltip
+ :content="item.sdk_name || item.name"
+ effect="light"
+ >
+ <div class="desc-1">{{ item.sdk_name || item.name }}</div>
+ </el-tooltip>
+ <div class="desc-2">鐗堟湰 {{ item.version }}</div>
+ </div>
+ <div class="right-btn">
+ <el-button
+ size="small"
+ type="primary"
+ class="other-btn"
+ round
+ v-if="activeTab == 'sdk' && !item.upgradeLoading"
+ @click.stop="donwloadSDK(item)"
+ >瀹夎</el-button
+ >
+ <el-button
+ size="small"
+ type="primary"
+ class="other-btn"
+ round
+ v-if="activeTab == 'app' && !item.upgradeLoading"
+ @click.stop="downloadApp(item)"
+ >瀹夎</el-button
+ >
+ <div class="spin-icon">
+ <span
+ class="icon iconfont anz-font"
+ v-if="item.upgradeLoading"
+ ></span
+ >
+ </div>
+ <div class="status">
+ {{ item.progressMsg }}
+ </div>
+ </div>
+ </div>
+ </div>
+
+ <div class="upload-pkg" v-if="activeName == '绂荤嚎鍗囩骇/瀹夎'">
+ <div class="upload-head">
+ <div class="left">
+ <span class="icon iconfont"></span>
+ <span class="txt">涓婁紶瀹夎杞欢</span>
+ </div>
+ </div>
+
+ <FileUploader
+ class="upload-demo"
+ single
+ tip
+ :sourceType="3"
+ :isDrag="true"
+ :attrs="{ accept: '.zip,.tar,.gz,.tar.gz' }"
+ tipWords="鐐瑰嚮涓婁紶"
+ uploadPlaceholder="绠楁硶杞欢"
+ url="/data/api-v/sdk/upload"
+ @complete="onFileUpload"
+ @file-added="onFileAdded"
+ />
+ </div>
+ </div>
</div>
+
+ <detailPage
+ :detailProductID="detailProductID"
+ :detailType="detailType"
+ :detailPrice="detailPrice"
+ :isSdk="isSdk"
+ v-if="inDetail"
+ @flushSdk="getAllSdk"
+ @flushApp="getAllApps"
+ @goback="goback"
+ ></detailPage>
</div>
</div>
</div>
+
<el-dialog
title="瀹夎鍖呬俊鎭�"
:visible.sync="installDialogVisible"
@@ -615,265 +437,6 @@
<el-button type="primary" @click="offlineInstall">瀹� 瑁�</el-button>
</div>
</el-dialog>
- <!-- <div class="dialog-content" v-if="productDetailVisible" > -->
- <el-dialog class="product-detail-dialog" :visible="productDetailVisible" @close="closeDial">
- <!-- <el-button-group> -->
- <div class="button-group" v-show="!backDisable||!forwardDisable">
- <el-button size="small" @click="backwards" :disabled="backDisable">
- <span><</span>
- </el-button>
- <!-- <el-button type="primary" size="small" icon="el-icon-arrow-left"></el-button> -->
- <el-button size="small" @click="forwards" :disabled="forwardDisable">></el-button>
- <!-- <el-button type="primary" size="small"><i class="el-icon-arrow-right el-icon--right"></i></el-button> -->
- </div>
- <!-- </el-button-group> -->
- <div class="dialog-title" slot="title">{{isSDKDialog?"绠楁硶璇︽儏":"搴旂敤璇︽儏"}}</div>
- <div class="dialog-content">
- <div class="box-top">
- <div class="top-left">
- <div class="banner">
- <el-carousel
- ref="carousel"
- :autoplay="false"
- indicator-position="none"
- :arrow="
- productDetail.pics !== undefined
- ? productDetail.pics.length > 1
- ? 'always'
- : 'never'
- : 'never'
- "
- @change="changeHandle"
- >
- <!-- :arrow="productDetail.pics.length > 1 ? 'always' : 'never'" -->
- <el-carousel-item v-for="(item, index) in productDetail.pics" :key="index">
- <div class="imgwrap">
- <img
- v-if="item.type != 'video'"
- :src="item.url"
- class="cursor-pointer"
- preview
- />
- <video v-if="item.type == 'video'" :src="item.url" controls></video>
- </div>
- </el-carousel-item>
- </el-carousel>
- </div>
- </div>
- <div class="top-right">
- <!-- <div class="title">{{curCheckTarget.sdk_name}}</div> -->
- <div class="summary">
- <div class="icon">
- <img
- v-if="productDetail.iconBlob"
- class="baseImg"
- :src="
- productDetail.iconBlob.indexOf(',') > 0
- ? productDetail.iconBlob
- : `data:image/png;base64,${productDetail.iconBlob}`
- "
- alt
- />
- </div>
- <div class="right-desc">
- <div class="name">
- <el-tooltip
- class
- effect="dark"
- :content="productDetail.productName"
- placement="right-start"
- >
- <span>{{ productDetail.productName }}</span>
- </el-tooltip>
- </div>
- <div class="tags">
- <el-tag type="info" size="small" color="#fff" v-if="!isSDKDialog">搴旂敤</el-tag>
- <el-tag type="info" size="small" color="#fff" v-if="isSDKDialog">绠楁硶</el-tag>
- </div>
- <div class="btns">
- <el-button
- size="small"
- type="warning"
- v-if="needToUpgradeInWin||productDetail.isUpgrade"
- @click="upgradeSDKinWin"
- >
- {{
- isUpgrading ? "鍗囩骇涓�.." : "鍗囩骇"
- }}
- </el-button>
- <el-button
- size="small"
- type="primary"
- v-if="isActive&&!isDefaultApp"
- @click="unloadSDKinWin"
- >鍗歌浇</el-button>
- <el-button
- size="small"
- type="primary"
- v-if="!isActive&&!showInstallNotActive"
- @click="showInputCode=!showInputCode"
- >婵�娲�</el-button>
- <el-button
- size="small"
- type="primary"
- v-if="!isActive&&showInstallNotActive"
- @click="downloadSdkInSide"
- >{{isUpgrading?"瀹夎涓�..":"瀹夎"}}</el-button>
- <el-button
- size="small"
- type="success"
- v-if="!isSDKDialog&&isActive"
- @click="openApp"
- >鎵撳紑</el-button>
- </div>
- </div>
- </div>
- <div class="jihuo-input" v-if="showInputCode">
- <el-input
- size="small"
- v-model="activeCode"
- placeholder="00000-00000-00000-00000-00000"
- @blur="getCodeDetail"
- ></el-input>
- <el-button type="primary" size="small" @click="actived">婵�娲�</el-button>
- <el-button type="primary" size="small" @click="cancelActivate">鍙栨秷</el-button>
- </div>
- <div class="product-intruduction">
- <div class="part-title" v-if="!showInputCode">绠�浠�</div>
- <div class="text">
- <div class="single-desc">
- <div>鐗堟湰锛�</div>
- <div>
- {{
- productDetail.productVersion === ""
- ? "鏆傛棤"
- : productDetail.productVersion
- }}
- </div>
- </div>
- <div class="single-desc">
- <div>姒傝堪锛�</div>
- <div>
- {{
- productDetail.description === ""
- ? "鏆傛棤"
- : productDetail.description
- }}
- </div>
- </div>
- <div class="single-desc">
- <div>璇﹁堪锛�</div>
- <div>
- {{
- productDetail.summary === ""
- ? "鏆傛棤"
- : productDetail.summary
- }}
- </div>
- </div>
- </div>
- </div>
- </div>
- </div>
- <div class="box-bottom">
- <div class="bot-left">
- <div class="part-title">{{ isSDKDialog ? "搴旂敤鍦烘櫙" : "鍔熻兘鐗圭偣" }}</div>
- <div class="list-zone">
- <div class="list-item" v-for="(item, index) in productDetail.funcInfo" :key="index">
- <el-tag
- type
- size="small"
- effect="dark"
- >{{ item.title === "" ? "鏆傛棤鏁版嵁" : item.title }}</el-tag>
- <div class="desc">
- {{
- item.desc === ""
- ? "鏆傛棤鏁版嵁"
- : item.desc
- }}
- </div>
- </div>
- </div>
- </div>
- <div class="bot-right">
- <div class="part-title">鎺ㄨ崘绠楁硶</div>
- <div class="item-zone">
- <div class="item" v-for="(item, index) in otherProducts" :key="index">
- <el-tag type="info" color="inherit" size="small">
- {{
- item.productTypeName === ""
- ? "鏆傛棤鏁版嵁"
- : item.productTypeName
- }}
- </el-tag>
- <div class="icon">
- <img
- v-if="item.iconBlob"
- class="baseImg"
- :src="
- item.iconBlob.indexOf(',') > 0
- ? item.iconBlob
- : `data:image/png;base64,${item.iconBlob}`
- "
- alt
- />
-
- <div class="icon-name">
- <el-tooltip
- class
- effect="dark"
- :content="item.name === '' ? '鏆傛棤鏁版嵁':item.name"
- placement="top-start"
- >
- <span>{{ item.name === "" ? "鏆傛棤鏁版嵁" : item.name }}</span>
- </el-tooltip>
- </div>
- </div>
- <div class="look-button">
- <el-button type="primary" size="mini" @click="checkInWindow(item)">鏌ョ湅</el-button>
- </div>
- </div>
- </div>
- </div>
- </div>
- </div>
- </el-dialog>
- <el-dialog
- :visible.sync="showActivateSuccess"
- title="婵�娲绘垚鍔燂紒"
- width="30%"
- class="active-Dial"
- :before-close="handleClose"
- >
- <div class="dialog-active">
- <ul class="desc">
- <li>
- <label>婵�娲荤爜:</label>
- <span>{{ activedSdkOrApp.activateCode }}</span>
- </li>
- <li>
- <label>浜у搧鍚嶇О:</label>
- <span>{{ activedSdkOrApp.productName }}</span>
- </li>
- <li>
- <label>閰嶇疆璇︽儏:</label>
- <span>{{ activedSdkOrApp.setting }}</span>
- </li>
- <li>
- <label>鏈嶅姟鍒版湡鏃�:</label>
- <span>{{ activedSdkOrApp.expireTime }}</span>
- </li>
- <li>
- <label>璁稿彲璇�:</label>
- <span>{{ activedSdkOrApp.licence }}</span>
- </li>
- </ul>
- <div class="text-right">
- <el-button type="primary" @click="checkMyAlgorith">纭畾</el-button>
- <p class="tip">鎻愮ず锛氳鍦ㄢ�滃凡婵�娲烩�濅腑鏌ョ湅骞跺畨瑁呯畻娉�</p>
- </div>
- </div>
- </el-dialog>
</div>
</template>
<script>
@@ -883,6 +446,7 @@
installSdk,
getInstallInfo,
removeSdk,
+ uploadSDK,
} from "./api";
import {
getApps,
@@ -894,39 +458,19 @@
getUnActivedApp,
actApp,
} from "@/api/app";
-
-import bus from "@/plugin/bus";
-import FileUploader from "@/components/subComponents/FileUpload/index";
+import { getUrlKey } from "@/api/utils";
+import FileUploader from "../FileUpload/index";
+import detailPage from "./detail";
export default {
name: "algorithmManage",
- props: {},
components: {
FileUploader,
+ detailPage,
},
computed: {
updateNum() {
return this.hasNewVersionApp.length + this.hasNewVersionSdk.length;
},
- // notInstalledList () {
- // return this.sdkList.filter(sdk => {
- // return sdk.installed === false;
- // });
- // },
- // installedList () {
- // return this.sdkList.filter(sdk => {
- // return sdk.installed === true && !sdk.isUpgrade;
- // });
- // },
- // ungradeList () {
- // // 鍗囩骇澶勭悊浼氬鑷撮噸澶嶇殑key,闇�瑕佷慨鏀�
- // let arr = this.sdkList.filter(sdk => {
- // return sdk.isUpgrade === true;
- // });
- // arr.forEach(sdk => {
- // sdk.upgradeLoading = false;
- // });
- // return arr;
- // },
isAdmin() {
if (
sessionStorage.getItem("userInfo") &&
@@ -935,40 +479,46 @@
let loginName = JSON.parse(sessionStorage.getItem("userInfo")).username;
return loginName === "superadmin" || loginName === "basic";
}
-
return false;
},
},
data() {
return {
- sdkList: [],
installedList: [],
+ recomandUpdateList: [],
hasNewVersionSdk: [],
+ activeTab: "sdk",
hasNewVersionApp: [],
+ tempDarkList: [],
notInstalledList: [],
+ showUpload: false,
+ detailType: "",
+ detailProductID: "",
+ detailPrice: "",
buttonAuthority: sessionStorage.getItem("buttonAuthoritys") || [],
- activeName: "myAlgorithm",
+ activeName: "搴旂敤涓績",
patchUpdateStatus: "",
downloadItem: "",
downloading: false,
- direction: "rtl",
actStep: 0,
+ showQuickPath: true,
showActivateSuccess: false,
activeCode: "",
isInstall: false,
installDialogVisible: false,
- installPackage: {},
installAppPackage: null,
installSdkPackage: null,
isActive: true,
isDefaultApp: false,
- installPercentage: 0,
unActivedSDKList: [],
unActivedAppList: [],
+ inDetail: false,
isSDKDialog: true,
- //actSdkId: '',
actType: "",
actId: "",
+ inputText: "",
+ tempList: [],
+ select: "",
activedSdkOrApp: {
activateCode: "",
productName: "",
@@ -977,28 +527,26 @@
licence: "",
devIds: "",
},
- // unloadLoading: false,
- // installLoading: false,
installedApps: [],
storeApps: [],
installFile: {},
- freshTimer: null,
- appUpgreading: true,
- sdkUpgreading: true,
+ appUpgreading: false,
+ sdkUpgreading: false,
autoRefresh: true,
- curCheckTarget: {},
productDetailVisible: false,
isUpgrading: false,
productDetail: {},
otherProducts: [],
backStack: [],
+ toUpdateArr1: [],
forwardStack: [],
+ rocketIf: false,
backDisable: true,
forwardDisable: true,
showInputCode: false,
needToUpgradeInWin: false,
- errMsg: "",
- showInstallNotActive: false
+ showInstallNotActive: false,
+ menuArr: ["搴旂敤涓績", "宸叉縺娲�", "绂荤嚎鍗囩骇/瀹夎", "鏇存柊"],
};
},
directives: {
@@ -1008,223 +556,174 @@
},
},
},
-
mounted() {
- // 鑾峰彇鎵�鏈夊簲鐢�
+ var name = getUrlKey("activeName");
+ if (name) {
+ this.pickMenu(name);
+ }
this.autoRefreshAppAndSdkState();
-
- this.getUnActivedList();
+ this.getUnActivedList(1);
this.getUnActivedAppList();
},
beforeDestroy() {
this.autoRefresh = false;
},
methods: {
- isShow(authority) {
- return (
- this.isAdmin || this.buttonAuthority.indexOf("," + authority + ",") > -1
- );
+ searchAll() {
+ this.getAllApps();
+ this.getAllSdk();
+ this.getUnActivedList(1);
+ this.getUnActivedAppList();
},
- batchUpdate(type) {
- if (type == "sdk") {
- this.hasNewVersionSdk.forEach((sdk) => {
- this.donwload(sdk, 0);
- });
+ goback() {
+ this.inDetail = false;
+ },
+ batchUpdate(s) {
+ if (s == "both") {
+ this.batchUpdateSDK();
+ this.batchUpdateApp();
+ } else if (this.activeTab == "sdk") {
+ this.batchUpdateSDK();
} else {
- this.hasNewVersionApp.forEach((app) => {
- this.downloadApp(app, "upgrade");
- });
+ this.batchUpdateApp();
}
},
- closeDial() {
- this.productDetailVisible = false
- this.productDetail = {}
- this.otherProducts = []
- },
- checkDetail(item, type) {
- if (type == 'inactive') {
- this.isActive = false
- this.showInstallNotActive = false
- this.showInputCode = false
- } else if (type == 'active') {
- this.showInputCode = false
- this.showInstallNotActive = false
- this.isActive = true
- } else if (type == 'activeNotInstall') {
- this.showInputCode = false
- this.isActive = false
- this.showInstallNotActive = true
- }
- this.checkIsDefOrNot(item.id)
- this.needToUpgradeInWin = item.isUpgrade ? true : false
- this.resetStack()
- if (item.sdk_type === undefined) {
- this.isSDKDialog = false
- } else {
- this.isSDKDialog = true
- }
- this.productDetailVisible = true;
- let _this = this;
- getAppDetail({ id: item.id }).then((res) => {
- _this.productDetail = res.data.detail;
- _this.productDetail.isUpgrade = item.isUpgrade;
- _this.productDetail.iconBlob = item.iconBlob;
-
- _this.otherProducts = res.data.randoms;
+ batchUpdateSDK() {
+ this.hasNewVersionSdk.forEach((sdk) => {
+ this.donwloadSDK(sdk);
});
},
- resetStack() {
- this.forwardStack = []
- this.backStack = []
- this.backDisable = true
- this.forwardDisable = true
-
- },
- checkInWindow(item) {
- this.backStack.push([this.productDetail, this.otherProducts])
- this.backDisable = false
- this.checkIsDefOrNot(item.id)
-
- let _this = this;
- getAppDetail({ id: item.id }).then((res) => {
- _this.productDetail = res.data.detail;
- _this.productDetail.iconBlob = item.iconBlob
- this.actId = _this.productDetail.productBaseId
- let flag = false
- const allNeedToNew = [...this.hasNewVersionSdk, ...this.hasNewVersionApp]
- for (let i = 0; i < allNeedToNew.length; i++) {
- const item = allNeedToNew[i];
- if (item.id == _this.productDetail.productBaseId) {
- flag = true
- }
- }
- this.needToUpgradeInWin = flag
- _this.productDetail.isUpgrade = flag
-
- _this.otherProducts = res.data.randoms;
+ batchUpdateApp() {
+ this.hasNewVersionApp.forEach((app) => {
+ this.downloadApp(app, "upgrade");
});
+ },
+ pickMenu(name) {
+ this.activeName = name;
+ this.activeTab = "sdk";
+ this.showQuickPath = true;
+ switch (name) {
+ case "搴旂敤涓績":
+ this.tempList = this.unActivedSDKList;
+ this.tempDarkList = [];
+ break;
+ case "宸叉縺娲�":
+ this.tempList = this.installedList;
+ this.tempDarkList = this.notInstalledList;
+ break;
+ case "鏇存柊":
+ this.showQuickPath = false;
+ this.tempList = this.hasNewVersionSdk;
+ this.tempDarkList = [];
+ break;
+ default:
+ this.tempList = [];
+ this.tempDarkList = [];
+ break;
+ }
+ },
+ pickTab(val) {
+ if (val) {
+ this.activeTab = val;
+ }
+ if (this.activeName == "搴旂敤涓績") {
+ this.tempList =
+ this.activeTab == "sdk"
+ ? this.unActivedSDKList
+ : this.unActivedAppList;
+ this.tempDarkList = [];
+ } else if (this.activeName == "宸叉縺娲�") {
+ this.tempList =
+ this.activeTab == "sdk" ? this.installedList : this.installedApps;
+ this.tempDarkList =
+ this.activeTab == "sdk" ? this.notInstalledList : this.storeApps;
+ } else if (this.activeName == "鏇存柊") {
+ this.tempList =
+ this.activeTab == "sdk"
+ ? this.hasNewVersionSdk
+ : this.hasNewVersionApp;
+
+ this.tempDarkList = [];
+ }
+ },
+ checkDetail(item, typ, sdkName) {
+ /* if (!item.canUpOrIns && typ == "Appcenter") {
+ return false;
+ } */
+ this.isSdk = Boolean(sdkName);
+ this.inDetail = true;
+ this.detailProductID = item.id;
+ this.detailPrice = item.price;
+ if (typ) {
+ this.detailType = typ;
+ } else {
+ this.detailType = this.activeName == "搴旂敤涓績" ? "inactive" : "active";
+ }
},
checkIsDefOrNot(id) {
- if (id.length > 10) {
- this.isDefaultApp = false
- } else {
- this.isDefaultApp = true
- }
- },
- backwards() {
- if (this.backStack.length == 0) {
- this.backDisable = true
- return
- }
-
- this.forwardStack.push([this.productDetail, this.otherProducts])
- let item = this.backStack.pop()
- this.productDetail = item[0]
- this.checkIsDefOrNot(this.productDetail.productBaseId)
- this.otherProducts = item[1]
- this.forwardDisable = false
- if (this.backStack.length == 0) {
- this.backDisable = true
-
- }
+ this.isDefaultApp = id.length <= 10;
},
forwards() {
if (this.forwardStack.length == 0) {
- this.forwardDisable = true
- return
+ this.forwardDisable = true;
+ return;
}
- this.backStack.push([this.productDetail, this.otherProducts])
- this.backDisable = false
- let item = this.forwardStack.pop()
+ this.backStack.push([this.productDetail, this.otherProducts]);
+ this.backDisable = false;
+ let item = this.forwardStack.pop();
- this.productDetail = item[0]
- this.otherProducts = item[1]
+ this.productDetail = item[0];
+ this.otherProducts = item[1];
if (this.forwardStack.length == 0) {
- this.forwardDisable = true
+ this.forwardDisable = true;
}
-
},
- //绂荤嚎瀹夎
offlineInstall() {
this.installDialogVisible = false;
this.isInstall = true;
- //瀹夎
installSdk(this.installFile)
.then((res) => {
if (res.success) {
this.isInstall = false;
- this.$message({
- type: "success",
- message: '瀹夎鎴愬姛,灏嗚烦杞嚦"宸叉縺娲�"涓煡鐪�',
- });
+ this.$message.success('瀹夎鎴愬姛,灏嗚烦杞嚦"宸叉縺娲�"涓煡鐪�');
setTimeout(() => {
this.getAllSdk();
- window.parent.postMessage(
- {
- msg: "AppUpdate",
- },
- "*"
- );
- this.activeName = "myAlgorithm";
+ window.parent.postMessage({ msg: "AppUpdate" }, "*");
+ this.activeName = "宸叉縺娲�";
}, 3000);
}
})
.catch((e) => {
this.isInstall = false;
- this.$message({
- type: "error",
- message: e.data,
- });
+ this.$message.error(e.msg);
});
},
-
downloadApp(app, action) {
- if (action == "upgrade") {
- app.upgradeLoading = true;
- } else {
- app.installLoading = true;
- }
- let _this = this;
+ let timer = null;
+ app.upgradeLoading = true;
+ timer = setInterval(() => {
+ this.rocketIf = !this.rocketIf;
+ }, 350);
+ let _this = this;
installApp({ path: app.id })
.then((res) => {
if (res && res.success) {
- _this.$notify({
- title: "鎴愬姛",
- message: "瀹夎搴旂敤鎴愬姛",
- type: "success",
- });
+ _this.$notify.success("瀹夎搴旂敤鎴愬姛");
+ clearInterval(timer);
+ app.upgradeLoading = false;
setTimeout(() => {
- if (action == "upgrade") {
- app.upgradeLoading = false;
- } else {
- app.installLoading = false;
- }
- // _this.getAllApps();
- window.parent.postMessage(
- {
- msg: "AppUpdate",
- },
- "*"
- );
+ window.parent.postMessage({ msg: "AppUpdate" }, "*");
}, 3000);
} else {
}
})
.catch((e) => {
- _this.$notify({
- title: "瀹夎澶辫触",
- message: e.data,
- type: "warning",
- });
- if (action == "upgrade") {
- app.upgradeLoading = false;
- } else {
- app.installLoading = false;
- }
+ _this.$notify.warning(e.msg);
+ clearInterval(timer);
+ app.upgradeLoading = false;
});
-
// 寮�鍚嚜鍔ㄥ埛鏂�
this.appUpgreading = true;
},
@@ -1232,7 +731,7 @@
let iArry = [];
let sArry = [];
let nArry = [];
- let rsp = await getApps();
+ let rsp = await getApps({ appName: this.inputText });
if (rsp && rsp.success) {
// 閬嶅巻app鐨勮繃绋嬮噸缃�
this.appUpgreading = false;
@@ -1242,11 +741,19 @@
{ unloadLoading: false, upgradeLoading: false },
item
);
- if (obj.progressMsg !== "" && obj.progressMsg !== "宸插畨瑁�") {
+ if (
+ obj.progressMsg !== "" &&
+ obj.progressMsg !== "宸插畨瑁�" &&
+ obj.progressMsg != "100%"
+ ) {
obj.upgradeLoading = true;
-
this.appUpgreading = true;
}
+
+ if (obj.upgradeDone) {
+ this.$notify.success(1 ? "绠楁硶瀹夎鎴愬姛" : "绠楁硶鍗囩骇鎴愬姛");
+ }
+
item.installed ? iArry.push(obj) : sArry.push(obj);
item.isUpgrade && nArry.push(obj);
});
@@ -1255,13 +762,11 @@
this.storeApps = sArry;
this.hasNewVersionApp = nArry;
},
-
- //鍗歌浇
- unLoad(app) {
+ unloadApp(app) {
let _this = this;
this.$confirm("纭畾瑕佸嵏杞借搴旂敤鍚�?", "鎻愮ず")
.then(() => {
- _this.productDetailVisible = false
+ _this.productDetailVisible = false;
app.unloadLoading = true;
removeApp({ appId: app.id })
@@ -1269,41 +774,15 @@
if (res && res.success) {
app.unloadLoading = false;
_this.getAllApps();
- window.parent.postMessage(
- {
- msg: "AppUpdate",
- },
- "*"
- );
- _this.$notify({
- title: "鎴愬姛",
- message: "鍗歌浇搴旂敤鎴愬姛",
- type: "success",
- });
+ window.parent.postMessage({ msg: "AppUpdate" }, "*");
+ _this.$notify.success("鍗歌浇搴旂敤鎴愬姛");
}
})
.catch((e) => {
- console.log(e);
app.unloadLoading = false;
});
})
- .catch((e) => {
- console.log(e);
- });
- },
-
- actSdkOrApp(item, type = "sdk") {
- this.checkDetail(item, "inactive");
- this.actType = type;
- this.actId = item.id;
- this.actStep = 0;
- this.activeCode = "";
- this.activedSdkOrApp = this.newActInfo();
- },
-
- cancelActivate() {
- this.showInputCode = false
- this.activeCode = ""
+ .catch((e) => {});
},
newActInfo() {
return {
@@ -1315,80 +794,77 @@
devIds: "",
};
},
- getUnActivedList() {
- getUnActivedSdk().then((res) => {
+ getUnActivedList(v) {
+ getUnActivedSdk({ sdkName: this.inputText }).then((res) => {
if (res.code == 200) {
this.unActivedSDKList = res.data;
+ const len = this.unActivedSDKList.length;
+ const set = new Set();
+ if (len <= 3) {
+ this.recomandUpdateList = [...this.unActivedSDKList];
+ } else {
+ for (let i = 0; i < 3; i++) {
+ const pickI = Math.floor(Math.random() * len);
+ if (set.has(pickI)) {
+ i--;
+ continue;
+ }
+ set.add(pickI);
+ this.recomandUpdateList.push(this.unActivedSDKList[pickI]);
+ }
+ }
+ v == 1 ? (this.tempList = res.data) : null;
}
});
},
getUnActivedAppList() {
- getUnActivedApp().then((res) => {
+ getUnActivedApp({ appName: this.inputText }).then((res) => {
if (res.code == 200) {
this.unActivedAppList = res.data;
+ this.pickTab();
}
});
},
- actived() {
- let _this = this;
- if (this.activeCode.trim() == "") {
- this.$notify({
- type: "error",
- message: "婵�娲荤爜涓嶈兘涓虹┖",
- });
- return;
+ actived(item) {
+ if (!item.canUpOrIns) {
+ return false;
}
- if (this.actType == "sdk") {
- //婵�娲荤畻娉�
- actPageAlg(this.actId, this.activeCode)
+
+ let _this = this;
+ if (this.activeTab == "sdk") {
+ actPageAlg(item.id, "")
.then((res) => {
if (res.data.isSuccess) {
this.productDetailVisible = false;
_this.activedSdkOrApp = res.data.successMsg;
- this.showActivateSuccess = true
+ this.showActivateSuccess = true;
_this.actStep++;
- _this.getUnActivedList();
+ _this.getUnActivedList(1);
_this.getAllSdk();
} else {
- _this.$notify({
- type: "error",
- message: res.data.failMsg.failMsg,
- });
+ _this.$notify.error(res.data.failMsg.failMsg);
}
})
- .catch((e) => {
- console.log(e);
- });
- } else if (this.actType == "app") {
+ .catch((e) => {});
+ } else if (this.activeTab == "app") {
//婵�娲诲簲鐢�
- actApp(this.actId, this.activeCode)
+ actApp(item.id, "")
.then((res) => {
if (res.data.isSuccess) {
this.productDetailVisible = false;
_this.activedSdkOrApp = res.data.successMsg;
- this.showActivateSuccess = true
+ this.showActivateSuccess = true;
_this.actStep++;
_this.getUnActivedAppList();
_this.getAllApps();
} else {
- _this.$notify({
- type: "error",
- message: res.data.failMsg.failMsg,
- });
+ _this.$notify.error(res.data.failMsg.failMsg);
}
})
- .catch((e) => {
- console.log(e);
- });
+ .catch((e) => {});
}
},
- getCodeDetail() { },
- checkMyAlgorith() {
- this.showActivateSuccess = false;
- this.activeName = "myAlgorithm";
- },
onFileUpload(file) {
- //this.patchUpdateStatus = `<span style="color:green">涓婁紶鎴愬姛, 鐐瑰嚮鍗囩骇鎸夐挳寮�濮嬪畨瑁�</span>`;
this.patchFile = { ...file };
this.fileAdded = true;
const h = this.$createElement;
@@ -1415,31 +891,22 @@
installContent: res.data.sdks[0].installContent,
};
}
+ } else {
+ this.$message.error(res.msg);
}
})
.catch((e) => {
- this.$message({
- type: "error",
- message: e.data,
- });
+ this.$message.error(e.msg);
});
},
- openApp() {
- let message = 'toOpenApp?' + this.productDetail.productBaseId;
- window.parent.postMessage({
- msg: message
- }, "*")
- },
-
onFileAdded(f) {
this.patchUpdateStatus = "";
},
-
async getAllSdk() {
let installedList = [];
let unInstalledList = [];
let hasNewVersionList = [];
- let res = await findAllSdk();
+ let res = await findAllSdk({ sdkName: this.inputText });
if (res && res.success) {
this.sdkUpgreading = false;
@@ -1448,197 +915,84 @@
{ unloadLoading: false, upgradeLoading: false },
item
);
- if (obj.progressMsg !== "" && obj.progressMsg !== "宸插畨瑁�") {
+ if (
+ obj.progressMsg !== "" &&
+ obj.progressMsg !== "宸插畨瑁�" &&
+ obj.progressMsg !== "100%"
+ ) {
obj.upgradeLoading = true;
-
this.sdkUpgreading = true;
}
//绠楁硶杞欢 宸插畨瑁呭叾涓寘鍚緟鍗囩骇 鏈畨瑁�
item.installed ? installedList.push(obj) : unInstalledList.push(obj);
- item.isUpgrade ? hasNewVersionList.push(obj) : null
+ item.isUpgrade ? hasNewVersionList.push(obj) : null;
});
}
this.installedList = installedList;
this.notInstalledList = unInstalledList;
+ this.toUpdateArr1 = this.installedList.slice(0, 10);
this.hasNewVersionSdk = hasNewVersionList;
+ this.pickTab();
},
- unloadSDKinWin() {
-
- let appToUnload
- let sdkToUnload
- if (this.productDetail.productTypeName == "搴旂敤") {
- appToUnload = this.installedApps.find((item) => {
- return item.id == this.productDetail.productBaseId
- })
- this.unLoad(appToUnload)
- } else {
- sdkToUnload = this.installedList.find((item) => {
- return item.id == this.productDetail.productBaseId
- })
- this.unLoadSdk(sdkToUnload)
- }
- },
- //鍗歌浇绠楁硶
- unLoadSdk(sdk) {
+ unloadSdk(sdk) {
let _this = this;
this.$confirm("纭畾瑕佸嵏杞借绠楁硶鍚�?", "鎻愮ず")
.then(() => {
- _this.productDetailVisible = false
+ _this.productDetailVisible = false;
sdk.unloadLoading = true;
removeSdk({ sdkId: sdk.id })
.then((res) => {
if (res && res.success) {
sdk.unloadLoading = false;
- this.$notify({
- title: "鎴愬姛",
- message: "鍗歌浇瀹屾垚",
- type: "success",
- });
+ this.$notify.success("鍗歌浇瀹屾垚");
_this.getAllSdk();
- window.parent.postMessage(
- {
- msg: "AppUpdate",
- },
- "*"
- );
+ window.parent.postMessage({ msg: "AppUpdate" }, "*");
}
})
.catch((e) => {
- console.log(e);
sdk.unloadLoading = false;
});
})
- .catch((e) => {
- console.log(e);
- });
+ .catch((e) => {});
},
- upgradeSDKinWin() {
- this.isUpgrading = !this.isUpgrading;
-
- let _this = this;
- if (this.productDetail.productTypeName == "搴旂敤") {
- installApp({ path: this.productDetail.productBaseId })
- .then((res) => {
- if (res && res.success) {
- this.$notify({
- title: "鎴愬姛",
- message: "鍗囩骇瀹屾垚",
- type: "success",
- });
- this.needToUpgradeInWin = false
- this.productDetail.isUpgrade = false
- this.isUpgrading = !this.isUpgrading;
-
- }
- })
- .catch((e) => {
- _this.$notify({
- title: "鍗囩骇澶辫触",
- message: e.data,
- type: "warning",
- });
- this.isUpgrading = !this.isUpgrading;
- });
-
- // 寮�鍚嚜鍔ㄥ埛鏂�
- this.appUpgreading = true;
- } else {
- downloadSdk({ path: this.productDetail.productBaseId }).then((res) => {
- this.needToUpgradeInWin = false
- this.productDetail.isUpgrade = false
- this.isUpgrading = !this.isUpgrading;
- this.$notify({
- title: "鎴愬姛",
- message: "鍗囩骇瀹屾垚",
- type: "success",
- });
- }).catch((err) => {
- this.$notify({
- title: "鍗囩骇澶辫触",
- message: err.data,
- type: "warning",
- });
- this.isUpgrading = !this.isUpgrading;
- })
- this.sdkUpgreading = true;
- }
-
-
-
- },
- downloadSdkInSide() {
- this.downloadItem = this.productDetail.productBaseId;
- this.isUpgrading = true;
- downloadSdk({ path: this.productDetail.productBaseId })
- .then((rsp) => {
- this.productDetailVisible = false;
- this.downloadItem = "";
- this.$notify({
- type: "success",
- message: "绠楁硶宸插畨瑁�",
- });
- this.isUpgrading = false
- })
- .catch((err) => {
- this.$notify({
- type: "warning",
- message: err.data,
- });
- this.downloadItem = "";
- this.isUpgrading = false
- });
- // 寮�鍚嚜鍔ㄥ埛鏂�
- this.sdkUpgreading = true;
- },
- donwload(item, typ) {
+ donwloadSDK(item) {
+ let timer = null;
item.upgradeLoading = true;
+ timer = setInterval(() => {
+ this.rocketIf = !this.rocketIf;
+ }, 350);
this.downloadItem = item.id;
-
downloadSdk({ path: item.id })
.then((rsp) => {
+ clearInterval(timer);
item.upgradeLoading = false;
- //this.downloading = false;
this.downloadItem = "";
- this.$notify({
- type: "success",
- message: typ == 1 ? "绠楁硶瀹夎鎴愬姛" : "绠楁硶鍗囩骇鎴愬姛"
- });
+
+ window.parent.postMessage({ msg: "AppUpdate" }, "*");
})
.catch((err) => {
- this.$notify({
- type: "warning",
- message: err.data,
- });
+ this.$notify.warning(err.data);
item.upgradeLoading = false;
- //this.downloading = false;
this.downloadItem = "";
});
// 寮�鍚嚜鍔ㄥ埛鏂�
this.sdkUpgreading = true;
},
- inputBlur(item) {
- this.$set(item, "isEdit", false);
- },
- handleTabClick() { },
autoRefreshAppAndSdkState() {
- // 鍏抽棴鍚庨��鍑�
+ this.getAllApps();
+ this.getAllSdk();
if (!this.autoRefresh) {
return;
}
-
- if (this.appUpgreading) {
- this.getAllApps();
- }
-
- if (this.sdkUpgreading) {
- this.getAllSdk();
- }
-
- let _this = this;
setTimeout(() => {
- _this.autoRefreshAppAndSdkState();
- }, 500);
+ if (this.appUpgreading) {
+ this.getAllApps();
+ }
+ if (this.sdkUpgreading) {
+ this.getAllSdk();
+ }
+ }, 1000);
},
},
};
@@ -1646,347 +1000,13 @@
<style lang="scss">
.s-task-manage {
width: 100% !important;
+ min-width: 754px !important;
height: 100%;
box-sizing: border-box;
text-align: left;
- min-width: 1106px;
-
- .el-tabs {
- height: calc(100% - 50px);
- // margin-top: 5px !important;
- }
- .el-tabs--border-card > .el-tabs__header {
- border: none;
- }
- .el-tabs__item.is-top {
- height: 50px;
- padding: 5px 50px !important;
- font-size: 15px;
- border: none !important;
- }
- .el-tabs__item.is-top.is-active {
- font-weight: bold;
- }
- .el-tabs__content {
- width: 100%;
- height: calc(100% - 34px);
- box-sizing: border-box;
- }
- .el-tab-pane {
- width: 100%;
- height: 100%;
- }
- .product-detail-dialog {
- .dialog-title {
- font-size: 13px;
- }
- .el-dialog {
- width: 50%;
- min-width: 920px;
- position: relative;
- }
- .el-dialog__header {
- text-align: center;
- padding: 6px;
-
- .el-dialog__headerbtn {
- position: absolute;
- top: 5px;
-
- right: 20px;
- padding: 0;
- background: transparent;
- outline: none;
- cursor: pointer;
- font-size: 20px;
- }
- }
- .el-dialog__body {
- background-color: rgba(222, 225, 230, 1);
- padding: 8px 3px;
- .button-group {
- position: absolute;
- top: 3px;
-
- left: 6px;
- left: 10px;
- .el-button--small {
- padding: 5px 12px;
- }
- button {
- font-size: 18px;
- line-height: 12px;
- }
- }
- }
-
- .dialog-content {
- .box-top {
- height: 330px;
- .top-left {
- float: left;
- width: 55%;
- background-color: rgba(253, 253, 253, 1);
- margin: 0 0.5%;
- height: 330px;
- border-radius: 2px;
- .banner {
- text-align: center;
- margin-top: 3px;
- video {
- margin: 0px auto;
- margin-top: 23px;
-
- width: 443px;
- height: 277px;
- }
- img {
- max-width: 90%;
- margin-top: 28px;
- }
- }
- }
- .top-right {
- float: left;
- width: 43%;
- margin: 0 0.5%;
- height: 330px;
- background-color: rgba(253, 253, 253, 1);
- position: relative;
- border-radius: 2px;
- overflow: hidden;
- .summary {
- height: 120px;
- margin: 5px 5px 0 5px;
- .icon {
- margin: 0 10px;
- margin-top: 8px;
- float: left;
- .baseImg {
- max-width: 106px;
- max-height: 106px;
- }
- }
-
- .right-desc {
- float: left;
- position: absolute;
- left: 140px;
- .name {
- font-size: 28px;
-
- margin-bottom: 5px;
- text-overflow: ellipsis;
- white-space: nowrap;
- overflow: hidden;
- width: 250px;
- }
- .tags {
- margin-bottom: 10px;
- .el-tag {
- margin-right: 10px;
- }
- }
- }
- }
- .jihuo-input {
- margin-left: 10px;
- margin-bottom: 10px;
- .el-input {
- float: left;
- width: 63%;
- margin-bottom: 8px;
- margin-right: 10px;
- }
- el-button {
- float: left;
- }
- }
- .product-intruduction {
- height: 200px;
- margin-top: 3px;
-
- .part-title {
- display: block;
- line-height: 20px;
-
- font-size: 16px;
- margin-left: 24px;
- border-bottom: 3px solid #3d68e1;
- width: fit-content;
- height: 26px;
- margin-bottom: 8px;
- }
- .text {
- height: 156px;
- overflow: auto;
- padding: 0 15px 0px 15px;
-
- .single-desc {
- margin-bottom: 10px;
- font-size: 13px;
- }
- }
- }
- }
- }
- .box-bottom {
- margin-top: 8px;
-
- height: 240px;
- .bot-left {
- width: 49%;
- height: 240px;
- background-color: rgba(253, 253, 253, 1);
- margin: 0 0.5%;
- border-radius: 2px;
- float: left;
- .part-title {
- display: block;
- line-height: 35px;
- font-size: 16px;
- margin-left: 24px;
- border-bottom: 3px solid #3d68e1;
- width: fit-content;
- margin-bottom: 10px;
-
- height: 33px;
- }
- .list-zone {
- overflow: auto;
- height: 190px;
- padding: 0 20px;
- .list-item {
- .desc {
- background-color: rgba(242, 242, 242, 1.3);
- margin: 5px 12px 0 12px;
- font-size: 12px;
- line-height: 18px;
- }
- margin-bottom: 12px;
- }
- }
- }
- .bot-right {
- height: 240px;
- float: left;
- background-color: rgba(253, 253, 253, 1);
- width: 49%;
- margin: 0 0.5%;
- border-radius: 2px;
-
- .part-title {
- display: block;
- line-height: 35px;
- font-size: 16px;
- margin-left: 24px;
- border-bottom: 3px solid #3d68e1;
- width: fit-content;
- margin-bottom: 5px;
- height: 33px;
- }
- .item-zone {
- overflow: auto;
- height: 225px;
- padding: 0px 12px;
-
- .item {
- height: 165px;
- width: 130px;
- float: left;
- border-radius: 10px;
- box-shadow: 0px 5px 14px rgba(0, 0, 0, 0.0666666666666667);
- position: relative;
-
- .el-tag {
- float: right;
- margin: 8px;
- }
- .icon {
- margin: 0 auto;
- img {
- max-width: 60px;
- max-height: 60px;
- position: absolute;
- top: 20%;
- left: 26%;
- }
- .icon-name {
- text-align: center;
- position: absolute;
- top: 61%;
- left: 12%;
- width: 100px;
- text-overflow: ellipsis;
- white-space: nowrap;
- overflow: hidden;
- font-size: 13px;
- }
- }
- .look-button {
- position: absolute;
- left: 30%;
-
- top: 76%;
- }
- }
- }
- }
- }
- }
- }
-}
-.flex-title {
- display: flex;
- justify-content: space-between;
- align-items: center;
+ background-color: #fff;
}
-.el-loading-mask .el-loading-spinner {
- top: 40px !important;
-}
-.el-loading-mask .el-loading-spinner svg {
- transform: none !important;
- top: 20px !important;
- left: 40% !important;
-}
-.el-loading-mask .el-loading-spinner p.el-loading-text {
- display: block !important;
- text-align: center !important;
- bottom: 10px !important;
- top: 80px !important;
- right: 0 !important;
- color: #78adf7;
-}
-.el-loading-mask .el-loading-spinner .path {
- stroke: #78adf7;
-}
-.installInfo {
- text-indent: 2em;
- font-size: 14px;
- line-height: 26px;
- p {
- text-align: center;
- }
-}
-.src-title {
- //color: #bfbfbf;
- color: #bbcee8;
- font-family: "PingFangSC-Semibold", "PingFang SC Semibold", "PingFang SC";
- font-weight: 650;
- font-style: normal;
- height: 36px;
- font-size: 15px;
- padding-left: 25px;
-}
-.update-badge .el-badge__content.is-fixed {
- top: 10px;
- right: 4px;
-}
-.empty-tip {
- padding-left: 25px;
- color: #ccc;
-}
.task-manage {
height: 100%;
.installModel {
@@ -2000,7 +1020,7 @@
.progress-bar {
width: 70%;
height: 17px;
- border-radius: 3px;
+ border-radius: 3pxd;
background-color: rgb(227, 229, 231);
position: absolute;
top: 50%;
@@ -2019,28 +1039,11 @@
}
}
}
- .el-tab-pane {
- height: auto !important;
- }
- .el-tabs--border-card > .el-tabs__content {
- padding: 0 !important;
- overflow: auto !important;
- background-color: #fff;
- }
- .el-tabs__content {
- padding: 0 !important;
- overflow: auto !important;
- }
- //height: calc(100% - 10px);
- // .super {
- // .right-box {
- // width: 58% !important;
- // }
- // }
.super {
width: 100%;
height: 100%;
+ // caret-color: rgba(0, 0, 0, 0);
.title {
margin-bottom: 10px;
line-height: 30px;
@@ -2049,182 +1052,476 @@
color: #222222;
}
.left-box {
- // width: 41%;
height: 100%;
box-sizing: border-box;
- // float: left;
- .el-drawer__header {
- border-bottom: 2px solid #eee;
- padding-bottom: 10px;
- font-size: 16px;
- margin-bottom: 0px;
- span {
- outline: none !important;
- }
- }
- .action-bar {
- margin-bottom: 30px;
- .el-input {
- width: 100%;
- }
- }
- .task-list {
- // background: #1c364a;
- background: #fff;
- padding: 20px;
- box-sizing: border-box;
-
- .flex-list {
- display: flex;
- flex-direction: row;
- flex-wrap: wrap;
- min-height: 200px;
- .wrap-box {
- width: 11%;
- }
- .list-choose-item-left {
- width: 80%;
- height: auto;
- margin: auto;
- margin-bottom: 30px;
- max-width: 150px;
- .mask {
- width: 100%;
-
- .el-button + .el-button {
- margin-left: 0 !important;
- }
- }
- }
- }
- }
- .store-list,
- .app-list {
+ .nav-box {
+ height: 200px;
display: flex;
- flex-wrap: wrap;
- .wrap-box {
- width: 11%;
- margin-bottom: 30px;
- .list-choose-item-left {
- width: 80%;
- height: auto;
- margin: auto;
- margin-bottom: 30px;
- max-width: 150px;
- }
- .inner {
- width: 80%;
- box-sizing: border-box;
- position: relative;
+ justify-content: space-between;
+ padding: 35px 60px;
+ position: relative;
+ .nav-box-menu {
+ width: 200px;
+ height: 200px;
+ z-index: 99;
+ .menu-item {
font-size: 14px;
- padding-bottom: 10px;
- transition: all 1s;
- background: #ffffff;
- border: 1px solid #e2e2e2;
- box-shadow: 0 5px 12px 0 rgba(0, 0, 0, 0.07);
- border-radius: 4px;
- margin: auto;
- .alg-icon {
- position: relative;
- width: 80%;
- margin: auto;
- padding-top: 80%;
- svg {
- position: absolute;
- top: 50%;
- left: 50%;
- transform: translate(-50%, -50%);
+ line-height: 50px;
+ height: 50px;
+ letter-spacing: 0.5px;
+ color: #828282;
+ padding-left: 20px;
+ border-left: 3px solid #f3f6fc;
+ cursor: pointer;
+ caret-color: transparent;
+ sup {
+ background-color: #f52323;
+ font-size: 12px;
+ color: #fff;
+ height: 18px;
+ line-height: 18px;
+ padding: 0 3.5px;
+ border-radius: 50%;
+ }
+ }
+ .menu-item:hover {
+ font-weight: 600;
+ color: #333;
+ transition: all 0.15s;
+ }
+ .menu-item-actiove {
+ border-left: 3px solid #23d7ee;
+ font-weight: 700;
+ font-size: 16px;
+ color: #333;
+ }
+ }
+ .nav-box-search {
+ z-index: 99;
+ position: relative;
+ .all-scene {
+ position: absolute;
+ z-index: 100;
+ right: 64px;
+
+ top: 10px;
+ font-size: 12px;
+ }
+ .el-input {
+ position: relative;
+ font-size: 12px;
+ border: 2px solid #f2f2f7;
+ border-radius: 20px;
+ .el-input__inner {
+ border: none;
+ height: 30px;
+ line-height: 30px;
+ padding: 0 12px;
+ }
+ .el-input-group__prepend {
+ border-right: 0;
+ border: none;
+ border-radius: 20px;
+ background: #fff;
+ padding: 0 0 0 15px;
+
+ i {
+ font-weight: 600;
+ color: #333;
+ font-size: 16px;
}
}
- .alg-name {
- height: 20px;
- text-align: center;
- line-height: 20px;
+ .el-input-group--append .el-input__inner,
+ .el-input-group__prepend {
+ border-top-right-radius: 0;
+ border-bottom-right-radius: 0;
+ border: none;
}
- .mask {
- position: absolute;
- top: 0;
- left: 0;
- width: 100%;
- height: 100%;
- background: rgba(0, 0, 0, 0.65);
- backdrop-filter: blur(1px) brightness(100%);
- text-align: center;
- z-index: 1;
- border-radius: 3px;
- display: none;
- svg {
- position: absolute;
- top: 49%;
- left: 50%;
- transform: translate(-50%, -50%);
- z-index: 33;
+ .el-input-group__append {
+ border-left: 0;
+ border: none;
+ border-radius: 20px;
+ width: 52px;
+ background: linear-gradient(
+ 180deg,
+ #ecfcfe 0%,
+ #ebf4fd 47.92%,
+ #f4f4fe 100%
+ );
+ .el-input--suffix {
+ border: none;
+ .el-input__icon {
+ line-height: 30px;
+ }
+ .el-input__inner {
+ font-size: 12px;
+ font-weight: bold;
+ letter-spacing: 0.5px;
+ padding: 0 0px 0 30px;
+ color: #474747;
+ }
+ .el-input__suffix {
+ display: none;
+ }
+ }
+ .el-input__inner::placeholder {
+ color: rgb(71, 71, 71);
+ }
+ .el-select-dropdown {
+ min-width: 120px !important;
+ left: -26px !important;
+ background: rgba(236, 245, 253, 0.6);
+ border-radius: 2px;
+ border: none;
+ .el-select-dropdown__item {
+ height: 22px;
+ line-height: 22px;
+ font-size: 12px;
+ letter-spacing: 0.4px;
+ color: #333333;
+ .icon {
+ margin-right: 5px;
+ font-size: 15px;
+ }
+ }
+ .el-select-dropdown__item.hover,
+ .el-select-dropdown__item:hover {
+ background-color: #ebf4fd;
+ font-weight: 600;
+ }
}
}
- &:hover {
- .mask {
- display: block;
- }
+ .el-input-group__prepend .el-select {
+ display: inline-block;
+ margin: -10px -20px;
+ border: none;
+ border-radius: 20px;
+ background: linear-gradient(
+ 180deg,
+ #ecfcfe 0%,
+ #ebf4fd 47.92%,
+ #f4f4fe 100%
+ );
}
+ }
+ }
+ .bg-img-wrap {
+ position: absolute;
+ z-index: 1;
+ right: 0;
+ top: 41px;
+ height: 229px;
+ img {
+ height: 100%;
}
}
}
- .drawer-content {
- font-family: "PingFangSC-Regular";
- .el-step__title.is-process {
- border-color: #3d68e1 !important;
- color: #3d68e1 !important;
- font-family: Tahoma, Helvetica, Arial, "\5B8B\4F53", sans-serif;
+ .quick-path {
+ position: relative;
+ height: 200px;
+ margin: 0 60px;
+ z-index: 99;
+ background: linear-gradient(
+ 180deg,
+ #ecfcfe 0%,
+ #ebf4fd 47.92%,
+ #f4f4fe 100%
+ );
+ border-radius: 4px;
+ height: 75px;
+ display: flex;
+ align-items: center;
+ .left-items {
+ display: flex;
}
- .el-step__head.is-process {
- border-color: #3d68e1 !important;
- color: #3d68e1 !important;
- font-family: Tahoma, Helvetica, Arial, "\5B8B\4F53", sans-serif;
- }
- .el-input {
- width: 100%;
- margin-bottom: 30px;
- }
- .current-step {
- margin: 40px 30px 30px;
- }
- .act-code {
- padding: 0 30px;
- p {
- font-size: 15px;
- margin-bottom: 16px;
+ .quick-item {
+ display: flex;
+ cursor: pointer;
+ padding: 2px 20px;
+ height: 52px;
+ box-sizing: border-box;
+
+ .icon-img {
+ width: 48px;
+ height: 48px;
+ position: relative;
+ .icon {
+ position: absolute;
+ right: -7px;
+ top: -7px;
+ font-size: 13px;
+ }
+ img {
+ width: 48px;
+ height: 48px;
+ }
+ }
+ .desc {
+ box-sizing: border-box;
+ padding: 0 12px;
+ color: #828282;
+ width: 140px;
+ .desc-1 {
+ font-size: 14px;
+ font-weight: bold;
+ line-height: 26px;
+ height: 26px;
+ overflow: hidden;
+ white-space: nowrap;
+ text-overflow: ellipsis;
+ }
+ .desc-2 {
+ font-size: 12px;
+ }
+ }
+ .right-icon {
+ padding: 2px 0;
+
+ .icon {
+ font-size: 21px;
+ }
}
}
- .desc {
- padding: 0 30px;
- margin-bottom: 30px;
- li {
- border-bottom: 1px solid #eee;
- height: 45px;
- line-height: 45px;
- font-size: 14px;
- &:last-child {
- border-bottom: none;
+ .quick-item:not(:last-child) {
+ border-right: 1px solid #e0e0e0;
+ }
+ .down-all-btn {
+ position: absolute;
+ right: 30px;
+ .el-button {
+ width: 78px;
+ font-size: 12px;
+ font-weight: 600;
+ padding: 3px 10px;
+ border: 1px solid #eef0f7;
+ }
+ }
+ }
+ .main-content {
+ padding: 35px 82px;
+ z-index: 99;
+ .main-title {
+ line-height: 25px;
+ font-size: 16px;
+ font-weight: 600;
+ margin-bottom: 10px;
+ }
+ .tab-btns {
+ display: flex;
+ justify-content: space-between;
+ .group-left {
+ display: flex;
+ .tab {
+ font-size: 14px;
+ margin-right: 25px;
+ line-height: 28px;
+ cursor: pointer;
+ color: #828282;
}
- label {
- display: inline-block;
- width: 90px;
- padding-left: 14px;
+ .tab-active {
+ border-bottom: 2px solid #23d7ee;
+ color: #333333;
font-weight: bold;
}
}
- }
- .text-right {
- padding-right: 30px;
- text-align: right;
- .tip {
- color: #999;
- line-height: 38px;
+
+ .batch-update {
+ display: flex;
+ align-items: center;
+ .el-button {
+ padding: 3px 12px;
+ background-color: #1dd4ec !important;
+ border-color: #1dd4ec !important;
+ border-radius: 22px;
+ }
+ .el-button--primary:hover {
+ background: #089fb3 !important;
+ border-color: #089fb3 !important;
+ }
}
}
- }
- .tab-content {
- padding: 20px 20px;
+ .front-page-items {
+ padding-top: 25px;
+ .front-page-item {
+ float: left;
+ display: flex;
+ margin: 0 5px;
+ margin-bottom: 15px;
+ box-sizing: border-box;
+ width: 274px;
+
+ justify-content: center;
+ cursor: pointer;
+
+ padding: 10px 0;
+ height: 76px;
+ border-radius: 4px;
+
+ /* &.disabled {
+ cursor: default;
+ } */
+
+ .icon-img {
+ width: 58px;
+ height: 58px;
+ position: relative;
+ .icon {
+ position: absolute;
+ right: -9px;
+ top: -9px;
+ font-size: 16px;
+ }
+ img {
+ width: 58px;
+ height: 58px;
+ border-radius: 10px;
+ }
+ }
+ .desc {
+ box-sizing: border-box;
+ padding: 0 12px;
+ width: 147px;
+
+ .desc-1 {
+ font-size: 14px;
+ font-weight: bold;
+ color: #4f4f4f;
+ line-height: 28px;
+ height: 28px;
+ letter-spacing: 0.1px;
+ overflow: hidden;
+ white-space: nowrap;
+ text-overflow: ellipsis;
+ }
+ .desc-2 {
+ color: #828282;
+ font-size: 12px;
+ }
+ }
+ .right-btn {
+ padding: 2px 0;
+ width: 50px;
+ text-align: center;
+ position: relative;
+ .check-btn {
+ background-color: #ffffff !important;
+ border-color: #bdbdbd !important;
+ color: #333333;
+ }
+ .update-btn {
+ border-color: #23d7ee !important;
+ background-color: rgba(29, 212, 236, 0.1) !important;
+ color: #4f4f4f;
+ }
+ .other-btn {
+ background-color: #1dd4ec !important;
+ border-color: #1dd4ec !important;
+ color: #ffffff;
+ }
+ @keyframes spin {
+ from {
+ transform: rotate(0deg);
+ }
+ to {
+ transform: rotate(360deg);
+ }
+ }
+ .anz-font {
+ font-size: 28px;
+ color: #333;
+ }
+
+ .spin-icon {
+ animation: spin 0.8s linear infinite;
+ }
+ .status {
+ font-size: 12px;
+ color: #828282;
+ white-space: nowrap;
+ overflow: hidden;
+ text-overflow: ellipsis;
+ min-width: 100px;
+ text-align: end;
+ position: absolute;
+ right: 0;
+ width: 120px;
+ margin-top: 2px;
+ }
+ .rocket-icon {
+ font-size: 20px;
+ }
+ .el-button {
+ padding: 3px 12px;
+ border-radius: 22px;
+ font-weight: bold;
+ letter-spacing: 0.5px;
+ }
+ }
+ }
+ .front-page-item:hover {
+ background-color: #f2f2f7;
+ }
+ .item-dimmed {
+ color: gray;
+ filter: grayscale(100%);
+ }
+ }
+ .front-page-items:after {
+ content: "";
+ display: block;
+ height: 0;
+ clear: both;
+ visibility: hidden;
+ }
+ .upload-pkg {
+ .upload-head {
+ display: flex;
+ justify-content: space-between;
+ align-items: center;
+ .left {
+ display: flex;
+ align-items: center;
+ .iconfont {
+ font-size: 18px;
+ margin-right: 6px;
+ }
+ .txt {
+ font-size: 16px;
+ }
+ }
+ .right {
+ .icon {
+ margin-right: 11px;
+ font-size: 17px;
+ cursor: pointer;
+ }
+ }
+ }
+ }
+ .upload-demo {
+ margin: 30px 0px;
+ .drag-txt {
+ width: 340px;
+ height: 45px;
+ border: 1px dashed #bdbdbd;
+ display: flex;
+ margin-top: 30px;
+ align-items: center;
+ justify-content: center;
+ color: #828282;
+ font-size: 14px;
+ }
+ .txt-btn {
+ width: 78px;
+ margin-top: 18px;
+ height: 19px;
+ background: #23d7ee;
+ border-radius: 22px;
+ color: #ffffff;
+ font-weight: bold;
+ font-size: 12px;
+ }
+ }
}
}
.mask {
@@ -2262,312 +1559,13 @@
}
}
- .text-css {
- width: 100%;
- overflow: hidden;
- text-overflow: ellipsis;
- }
- .move-hear {
- margin: 10px 0 0 0;
- font-size: 5rem;
- }
- .list-choose-item {
- cursor: pointer;
- position: relative;
- font-size: 14px;
- display: inline-block;
- @media screen and(min-width: 1640px) {
- margin: 30px 20px 20px 20px;
- }
- @media screen and(min-width: 1460px) and(max-width: 1640px) {
- margin: 30px 20px 20px 10px;
- }
- @media screen and(max-width: 1460px) {
- margin: 30px 10px 20px 10px;
- }
- min-width: 126px;
- height: 120px;
- transition: all 1s;
- background: #fff;
- border: 1px solid #e2e2e2;
- box-shadow: 0 5px 12px 0 rgba(0, 0, 0, 0.07);
- border-radius: 4px;
- }
- .list-choose-item:hover {
- .mask {
- display: block;
- }
- }
-
- .alg-shadow {
- -webkit-box-shadow: 0px 0px 10px 3px rgba(0, 0, 0, 0.3);
- -moz-box-shadow: 0px 0px 10px 3px rgba(0, 0, 0, 0.3);
- box-shadow: 0px 0px 10px 3px rgba(0, 0, 0, 0.3);
- }
- .select-color {
- margin-top: 16px;
- text-align: center;
- line-height: 28px;
- // background-color: #3498DB;
- }
- .list-choose-item-left {
- cursor: pointer;
- position: relative;
- font-size: 14px;
-
- transition: all 1s;
- // background: #ffffff;
- border-radius: 4px;
- p {
- display: none;
- text-align: right;
- width: 100%;
- position: absolute;
- right: 10px;
- top: 5px;
- }
- .click-download {
- position: absolute;
- left: 80%;
- top: 5%;
- }
- }
- .list-choose-item-left:hover {
- .mask {
- display: flex;
- align-items: flex-end;
- flex-wrap: wrap;
- justify-content: center;
- top: 0;
-
- .bot-btn {
- flex: 1;
- }
- &.flex-center {
- align-items: center;
- justify-content: center;
- }
- }
- }
- .list-choose-item-left-uninstal {
- color: gray;
- filter: grayscale(100%);
- }
- .list-complete-item.sortable-chosen {
- background: #4ab7bd;
- }
- .list-choose-item.sortable-ghost {
- background: #30b08f;
- }
- .width-new-line {
- word-wrap: break-word;
- word-break: break-all;
- }
- .dndList-list {
- max-width: 40%;
- }
- .dic-border {
- width: 98%;
- min-height: 170px;
- background: #fff;
- padding: 10px 10px 10px 20px;
- }
- .min-h {
- min-height: 130px;
- }
- .parent-div {
- border-right: 1px solid rgba(24, 28, 33, 0.5);
- max-width: 140px;
- position: relative;
- }
- .list-choose-header {
- position: relative;
- width: 74px;
- height: 74px;
- background-image: linear-gradient(-137deg, #7076f2 0%, #3d63e1 100%);
- box-shadow: 0 5px 12px 0 rgba(0, 0, 0, 0.07);
- border-radius: 37px;
- margin: 10px 25px;
- }
-
- .task-name-div {
- font-family: PingFangSC-Medium;
- font-size: 15px;
- color: #4b68e6;
- text-align: center;
- margin-top: 6px;
- max-width: 120px;
- overflow: hidden;
- text-overflow: ellipsis;
- white-space: nowrap;
- }
- .border-dash {
- height: 30px;
- width: 96%;
- margin-bottom: 10px;
- border: 1px dashed rgba(24, 28, 33, 0.5);
- }
- .i-setting {
- position: absolute;
- font-size: 28px;
- margin-top: -25px;
- margin-left: -30px;
- }
- .i-delete {
- position: absolute;
- font-size: 28px;
- margin-top: -25px;
- margin-left: -8px;
- color: red;
- }
- .i-bell {
- float: left;
- position: relative;
- left: 10px;
- top: 10px;
- font-size: 24px;
- color: red;
- }
- .task-msg {
- padding-left: 10px;
- }
- .b-top {
- width: 100%;
- padding-top: 10px;
- }
- .b-bottom {
- width: 100%;
- border-bottom: 1px solid rgba(24, 28, 33, 0.5);
- }
- .i-set-right {
- position: absolute;
- left: 80px;
- top: -11px;
- font-size: 24px;
- }
- .i-remove-right {
- position: absolute;
- right: -1px;
- top: -11px;
- font-size: 24px;
- color: red;
- }
- .alg-t {
- line-height: 31px;
- font-family: PingFangSC-Medium;
- font-size: 14px;
- color: #222222;
- }
- .alg-name {
- //margin-top: 12px;
- line-height: 20px;
- font-family: PingFangSC-Regular;
- font-size: 14px;
- letter-spacing: 0.05em;
- color: #333;
- // background-color: #ecf5ff;
- .el-input {
- position: relative;
- font-size: 14px;
- display: inline-block;
- width: 100%;
- }
- }
- .unit-class {
- margin-left: 10px;
- text-align: center;
- line-height: 38px;
- }
.el-input {
position: relative;
font-size: 14px;
- display: inline-block;
- width: 80%;
+ // display: inline-block;
+ // width: 80%;
}
- .list-complete-item-handle {
- height: 100%;
- //padding-bottom: 10px;
- text-align: center;
- .svg-wrap {
- //width: 80%;
- width: 100%;
- margin: auto;
- padding-top: 80%;
- padding-top: 100%;
- position: relative;
- box-shadow: 0 5px 12px 0 rgba(0, 0, 0, 0.07);
- border-radius: 25px;
- svg {
- position: absolute;
- top: 50%;
- left: 50%;
- transform: translate(-50%, -50%);
- }
- .baseImg {
- width: 100%;
- position: absolute;
- top: 50%;
- left: 50%;
- transform: translate(-50%, -50%);
- max-height: 150px;
- // max-width: 106px;
- // max-height: 106px;
- }
- }
- .willUpGrade {
- .update-icon {
- position: absolute;
- top: -8px;
- right: -8px;
- z-index: 999;
- }
- .iconupdate {
- color: #01e667;
- position: absolute;
- top: 5px;
- right: 5px;
- font-weight: 550;
- font-size: 26px;
- z-index: 999;
- }
- }
- &.uninstall {
- .svg-wrap {
- filter: grayscale(100%);
- }
- .alg-name {
- color: grey;
- }
- }
- }
- .dragAreaR {
- height: 100%;
- }
- .drag-info {
- min-width: 126px;
- height: 120px;
- border: 1px dashed #3d68e1;
- box-shadow: 0 5px 12px 0 rgba(0, 0, 0, 0.07);
- // box-shadow: 0px 0px 10px 3px rgba(0,0,0,0.3);
- border-radius: 4px;
- margin: 30px 10px 20px 10px;
- }
- .drag-info-text {
- letter-spacing: 3px;
- line-height: 20px;
- width: 80px;
- height: 42px;
- font-family: PingFangSC-Regular;
- font-size: 13px;
- color: #3d68e1;
- text-align: center;
- }
- .task-edit {
- font-size: 26px;
- position: relative;
- bottom: -6px;
- }
.el-button--cancle {
background: #eaeaea;
border-radius: 2px;
@@ -2577,85 +1575,15 @@
color: #222222;
margin-right: 12px;
}
- .click-changeImg {
- cursor: pointer;
- display: none;
- background: rgba(0, 0, 0, 0.35);
- width: 74px;
- line-height: 20px;
- color: rgb(255, 255, 255);
- font-size: 14px;
- opacity: 1;
- border-radius: 6px;
- }
-
- .task-name-google {
- position: relative;
- top: 30px;
- width: 126px;
- height: 120px;
- border: 1px solid #fff;
- background: #fff;
- border-radius: 4px;
- cursor: pointer;
- .set-task {
- display: none;
- cursor: pointer;
- }
-
- .el-switch__core {
- width: 27px !important;
- height: 14px;
- }
- .el-switch__core:after {
- width: 10px;
- height: 10px;
- }
- .el-switch.is-checked .el-switch__core::after {
- left: 100%;
- margin-left: -11px;
- }
- }
- .task-name-google:hover {
- .mask {
- display: block;
- }
- }
}
}
-.active-Dial {
- .el-dialog {
- min-width: 400px;
- }
- .dialog-active {
- .desc {
- padding: 0 30px;
- margin-bottom: 30px;
- li {
- border-bottom: 1px solid #eee;
- height: 45px;
- line-height: 45px;
- font-size: 14px;
- &:last-child {
- border-bottom: none;
- }
- label {
- display: inline-block;
- width: 90px;
- padding-left: 14px;
- font-weight: bold;
- }
- }
- }
- .text-right {
- padding-right: 30px;
- text-align: right;
- .tip {
- color: #999;
- line-height: 38px;
- }
- }
+@media screen and (max-width: 800px) {
+ .quick-path .left-items .quick-item:last-child {
+ display: none !important;
+ }
+ .quick-path .left-items .quick-item:nth-child(2) {
+ border: none !important;
}
}
</style>
diff --git a/src/pages/ai/index/api.ts b/src/pages/ai/index/api.ts
index 371bbfc..7acc4d6 100644
--- a/src/pages/ai/index/api.ts
+++ b/src/pages/ai/index/api.ts
@@ -142,6 +142,14 @@
params: data
})
}
+export const uploadSDK = (data: any) => {
+ return request({
+ url: "/data/api-v/sdk/upload",
+ method: "post",
+ data
+ })
+}
+
//瀹夎宸蹭笂浼犵殑绠楁硶鎺ュ彛
export const installSdk = (file: any) => {
return request({
diff --git a/src/pages/ai/index/detail.vue b/src/pages/ai/index/detail.vue
new file mode 100644
index 0000000..8eb62e4
--- /dev/null
+++ b/src/pages/ai/index/detail.vue
@@ -0,0 +1,1117 @@
+<template>
+ <div class="detail-page">
+ <div class="detail-top">
+ <div class="title-area">
+ <div class="icon-img">
+ <img v-if="productDetail.logoUrl" :src="productDetail.logoUrl" alt />
+ </div>
+ <div class="right-info">
+ <div class="right-info-1">
+ <span class="name">{{ productDetail.productName }}</span>
+ <el-tag type="info" size="mini" color="#fff">{{ isSDKDetail ? "绠楁硶" : "搴旂敤" }}</el-tag>
+ </div>
+ <div class="right-info-2">
+ <el-button size="mini" round class="update-btn" @click="upgradeSDKinWin" v-if="productDetail.isUpgrade"
+ >鏇存柊</el-button
+ >
+ <el-button size="mini" round v-if="!isSDKDetail && isActive" @click="openApp">鎵撳紑</el-button>
+ <el-button size="mini" round v-if="isActive && !isDefaultApp" @click="unloadSDKinWin">鍗歌浇</el-button>
+ <el-button
+ size="mini"
+ round
+ v-if="!isActive && (!detailPrice || showInstallNotActive)"
+ @click="downloadSdkInSide"
+ >瀹夎</el-button
+ >
+ <!-- suffix-icon="iconfont iconchushaixuanxiang" -->
+ <el-input
+ class="activeInput"
+ placeholder="璇疯緭鍏ユ縺娲荤爜"
+ size="mini"
+ clearable
+ :autofocus="true"
+ v-model="activeCode"
+ v-if="!isActive && !showInstallNotActive && detailPrice"
+ >
+ </el-input>
+ <el-button
+ size="mini"
+ round
+ class="act-btn"
+ v-if="!isActive && !showInstallNotActive && detailPrice"
+ @click="actived"
+ >婵�娲�</el-button
+ >
+ <!-- <span
+ class="icon iconfont"
+ v-if="!isActive && !showInstallNotActive"
+ @click="activeCode = ''"
+ ></span
+ > -->
+ </div>
+ </div>
+ <!-- <div class="back-btn" @click="goback">
+ <span class="icon iconfont"></span>
+ <span class="back-text">杩斿洖</span>
+ </div> -->
+ </div>
+ <div class="text-area">
+ <div class="text-line">
+ <span class="icon iconfont"></span>
+ <span class="title">鐗堟湰锛�</span>
+ <span class="desc">{{ productDetail.productVersion }}</span>
+ </div>
+ <div class="text-line">
+ <span class="icon iconfont"></span>
+ <span class="title">姒傝堪锛�</span>
+ <span class="desc">{{ productDetail.description || "鏆傛棤" }}</span>
+ </div>
+ <div class="text-line">
+ <span class="icon iconfont"></span>
+ <span class="title">璇﹁堪锛�</span>
+ <span class="desc">{{ productDetail.summary || "鏆傛棤" }}</span>
+ </div>
+ </div>
+ </div>
+ <div class="detail-mid">
+ <div class="mid-left">
+ <div class="mid-title">{{ isSDKDetail ? "搴旂敤鍦烘櫙" : "鍔熻兘鐗圭偣" }}</div>
+ <div v-for="(item, index) in productDetail.funcInfo" :key="index" class="desc-item">
+ <div class="title">{{ item.title }}</div>
+ <div class="desc">{{ item.desc }}</div>
+ </div>
+ </div>
+ <div class="mid-right">
+ <el-carousel
+ trigger="click"
+ :autoplay="false"
+ indicator-position="none"
+ :arrow="productDetail.pics !== undefined ? (productDetail.pics.length > 1 ? 'always' : 'never') : 'never'"
+ >
+ <el-carousel-item v-for="(item, index) in productDetail.pics" :key="index">
+ <img v-if="item.type != 'video'" :src="item.url" class="cursor-pointer" preview />
+ <video v-if="item.type == 'video'" :src="'/httpImage/' + item.url" controls></video>
+ </el-carousel-item>
+ </el-carousel>
+ </div>
+ </div>
+ <div class="rec-bot">
+ <div class="rec-title">{{ isSDKDetail ? "鎺ㄨ崘绠楁硶" : "鎺ㄨ崘搴旂敤" }}</div>
+
+ <div class="rec-items">
+ <div class="rec-item" v-for="(item, index) in otherProducts" :key="index" @click="checkInWindow(item)">
+ <div class="icon-img">
+ <img
+ v-if="item.iconBlob"
+ :src="item.iconBlob.indexOf(',') > 0 ? item.iconBlob : `data:image/png;base64,${item.iconBlob}`"
+ alt
+ />
+ </div>
+ <div class="desc">
+ <el-tooltip :content="item.name" effect="light">
+ <div class="desc-1">{{ item.name }}</div>
+ </el-tooltip>
+ <div class="desc-2">鐗堟湰 {{ item.productVersion || "2.0.0" }}</div>
+ </div>
+ <div class="right-btn">
+ <el-button size="small" type="primary" round @click="checkInWindow(item)">鏌ョ湅</el-button>
+ </div>
+ </div>
+ </div>
+ </div>
+
+ <el-dialog :visible.sync="showActivateSuccess" title="婵�娲绘垚鍔燂紒" width="30%" class="active-Dial">
+ <div class="dialog-active">
+ <ul class="desc">
+ <li>
+ <label>婵�娲荤爜:</label>
+ <span>{{ activedSdkOrApp.activateCode }}</span>
+ </li>
+ <li>
+ <label>浜у搧鍚嶇О:</label>
+ <span>{{ activedSdkOrApp.productName }}</span>
+ </li>
+ <li>
+ <label>閰嶇疆璇︽儏:</label>
+ <span>{{ activedSdkOrApp.setting }}</span>
+ </li>
+ <li>
+ <label>鏈嶅姟鍒版湡鏃�:</label>
+ <span>{{ activedSdkOrApp.expireTime }}</span>
+ </li>
+ <li>
+ <label>璁稿彲璇�:</label>
+ <span>{{ activedSdkOrApp.licence }}</span>
+ </li>
+ </ul>
+ <div class="text-right">
+ <el-button type="primary" @click="checkMyAlgorith">纭畾</el-button>
+ <p class="tip">鎻愮ず锛氳鍦ㄢ�滃凡婵�娲烩�濅腑鏌ョ湅骞跺畨瑁呯畻娉�</p>
+ </div>
+ </div>
+ </el-dialog>
+ </div>
+</template>
+<script>
+import { findAllSdk, downloadSdk, installSdk, getInstallInfo, removeSdk } from "./api"
+import {
+ getApps,
+ installApp,
+ getAppDetail,
+ removeApp,
+ getUnActivedSdk,
+ actPageAlg,
+ getUnActivedApp,
+ actApp
+} from "@/api/app"
+import { getUrlKey } from "@/api/utils"
+export default {
+ components: {},
+ computed: {
+ updateNum() {
+ return this.hasNewVersionApp.length + this.hasNewVersionSdk.length
+ },
+ isAdmin() {
+ if (sessionStorage.getItem("userInfo") && sessionStorage.getItem("userInfo") !== "") {
+ let loginName = JSON.parse(sessionStorage.getItem("userInfo")).username
+ return loginName === "superadmin" || loginName === "basic"
+ }
+
+ return false
+ }
+ },
+ data() {
+ return {
+ installedList: [],
+ hasNewVersionSdk: [],
+ hasNewVersionApp: [],
+ notInstalledList: [],
+ buttonAuthority: sessionStorage.getItem("buttonAuthoritys") || [],
+ activeName: "myAlgorithm",
+ patchUpdateStatus: "",
+ downloadItem: "",
+ downloading: false,
+ actStep: 0,
+ showActivateSuccess: false,
+ activeCode: "",
+ isInstall: false,
+ installDialogVisible: false,
+ installAppPackage: null,
+ installSdkPackage: null,
+ isActive: true,
+ isDefaultApp: false,
+ unActivedSDKList: [],
+ unActivedAppList: [],
+ isSDKDetail: true,
+ actType: "",
+ actId: "",
+ select: "",
+ activedSdkOrApp: {
+ activateCode: "",
+ productName: "",
+ setting: "",
+ expireTime: "",
+ licence: "",
+ devIds: ""
+ },
+ installedApps: [],
+ storeApps: [],
+ installFile: {},
+ appUpgreading: false,
+ sdkUpgreading: false,
+ autoRefresh: true,
+ productDetailVisible: false,
+ isUpgrading: false,
+ productDetail: {},
+ otherProducts: [],
+ backStack: [],
+ toUpdateArr: [],
+ toUpdateArr1: [],
+ forwardStack: [],
+ backDisable: true,
+ forwardDisable: true,
+ showInputCode: false,
+ needToUpgradeInWin: false,
+ showInstallNotActive: false
+ }
+ },
+ props: {
+ detailType: {
+ type: String
+ },
+ detailProductID: {
+ type: String
+ },
+ detailPrice: {},
+ isSdk: {}
+ },
+ directives: {
+ focus: {
+ inserted: function(el) {
+ el.querySelector("input").focus()
+ }
+ }
+ },
+ mounted() {
+ this.getDetail()
+ this.autoRefreshAppAndSdkState()
+ // this.getUnActivedList();
+ // this.getUnActivedAppList();
+ this.showBackBtn()
+ this.addBackListener()
+ },
+ beforeDestroy() {
+ this.autoRefresh = false
+ this.hiddenBackBtn()
+ },
+ methods: {
+ getDetail(id) {
+ getAppDetail({ id: id || this.detailProductID })
+ .then((res) => {
+ if (res.success) {
+ this.productDetail = res.data.detail
+ this.otherProducts = res.data.randoms
+
+ this.isSDKDetail = this.productDetail.productTypeName == "SDK"
+ this.isDefaultApp = this.productDetail.productBaseId.length < 10
+ } else {
+ this.$message.error(res.msg)
+ }
+ })
+ .catch((err) => {
+ this.$message.error(err.msg)
+ })
+ this.isActive = this.detailType == "active"
+ this.showInstallNotActive = this.detailType == "activeNotInstall"
+ },
+ goback() {
+ this.productDetail = {}
+ this.$emit("goback")
+ },
+ isShow(authority) {
+ return this.isAdmin || this.buttonAuthority.indexOf("," + authority + ",") > -1
+ },
+ closeDial() {
+ this.productDetailVisible = false
+ this.productDetail = {}
+ this.otherProducts = []
+ },
+
+ resetStack() {
+ this.forwardStack = []
+ this.backStack = []
+ this.backDisable = true
+ this.forwardDisable = true
+ },
+ checkInWindow(item) {
+ getAppDetail({ id: item.id }).then((res) => {
+ this.productDetail = res.data.detail
+ this.productDetail.iconBlob = item.iconBlob
+ this.actId = this.productDetail.productBaseId
+ this.isSDKDetail = this.productDetail.productTypeName == "SDK"
+ this.isDefaultApp = this.productDetail.productBaseId.length < 10
+
+ this.otherProducts = res.data.randoms
+ })
+ },
+ checkIsDefOrNot(id) {
+ if (id.length > 10) {
+ this.isDefaultApp = false
+ } else {
+ this.isDefaultApp = true
+ }
+ },
+ backwards() {
+ if (this.backStack.length == 0) {
+ this.backDisable = true
+ return
+ }
+ this.forwardStack.push([this.productDetail, this.otherProducts])
+ let item = this.backStack.pop()
+ this.productDetail = item[0]
+ this.checkIsDefOrNot(this.productDetail.productBaseId)
+ this.otherProducts = item[1]
+ this.forwardDisable = false
+ if (this.backStack.length == 0) {
+ this.backDisable = true
+ }
+ },
+ forwards() {
+ if (this.forwardStack.length == 0) {
+ this.forwardDisable = true
+ return
+ }
+
+ this.backStack.push([this.productDetail, this.otherProducts])
+ this.backDisable = false
+ let item = this.forwardStack.pop()
+
+ this.productDetail = item[0]
+ this.otherProducts = item[1]
+ if (this.forwardStack.length == 0) {
+ this.forwardDisable = true
+ }
+ },
+ //绂荤嚎瀹夎
+ offlineInstall() {
+ this.installDialogVisible = false
+ this.isInstall = true
+ //瀹夎
+ installSdk(this.installFile)
+ .then((res) => {
+ if (res.success) {
+ this.isInstall = false
+ this.$message({
+ type: "success",
+ message: '瀹夎鎴愬姛,灏嗚烦杞嚦"宸叉縺娲�"涓煡鐪�'
+ })
+ setTimeout(() => {
+ this.getAllSdk()
+ window.parent.postMessage(
+ {
+ msg: "AppUpdate"
+ },
+ "*"
+ )
+ this.activeName = "myAlgorithm"
+ }, 3000)
+ }
+ })
+ .catch((e) => {
+ console.log(e)
+ this.isInstall = false
+ this.$message({
+ type: "error",
+ message: e.msg
+ })
+ })
+ },
+ downloadApp(app, action) {
+ if (action == "upgrade") {
+ app.upgradeLoading = true
+ } else {
+ app.installLoading = true
+ }
+ let _this = this
+
+ installApp({ path: app.id })
+ .then((res) => {
+ if (res && res.success) {
+ _this.$notify({
+ title: "鎴愬姛",
+ message: "瀹夎搴旂敤鎴愬姛",
+ type: "success"
+ })
+ setTimeout(() => {
+ if (action == "upgrade") {
+ app.upgradeLoading = false
+ } else {
+ app.installLoading = false
+ }
+ window.parent.postMessage(
+ {
+ msg: "AppUpdate"
+ },
+ "*"
+ )
+ }, 3000)
+ } else {
+ }
+ })
+ .catch((e) => {
+ _this.$notify({
+ title: "瀹夎澶辫触",
+ message: e.data,
+ type: "warning"
+ })
+ if (action == "upgrade") {
+ app.upgradeLoading = false
+ } else {
+ app.installLoading = false
+ }
+ })
+
+ // 寮�鍚嚜鍔ㄥ埛鏂�
+ this.appUpgreading = true
+ },
+ async getAllApps() {
+ let iArry = [],
+ sArry = [],
+ nArry = []
+ let rsp = await getApps()
+ if (rsp && rsp.success) {
+ // 閬嶅巻app鐨勮繃绋嬮噸缃�
+ this.appUpgreading = false
+
+ rsp.data.forEach((item) => {
+ let obj = Object.assign({ unloadLoading: false, upgradeLoading: false }, item)
+ if (obj.progressMsg !== "" && obj.progressMsg !== "宸插畨瑁�") {
+ obj.upgradeLoading = true
+ this.appUpgreading = true
+ }
+
+ if (obj.upgradeDone) {
+ this.$notify({
+ type: "success",
+ message: 1 ? "绠楁硶瀹夎鎴愬姛" : "绠楁硶鍗囩骇鎴愬姛"
+ })
+ }
+
+ item.installed ? iArry.push(obj) : sArry.push(obj)
+ item.isUpgrade && nArry.push(obj)
+ })
+ }
+ this.installedApps = iArry
+ this.storeApps = sArry
+ this.hasNewVersionApp = nArry
+ },
+ unLoad(app) {
+ let _this = this
+ this.$confirm("纭畾瑕佸嵏杞借搴旂敤鍚�?", "鎻愮ず")
+ .then(() => {
+ _this.productDetailVisible = false
+ app.unloadLoading = true
+ removeApp({ appId: app.id })
+ .then((res) => {
+ if (res && res.success) {
+ app.unloadLoading = false
+ this.$emit("flushApp")
+ window.parent.postMessage(
+ {
+ msg: "AppUpdate"
+ },
+ "*"
+ )
+ _this.$notify({
+ title: "鎴愬姛",
+ message: "鍗歌浇搴旂敤鎴愬姛",
+ type: "success"
+ })
+ this.goback()
+ }
+ })
+ .catch((e) => {
+ app.unloadLoading = false
+ })
+ })
+ .catch((e) => {})
+ },
+ actSdkOrApp(item, type = "sdk") {
+ this.checkDetail(item, "inactive")
+ this.actType = type
+ this.actId = item.id
+ this.actStep = 0
+ this.activeCode = ""
+ this.activedSdkOrApp = this.newActInfo()
+ },
+ cancelActivate() {
+ this.showInputCode = false
+ this.activeCode = ""
+ },
+ newActInfo() {
+ return {
+ activateCode: "",
+ productName: "",
+ setting: "",
+ expireTime: "",
+ licence: "",
+ devIds: ""
+ }
+ },
+ getUnActivedList() {
+ getUnActivedSdk().then((res) => {
+ if (res.code == 200) {
+ this.unActivedSDKList = res.data
+ }
+ })
+ },
+ getUnActivedAppList() {
+ getUnActivedApp().then((res) => {
+ if (res.code == 200) {
+ this.unActivedAppList = res.data
+ }
+ })
+ },
+ actived() {
+ let _this = this
+ if (this.activeCode.trim() == "") {
+ this.$notify({
+ type: "error",
+ message: "婵�娲荤爜涓嶈兘涓虹┖"
+ })
+ return
+ }
+ if (this.isSdk) {
+ //婵�娲荤畻娉�
+ actPageAlg(this.detailProductID, this.activeCode)
+ .then((res) => {
+ if (res.data.isSuccess) {
+ this.productDetailVisible = false
+ _this.activedSdkOrApp = res.data.successMsg
+ this.showActivateSuccess = true
+ _this.actStep++
+ _this.getUnActivedList()
+ _this.getAllSdk()
+ } else {
+ _this.$notify({
+ type: "error",
+ message: res.data.failMsg.failMsg
+ })
+ }
+ })
+ .catch((e) => {
+ this.$notify({
+ type: "error",
+ message: e.msg
+ })
+ })
+ } else {
+ //婵�娲诲簲鐢�
+ actApp(this.detailProductID, this.activeCode)
+ .then((res) => {
+ if (res.data.isSuccess) {
+ this.productDetailVisible = false
+ _this.activedSdkOrApp = res.data.successMsg
+ this.showActivateSuccess = true
+ _this.actStep++
+ _this.getUnActivedAppList()
+ _this.getAllApps()
+ } else {
+ _this.$notify({
+ type: "error",
+ message: res.data.failMsg.failMsg
+ })
+ }
+ })
+ .catch((e) => {
+ this.$notify({
+ type: "error",
+ message: e.msg
+ })
+ })
+ }
+ },
+ checkMyAlgorith() {
+ this.showActivateSuccess = false
+ this.goback()
+ this.activeName = "宸叉縺娲�"
+ },
+ onFileUpload(file) {
+ this.patchFile = { ...file }
+ this.fileAdded = true
+ const h = this.$createElement
+ //涓婁紶瀹屾垚鑾峰彇瀹夎淇℃伅
+ let _this = this
+ getInstallInfo(file)
+ .then((res) => {
+ _this.installFile = file
+ if (res.success) {
+ _this.installDialogVisible = true
+ if (res.data.apps.length > 0) {
+ _this.installAppPackage = {
+ appId: res.data.apps[0].appId,
+ version: res.data.apps[0].version,
+ productName: res.data.productName,
+ installContent: res.data.apps[0].installContent
+ }
+ }
+ if (res.data.sdks.length > 0) {
+ _this.installSdkPackage = {
+ appId: res.data.sdks[0].sdkId,
+ version: res.data.sdks[0].version,
+ productName: res.data.productName,
+ installContent: res.data.sdks[0].installContent
+ }
+ }
+ } else {
+ this.$message({
+ type: "error",
+ message: res.msg
+ })
+ }
+ })
+ .catch((e) => {
+ this.$message({
+ type: "error",
+ message: e.msg
+ })
+ })
+ },
+ openApp() {
+ window.parent.postMessage({ msg: "toOpenApp?" + this.productDetail.productBaseId }, "*")
+ },
+ onFileAdded(f) {
+ this.patchUpdateStatus = ""
+ },
+ async getAllSdk() {
+ let installedList = []
+ let unInstalledList = []
+ let hasNewVersionList = []
+ let res = await findAllSdk()
+ if (res && res.success) {
+ this.sdkUpgreading = false
+
+ res.data.forEach((item) => {
+ let obj = Object.assign({ unloadLoading: false, upgradeLoading: false }, item)
+ if (obj.progressMsg !== "" && obj.progressMsg !== "宸插畨瑁�") {
+ obj.upgradeLoading = true
+ this.sdkUpgreading = true
+ }
+
+ //绠楁硶杞欢 宸插畨瑁呭叾涓寘鍚緟鍗囩骇 鏈畨瑁�
+ item.installed ? installedList.push(obj) : unInstalledList.push(obj)
+ item.isUpgrade ? hasNewVersionList.push(obj) : null
+ })
+ }
+ this.installedList = installedList
+ this.notInstalledList = unInstalledList
+ this.toUpdateArr = this.installedList.slice(0, 4)
+ this.hasNewVersionSdk = hasNewVersionList
+ },
+ unloadSDKinWin() {
+ let appToUnload
+ let sdkToUnload
+ if (this.productDetail.productTypeName == "搴旂敤") {
+ appToUnload = this.installedApps.find((item) => {
+ return item.id == this.productDetail.productBaseId
+ })
+ this.unLoad(appToUnload)
+ } else {
+ sdkToUnload = this.installedList.find((item) => {
+ return item.id == this.productDetail.productBaseId
+ })
+ this.unLoadSdk(sdkToUnload)
+ }
+ },
+ //鍗歌浇绠楁硶
+ unLoadSdk(sdk) {
+ let _this = this
+ this.$confirm("纭畾瑕佸嵏杞借绠楁硶鍚�?", "鎻愮ず")
+ .then(() => {
+ _this.productDetailVisible = false
+ sdk.unloadLoading = true
+ removeSdk({ sdkId: sdk.id })
+ .then((res) => {
+ if (res && res.success) {
+ sdk.unloadLoading = false
+ this.$notify.success("鍗歌浇瀹屾垚")
+ // _this.getAllSdk();
+ this.$emit("flushSdk")
+ window.parent.postMessage({ msg: "AppUpdate" }, "*")
+ this.goback()
+ }
+ })
+ .catch((e) => {
+ console.log(e)
+ sdk.unloadLoading = false
+ })
+ })
+ .catch((e) => {
+ console.log("鍙栨秷", e)
+ })
+ },
+ upgradeSDKinWin() {
+ this.isUpgrading = !this.isUpgrading
+ if (this.productDetail.productTypeName == "搴旂敤") {
+ installApp({ path: this.productDetail.productBaseId })
+ .then((res) => {
+ if (res && res.success) {
+ this.$notify.success("鍗囩骇瀹屾垚")
+ this.needToUpgradeInWin = false
+ this.productDetail.isUpgrade = false
+ this.isUpgrading = !this.isUpgrading
+ }
+ })
+ .catch((e) => {
+ this.$notify.error("鍗囩骇澶辫触")
+ this.isUpgrading = !this.isUpgrading
+ })
+
+ // 寮�鍚嚜鍔ㄥ埛鏂�
+ this.appUpgreading = true
+ } else {
+ downloadSdk({ path: this.productDetail.productBaseId })
+ .then((res) => {
+ this.needToUpgradeInWin = false
+ this.productDetail.isUpgrade = false
+ this.isUpgrading = !this.isUpgrading
+ this.$notify.success("鍗囩骇瀹屾垚")
+ })
+ .catch((err) => {
+ this.$notify.error("鍗囩骇澶辫触")
+ this.isUpgrading = !this.isUpgrading
+ })
+ this.sdkUpgreading = true
+ }
+ },
+ downloadSdkInSide() {
+ this.downloadItem = this.productDetail.productBaseId
+ this.isUpgrading = true
+ downloadSdk({ path: this.productDetail.productBaseId })
+ .then((rsp) => {
+ this.productDetailVisible = false
+ this.downloadItem = ""
+ this.$notify.success("绠楁硶宸插畨瑁�")
+ this.isUpgrading = false
+ })
+ .catch((err) => {
+ this.$notify.warning(err.data)
+ this.downloadItem = ""
+ this.isUpgrading = false
+ })
+ // 寮�鍚嚜鍔ㄥ埛鏂�
+ this.sdkUpgreading = true
+ },
+ donwload(item, typ) {
+ item.upgradeLoading = true
+ this.downloadItem = item.id
+ downloadSdk({ path: item.id })
+ .then((rsp) => {
+ item.upgradeLoading = false
+ this.downloadItem = ""
+ window.parent.postMessage(
+ {
+ msg: "AppUpdate"
+ },
+ "*"
+ )
+ })
+ .catch((err) => {
+ this.$notify({
+ type: "warning",
+ message: err.data
+ })
+ item.upgradeLoading = false
+ this.downloadItem = ""
+ })
+ // 寮�鍚嚜鍔ㄥ埛鏂�
+ this.sdkUpgreading = true
+ },
+ inputBlur(item) {
+ this.$set(item, "isEdit", false)
+ },
+ autoRefreshAppAndSdkState() {
+ this.getAllApps()
+ this.getAllSdk()
+ if (!this.autoRefresh) {
+ return
+ }
+ setTimeout(() => {
+ if (this.appUpgreading) {
+ this.getAllApps()
+ }
+ if (this.sdkUpgreading) {
+ this.getAllSdk()
+ }
+ }, 1000)
+ },
+ showBackBtn() {
+ window.parent.postMessage(
+ {
+ msg: "showBack"
+ },
+ "*"
+ )
+ },
+ hiddenBackBtn() {
+ window.parent.postMessage(
+ {
+ msg: "hiddenBack"
+ },
+ "*"
+ )
+ },
+ addBackListener() {
+ window.addEventListener("message", (e) => {
+ if (e.data.msg === "杩斿洖搴旂敤涓績") {
+ this.goback()
+ }
+ })
+ }
+ }
+}
+</script>
+<style lang="scss">
+.detail-page {
+ width: 100% !important;
+ height: 100%;
+ box-sizing: border-box;
+ text-align: left;
+ // min-width: 1106px;
+ .detail-top {
+ padding: 35px 60px;
+ padding-bottom: 20px;
+ border-bottom: 3px solid #f2f2f2;
+ .title-area {
+ display: flex;
+ margin-bottom: 10px;
+ position: relative;
+ .back-btn {
+ position: absolute;
+ right: 0;
+ top: 0;
+ width: 51px;
+ height: 20px;
+ line-height: 20px;
+ display: flex;
+ justify-content: center;
+ align-items: center;
+ cursor: pointer;
+ .icon {
+ margin-right: 3px;
+ font-size: 18px;
+ }
+ .back-text {
+ font-size: 14px;
+ letter-spacing: 0.5px;
+ }
+ }
+ .icon-img {
+ height: 60px;
+ width: 60px;
+ margin-right: 20px;
+ img {
+ width: 60px;
+ height: 60px;
+ }
+ }
+ .right-info {
+ .right-info-1 {
+ display: flex;
+ align-items: center;
+ margin-bottom: 10px;
+
+ .name {
+ font-size: 16px;
+ font-weight: bold;
+ letter-spacing: 0.5px;
+ line-height: 26px;
+ margin-right: 12px;
+ }
+ .el-tag {
+ line-height: 18px;
+ height: 18px;
+ padding: 0 5px;
+ color: #bdbdbd;
+ border: 1px solid #e0e0e0;
+ }
+ }
+ .right-info-2 {
+ display: flex;
+ align-items: center;
+ .activeInput {
+ .el-input__suffix {
+ display: flex;
+ align-items: center;
+ .el-input__suffix-inner {
+ border-color: none;
+ .el-icon-circle-close:before {
+ content: "\e79d" !important;
+ font-size: 14px;
+ }
+ }
+ }
+ }
+ .iconfont {
+ margin-left: 10px;
+ font-size: 15px;
+ cursor: pointer;
+ }
+ .el-input {
+ margin-right: 12px;
+ width: 224px;
+ font-size: 12px;
+ .el-input__inner {
+ border: 1px solid #bdbdbd;
+ border-radius: 20px;
+ height: 22px;
+ line-height: 22px;
+ }
+ }
+ .el-button {
+ padding: 3px 13px;
+ color: #4f4f4f;
+ font-weight: bold;
+ letter-spacing: 0.5px;
+ background: #f2f2f7;
+ border: 1px solid #f2f2f7;
+ }
+ .update-btn {
+ border-color: #23d7ee;
+ background-color: rgba(29, 212, 236, 0.1);
+ }
+ .act-btn {
+ background: #23d7ee;
+ border: 1px solid #23d7ee;
+ color: #f2f2f2;
+ }
+ // .act-btn:hover {
+ // background: #089fb3 !important;
+ // border-color: #089fb3 !important;
+ // }
+ // .el-button:hover {
+ // border-color: #23d7ee;
+ // background-color: rgba(29, 212, 236, 0.1);
+ // }
+ .el-button + .el-button {
+ margin-left: 12px;
+ }
+ }
+ }
+ }
+ .text-area {
+ .text-line {
+ line-height: 17px;
+ height: 25px;
+ .icon {
+ font-size: 14px;
+ margin-right: 4px;
+ }
+ .title {
+ font-size: 12px;
+ font-weight: bold;
+ letter-spacing: 0.5px;
+ }
+ .desc {
+ letter-spacing: 0.5px;
+ }
+ }
+ }
+ }
+ .detail-mid {
+ padding: 20px 60px;
+ display: flex;
+ justify-content: space-between;
+ border-bottom: 3px solid #f2f2f2;
+ .mid-left {
+ max-width: 560px;
+
+ .mid-title {
+ font-size: 16px;
+ font-weight: bold;
+ letter-spacing: 0.5px;
+ line-height: 26px;
+ margin-bottom: 10px;
+ }
+ .desc-item {
+ margin-bottom: 10px;
+
+ .title {
+ display: inline-block;
+ line-height: 20px;
+ padding: 0px 10px;
+ letter-spacing: 0.5px;
+ font-size: 12px;
+ color: #828282;
+ font-weight: bold;
+ border: 1px solid #e0e0e0;
+ box-sizing: border-box;
+ border-radius: 22px;
+ }
+ .desc {
+ margin-left: 20px;
+ color: #4f4f4f;
+ font-size: 12px;
+ line-height: 17px;
+ }
+ }
+ }
+ .mid-right {
+ width: 460px;
+ .el-carousel__container {
+ position: relative;
+ height: 280px;
+ .el-carousel__item {
+ display: flex;
+ align-items: center;
+ img {
+ width: 100%;
+ }
+ }
+ }
+ .imgwrap {
+ img {
+ width: 100%;
+ }
+ }
+ }
+ }
+ .rec-bot {
+ padding: 20px 60px;
+ .rec-title {
+ font-size: 16px;
+ font-weight: bold;
+ letter-spacing: 0.5px;
+ line-height: 26px;
+ margin-bottom: 20px;
+ }
+ }
+ .rec-items {
+ .rec-item {
+ cursor: pointer;
+ float: left;
+ display: flex;
+ margin: 0 15px;
+ margin-bottom: 30px;
+ padding: 2px 0;
+ height: 62px;
+ box-sizing: border-box;
+ width: 248px;
+ .icon-img {
+ width: 58px;
+ height: 58px;
+ img {
+ width: 58px;
+ height: 58px;
+ }
+ }
+ .desc {
+ box-sizing: border-box;
+ padding: 0 12px;
+
+ width: 100%;
+ .desc-1 {
+ font-size: 14px;
+ font-weight: bold;
+ line-height: 28px;
+ width: 116px;
+ height: 28px;
+ letter-spacing: 0.1px;
+ color: #4f4f4f;
+
+ overflow: hidden;
+ white-space: nowrap;
+ text-overflow: ellipsis;
+ }
+ .desc-2 {
+ font-size: 12px;
+ color: #828282;
+ }
+ }
+ .right-btn {
+ padding: 5px 0;
+ .el-button {
+ padding: 3px 12px;
+ border-radius: 22px;
+ background-color: #f2f2f7 !important;
+ border-color: #f2f2f7 !important;
+ color: #4f4f4f;
+ font-size: 12px;
+ font-weight: bold;
+ }
+ // .el-button--primary:hover {
+ // background: #089fb3 !important;
+ // border-color: #089fb3 !important;
+ // }
+ }
+ }
+ }
+ .rec-items:after {
+ content: "";
+ display: block;
+ height: 0;
+ clear: both;
+ visibility: hidden;
+ }
+}
+</style>
diff --git a/src/pages/ai/index/mixins.ts b/src/pages/ai/index/mixins.ts
deleted file mode 100644
index e69de29..0000000
--- a/src/pages/ai/index/mixins.ts
+++ /dev/null
diff --git a/src/pages/desktop/index/components/ToolsEntry.vue b/src/pages/desktop/index/components/ToolsEntry.vue
index a69a0af..34a4eae 100644
--- a/src/pages/desktop/index/components/ToolsEntry.vue
+++ b/src/pages/desktop/index/components/ToolsEntry.vue
@@ -185,7 +185,7 @@
if (dock.type === "1") {
window.open(dock.url)
} else if (dock.type === "2" && !dock.isOpen) {
- if (dock.url == "/view/debuggTool/") {
+ if ((dock.url).indexOf('/view/debuggTool')>=0||(dock.url).indexOf('/view/knowledge')>=0) {
return true
}
this.$store.dispatch("desktop/addFrame", {
--
Gitblit v1.8.0