| | |
| | | .app-container {
|
| | | padding: 20px;
|
| | | }
|
| | |
|
| | | .search_form {
|
| | | display: flex;
|
| | | align-items: center;
|
| | | justify-content: space-between;
|
| | | .search_title {
|
| | | font-size: 14px;
|
| | | font-weight: 700;
|
| | | color: #333333;
|
| | | }
|
| | | }
|
| | | .table_list {
|
| | | height: calc(100vh - 11em);
|
| | | margin-top: 20px;
|
| | | background: #fff;
|
| | | padding: 18px
|
| | | }
|
| | | .components-container {
|
| | | margin: 30px 50px;
|
| | | position: relative;
|
| | |
| | | /** è¡¨æ ¼æ´å¤æä½ä¸ææ ·å¼ */
|
| | | .el-table .el-dropdown-link {
|
| | | cursor: pointer;
|
| | | color: #409EFF;
|
| | | color: #3472D7;
|
| | | margin-left: 10px;
|
| | | }
|
| | |
|
| | |
| | | transition: margin-left .28s;
|
| | | margin-left: $base-sidebar-width;
|
| | | position: relative;
|
| | | background: #F5F7FB;
|
| | | }
|
| | |
|
| | | .sidebarHide {
|
| | |
| | | .sub-menu-title-noDropdown,
|
| | | .el-sub-menu__title {
|
| | | &:hover {
|
| | | background-color: rgba(0, 0, 0, 0.06) !important;
|
| | | background-color: rgba(212,221,255,0.56) !important;
|
| | | }
|
| | | }
|
| | |
|
| | | & .theme-dark .is-active > .el-sub-menu__title {
|
| | | color: $base-menu-color-active !important;
|
| | | & .theme-light .is-active > .el-sub-menu__title {
|
| | | color: #000000 !important;
|
| | | }
|
| | |
|
| | | & .nest-menu .el-sub-menu>.el-sub-menu__title,
|
| | |
| | | min-width: $base-sidebar-width !important;
|
| | |
|
| | | &:hover {
|
| | | background-color: rgba(0, 0, 0, 0.06) !important;
|
| | | background-color: rgba(212,221,255,0.56) !important;
|
| | | }
|
| | | &.is-active {
|
| | | background-color: rgba(212,221,255,0.56) !important;
|
| | | }
|
| | | }
|
| | |
|
| | | & .theme-dark .nest-menu .el-sub-menu>.el-sub-menu__title,
|
| | | & .theme-dark .el-sub-menu .el-menu-item {
|
| | | background-color: $base-sub-menu-background;
|
| | | & .theme-light .nest-menu .el-sub-menu>.el-sub-menu__title,
|
| | | & .theme-light .el-sub-menu .el-menu-item {
|
| | | //background-color: transparent;
|
| | |
|
| | | &:hover {
|
| | | background-color: $base-sub-menu-hover !important;
|
| | | background-color: rgba(212,221,255,0.56) !important;
|
| | | }
|
| | | }
|
| | | }
|
| | |
| | | }
|
| | | }
|
| | | }
|
| | |
|
| | | .el-sub-menu {
|
| | | overflow: hidden;
|
| | |
|
| | |
| | | .el-menu-item {
|
| | | &:hover {
|
| | | // you can use $sub-menuHover
|
| | | background-color: rgba(0, 0, 0, 0.06) !important;
|
| | | background-color: rgba(212,221,255,0.56) !important;
|
| | | }
|
| | | &.is-active {
|
| | | background-color: rgba(212,221,255,0.56) !important;
|
| | | }
|
| | | }
|
| | |
|
¶Ô±ÈÐÂÎļþ |
| | |
| | | <template> |
| | | <el-table ref="multipleTable" v-loading="tableLoading" :border="border" :data="tableData" |
| | | :header-cell-style="{ background: '#F0F1F5', color: '#333333' }" :height="height" |
| | | :highlight-current-row="highlightCurrentRow" :row-class-name="rowClassName" :row-style="rowStyle" |
| | | :row-key="rowKey" :span-method="spanMethod" stripe style="width: 100%" tooltip-effect="dark" @row-click="rowClick" |
| | | @current-change="currentChange" @selection-change="handleSelectionChange" class="lims-table"> |
| | | <el-table-column align="center" type="selection" width="55" v-if="isSelection" /> |
| | | <el-table-column align="center" label="åºå·" type="index" width="60" :index="indexMethod" /> |
| | | |
| | | <el-table-column v-for="(item, index) in column" :key="index" :column-key="item.columnKey" |
| | | :filter-method="item.filterHandler" :filter-multiple="item.filterMultiple" :filtered-value="item.filteredValue" |
| | | :filters="item.filters" :fixed="item.fixed" :label="item.label" :prop="item.prop" |
| | | :show-overflow-tooltip="!(item.dataType === 'action' || item.dataType === 'slot')" |
| | | :min-width="item.dataType == 'action' ? btnWidth : item.width" |
| | | :sortable="!!item.sortable" :type="item.type" :width="item.dataType == 'action' ? btnWidth : item.width" align="center"> |
| | | <template v-if="item.hasOwnProperty('colunmTemplate')" #[item.colunmTemplate]="scope"> |
| | | <slot v-if="item.theadSlot" :name="item.theadSlot" :index="scope.$index" :row="scope.row" /> |
| | | </template> |
| | | |
| | | <template #default="scope"> |
| | | <!-- ææ§½ --> |
| | | <div v-if="item.dataType == 'slot'"> |
| | | <slot v-if="item.slot" :index="scope.$index" :name="item.slot" :row="scope.row" /> |
| | | </div> |
| | | <!-- è¿åº¦æ¡ --> |
| | | <div v-else-if="item.dataType == 'progress'"> |
| | | <el-progress :percentage="Number(scope.row[item.prop])" /> |
| | | </div> |
| | | <!-- å¾ç --> |
| | | <div v-else-if="item.dataType == 'image'"> |
| | | <img :src="javaApi + '/img/' + scope.row[item.prop]" alt="" style="width: 40px; height: 40px; margin-top: 10px" /> |
| | | </div> |
| | | |
| | | <!-- tag --> |
| | | <div v-else-if="item.dataType == 'tag'"> |
| | | <el-tag v-if="typeof dataTypeFn(scope.row[item.prop], item.formatData) === 'string'" |
| | | :title="formatters(scope.row[item.prop], item.formatData)" |
| | | :type="formatType(scope.row[item.prop], item.formatType)"> |
| | | {{ formatters(scope.row[item.prop], item.formatData) }} |
| | | </el-tag> |
| | | |
| | | <el-tag v-for="(tag, index) in dataTypeFn(scope.row[item.prop], item.formatData)" |
| | | v-else-if="typeof dataTypeFn(scope.row[item.prop], item.formatData) === 'object'" |
| | | :key="index" :title="formatters(scope.row[item.prop], item.formatData)" :type="formatType(tag, item.formatType)"> |
| | | {{ item.tagGroup ? tag[item.tagGroup.label] ?? tag : tag }} |
| | | </el-tag> |
| | | |
| | | <el-tag v-else :title="formatters(scope.row[item.prop], item.formatData)" :type="formatType(scope.row[item.prop], item.formatType)"> |
| | | {{ formatters(scope.row[item.prop], item.formatData) }} |
| | | </el-tag> |
| | | </div> |
| | | |
| | | <!-- æé® --> |
| | | <div v-else-if="item.dataType == 'action'" |
| | | :style="`min-width:${getWidth(item.operation, scope.row)}`"> |
| | | <template v-for="(o, key) in item.operation" :key="key"> |
| | | <el-button v-show="o.type != 'upload'" size="small" v-if="o.showHide ? o.showHide(scope.row) : true" |
| | | :disabled="o.disabled ? o.disabled(scope.row) : false" :plain="o.plain" |
| | | :style="{ color: (o.name === 'å é¤' || o.name === 'delete') ? '#f56c6c' : o.color }" :type="typeFn(o.type, scope.row)" |
| | | @click="o.clickFun(scope.row)" :key="key"> |
| | | {{ o.name }} |
| | | </el-button> |
| | | <el-upload :action="javaApi + o.url + '?id=' + (o.uploadIdFun ? o.uploadIdFun(scope.row) : scope.row.id)" |
| | | ref="uploadRef" size="small" :multiple="o.multiple ? o.multiple : false" :limit="1" |
| | | :disabled="o.disabled ? o.disabled(scope.row) : false" |
| | | :accept="o.accept ? o.accept : '.jpg,.jpeg,.png,.gif,.doc,.docx,.xls,.xlsx,.ppt,.pptx,.pdf,.zip,.rar'" |
| | | v-if="o.type == 'upload'" style="display: inline-block; width: 50px" |
| | | v-show="o.showHide ? o.showHide(scope.row) : true" :headers="uploadHeader" |
| | | :before-upload="(file) => beforeUpload(file, scope.$index)" |
| | | :on-change="(file, fileList) => handleChange(file, fileList, scope.$index)" |
| | | :on-error="(error, file, fileList) => onError(error, file, fileList, scope.$index)" |
| | | :on-success="(response, file, fileList) => handleSuccessUp(response, file, fileList, scope.$index)" |
| | | :on-exceed="onExceed" :show-file-list="false"> |
| | | <el-button :size="o.size ? o.size : 'small'" type="text" |
| | | :disabled="o.disabled ? o.disabled(scope.row) : false">{{ o.name }}</el-button> |
| | | </el-upload> |
| | | </template> |
| | | </div> |
| | | <!-- å¯ç¹å»çæå --> |
| | | <div v-else-if="item.dataType == 'link'" class="cell link" style="width: 100%" |
| | | @click="goLink(scope.row, item.linkMethod)"> |
| | | <span v-if="!item.formatData">{{ scope.row[item.prop] }}</span> |
| | | </div> |
| | | <!-- é»è®¤çº¯å±ç¤ºæ°æ® --> |
| | | <div v-else class="cell" style="width: 100%"> |
| | | <span v-if="!item.formatData">{{ scope.row[item.prop] }}</span> |
| | | <span v-else>{{ formatters(scope.row[item.prop], item.formatData) }}</span> |
| | | </div> |
| | | </template> |
| | | </el-table-column> |
| | | </el-table> |
| | | <pagination v-show="page.total > 0" :total="page.total" :layout="page.layout" :page="page.current" |
| | | :limit="page.size" @pagination="paginationSearch" /> |
| | | </template> |
| | | |
| | | <script setup> |
| | | import pagination from './Pagination.vue' |
| | | import { ref, inject, getCurrentInstance } from "vue" |
| | | import { ElMessage } from "element-plus" |
| | | |
| | | // è·åå
¨å±ç uploadHeader |
| | | const { proxy } = getCurrentInstance() |
| | | const uploadHeader = proxy.uploadHeader |
| | | const javaApi = proxy.javaApi |
| | | |
| | | // Filters |
| | | const typeFn = (val, row) => { |
| | | return typeof val === 'function' ? val(row) : val |
| | | } |
| | | |
| | | const formatters = (val, format) => { |
| | | return typeof format === 'function' ? format(val) : val |
| | | } |
| | | |
| | | // Propsï¼ä½¿ç¨ defineProps çé TS å½¢å¼ï¼ |
| | | const props = defineProps({ |
| | | isSelection: { |
| | | type: Boolean, |
| | | default: false |
| | | }, |
| | | height: { |
| | | type: [String, null], |
| | | default: null |
| | | }, |
| | | tableLoading: { |
| | | type: Boolean, |
| | | default: false |
| | | }, |
| | | handleSelectionChange: { |
| | | type: Function, |
| | | default: () => {} |
| | | }, |
| | | rowClick: { |
| | | type: Function, |
| | | default: () => {} |
| | | }, |
| | | currentChange: { |
| | | type: Function, |
| | | default: () => {} |
| | | }, |
| | | border: { |
| | | type: Boolean, |
| | | default: true |
| | | }, |
| | | highlightCurrentRow: { |
| | | type: Boolean, |
| | | default: false |
| | | }, |
| | | headerCellStyle: { |
| | | type: Object, |
| | | default: () => ({}) |
| | | }, |
| | | column: { |
| | | type: Array, |
| | | default: () => [] |
| | | }, |
| | | rowClassName: { |
| | | type: Function, |
| | | default: () => '' |
| | | }, |
| | | rowStyle: { |
| | | type: [Object, Function], |
| | | default: () => ({}) |
| | | }, |
| | | tableData: { |
| | | type: Array, |
| | | default: () => [] |
| | | }, |
| | | rowKey: { |
| | | type: String, |
| | | default: undefined |
| | | }, |
| | | page: { |
| | | type: Object, |
| | | default: () => ({ |
| | | total: 0, |
| | | current: 0, |
| | | size: 10, |
| | | layout: 'total, sizes, prev, pager, next, jumper' |
| | | }) |
| | | } |
| | | }) |
| | | |
| | | // Data |
| | | const spanList = ref([]) |
| | | const btnWidth = ref('120px') |
| | | const uploadRefs = ref([]) |
| | | const currentFiles = ref({}) |
| | | const uploadKeys = ref({}) |
| | | |
| | | // åå¹¶åå
æ ¼æ¹æ³ |
| | | const spanMethod = ({ row, column, rowIndex, columnIndex }) => { |
| | | if (column.find((m) => m.mergeCol)) { |
| | | let i = Number(rowIndex) |
| | | const obj = spanList.value.find((item, index) => { |
| | | i = index |
| | | return item.index == columnIndex |
| | | }) |
| | | if (obj) { |
| | | const _row = spanList[i].arr[rowIndex] |
| | | const _col = _row > 0 ? 1 : 0 |
| | | return { |
| | | rowspan: _row, |
| | | colspan: _col |
| | | } |
| | | } |
| | | } |
| | | } |
| | | |
| | | const indexMethod = (index) => { |
| | | return (props.page.current - 1) * props.page.size + index + 1 |
| | | } |
| | | |
| | | const getWidth = (row, row0) => { |
| | | let count = 0 |
| | | row.forEach((a) => { |
| | | if (a.showHide !== undefined && a.showHide(row0)) { |
| | | count += a.name.length |
| | | } else if (!a.showHide) { |
| | | count += a.name.length |
| | | } |
| | | }) |
| | | btnWidth.value = count * 15 + 60 + "px" |
| | | return count * 15 + 60 + "px" |
| | | } |
| | | |
| | | // ç¹å» link äºä»¶ |
| | | const goLink = (row, linkMethod) => { |
| | | if (!linkMethod) { |
| | | return ElMessage.warning("请é
ç½® link äºä»¶") |
| | | } |
| | | const parentMethod = getParentMethod(linkMethod) |
| | | if (typeof parentMethod === 'function') { |
| | | parentMethod(row) |
| | | } else { |
| | | console.warn(`ç¶ç»ä»¶ä¸æªæ¾å°æ¹æ³: ${linkMethod}`) |
| | | } |
| | | } |
| | | |
| | | // è·åç¶ç»ä»¶æ¹æ³ï¼ç¤ºä¾å®ç°ï¼ |
| | | const getParentMethod = (methodName) => { |
| | | const parentMethods = inject('parentMethods', {}) |
| | | return parentMethods[methodName] |
| | | } |
| | | |
| | | const dataTypeFn = (val, format) => { |
| | | if (typeof format === "function") { |
| | | return format(val) |
| | | } else return val |
| | | } |
| | | |
| | | const formatType = (val, format) => { |
| | | if (typeof format === "function") { |
| | | return format(val) |
| | | } else return "" |
| | | } |
| | | |
| | | // æä»¶ååå¤ç |
| | | const handleChange = (file, fileList, index) => { |
| | | if (fileList.length > 1) { |
| | | const earliestFile = fileList[0] |
| | | uploadRefs.value[index]?.handleRemove(earliestFile) |
| | | } |
| | | currentFiles.value[index] = file |
| | | } |
| | | |
| | | // æä»¶ä¸ä¼ åæ ¡éª |
| | | const beforeUpload = (rawFile, index) => { |
| | | currentFiles.value[index] = {} |
| | | if (rawFile.size > 1024 * 1024 * 10) { |
| | | ElMessage.error('ä¸ä¼ æä»¶ä¸è¶
è¿10M') |
| | | return false |
| | | } |
| | | return true |
| | | } |
| | | |
| | | // ä¸ä¼ æå |
| | | const handleSuccessUp = (response, file, fileList, index) => { |
| | | if (response.code == 200) { |
| | | if (uploadRefs[index]) { |
| | | uploadRefs[index].clearFiles() |
| | | } |
| | | currentFiles[index] = file |
| | | ElMessage.success("ä¸ä¼ æå") |
| | | resetUploadComponent(index) |
| | | } else { |
| | | ElMessage.error(response.message) |
| | | } |
| | | } |
| | | |
| | | const resetUploadComponent = (index) => { |
| | | uploadKeys[index] = Date.now() |
| | | } |
| | | |
| | | // ä¸ä¼ 失败 |
| | | const onError = (error, file, fileList, index) => { |
| | | ElMessage.error('æä»¶ä¸ä¼ 失败ï¼è¯·éè¯') |
| | | if (uploadRefs.value[index]) { |
| | | uploadRefs.value[index].clearFiles() |
| | | } |
| | | } |
| | | |
| | | // æä»¶æ°éè¶
éæç¤º |
| | | const onExceed = () => { |
| | | ElMessage.warning('è¶
åºæä»¶ä¸ªæ°') |
| | | } |
| | | |
| | | const paginationSearch = ({ page, limit }) => { |
| | | emit("pagination", { page: page, limit: limit }); |
| | | } |
| | | </script> |
| | | |
| | | <style scoped lang="scss"> |
| | | </style> |
¶Ô±ÈÐÂÎļþ |
| | |
| | | <template> |
| | | <div :class="{ hidden }" class="pagination-container"> |
| | | <el-pagination |
| | | :background="background" |
| | | v-model:current-page="currentPage" |
| | | v-model:page-size="pageSize" |
| | | :layout="layout" |
| | | :page-sizes="pageSizes" |
| | | :pager-count="pagerCount" |
| | | :total="total" |
| | | v-bind="$attrs" |
| | | @size-change="handleSizeChange" |
| | | @current-change="handleCurrentChange" |
| | | /> |
| | | </div> |
| | | </template> |
| | | |
| | | <script setup> |
| | | import { computed } from 'vue' |
| | | import { scrollTo } from '@/utils/scroll-to' |
| | | |
| | | const props = defineProps({ |
| | | total: { |
| | | type: Number, |
| | | required: true |
| | | }, |
| | | page: { |
| | | type: Number, |
| | | default: 1 |
| | | }, |
| | | limit: { |
| | | type: Number, |
| | | default: 20 |
| | | }, |
| | | pageSizes: { |
| | | type: Array, |
| | | default: () => [10, 20, 30, 50, 100] |
| | | }, |
| | | pagerCount: { |
| | | type: Number, |
| | | default: () => (document.body.clientWidth < 992 ? 5 : 7) |
| | | }, |
| | | layout: { |
| | | type: String, |
| | | default: 'total, sizes, prev, pager, next, jumper' |
| | | }, |
| | | background: { |
| | | type: Boolean, |
| | | default: true |
| | | }, |
| | | autoScroll: { |
| | | type: Boolean, |
| | | default: true |
| | | }, |
| | | hidden: { |
| | | type: Boolean, |
| | | default: false |
| | | } |
| | | }) |
| | | |
| | | const emit = defineEmits(['update:page', 'update:limit', 'pagination']) |
| | | |
| | | const currentPage = computed({ |
| | | get: () => props.page, |
| | | set: (val) => emit('update:page', val) |
| | | }) |
| | | |
| | | const pageSize = computed({ |
| | | get: () => props.limit, |
| | | set: (val) => emit('update:limit', val) |
| | | }) |
| | | |
| | | const handleSizeChange = (val) => { |
| | | if (currentPage.value * val > props.total) { |
| | | currentPage.value = 1 |
| | | } |
| | | emit('pagination', { page: currentPage.value, limit: val }) |
| | | if (props.autoScroll) { |
| | | scrollTo(0, 800) |
| | | } |
| | | } |
| | | |
| | | const handleCurrentChange = (val) => { |
| | | emit('pagination', { page: val, limit: pageSize.value }) |
| | | if (props.autoScroll) { |
| | | scrollTo(0, 800) |
| | | } |
| | | } |
| | | </script> |
| | | |
| | | <style scoped> |
| | | .pagination-container { |
| | | background: #fff; |
| | | padding: 28px 16px; |
| | | margin-top: 10px; |
| | | } |
| | | .pagination-container.hidden { |
| | | display: none; |
| | | } |
| | | </style> |
| | |
| | | width: 100%;
|
| | | position: relative;
|
| | | overflow: hidden;
|
| | | background: #F5F7FB;
|
| | | }
|
| | |
|
| | | .fixed-header + .app-main {
|
| | |
| | | <template>
|
| | | <div class="navbar">
|
| | | <hamburger id="hamburger-container" :is-active="appStore.sidebar.opened" class="hamburger-container" @toggleClick="toggleSideBar" />
|
| | | <breadcrumb v-if="!settingsStore.topNav" id="breadcrumb-container" class="breadcrumb-container" />
|
| | | <top-nav v-if="settingsStore.topNav" id="topmenu-container" class="topmenu-container" />
|
| | |
|
| | | <div>
|
| | | <hamburger id="hamburger-container" :is-active="appStore.sidebar.opened" class="hamburger-container" @toggleClick="toggleSideBar" />
|
| | | <breadcrumb v-if="!settingsStore.topNav" id="breadcrumb-container" class="breadcrumb-container" />
|
| | | </div>
|
| | | <!-- <top-nav v-if="settingsStore.topNav" id="topmenu-container" class="topmenu-container" />-->
|
| | | <div class="center-menu">
|
| | | <span class="label">ç³»ç»åç§°ç³»ç»åç§°</span>
|
| | | </div>
|
| | | <div class="right-menu">
|
| | | <template v-if="appStore.device !== 'mobile'">
|
| | | <header-search id="header-search" class="right-menu-item" />
|
| | |
|
| | | <el-tooltip content="æºç å°å" effect="dark" placement="bottom">
|
| | | <ruo-yi-git id="ruoyi-git" class="right-menu-item hover-effect" />
|
| | | </el-tooltip>
|
| | |
|
| | | <el-tooltip content="ææ¡£å°å" effect="dark" placement="bottom">
|
| | | <ruo-yi-doc id="ruoyi-doc" class="right-menu-item hover-effect" />
|
| | | </el-tooltip>
|
| | |
|
| | | <screenfull id="screenfull" class="right-menu-item hover-effect" />
|
| | |
|
| | | <el-tooltip content="䏻颿¨¡å¼" effect="dark" placement="bottom">
|
| | | <div class="right-menu-item hover-effect theme-switch-wrapper" @click="toggleTheme">
|
| | | <svg-icon v-if="settingsStore.isDark" icon-class="sunny" />
|
| | | <svg-icon v-if="!settingsStore.isDark" icon-class="moon" />
|
| | | </div>
|
| | | </el-tooltip>
|
| | |
|
| | | <el-tooltip content="å¸å±å¤§å°" effect="dark" placement="bottom">
|
| | | <size-select id="size-select" class="right-menu-item hover-effect" />
|
| | | </el-tooltip>
|
| | | </template>
|
| | | <div class="avatar-container">
|
| | | <el-dropdown @command="handleCommand" class="right-menu-item hover-effect" trigger="click">
|
| | | <div class="avatar-wrapper">
|
| | |
| | | position: relative;
|
| | | background: var(--navbar-bg);
|
| | | box-shadow: 0 1px 4px rgba(0, 21, 41, 0.08);
|
| | | .center-menu {
|
| | | line-height: 50px;
|
| | | position: absolute;
|
| | | left: 50%;
|
| | | transform: translateX(-50%);
|
| | | .label {
|
| | | font-weight: bold;
|
| | | font-size: 18px;
|
| | | color: #333333;
|
| | | }
|
| | | }
|
| | |
|
| | | .hamburger-container {
|
| | | line-height: 46px;
|
| | |
| | | cursor: pointer;
|
| | | width: 40px;
|
| | | height: 40px;
|
| | | border-radius: 10px;
|
| | | border-radius: 50px;
|
| | | }
|
| | |
|
| | | i {
|
| | | cursor: pointer;
|
| | | position: absolute;
|
| | | right: -20px;
|
| | | top: 25px;
|
| | | top: 14px;
|
| | | font-size: 12px;
|
| | | }
|
| | | }
|
| | |
| | | .tags-view-container {
|
| | | height: 34px;
|
| | | width: 100%;
|
| | | background: var(--tags-bg, #fff);
|
| | | border-bottom: 1px solid var(--tags-item-border, #d8dce5);
|
| | | box-shadow: 0 1px 3px 0 rgba(0, 0, 0, .12), 0 0 3px 0 rgba(0, 0, 0, .04);
|
| | | background: transparent;
|
| | |
|
| | | .tags-view-wrapper {
|
| | | .tags-view-item {
|
| | | display: inline-block;
|
| | | position: relative;
|
| | | cursor: pointer;
|
| | | height: 26px;
|
| | | line-height: 26px;
|
| | | border: 1px solid var(--tags-item-border, #d8dce5);
|
| | | color: var(--tags-item-text, #495060);
|
| | | background: var(--tags-item-bg, #fff);
|
| | | padding: 0 8px;
|
| | | height: 32px;
|
| | | line-height: 32px;
|
| | | //border: 1px solid var(--tags-item-border, #d8dce5);
|
| | | color: #4E5463;
|
| | | background: #E5E7EA;
|
| | | padding: 0 16px;
|
| | | font-size: 12px;
|
| | | margin-left: 5px;
|
| | | margin-top: 4px;
|
| | | //margin-left: 5px;
|
| | | //margin-top: 4px;
|
| | |
|
| | | &:first-of-type {
|
| | | margin-left: 15px;
|
| | | }
|
| | |
|
| | | &:last-of-type {
|
| | | margin-right: 15px;
|
| | | }
|
| | | //&:first-of-type {
|
| | | // margin-left: 8px;
|
| | | //}
|
| | | //
|
| | | //&:last-of-type {
|
| | | // margin-right: 15px;
|
| | | //}
|
| | |
|
| | | &.active {
|
| | | background-color: #42b983;
|
| | | color: #fff;
|
| | | border-color: #42b983;
|
| | |
|
| | | &::before {
|
| | | content: '';
|
| | | background: #fff;
|
| | | display: inline-block;
|
| | | width: 8px;
|
| | | height: 8px;
|
| | | border-radius: 50%;
|
| | | position: relative;
|
| | | margin-right: 5px;
|
| | | }
|
| | | background-color: #FFFFFF !important;
|
| | | color: #2C51D9;
|
| | | }
|
| | | }
|
| | | //.tags-view-item div {
|
| | | // transform: skew(12deg);
|
| | | // display: inline-block;
|
| | | //}
|
| | | }
|
| | |
|
| | | .contextmenu {
|
| | |
| | | import ImagePreview from "@/components/ImagePreview"
|
| | | // åå
¸æ ç¾ç»ä»¶
|
| | | import DictTag from '@/components/DictTag'
|
| | | // è¡¨æ ¼ç»ä»¶
|
| | | import PIMTable from "@/components/PIMTable/PIMTable.vue";
|
| | |
|
| | | import { getToken } from "@/utils/auth";
|
| | |
|
| | | const app = createApp(App)
|
| | |
|
| | |
| | | app.config.globalProperties.addDateRange = addDateRange
|
| | | app.config.globalProperties.selectDictLabel = selectDictLabel
|
| | | app.config.globalProperties.selectDictLabels = selectDictLabels
|
| | | app.config.globalProperties.javaApi = 'http://192.168.1.36:8080'
|
| | | app.config.globalProperties.HaveJson = (val) => {
|
| | | return JSON.parse(JSON.stringify(val));
|
| | | };
|
| | | app.config.globalProperties.uploadHeader = {
|
| | | Authorization: "Bearer " + getToken(),
|
| | | };
|
| | |
|
| | | // å
¨å±ç»ä»¶æè½½
|
| | | app.component('DictTag', DictTag)
|
| | |
| | | app.component('ImagePreview', ImagePreview)
|
| | | app.component('RightToolbar', RightToolbar)
|
| | | app.component('Editor', Editor)
|
| | | app.component('PIMTable', PIMTable)
|
| | |
|
| | | app.use(router)
|
| | | app.use(store)
|
| | |
| | | /**
|
| | | * ä¾§è¾¹æ ä¸»é¢ æ·±è²ä¸»é¢theme-darkï¼æµ
è²ä¸»é¢theme-light
|
| | | */
|
| | | sideTheme: 'theme-dark',
|
| | | sideTheme: 'theme-light',
|
| | | /**
|
| | | * æ¯å¦ç³»ç»å¸å±é
ç½®
|
| | | */
|
| | |
| | | /**
|
| | | * æ¯å¦åºå®å¤´é¨
|
| | | */
|
| | | fixedHeader: false,
|
| | | fixedHeader: true,
|
| | |
|
| | | /**
|
| | | * æ¯å¦æ¾ç¤ºlogo
|
| | |
| | | {
|
| | | state: () => ({
|
| | | title: '',
|
| | | theme: storageSetting.theme || '#409EFF',
|
| | | theme: storageSetting.theme || '#3472D7',
|
| | | sideTheme: storageSetting.sideTheme || sideTheme,
|
| | | showSettings: showSettings,
|
| | | topNav: storageSetting.topNav === undefined ? topNav : storageSetting.topNav,
|
¶Ô±ÈÐÂÎļþ |
| | |
| | | <template> |
| | | <div class="app-container"> |
| | | <div class="search_form"> |
| | | <div> |
| | | <span class="search_title">客æ·åç§°ï¼</span> |
| | | <el-input |
| | | v-model="input2" |
| | | style="width: 240px" |
| | | placeholder="请è¾å
¥" |
| | | :prefix-icon="Search" |
| | | /> |
| | | </div> |
| | | <div> |
| | | <el-button type="primary">æ°å¢å®¢æ·</el-button> |
| | | <el-button>导åº</el-button> |
| | | <el-button type="danger" plain>å é¤</el-button> |
| | | </div> |
| | | </div> |
| | | <div class="table_list"> |
| | | <PIMTable :column="tableColumn"></PIMTable> |
| | | </div> |
| | | </div> |
| | | </template> |
| | | |
| | | <script setup> |
| | | import { ref } from 'vue' |
| | | import {Search} from "@element-plus/icons-vue"; |
| | | |
| | | const input2 = ref('') |
| | | const tableColumn = ref([ |
| | | { |
| | | label: 'æ¹åå
容', |
| | | prop: 'ratifyRemark' |
| | | }, { |
| | | label: 'æ¹å人', |
| | | prop: 'ratifyName', |
| | | }, |
| | | ]) |
| | | </script> |
| | | |
| | | <style scoped lang="scss"> |
| | | |
| | | </style> |
| | |
| | | <div class="login">
|
| | | <el-form ref="loginRef" :model="loginForm" :rules="loginRules" class="login-form">
|
| | | <h3 class="title">{{ title }}</h3>
|
| | | <el-divider />
|
| | | <el-form-item prop="username">
|
| | | <el-input
|
| | | v-model="loginForm.username"
|
| | |
| | | auto-complete="off"
|
| | | placeholder="è´¦å·"
|
| | | >
|
| | | <template #prefix><svg-icon icon-class="user" class="el-input__icon input-icon" /></template>
|
| | | <template #prefix><el-icon><User /></el-icon></template>
|
| | | </el-input>
|
| | | </el-form-item>
|
| | | <el-form-item prop="password">
|
| | |
| | | size="large"
|
| | | auto-complete="off"
|
| | | placeholder="å¯ç "
|
| | | show-password
|
| | | @keyup.enter="handleLogin"
|
| | | >
|
| | | <template #prefix><svg-icon icon-class="password" class="el-input__icon input-icon" /></template>
|
| | | </el-input>
|
| | | </el-form-item>
|
| | | <el-form-item prop="code" v-if="captchaEnabled">
|
| | | <el-input
|
| | | v-model="loginForm.code"
|
| | | size="large"
|
| | | auto-complete="off"
|
| | | placeholder="éªè¯ç "
|
| | | style="width: 63%"
|
| | | @keyup.enter="handleLogin"
|
| | | >
|
| | | <template #prefix><svg-icon icon-class="validCode" class="el-input__icon input-icon" /></template>
|
| | | </el-input>
|
| | | <div class="login-code">
|
| | | <img :src="codeUrl" @click="getCode" class="login-code-img"/>
|
| | | </div>
|
| | | </el-form-item>
|
| | | <el-checkbox v-model="loginForm.rememberMe" style="margin:0px 0px 25px 0px;">è®°ä½å¯ç </el-checkbox>
|
| | | <!-- <el-form-item prop="code" v-if="captchaEnabled">-->
|
| | | <!-- <el-input-->
|
| | | <!-- v-model="loginForm.code"-->
|
| | | <!-- size="large"-->
|
| | | <!-- auto-complete="off"-->
|
| | | <!-- placeholder="éªè¯ç "-->
|
| | | <!-- style="width: 63%"-->
|
| | | <!-- @keyup.enter="handleLogin"-->
|
| | | <!-- >-->
|
| | | <!-- <template #prefix><svg-icon icon-class="validCode" class="el-input__icon input-icon" /></template>-->
|
| | | <!-- </el-input>-->
|
| | | <!-- <div class="login-code">-->
|
| | | <!-- <img :src="codeUrl" @click="getCode" class="login-code-img"/>-->
|
| | | <!-- </div>-->
|
| | | <!-- </el-form-item>-->
|
| | | <el-form-item style="width:100%;">
|
| | | <el-button
|
| | | :loading="loading"
|
| | |
| | | <router-link class="link-type" :to="'/register'">ç«å³æ³¨å</router-link>
|
| | | </div>
|
| | | </el-form-item>
|
| | | <el-checkbox v-model="loginForm.rememberMe" style="margin:0px 0px 25px 0px;">è®°ä½å¯ç </el-checkbox>
|
| | | </el-form>
|
| | | <!-- åºé¨ -->
|
| | | <div class="el-login-footer">
|
| | | <span>Copyright © 2018-2025 ruoyi.vip All Rights Reserved.</span>
|
| | | </div>
|
| | | <!-- <div class="el-login-footer">-->
|
| | | <!-- <span>Copyright © 2018-2025 ruoyi.vip All Rights Reserved.</span>-->
|
| | | <!-- </div>-->
|
| | | </div>
|
| | | </template>
|
| | |
|
| | |
| | | username: "admin",
|
| | | password: "admin123",
|
| | | rememberMe: false,
|
| | | code: "",
|
| | | // code: "",
|
| | | uuid: ""
|
| | | })
|
| | |
|
| | | const loginRules = {
|
| | | username: [{ required: true, trigger: "blur", message: "请è¾å
¥æ¨çè´¦å·" }],
|
| | | password: [{ required: true, trigger: "blur", message: "请è¾å
¥æ¨çå¯ç " }],
|
| | | code: [{ required: true, trigger: "change", message: "请è¾å
¥éªè¯ç " }]
|
| | | // code: [{ required: true, trigger: "change", message: "请è¾å
¥éªè¯ç " }]
|
| | | }
|
| | |
|
| | | const codeUrl = ref("")
|
| | |
| | |
|
| | | <style lang='scss' scoped>
|
| | | .login {
|
| | | display: flex;
|
| | | justify-content: center;
|
| | | align-items: center;
|
| | | height: 100%;
|
| | | background-image: url("../assets/images/login-background.jpg");
|
| | | background-size: cover;
|
| | | position: relative;
|
| | | }
|
| | | .title {
|
| | | margin: 0px auto 30px auto;
|
| | | margin: 20px auto 14px auto;
|
| | | text-align: center;
|
| | | color: #707070;
|
| | | color: #3472D7;
|
| | | font-size: 28px;
|
| | | font-weight: 700;
|
| | | }
|
| | |
|
| | | .login-form {
|
| | | position: absolute;
|
| | | top: 50%;
|
| | | right: 19%;
|
| | | transform: translate(0, -50%);
|
| | | border-radius: 6px;
|
| | | background: #ffffff;
|
| | | width: 400px;
|
| | | padding: 25px 25px 5px 25px;
|
| | | width: 420px;
|
| | | height: 500px;
|
| | | padding: 40px;
|
| | | z-index: 1;
|
| | | .el-input {
|
| | | height: 40px;
|
| | |
| | | height: 40px;
|
| | | padding-left: 12px;
|
| | | }
|
| | | :deep() {
|
| | | .el-form-item--default {
|
| | | margin-bottom: 36px;
|
| | | }
|
| | | }
|
| | | </style>
|
| | |
| | | </script>
|
| | |
|
| | | <style lang='scss'>
|
| | | $lighterBlue: #409EFF;
|
| | | $lighterBlue: #3472D7;
|
| | |
|
| | | .container {
|
| | | position: relative;
|