diff --git a/app/Http/Controllers/Api/ProjectController.php b/app/Http/Controllers/Api/ProjectController.php index 293a48ce..4faf89b6 100755 --- a/app/Http/Controllers/Api/ProjectController.php +++ b/app/Http/Controllers/Api/ProjectController.php @@ -646,6 +646,72 @@ class ProjectController extends AbstractController return Base::retSuccess('success', $data); } + /** + * 获取任务详细描述 + * + * @apiParam {Number} task_id 任务ID + */ + public function task__content() + { + $user = User::authE(); + if (Base::isError($user)) { + return $user; + } else { + $user = User::IDE($user['data']); + } + // + $task_id = intval(Request::input('task_id')); + // 任务 + $task = ProjectTask::whereId($task_id)->first(); + if (empty($task)) { + return Base::retError('任务不存在'); + } + // 项目 + $project = Project::select($this->projectSelect) + ->join('project_users', 'projects.id', '=', 'project_users.project_id') + ->where('projects.id', $task->project_id) + ->where('project_users.userid', $user->userid) + ->first(); + if (empty($project)) { + return Base::retError('项目不存在或不在成员列表内'); + } + // + return Base::retSuccess('success', $task->content); + } + + /** + * 获取任务文件列表 + * + * @apiParam {Number} task_id 任务ID + */ + public function task__files() + { + $user = User::authE(); + if (Base::isError($user)) { + return $user; + } else { + $user = User::IDE($user['data']); + } + // + $task_id = intval(Request::input('task_id')); + // 任务 + $task = ProjectTask::whereId($task_id)->first(); + if (empty($task)) { + return Base::retError('任务不存在'); + } + // 项目 + $project = Project::select($this->projectSelect) + ->join('project_users', 'projects.id', '=', 'project_users.project_id') + ->where('projects.id', $task->project_id) + ->where('project_users.userid', $user->userid) + ->first(); + if (empty($project)) { + return Base::retError('项目不存在或不在成员列表内'); + } + // + return Base::retSuccess('success', $task->taskFile); + } + /** * {post} 添加任务 * diff --git a/app/Models/ProjectTask.php b/app/Models/ProjectTask.php index 2638d207..d0b90b2f 100644 --- a/app/Models/ProjectTask.php +++ b/app/Models/ProjectTask.php @@ -30,6 +30,7 @@ use Illuminate\Database\Eloquent\SoftDeletes; * @property \Illuminate\Support\Carbon|null $created_at * @property \Illuminate\Support\Carbon|null $updated_at * @property \Illuminate\Support\Carbon|null $deleted_at + * @property-read \App\Models\ProjectTaskContent|null $content * @property-read int $dialog_id * @property-read int $file_num * @property-read int $msg_num @@ -39,6 +40,8 @@ use Illuminate\Database\Eloquent\SoftDeletes; * @property-read int $sub_num * @property-read bool $today * @property-read \App\Models\Project|null $project + * @property-read \Illuminate\Database\Eloquent\Collection|\App\Models\ProjectTaskFile[] $taskFile + * @property-read int|null $task_file_count * @property-read \Illuminate\Database\Eloquent\Collection|\App\Models\ProjectTaskTag[] $taskTag * @property-read int|null $task_tag_count * @property-read \Illuminate\Database\Eloquent\Collection|\App\Models\ProjectTaskUser[] $taskUser @@ -214,6 +217,22 @@ class ProjectTask extends AbstractModel return $this->hasOne(Project::class, 'id', 'project_id'); } + /** + * @return \Illuminate\Database\Eloquent\Relations\HasOne + */ + public function content(): \Illuminate\Database\Eloquent\Relations\HasOne + { + return $this->hasOne(ProjectTaskContent::class, 'task_id', 'id'); + } + + /** + * @return \Illuminate\Database\Eloquent\Relations\HasMany + */ + public function taskFile(): \Illuminate\Database\Eloquent\Relations\HasMany + { + return $this->hasMany(projectTaskFile::class, 'task_id', 'id')->orderBy('id'); + } + /** * @return \Illuminate\Database\Eloquent\Relations\HasMany */ @@ -227,7 +246,7 @@ class ProjectTask extends AbstractModel */ public function taskTag(): \Illuminate\Database\Eloquent\Relations\HasMany { - return $this->hasMany(projectTaskTag::class, 'task_id', 'id')->orderByDesc('id'); + return $this->hasMany(projectTaskTag::class, 'task_id', 'id')->orderBy('id'); } /** diff --git a/package.json b/package.json index 16389cb9..be64bfe1 100644 --- a/package.json +++ b/package.json @@ -20,7 +20,7 @@ "lodash": "^4.17.19", "node-sass": "^4.11.0", "postcss": "^8.1.14", - "resolve-url-loader": "^3.1.3", + "resolve-url-loader": "^4.0.0", "sass": "^1.34.1", "sass-loader": "^7.1.0", "stylus": "^0.54.8", diff --git a/resources/assets/js/pages/manage.vue b/resources/assets/js/pages/manage.vue index 131cffd5..8e1ad407 100644 --- a/resources/assets/js/pages/manage.vue +++ b/resources/assets/js/pages/manage.vue @@ -103,11 +103,11 @@ @@ -169,7 +169,7 @@ export default { }, computed: { - ...mapState(['userId', 'userInfo', 'dialogMsgUnread', 'projectList', 'projectTask']), + ...mapState(['userId', 'userInfo', 'dialogMsgUnread', 'projectList', 'projectOpenTask']), }, watch: { diff --git a/resources/assets/js/pages/manage/components/ProjectList.vue b/resources/assets/js/pages/manage/components/ProjectList.vue index 8501071d..e06ed702 100644 --- a/resources/assets/js/pages/manage/components/ProjectList.vue +++ b/resources/assets/js/pages/manage/components/ProjectList.vue @@ -123,7 +123,7 @@ v-for="item in panelTask(column.project_task)" :class="['task-item task-draggable', item.complete_at ? 'complete' : '']" :style="item.color ? {backgroundColor: item.color} : {}" - @click="$store.commit('openTask', item)"> + @click="$store.dispatch('openTask', item.id)">
{{item.name}}
@@ -834,7 +834,7 @@ export default { this.$set(task, key, data[key]); }); if (data.parent_id) { - this.getTaskOne(data.parent_id); + this.$store.dispatch('taskOne', data.parent_id); } if (typeof updata.complete_at !== "undefined") { this.$store.commit('getProjectOne', data.project_id); @@ -848,26 +848,6 @@ export default { }); }, - getTaskOne(task_id) { - let task = null; - this.projectDetail.project_column.some(({project_task}) => { - task = project_task.find(({id}) => id === task_id); - if (task) return true; - }); - if (!task) return; - // - this.$store.dispatch("call", { - url: 'project/task/one', - data: { - task_id: task.id - }, - }).then((data, msg) => { - Object.keys(data).forEach(key => { - this.$set(task, key, data[key]); - }); - }); - }, - archivedOrRemoveTask(task, type) { if (task.loading === true) { return; diff --git a/resources/assets/js/pages/manage/components/TaskAdd.vue b/resources/assets/js/pages/manage/components/TaskAdd.vue index 8bcb7ee6..e7d2ca52 100644 --- a/resources/assets/js/pages/manage/components/TaskAdd.vue +++ b/resources/assets/js/pages/manage/components/TaskAdd.vue @@ -143,14 +143,14 @@ export default { autoresize_bottom_margin: 2, min_height: 200, max_height: 380, - valid_elements : 'a[href|target=_blank],em,strong/b,div[align],span[style],a,br,img,pre[class],code', + valid_elements : 'a[href|target=_blank],em,strong/b,div[align],span[style],a,br,img[src|alt|witdh|height],pre[class],code', toolbar: 'uploadImages | uploadFiles | bold italic underline forecolor backcolor | codesample | preview screenload' }, taskOptionFull: { menubar: 'file edit view', forced_root_block : false, remove_trailing_brs: false, - valid_elements : 'a[href|target=_blank],em,strong/b,div[align],span[style],a,br,img,pre[class],code', + valid_elements : 'a[href|target=_blank],em,strong/b,div[align],span[style],a,br,img[src|alt|witdh|height],pre[class],code', toolbar: 'uploadImages | uploadFiles | bold italic underline forecolor backcolor | codesample | preview screenload' }, diff --git a/resources/assets/js/pages/manage/components/TaskDetail.vue b/resources/assets/js/pages/manage/components/TaskDetail.vue index 84aee180..3f31ed06 100644 --- a/resources/assets/js/pages/manage/components/TaskDetail.vue +++ b/resources/assets/js/pages/manage/components/TaskDetail.vue @@ -1,8 +1,8 @@ @@ -109,8 +178,37 @@ export default { components: {TEditor}, data() { return { + nowTime: Math.round(new Date().getTime() / 1000), + nowInterval: null, + + innerHeight: window.innerHeight, + content: '随着互联网的发展,生活智能化越来越普及,各类智能产品逐渐出现到人们面前,在体验的过程中,其实里面有 很多细节需要深挖和思考。很多产品细节的背后都是为了提升用户操作效率、兼容用户使用场景、满足用户情感 表达,以最终达到对用户体验的提升。作为智能产品的设计师只有充分了解市面上的智能产品,才能设计出更好', + menuList: [ + { + command: 'priority', + icon: '', + name: '优先级', + }, { + command: 'owner', + icon: '', + name: '负责人', + }, { + command: 'times', + icon: '', + name: '截止时间', + }, { + command: 'file', + icon: '', + name: '附件', + }, { + command: 'subtask', + icon: '', + name: '子任务', + } + ], + taskPlugins: [ 'advlist autolink lists link image charmap print preview hr anchor pagebreak imagetools', 'searchreplace visualblocks visualchars code', @@ -126,20 +224,102 @@ export default { autoresize_bottom_margin: 2, min_height: 200, max_height: 380, - valid_elements : 'a[href|target=_blank],em,strong/b,div[align],span[style],a,br,img,pre[class],code', + valid_elements : 'a[href|target=_blank],em,strong/b,div[align],span[style],a,br,img[src|alt|witdh|height],pre[class],code', toolbar: 'uploadImages | uploadFiles | bold italic underline forecolor backcolor | codesample | preview screenload' }, taskOptionFull: { menubar: 'file edit view', forced_root_block : false, remove_trailing_brs: false, - valid_elements : 'a[href|target=_blank],em,strong/b,div[align],span[style],a,br,img,pre[class],code', + valid_elements : 'a[href|target=_blank],em,strong/b,div[align],span[style],a,br,img[src|alt|witdh|height],pre[class],code', toolbar: 'uploadImages | uploadFiles | bold italic underline forecolor backcolor | codesample | preview screenload' }, } }, - computed: { - ...mapState(['userId', 'projectTask']), + + mounted() { + this.nowInterval = setInterval(() => { + this.nowTime = Math.round(new Date().getTime() / 1000); + }, 1000); + window.addEventListener('resize', this.innerHeightListener); }, + + destroyed() { + clearInterval(this.nowInterval); + window.removeEventListener('resize', this.innerHeightListener); + }, + + computed: { + ...mapState(['userId', 'projectOpenTask']), + + scrollerStyle() { + const {innerHeight, projectOpenTask} = this; + if (!innerHeight || !projectOpenTask._dialog) { + return {}; + } + return { + maxHeight: (innerHeight - 70 - 66 - 30) + 'px' + } + }, + + expiresFormat() { + const {nowTime} = this; + return function (date) { + let time = Math.round(new Date(date).getTime() / 1000) - nowTime; + if (time < 86400 * 4 && time > 0 ) { + return this.formatSeconds(time); + } else if (time <= 0) { + return '-' + this.formatSeconds(time * -1); + } + return this.formatTime(date) + } + }, + }, + + watch: { + + }, + + methods: { + innerHeightListener() { + this.innerHeight = window.innerHeight; + }, + + formatTime(date) { + let time = Math.round(new Date(date).getTime() / 1000), + string = ''; + if ($A.formatDate('Ymd') === $A.formatDate('Ymd', time)) { + string = $A.formatDate('H:i', time) + } else if ($A.formatDate('Y') === $A.formatDate('Y', time)) { + string = $A.formatDate('m-d', time) + } else { + string = $A.formatDate('Y-m-d', time) + } + return string || ''; + }, + + formatBit(val) { + val = +val + return val > 9 ? val : '0' + val + }, + + formatSeconds(second) { + let duration + let days = Math.floor(second / 86400); + let hours = Math.floor((second % 86400) / 3600); + let minutes = Math.floor(((second % 86400) % 3600) / 60); + let seconds = Math.floor(((second % 86400) % 3600) % 60); + if (days > 0) { + if (hours > 0) duration = days + "d," + this.formatBit(hours) + "h"; + else if (minutes > 0) duration = days + "d," + this.formatBit(minutes) + "min"; + else if (seconds > 0) duration = days + "d," + this.formatBit(seconds) + "s"; + else duration = days + "d"; + } + else if (hours > 0) duration = this.formatBit(hours) + ":" + this.formatBit(minutes) + ":" + this.formatBit(seconds); + else if (minutes > 0) duration = this.formatBit(minutes) + ":" + this.formatBit(seconds); + else if (seconds > 0) duration = this.formatBit(seconds) + "s"; + return duration; + }, + } } diff --git a/resources/assets/js/pages/manage/components/TaskRow.vue b/resources/assets/js/pages/manage/components/TaskRow.vue index b544a77f..2a279cfe 100644 --- a/resources/assets/js/pages/manage/components/TaskRow.vue +++ b/resources/assets/js/pages/manage/components/TaskRow.vue @@ -50,7 +50,7 @@ -
{{item.name}}
+
{{item.name}}
{{item.sub_complete}}/{{item.sub_num}} @@ -158,12 +158,7 @@ export default { return; } this.$set(task, 'loading', true); - this.$store.dispatch("call", { - url: 'project/task/sublist', - data: { - task_id: task.id, - }, - }).then((data, msg) => { + this.$store.dispatch("subTask", task.id).then((data, msg) => { this.$set(task, 'loading', false); this.$set(task, 'sub_list', data); this.$set(task, 'sub_open', true); diff --git a/resources/assets/js/store/actions.js b/resources/assets/js/store/actions.js index 363c561e..c7f2ae6f 100644 --- a/resources/assets/js/store/actions.js +++ b/resources/assets/js/store/actions.js @@ -118,5 +118,142 @@ export default { } $A.ajaxc(params); }) - } + }, + + /** + * 获取任务信息 + * @param state + * @param dispatch + * @param task_id + * @returns {Promise} + */ + taskOne({state, dispatch}, task_id) { + return new Promise(function (resolve, reject) { + dispatch("call", { + url: 'project/task/one', + data: { + task_id, + }, + }).then((data, msg) => { + state.projectDetail.project_column.some(({project_task}) => { + let index = project_task.findIndex(({id}) => id === task_id); + if (index > -1) { + project_task.splice(index, 1, Object.assign(project_task[index], data)) + return true; + } + }); + if (task_id == state.projectOpenTask.id) { + state.projectOpenTask = Object.assign({}, state.projectOpenTask, data); + } + resolve(data, msg) + }).catch((data, msg) => { + reject(data, msg) + }); + }); + }, + + /** + * 获取任务详细描述 + * @param state + * @param dispatch + * @param task_id + * @returns {Promise} + */ + taskContent({state, dispatch}, task_id) { + return new Promise(function (resolve, reject) { + dispatch("call", { + url: 'project/task/content', + data: { + task_id, + }, + }).then((data, msg) => { + state.projectTaskContent[task_id] = data; + if (task_id == state.projectOpenTask.id) { + state.projectOpenTask = Object.assign({}, state.projectOpenTask, {content: data || {}}); + } + resolve(data, msg) + }).catch((data, msg) => { + reject(data, msg) + }); + }); + }, + + /** + * 获取任务文件 + * @param state + * @param dispatch + * @param task_id + * @returns {Promise} + */ + taskFiles({state, dispatch}, task_id) { + return new Promise(function (resolve, reject) { + dispatch("call", { + url: 'project/task/files', + data: { + task_id, + }, + }).then((data, msg) => { + state.projectTaskFiles[task_id] = data; + if (task_id == state.projectOpenTask.id) { + state.projectOpenTask = Object.assign({}, state.projectOpenTask, {files: data}); + } + resolve(data, msg) + }).catch((data, msg) => { + reject(data, msg) + }); + }); + }, + + /** + * 获取子任务 + * @param state + * @param dispatch + * @param task_id + * @returns {Promise} + */ + subTask({state, dispatch}, task_id) { + return new Promise(function (resolve, reject) { + dispatch("call", { + url: 'project/task/sublist', + data: { + task_id, + }, + }).then((data, msg) => { + state.projectSubTask[task_id] = data; + if (task_id == state.projectOpenTask.id) { + state.projectOpenTask = Object.assign({}, state.projectOpenTask, {sub_task: data}); + } + resolve(data, msg) + }).catch((data, msg) => { + reject(data, msg) + }); + }); + }, + + /** + * 打开任务详情页 + * @param state + * @param dispatch + * @param task_id + */ + openTask({state, dispatch}, task_id) { + let data = {id: task_id}; + state.projectDetail.project_column.some(({project_task}) => { + const task = project_task.find(({id}) => id === task_id); + if (task) { + data = Object.assign(data, task); + return true + } + }); + // + data.content = state.projectTaskContent[task_id] || {} + data.files = state.projectTaskFiles[task_id] || [] + data.subtask = state.projectSubTask[task_id] || [] + state.projectOpenTask = Object.assign({}, data, {_show: true}); + // + dispatch("taskOne", task_id); + dispatch("taskContent", task_id); + dispatch("taskFiles", task_id); + dispatch("subTask", task_id); + }, } diff --git a/resources/assets/js/store/mutations.js b/resources/assets/js/store/mutations.js index f808b3bf..dca74506 100644 --- a/resources/assets/js/store/mutations.js +++ b/resources/assets/js/store/mutations.js @@ -181,15 +181,6 @@ export default { } }, - /** - * 打开任务详情页 - * @param state - * @param task - */ - openTask(state, task) { - state.projectTask = Object.assign({_show:true}, task); - }, - /** * 获取用户基本信息 * @param state diff --git a/resources/assets/js/store/state.js b/resources/assets/js/store/state.js index e90cdbba..1165c4c3 100644 --- a/resources/assets/js/store/state.js +++ b/resources/assets/js/store/state.js @@ -244,13 +244,16 @@ state.wsListener = {}; state.wsReadTimeout = null; state.wsReadWaitList = []; -// 项目信息 +// 项目任务 state.projectLoad = 0; state.projectList = state.cacheProjectList; state.projectDetail = {id: 0, project_column: [], project_user: []}; -state.projectTask = {_show: false, id: 0, task_user: [], task_tag: []}; +state.projectOpenTask = {_show: false, id: 0, task_user: [], task_tag: []}; +state.projectTaskContent = {}; +state.projectTaskFiles = {}; +state.projectSubTask = {}; -// 会话消息 +// 会话聊天 state.dialogId = 0; state.dialogList = []; state.dialogDetail = {}; diff --git a/resources/assets/sass/pages/components/task-detail.scss b/resources/assets/sass/pages/components/task-detail.scss index e4cba0ed..20b587c1 100644 --- a/resources/assets/sass/pages/components/task-detail.scss +++ b/resources/assets/sass/pages/components/task-detail.scss @@ -1,6 +1,7 @@ .task-detail { display: flex; - padding-bottom: 36px; + flex-direction: column; + margin: 0 -10px 30px; .task-info { flex: 1; display: flex; @@ -16,14 +17,15 @@ content: ""; position: absolute; left: 36px; - right: -12px; + right: 0; bottom: 0; height: 1px; background-color: #f4f5f5; } - .radio { + .icon { width: 18px; - font-size: 16px; + font-size: 18px; + cursor: pointer; } .nav { flex: 1; @@ -48,76 +50,299 @@ } .menu { font-size: 22px; - margin: 0 18px; + margin: 0 32px; + cursor: pointer; } } - .title { - margin: 12px 36px 0; - .ivu-input { - font-weight: 500; - font-size: 24px; - padding: 4px 0; - resize: none; - border-color: transparent; - &:focus { - box-shadow: none + .scroller { + margin-left: 36px; + padding-right: 36px; + overflow-x: hidden; + overflow-y: auto; + .title { + margin-top: 18px; + .ivu-input { + font-weight: 500; + font-size: 24px; + padding: 4px 0; + line-height: 1.4; + resize: none; + border-color: transparent; + &:focus { + box-shadow: none + } } } - } - .desc { - margin: 12px 36px 0; - div[contenteditable="true"] { - outline: none - } - } - .items { - margin: 12px 36px 0; - .ivu-form-item { - margin-bottom: 10px; - } - .item-label { - display: flex; - align-items: center; - color: #aaaaaa; - .iconfont { - margin-right: 3px; + .desc { + margin-top: 10px; + div[contenteditable="true"] { + outline: none + } + .mce-content-body[data-mce-placeholder]:not(.mce-visualblocks)::before { + color: #bbbbbb; } } - .item-content { - margin-top: 5px; - margin-left: 12px; - > li { + .items { + margin-top: 12px; + .ivu-form-item { + margin-bottom: 10px; + } + .item-label { display: flex; align-items: center; - list-style: none; - line-height: 26px; + color: #bbbbbb; + .iconfont { + margin-right: 4px; + } } - &.file { - - } - &.subtask { + .item-content { + margin-top: 5px; + margin-left: 12px; + > li { + display: flex; + align-items: center; + list-style: none; + line-height: 26px; + } + &.user { + margin-top: 2px; + > li { + } + } + &.file { + > li { + margin-bottom: 2px; + .file-ext { + width: 16px; + } + .file-name { + padding-left: 8px; + } + .file-size { + padding-left: 10px; + height: 24px; + font-size: 12px; + color: #bbbbbb; + } + } + } + &.subtask { + > li { + align-items: flex-start; + margin-bottom: 2px; + .subtask-icon { + width: 16px; + height: 26px; + line-height: 26px; + font-size: 16px; + color: #cccccc; + margin-right: 8px; + cursor: pointer; + &.completed { + color: #87d068; + } + &.sub-icon { + font-size: 16px; + width: 16px; + height: 16px; + margin-left: -20px; + margin-right: 4px; + color: #cfcfcf; + transition: transform 0.2s; + &.active { + transform: rotate(90deg); + } + } + } + .subtask-name { + flex: 1; + margin-right: 16px; + display: flex; + .ivu-input { + margin: -1px 0; + padding: 4px 0; + resize: none; + border-color: transparent; + line-height: 20px; + &:focus { + box-shadow: none + } + } + } + .subtask-time { + overflow: hidden; + text-overflow: ellipsis; + white-space: nowrap; + margin-right: 6px; + font-size: 13px; + height: 26px; + line-height: 26px; + &.overdue { + font-weight: 600; + color: #ed4014; + } + &.today { + font-weight: 500; + color: #ff9900; + } + } + .subtask-avatar { + height: 26px; + line-height: 1; + .avatar-box { + &:before { + transform: scale(0.7); + right: -2px; + bottom: -1px; + } + } + } + } + } } } - } - .add { - margin: 12px 36px 0; - } - .add-button { - cursor: pointer; - color: #aaaaaa; - display: flex; - align-items: center; - > i { - font-size: 14px; - padding-right: 8px; + .add { + margin-top: 12px; } - &:hover { - color: #999999; + .add-button { + cursor: pointer; + color: #bbbbbb; + display: flex; + align-items: center; + margin-top: 6px; + > i { + font-size: 14px; + padding-right: 8px; + } + &:hover { + color: #999999; + } } } } .task-dialog { - display: none; + flex: 1; + display: flex; + flex-direction: column; + margin-top: 32px; + position: relative; + .head { + display: flex; + align-items: center; + height: 40px; + padding-bottom: 10px; + color: #888888; + position: relative; + &:before { + content: ""; + position: absolute; + left: 36px; + right: 0; + bottom: 0; + height: 1px; + background-color: #f4f5f5; + } + .icon { + width: 18px; + font-size: 18px; + } + .nav { + flex: 1; + display: flex; + align-items: center; + padding-left: 18px; + font-weight: 500; + color: #666666; + > p { + display: flex; + align-items: center; + margin-right: 28px; + &.active { + margin-top: -2px; + font-size: 18px; + font-weight: 600; + color: #555555; + } + } + } + } + .no-dialog { + flex: 1; + display: flex; + flex-direction: column; + .no-tip { + flex: 1; + display: none; + margin-left: 36px; + } + .no-input { + margin: 32px 0 0 36px; + background-color: #F4F5F7; + padding: 10px 12px; + border-radius: 10px; + .ivu-input { + border: 0; + resize: none; + background-color: transparent; + &:focus { + box-shadow: none; + } + } + } + } + } + + &.open-dialog { + flex-direction: row; + .task-info { + overflow: auto; + .head { + .menu { + margin-right: 0; + } + } + } + .task-dialog { + margin: 0 0 0 18px; + min-width: 320px; + max-width: 450px; + &:before { + content: ""; + position: absolute; + top: 0; + left: 0; + bottom: 0; + width: 1px; + background-color: #f4f5f5; + } + .head { + &:before { + left: 18px; + } + .icon { + &:before { + display: none; + } + } + .nav { + padding-left: 0; + } + } + .no-dialog { + .no-tip { + display: flex; + align-items: center; + justify-content: center; + margin-left: 18px; + color: #999999; + } + .no-input { + margin: 0 0 0 18px; + } + } + } } } + +