Commit 96b3f338 by liuyong
2 parents ea93fe08 c1b0bd01
<!--
* @Description: 列表页公共组件
* @Version: 2.0
* @Autor: pan
* @Date: 2024-03-12 14:01:57
* @LastEditors: pan
* @LastEditTime: 2024-03-12 16:02:21
-->
<template>
<div class="list-page">
<!-- 头部搜索区域 -->
<div class="formWrap">
<slot name="formWrap" />
</div>
<!-- 查询条件与表格中间的操作按钮 -->
<div class="operation-wrap">
<slot name="operationWrap" />
</div>
<!-- 表格 -->
<div class="table-wrap">
<slot name="tableWrap" />
</div>
</div>
</template>
<script>
export default {
name: 'list-page',
}
</script>
<style scoped lang="scss">
.list-page {
display: flex;
flex-direction: column;
height: 100%;
padding: 0 20px;
box-sizing: border-box;
.operation-wrap {
display: flex;
padding: 10px 0;
box-sizing: border-box;
}
.table-wrap {
flex: 1;
min-height: 180px;
}
}
</style>
<!--
* @Description: 列表查询条件封装
* @Version: 2.0
* @Autor: pan
* @Date: 2024-03-12 14:55:59
* @LastEditors: pan
* @LastEditTime: 2024-03-12 16:14:30
-->
<!-- /**
* 搜索栏公共组件
*/ -->
<template>
<div class="search-form-box">
<el-form :model="formData" ref="formRef" :inline="true">
<el-row>
<el-col
:xs="24"
:sm="12"
:md="8"
:lg="6"
:xl="4"
v-for="(item, index) in formOptions"
:key="newKeys[index]"
>
<el-form-item
:prop="item.prop"
:label="item.label"
:rules="item.rules"
@keyup.enter.native="onSearch"
>
<SearchFormItem v-model="formData[item.prop]" :itemOptions="item" />
</el-form-item>
</el-col>
</el-row>
<!-- 自定义插槽,可用于特殊表单块 -->
<slot></slot>
</el-form>
<!-- 提交按钮 -->
<div class="btn-box">
<el-button
v-if="btnItems.includes('search')"
size="medium"
type="primary"
class="btn-search"
icon="el-icon-search"
@click="onSearch"
>查询</el-button
>
<!-- <el-button
v-if="btnItems.includes('export')"
size="mini"
type="primary"
class="btn-export"
@click="onExport"
>导出</el-button
> -->
<el-button
size="medium"
type="default"
class="btn-reset"
icon="el-icon-refresh"
@click="onReset"
>重置</el-button
>
</div>
</div>
</template>
<script>
import SearchFormItem from './SearchFormItem.vue'
export default {
props: {
/**
* 表单配置
* 示例:
* [{
* label: '用户名', // label文字
* prop: 'username', // 字段名
* element: 'el-input', // 指定elementui组件
* initValue: '阿黄', // 字段初始值
* placeholder: '请输入用户名', // elementui组件属性
* rules: [{ required: true, message: '必填项', trigger: 'blur' }], // elementui组件属性
* events: { // elementui组件方法
* input (val) {
* console.log(val)
* },
* ...... // 可添加任意elementui组件支持的方法
* }
* ...... // 可添加任意elementui组件支持的属性
* }]
*/
formOptions: {
type: Array,
required: true,
default() {
return []
},
},
// 提交按钮项,多个用逗号分隔(search, export, reset)
btnItems: {
type: String,
default() {
return 'search'
},
},
},
data() {
return {
formData: {},
}
},
computed: {
newKeys() {
return this.formOptions.map((v) => {
return this.createUniqueString()
})
},
},
created() {
this.addInitValue()
},
methods: {
createUniqueString() {
const timestamp = +new Date() + ''
const randomNum = parseInt((1 + Math.random()) * 65536) + ''
return (+(randomNum + timestamp)).toString(32)
},
// 校验
onValidate(callback) {
this.$refs.formRef.validate((valid) => {
if (valid) {
// console.log('提交成功')
console.log(this.formData)
callback()
}
})
},
// 搜索
onSearch() {
this.onValidate(() => {
this.$emit('onSearch', this.formData)
})
},
// 导出
onExport() {
this.onValidate(() => {
this.$emit('onExport', this.formData)
})
},
onReset() {
this.$refs.formRef.resetFields()
},
// 添加初始值
addInitValue() {
const obj = {}
this.formOptions.forEach((v) => {
if (v.initValue !== undefined) {
obj[v.prop] = v.initValue
}
})
this.formData = obj
},
},
components: { SearchFormItem },
}
</script>
<style lang="scss" scoped>
.search-form-box {
display: flex;
margin-top: 10px;
.btn-box {
// padding-top: 5px;
display: flex;
height: 38px;
// button {
// height: 38px;
// }
}
.el-form {
/deep/ .el-form-item__label {
// padding-right: 0;
margin-bottom: 10px;
flex-shrink: 0;
color: #000;
}
.el-form-item {
margin-bottom: 0;
display: flex;
&.is-error {
margin-bottom: 25px;
}
}
// el-input宽度
/deep/ .form-item {
> .el-input:not(.el-date-editor) {
max-width: 220px;
}
}
/deep/ .el-select {
max-width: 220px;
}
/deep/ .el-cascader {
max-width: 200px;
}
}
}
</style>
<!--
* @Description: 表单匹配项
* @Version: 2.0
* @Autor: pan
* @Date: 2024-03-12 15:11:47
* @LastEditors: pan
* @LastEditTime: 2024-03-13 16:54:21
-->
<template>
<div class="form-item">
<el-input
v-if="isInput"
v-no-backslash
v-model="currentVal"
v-bind="bindProps"
v-on="bindEvents"
:placeholder="itemOptions.placeholder"
></el-input>
<el-input-number
v-if="isInputNumber"
v-model="currentVal"
v-bind="bindProps"
v-on="bindEvents"
:controls-position="itemOptions['controls-position'] || 'right'"
></el-input-number>
<el-select
v-if="isSelect"
v-model="currentVal"
v-bind="bindProps"
v-on="bindEvents"
clearable
>
<el-option
v-for="item in itemOptions.options"
:key="item.value"
:label="item.label"
:value="item.value"
></el-option>
</el-select>
<!-- datetimerange/daterange -->
<!-- <el-date-picker
v-if="isDatePickerDateRange"
v-model="currentVal"
v-bind="bindProps"
v-on="bindEvents"
:type="itemOptions.type || 'datetimerange'"
clearable
:picker-options="pickerOptionsRange"
start-placeholder="开始日期"
range-separator="至"
end-placeholder="结束日期"
:default-time="['00:00:00', '23:59:59']"
value-format="yyyy-MM-dd HH:mm:ss"
></el-date-picker> -->
<!-- monthrange -->
<!-- <el-date-picker
v-if="isDatePickerMonthRange"
v-model="currentVal"
v-bind="bindProps"
v-on="bindEvents"
:type="itemOptions.type"
clearable
:picker-options="pickerOptionsRangeMonth"
start-placeholder="开始日期"
range-separator="至"
end-placeholder="结束日期"
value-format="yyyy-MM"
></el-date-picker> -->
<!-- other -->
<el-date-picker
v-if="isDatePickerOthers"
v-model="currentVal"
v-bind="bindProps"
v-on="bindEvents"
:type="itemOptions.type"
clearable
value-format="yyyy-MM-dd"
placeholder="请选择日期"
style="width: 300px"
></el-date-picker>
<el-cascader
v-if="isCascader"
v-model="currentVal"
v-bind="bindProps"
v-on="bindEvents"
size="mini"
clearable
></el-cascader>
</div>
</template>
<script>
import { getDianXingAnLiSelectData } from '@/api/index.js'
export default {
inheritAttrs: false,
props: {
value: {},
itemOptions: {
type: Object,
default() {
return {}
},
},
},
data() {
return {
// pickerOptionsRange: tools.pickerOptionsRange,
// pickerOptionsRangeMonth: tools.pickerOptionsRangeMonth,
}
},
computed: {
// 双向绑定数据值
currentVal: {
get() {
return this.value
},
set(val) {
this.$emit('input', val)
},
},
// 绑定属性
bindProps() {
let obj = { ...this.itemOptions }
// 移除冗余属性
delete obj.label
delete obj.prop
delete obj.element
delete obj.initValue
delete obj.rules
delete obj.events
if (obj.element === 'el-select') {
delete obj.options
}
return obj
},
// 绑定方法
bindEvents() {
return this.itemOptions.events || {}
},
// el-input
isInput() {
return this.itemOptions.element === 'el-input'
},
// el-input-number
isInputNumber() {
return this.itemOptions.element === 'el-input-number'
},
// el-select
isSelect() {
return this.itemOptions.element === 'el-select'
},
// el-date-picker (type: datetimerange/daterange)
isDatePickerDateRange() {
const isDatePicker = this.itemOptions.element === 'el-date-picker'
const isDateRange =
!this.itemOptions.type ||
this.itemOptions.type === 'datetimerange' ||
this.itemOptions.type === 'daterange'
return isDatePicker && isDateRange
},
// el-date-picker (type: monthrange)
isDatePickerMonthRange() {
const isDatePicker = this.itemOptions.element === 'el-date-picker'
const isMonthRange = this.itemOptions.type === 'monthrange'
return isDatePicker && isMonthRange
},
// el-date-picker (type: other)
isDatePickerOthers() {
const isDatePicker = this.itemOptions.element === 'el-date-picker'
return (
isDatePicker &&
!this.isDatePickerDateRange &&
!this.isDatePickerMonthRange
)
},
// el-cascader
isCascader() {
return this.itemOptions.element === 'el-cascader'
},
},
created() {},
methods: {
async getDictTypeOptions(key) {
var dictTypeOptions = []
var storedDic = localStorage.getItem('dic_' + key)
if (storedDic) {
dictTypeOptions = JSON.parse(storedDic)
} else {
const params = { key }
const res = await getDianXingAnLiSelectData(params)
dictTypeOptions = res.data
const jsonStr = JSON.stringify(res.data)
localStorage.setItem('dic_' + key, jsonStr)
// await getDianXingAnLiSelectData(params).then((res) => {
// if (res.code === 200) {
// var options = res.data
// var jsonStr = JSON.stringify(options)
// localStorage.setItem('dic_' + key, jsonStr)
// dictTypeOptions = res.data
// console.log(dictTypeOptions)
// }
// })
}
return dictTypeOptions
},
},
components: {},
}
</script>
<style lang="scss" scoped></style>
<!--
* @Description: elementui表格组件二次封装
* @Version: 2.0
* @Autor: pan
* @Date: 2024-03-11 14:53:40
* @LastEditors: pan
* @LastEditTime: 2024-03-12 15:02:11
-->
<!-- 示例
columns: [{ label: '头像', prop: 'avatar', align: 'center', __slotName: 'avatar',callback: (row, title) => {
// console.log(row)
if (title) {
switch (title) {
case "查看":
return this.dialogShow(row);
}
}
},
}]
使用TableConfig组件
<table-config @fetchData="fetchData" :query="query" :columns="columns">
<template slot="icon" v-slot="scope">
<img slot="icon" width="40" :src="scope.data.row.avatar" />
</template>
</table-config> -->
<template>
<div class="tableConfig">
<el-table
class="config-table"
v-loading="loading"
v-bind="$attrs"
v-on="listeners"
:data="tableData"
:row-key="idKey"
stripe
border
height="100%"
>
<!-- <el-table-column
v-if="isCheck"
align="center"
width="70"
type="selection"
:reserve-selection="isCheckMemory"
>
</el-table-column> -->
<template v-for="item in columns">
<!-- v-html存在安全问题暂时弃用 -->
<!-- 如果接口返回的内容需要我们解析出来并渲染到页面中 比如:0 代表 已停用 1 代表 已发布 2 代表 暂存 -->
<!-- <el-table-column
v-if="item.type === 'function'"
v-bind="item"
:key="item.prop"
align="center"
>
<template slot-scope="scope">
<span v-html="item.callback && item.callback(scope.row)"></span>
</template>
</el-table-column> -->
<!-- 操作列 -->
<el-table-column
v-if="item.type === 'operation'"
:key="item.prop"
v-bind="item"
align="center"
>
<template #default="scope">
<el-button
class="btn"
v-for="items in item.actionButtons"
:key="items.title"
:type="items.type"
@click="item.callback(scope.row, items.title)"
:icon="items.icon"
:circle="items.circle"
><span v-if="!items.circle">{{ items.title }}</span></el-button
>
</template>
</el-table-column>
<!-- 普通渲染 -->
<el-table-column
v-else
:key="item.prop"
v-bind="item"
show-overflow-tooltip
align="center"
>
<!-- 自定义插槽 -->
<template v-if="item.__slotName" #default="scope">
<slot :name="item.__slotName" :data="scope"></slot>
</template>
<!-- 字典值匹配 如后端给state: 0 页面要渲染成已停用-->
<template v-if="item.collectionType">
<span></span>
</template>
</el-table-column>
</template>
</el-table>
<div class="config-pagenation">
<el-pagination
class="pagination"
background
v-if="hasPagination"
@size-change="sizeChange"
@current-change="currentChange"
:total="pagination.totalRow"
:current-page="pagination.current"
:page-size="pagination.pageSize"
:page-sizes="pageSizes"
:layout="layout"
>
</el-pagination>
</div>
</div>
</template>
<script>
import { get, post } from '@/utils/http'
export default {
name: 'tableConfig',
props: {
// columns: [{ label: '头像', prop: 'avatar', align: 'center', __slotName: 'avatar' }]
// 配置项
columns: {
type: Array,
default: () => [],
},
/**
* 分页需要传入后台的字段
*/
pageParam: {
type: Object,
default() {
return {
pageOffset: 'current',
pageSize: 'pageSize',
}
},
},
// 接口参数
query: {
type: Object,
default() {
return {
url: '',
method: '',
queryParam: {},
}
},
},
/**
* 是否需要跨页勾选
*/
// isCheckMemory: {
// type: Boolean,
// default: false,
// },
// /**
// * 表格行数据的唯一键
// */
idKey: {
type: String,
default: 'id',
},
// 是否显示分页组件
hasPagination: {
type: Boolean,
default: true,
},
layout: {
type: String,
default: 'total, sizes, prev, pager, next, jumper',
},
pageSizes: {
type: Array,
default() {
return [10, 20, 50, 100, 200]
},
},
},
data() {
return {
tableData: [],
pagination: {
current: 1,
pageSize: 10,
totalRow: 0,
},
loading: false,
}
},
computed: {
listeners: function () {
var vm = this
return Object.assign({}, this.$listeners, {
'selection-change': function (val) {
// dosomething
vm.selectData = val
vm.$emit('selection-change', val)
},
})
},
},
created() {
this.queryData()
},
methods: {
/**
* 切换分页数量
* @param { Number } pageSize 页数
*/
sizeChange(pageSize) {
this.pagination.current = 1
this.pagination.pageSize = pageSize
this.queryData()
},
/**
* 切换页码
* @param { Number } current 页码
*/
currentChange(current) {
this.pagination.current = current
this.queryData(true)
},
async queryData(isReset) {
if (this.query && this.query.url) {
this.loading = true
this.pagination.current = isReset ? this.pagination.current : 1
let param = Object.assign({}, this.query.queryParam, {
[this.pageParam.pageOffset]: this.pagination.current,
[this.pageParam.pageSize]: this.pagination.pageSize,
})
// if (this.order.sortName && this.order.sortOrder) {
// param.sortName = this.order.sortName
// param.sortOrder = this.order.sortOrder
// }
let result = null
console.log('param', param)
try {
switch (this.query.method) {
case 'get':
result = await get(this.query.url, param)
break
case 'post':
result = await post(this.query.url, param)
break
default:
result = await get(this.query.url, param)
break
}
} catch (e) {
console.warn(e)
} finally {
this.loading = false
// console.log('result', result)
const { data } = result
if (result && result.code === 200) {
this.pagination.totalRow = data.total
this.tableData = data.records
this.$emit('fetchData', data)
} else {
this.$message({
type: 'warning',
message: result ? result.msg : '查询失败!',
})
this.tableData = []
this.pagination.current = 1
this.pagination.totalRow = 0
}
}
}
},
},
}
</script>
<style lang="scss" scoped>
.tableConfig {
width: 100%;
height: 100%;
display: flex;
flex-direction: column;
.config-table {
flex: 1;
}
.config-pagenation {
margin-top: 20px;
margin-bottom: 30px;
}
}
</style>
<template>
<!-- onlyoffice展示 -->
<div class="qualityManual-container">
<div class="qualityManual-container-office">
<vab-only-office
id="office-preview"
:documentServerUrl="documentServerUrl"
:config="config"
/>
</div>
</div>
</template>
<script>
import vabOnlyOffice from './index.vue'
export default {
components: { vabOnlyOffice },
data() {
return {
documentServerUrl: 'http://121.201.2.228:53327/',
config: {
document: {
fileType: 'doc',
// 给服务端用的唯一id,同一个id就会获取服务器缓存里的文件(有这个key,就会先根据它去缓存里找),这项如果最开始只是先试用,可以先给个空字符串
key: '',
// 文件名
title: 'text.docx',
//相关权限
// permissions: {
// copy: true, //定义内容是否可以复制到剪贴板。如果该参数设置为false,则只能在当前文档编辑器中粘贴内容。默认值为true。
// download: true, //定义文档是可以下载还是只能在线查看或编辑。如果下载权限设置为“假”的下载为...菜单选项将是缺席的文件菜单。默认值为true。
// edit: true, //定义文档是可以编辑还是只能查看。如果编辑权限设置为“true”,则文件菜单将包含编辑文档菜单选项;请注意,如果编辑权限设置为“false”,文档将在查看器中打开,即使模式参数设置为edit,您也无法将其切换到编辑器。默认值为true。
// print: true, //定义是否可以打印文档。如果打印权限设置为“false”的打印菜单选项将是缺席的文件菜单。默认值为true
// },
// 所要渲染的文件的绝对路径,这个参数很重要,它传的不是文件的本地地址,而是需要把文件传到项目所依赖的服务器,然后拿到文件在服务器的url地址(这个一般情况需要后端支持)才可以用,这个参数决定了能不能实例化出来onlyoffice对象
url: 'http://172.20.10.9:9997/downloadFile/22',
},
documentType: 'word',
height: '100%',
width: '100%',
editorConfig: {
//语言:zh-CN简体中文/en英文
lang: 'zh-CN',
//阅读状态 view/edit
mode: 'edit',
customization: {
//是否显示插件
plugins: false,
},
user: {
// 当前正在view/edit此文档的用户信息
name: '',
},
// 指定文档存储服务器的绝对路径
callbackUrl: 'http://192.168.8.120:9997/callback?fileId=22',
},
},
}
},
methods: {
//这里的val是传递的参数
// loadOnlyOffice(val) {
// this.option.key = // key 默认置空则不走缓存
// this.option.title = '' // 该文件名在下载文档时也将用作文件名
// this.option.url = // 定义存储原始查看或编辑的文档的绝对URL
// this.option.fileType = 'docx' // 文件类型
// this.option.callbackUrl = '' // 回调地址
// this.show = true // 打开onlyOffice窗口
// console.log(val, '编辑word默认配置参数')
// },
},
}
</script>
<style rel="stylesheet/scss" lang="scss">
.qualityManual-container {
padding: 0 !important;
width: 100%;
height: calc(100vh - 180px);
}
.qualityManual-container-office {
width: 100%;
height: calc(100% - 55px);
}
</style>
<template>
<div :class="s.view">
<div :id="id"></div>
</div>
</template>
<script>
import loadScript from './loadScript.js'
export default {
name: 'DocumentEditor',
props: {
id: {
type: String,
default: '',
},
documentServerUrl: {
type: String,
default: '',
},
config: {
type: Object,
default: () => {},
},
document_fileType: {
type: String,
default: '',
},
document_title: {
type: String,
default: '',
},
documentType: {
type: String,
default: '',
},
editorConfig_lang: {
type: String,
default: '',
},
height: {
type: String,
default: '',
},
type: {
type: String,
default: '',
},
width: {
type: String,
default: '',
},
events_onAppReady: {
type: Function,
default: () => {},
},
events_onDocumentStateChange: {
type: Function,
default: () => {},
},
events_onMetaChange: {
type: Function,
default: () => {},
},
events_onDocumentReady: {
type: Function,
default: () => {},
},
events_onInfo: {
type: Function,
default: () => {},
},
events_onWarning: {
type: Function,
default: () => {},
},
events_onError: {
type: Function,
default: () => {},
},
events_onRequestSharingSettings: {
type: Function,
default: () => {},
},
events_onRequestRename: {
type: Function,
default: () => {},
},
events_onMakeActionLink: {
type: Function,
default: () => {},
},
events_onRequestInsertImage: {
type: Function,
default: () => {},
},
events_onRequestSaveAs: {
type: Function,
default: () => {},
},
events_onRequestMailMergeRecipients: {
type: Function,
default: () => {},
},
events_onRequestCompareFile: {
type: Function,
default: () => {},
},
events_onRequestEditRights: {
type: Function,
default: () => {},
},
events_onRequestHistory: {
type: Function,
default: () => {},
},
events_onRequestHistoryClose: {
type: Function,
default: () => {},
},
events_onRequestHistoryData: {
type: Function,
default: () => {},
},
events_onRequestRestore: {
type: Function,
default: () => {},
},
},
data() {
return {}
},
watch: {
config: {
handler() {
this.onChangeProps()
},
deep: true,
},
document_fileType() {
this.onChangeProps()
},
document_title() {
this.onChangeProps()
},
documentType() {
this.onChangeProps()
},
editorConfig_lang() {
this.onChangeProps()
},
height() {
this.onChangeProps()
},
type() {
this.onChangeProps()
},
width() {
this.onChangeProps()
},
},
mounted() {
let url = this.documentServerUrl
console.log('url', url)
if (!url.endsWith('/')) {
url += '/'
}
const docApiUrl = `${url}web-apps/apps/api/documents/api.js`
loadScript(docApiUrl, 'onlyoffice-api-script')
.then(() => this.onLoad())
.catch((err) => console.error(err))
},
beforeDestroy() {
const id = this.id || ''
if (window?.DocEditor?.instances[id]) {
window.DocEditor.instances[id].destroyEditor()
window.DocEditor.instances[id] = undefined
}
},
methods: {
onLoad() {
try {
const id = this.id || ''
if (!window.DocsAPI) throw new Error('DocsAPI is not defined')
if (window?.DocEditor?.instances[id]) {
console.log('Skip loading. Instance already exists', id)
return
}
if (!window?.DocEditor?.instances) {
window.DocEditor = { instances: {} }
}
const initConfig = {
document: {
fileType: this.document_fileType,
title: this.document_title,
},
documentType: this.documentType,
editorConfig: {
lang: this.editorConfig_lang,
},
events: {
onAppReady: this.onAppReady,
onDocumentStateChange: this.events_onDocumentStateChange,
onMetaChange: this.events_onMetaChange,
onDocumentReady: this.events_onDocumentReady,
onInfo: this.events_onInfo,
onWarning: this.events_onWarning,
onError: this.events_onError,
onRequestSharingSettings: this.events_onRequestSharingSettings,
onRequestRename: this.events_onRequestRename,
onMakeActionLink: this.events_onMakeActionLink,
onRequestInsertImage: this.events_onRequestInsertImage,
onRequestSaveAs: this.events_onRequestSaveAs,
onRequestMailMergeRecipients:
this.events_onRequestMailMergeRecipients,
onRequestCompareFile: this.events_onRequestCompareFile,
onRequestEditRights: this.events_onRequestEditRights,
onRequestHistory: this.events_onRequestHistory,
onRequestHistoryClose: this.events_onRequestHistoryClose,
onRequestHistoryData: this.events_onRequestHistoryData,
onRequestRestore: this.events_onRequestRestore,
},
height: this.height,
type: this.type,
width: this.width,
...(this.config || {}),
}
const editor = new DocsAPI.DocEditor(id, initConfig)
window.DocEditor.instances[id] = editor
} catch (err) {
console.error(err)
this.events_onError(err)
}
},
onAppReady() {
const id = this.id || ''
this.events_onAppReady(window.DocEditor.instances[id])
},
onChangeProps() {
const id = this.id || ''
if (window?.DocEditor?.instances[id]) {
window.DocEditor.instances[id].destroyEditor()
window.DocEditor.instances[id] = undefined
console.log('Important props have been changed. Load new Editor.')
this.onLoad()
}
},
},
}
</script>
<style lang="scss" module="s">
.view {
width: 100%;
height: 100%;
iframe {
width: 100%;
height: 100%;
}
}
</style>
const loadScript = async (url, id) =>
new Promise((resolve, reject) => {
try {
if (document.getElementById(id)) {
if (window.DocsAPI) return resolve(null)
const intervalHandler = setInterval(() => {
if (!window.DocsAPI) return
clearInterval(intervalHandler)
return resolve(null)
}, 500)
} else {
const script = document.createElement('script')
script.setAttribute('type', 'text/javascript')
script.setAttribute('id', id)
script.onload = resolve
script.onerror = reject
script.src = url
script.async = true
document.body.appendChild(script)
}
} catch (e) {
console.error(e)
}
})
export default loadScript
......@@ -2,19 +2,19 @@ import Vue from 'vue'
import App from './App.vue'
import router from './router'
import store from './store'
import ElementUI from 'element-ui';
import 'element-ui/lib/theme-chalk/index.css';
import initDirective from './directive';
import ElementUI from 'element-ui'
import 'element-ui/lib/theme-chalk/index.css'
import './styles/element-variables.scss'
import initDirective from './directive'
initDirective(Vue);
initDirective(Vue)
Vue.config.productionTip = false;
Vue.use(ElementUI);
Vue.config.productionTip = false
Vue.use(ElementUI)
new Vue({
router,
store,
render: h => h(App)
render: (h) => h(App),
}).$mount('#app')
$color-primary: #0d867f;
@for $i from 0 through 50 {
.m-#{$i} {
margin: #{$i}px;
}
.m-t-#{$i} {
margin-top: #{$i}px;
}
.m-b-#{$i} {
margin-bottom: #{$i}px;
}
.m-r-#{$i} {
margin-right: #{$i}px;
}
.m-l-#{$i} {
margin-left: #{$i}px;
}
.m-lr-#{$i} {
margin-left: #{$i}px;
margin-right: #{$i}px;
}
.m-tb-#{$i} {
margin-top: #{$i}px;
margin-bottom: #{$i}px;
}
.m-n#{$i} {
margin: -#{$i}px;
}
.m-t-n#{$i} {
margin-top: -#{$i}px;
}
.m-b-n#{$i} {
margin-top: -#{$i}px;
}
.p-#{$i} {
padding: #{$i}px;
}
.p-t-#{$i} {
padding-top: #{$i}px;
}
.p-b-#{$i} {
padding-bottom: #{$i}px;
}
.p-r-#{$i} {
padding-right: #{$i}px;
}
.p-l-#{$i} {
padding-left: #{$i}px;
}
.p-lr-#{$i} {
padding-left: #{$i}px;
padding-right: #{$i}px;
}
.p-tb-#{$i} {
padding-top: #{$i}px;
padding-bottom: #{$i}px;
}
.p-n#{$i} {
padding: -#{$i}px;
}
.p-t-n#{$i} {
padding-top: -#{$i}px;
}
}
.flex {
display: flex;
}
.flex-1 {
flex: 1;
}
.flex-c {
display: flex;
align-items: center;
justify-content: center;
}
.flex-column {
display: flex;
flex-direction: column;
}
.flex-b-c {
display: flex;
justify-content: space-between;
align-items: center;
}
.flex-e-c {
display: flex;
justify-content: flex-end;
align-items: center;
}
.w-100 {
width: 100%;
}
.h-100 {
height: 100%;
}
.searchTable {
width: 100%;
}
/* theme color */
$--color-primary: #0d867f !default;
// $--color-success: #13ce66;
// $--color-warning: #ffba00;
// $--color-danger: #ff4949;
$--font-path: '~element-ui/lib/theme-chalk/fonts';
@import '~element-ui/packages/theme-chalk/src/index';
<template>
<div class="reviewArchiPoliticeCheckDetails">
<el-tabs>
<el-tab-pane label="运安符合性审查">
<Tab1></Tab1>
</el-tab-pane>
<el-tab-pane label="功能满足审查">
<Tab2></Tab2>
</el-tab-pane>
<el-tab-pane label="运行可靠性审查">
<Tab3></Tab3>
</el-tab-pane>
<el-tab-pane label="系统实用性审查">
<Tab4></Tab4>
</el-tab-pane>
<el-tab-pane label="系统安全性审查">
<Tab5></Tab5>
</el-tab-pane>
<el-tab-pane label="资源复用性审查">
<Tab6></Tab6>
</el-tab-pane>
</el-tabs>
</div>
<div class="reviewArchiPoliticeCheckDetails">
<el-tabs class="m-lr-10" v-model="activeName" @tab-click="handleClick">
<el-tab-pane
:label="item.label"
:name="item.name"
v-for="item in tabOptions"
:key="item.name"
lazy
>
<keep-alive>
<component :is="componentTag"></component>
</keep-alive>
</el-tab-pane>
</el-tabs>
</div>
</template>
<script>
import Tab1 from './tab1.vue';
import Tab2 from './tab2.vue';
import Tab3 from './tab3.vue';
import Tab4 from './tab4.vue';
import Tab5 from './tab5.vue';
import Tab6 from './tab6.vue';
import { MessageBox, Message } from 'element-ui';
import $ from 'jquery';
import {
saveArchiViewManageCardDetails
} from '@/api/index.js';
export default {
name: 'reviewArchiPoliticeCheckDetails',
components: {
Tab1,
Tab2,
Tab3,
Tab4,
Tab5,
Tab6
},
data() {
return {
routerId: null,
};
},
mounted(){
},
methods: {
}
}
import Tab1 from './tab1.vue'
import Tab2 from './tab2.vue'
import Tab3 from './tab3.vue'
import Tab4 from './tab4.vue'
import Tab5 from './tab5.vue'
export default {
name: 'reviewArchiPoliticeCheckDetails',
components: {
Tab1,
Tab2,
Tab3,
Tab4,
Tab5,
},
data() {
return {
activeName: '',
tabOptions: [
{ label: '运安符合性审查', name: '1' },
{ label: '功能满足审查', name: '2' },
{ label: '运行可靠性审查', name: '3' },
{ label: '系统实用性审查', name: '4' },
{ label: '系统安全性审查', name: '5' },
{ label: '资源复用性审查', name: '6' },
],
componentTag: '',
}
},
created() {
const { name } = this.$route.query
if (name) {
this.activeName = name
this.componentTag = `tab${name}`
} else {
this.activeName = '1'
this.componentTag = 'tab1'
}
},
methods: {
handleClick(tab, event) {
console.log(tab, event)
this.componentTag = `tab${+tab.index + 1}`
},
},
}
</script>
<style>
.confirmClass{
background-color: #0D867F !important;
}
.el-message-box__content{
padding: 60px 15px 60px 15px;
}
</style>
<style scoped>
.el-tabs{
width: 100%;
height: 100%;
}
/deep/ .el-tabs__item.is-active {
color: #0D867F;
}
/deep/ .el-tabs__item:hover{
color: #0D867F;
}
/deep/ .el-tabs__active-bar{
background-color: #0D867F;
}
/deep/ .el-tabs__content{
height: calc(100% - 38px);
padding: 0;
}
.el-tab-pane{
height: 100%;
}
.reviewArchiPoliticeCheckDetails{
width: 100%;
height: 100%;
display: flex;
position: relative;
}
/deep/ .el-dialog__header{
background-color: #0D867F;
text-align: left;
}
/deep/ .el-dialog__title{
color: #fff;
}
/deep/ .el-dialog__close {
color: #fff;
}
.greenButton{
background-color: #0D867F;
color: #fff;
}
<style lang="scss" scoped>
@import '@/styles/common.scss';
.reviewArchiPoliticeCheckDetails {
width: 100%;
& > div {
height: 100%;
}
/deep/ .el-tabs__content {
height: calc(100% - 55px);
.el-tab-pane {
height: 100%;
}
}
}
</style>
@import '@/styles/common.scss';
// 详情部分样式
.content {
flex: 1;
.left_container,
.right_container {
width: 50%;
&_title {
height: 38px;
display: flex;
align-items: center;
font-size: 13px;
background: #dbf4f3;
}
&_content {
border: 1px solid #ccc;
border-top: none;
}
}
.icon {
color: $color-primary;
font-size: 18px;
}
}
.bottom_container {
&_title {
position: relative;
&::before {
content: '';
position: absolute;
left: 0;
top: 2px;
width: 6px;
border-radius: 4px;
height: 20px;
background-color: $color-primary;
}
}
}
<template>
<div class="tab1">
</div>
<div class="tab1 flex-column h-100">
<div class="content flex">
<div class="left_container m-r-10 flex-column">
<div class="left_container_title">
<i class="el-icon-caret-right icon"></i>
<span>评审标准</span>
</div>
<div class="left_container_content flex-1">123</div>
</div>
<div class="right_container flex-column">
<div class="right_container_title">
<i class="el-icon-caret-right icon"></i>
<span>评审内容</span>
</div>
<div class="right_container_content flex-1">123</div>
</div>
</div>
<div class="bottom_container">
<div class="flex-b-c p-r-20 m-tb-15">
<div class="flex-c">
<span class="m-r-50 p-l-20 bottom_container_title">评审结果</span>
<div class="label m-r-10">是否满足接入要求:</div>
<el-select v-model="isMeet" class="leftSelect">
<el-option
v-for="item in selectOptions"
:key="item.value"
:label="item.label"
:value="item.value"
></el-option>
</el-select>
</div>
<el-button type="primary" size="medium">保存结果</el-button>
</div>
<el-input
type="textarea"
:rows="4"
v-model="resultContent"
v-no-backslash
class="w-100"
></el-input>
</div>
</div>
</template>
<script>
import {
getArchiViewManageTable
} from '@/api/index.js';
import { MessageBox, Message } from 'element-ui';
import { getArchiViewManageTable } from '@/api/index.js'
import { MessageBox, Message } from 'element-ui'
export default {
name: 'tab1',
components: {
},
data() {
return {
};
},
mounted(){
},
methods: {
}
name: 'tab1',
components: {},
data() {
return {
resultContent: '',
isMeet: '',
selectOptions: [
{
label: '是',
value: '1',
},
{
label: '否',
value: '0',
},
],
}
},
mounted() {},
methods: {},
}
</script>
<style scoped>
</style>
\ No newline at end of file
<style lang="scss" scoped>
@import '@/styles/common.scss';
@import './index.scss';
</style>
Markdown is supported
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!