test.vue

<!-- 图片展示 -->
<template>
  <el-main>
    <div class="cateList1">
      <el-row :gutter="20">
        <el-col :span="6" v-for="(item, i) in dataList" :key="i">
          <el-card style="margin-top: 15px; position: relative" shadow="hover">
            <el-image
              style="width: 100%; height: 150px"
              :src="item.url"
              fit="cover"
            />
            <div class="pic_title">{{ item.name }}</div>
            <div class="pic_edit">
              <el-checkbox v-model="item.checked" @change="selectImg(item)" />
              <span @click="openDialog(item)">重命名</span>
              <span @click="delPic(item.id)">删除</span>
            </div>
          </el-card>
        </el-col>
      </el-row>
    </div>
    <div class="page1">
      <el-pagination
        v-model:current-page="querData.page"
        v-model:page-size="querData.limit"
        :page-sizes="[2, 8, 15, 20]"
        small="small"
        background="background"
        layout="total, sizes, prev, pager, next, jumper"
        :total="total"
        @size-change="handleSizeChange"
        @current-change="handleCurrentChange"
      />
    </div>
    <!-- 重命名 -->
    <el-dialog v-model="dialogVisible" title="重命名" width="40%">
      <el-form :model="formDate">
        <el-form-item label="图片名称">
          <el-input v-model="formDate.name" />
        </el-form-item>
      </el-form>
      <template #footer>
        <span class="dialog-footer">
          <el-button @click="dialogVisible = false">取消</el-button>
          <el-button type="primary" @click="submitOk"> 确定 </el-button>
        </span>
      </template>
    </el-dialog>

    <!-- 上传图片 -->
    <el-dialog v-model="dialogVisibleUpload" title="上传图片" width="40%">
      <UploadImg
        :data="{ image_class_id: querData.id }"
        @success="uploadSuccess"
      ></UploadImg>
      <template #footer>
        <span class="dialog-footer">
          <el-button @click="dialogVisible = false">取消</el-button>
          <el-button type="primary" @click="dialogVisible = false">
            确定
          </el-button>
        </span>
      </template>
    </el-dialog>
  </el-main>
</template>

<script setup>
import { reactive, ref, computed } from 'vue'
import { getPicListByIdFn, editPicNameFn, delPicFn } from '@/api/pic.js'
import { ElMessage, ElMessageBox } from 'element-plus'
import UploadImg from '@/components/UploadImg.vue'

const props = defineProps({
  num: {
    type: Number,
    default: 1,
  },
})

const checkedImg = computed(() => {
  return dataList.value.filter((item) => item.checked)
})

const emit = defineEmits('selectImgData')

//选择图片事件
const selectImg = (item) => {
  console.log(item)
  if (item.checked && checkedImg.value.length > props.num) {
    item.checked = false
    ElMessage.error(`只能选择${props.num}张图片`)
    return
  }
  emit('selectImgData', checkedImg.value)
}

//上传图片对话框显示和隐藏
const dialogVisibleUpload = ref(false)

const openDialogUpload = () => {
  dialogVisibleUpload.value = true
}

const uploadSuccess = () => {
  getPicList()
}

//删除
const delPic = async (id) => {
  const isdel = await ElMessageBox.confirm('是否删除?', '删除', {
    confirmButtonText: '确定',
    cancelButtonText: '取消',
    type: 'warning',
  }).catch((err) => err)

  console.log(isdel)

  if (isdel !== 'confirm') {
    return
  }

  const res = await delPicFn([id])
  console.log(res)
  getPicList()
}

const dialogVisible = ref(false)
//打开对话框
const openDialog = (item) => {
  console.log(item)
  formDate.id = item.id
  formDate.name = item.name
  dialogVisible.value = true
}

const formDate = reactive({
  id: 0,
  name: '',
})

//确定修改图片名称
const submitOk = async () => {
  const res = await editPicNameFn(formDate.id, formDate.name)
  console.log(res)
  if (res.msg && res.msg !== 'ok') {
    return
  }
  dialogVisible.value = false
  getPicList()
}

const querData = reactive({
  //图库分类ID
  id: 0,
  page: 1,
  limit: 8,
})

//分页
const handleSizeChange = (val) => {
  console.log(val)
  querData.limit = val
  getPicList()
}
const handleCurrentChange = (val) => {
  querData.page = val
  getPicList()
}

const dataList = ref([])
const total = ref(0)

const getPicList = async () => {
  const res = await getPicListByIdFn(querData.id, querData.page, querData.limit)

  if (res.msg && res.msg !== 'ok') {
    return
  }
  dataList.value = res.data.list.map((item) => {
    item.checked = false
    return item
  })
  console.log(dataList.value)
  total.value = res.data.totalCount
}
//getPicList()

//获取父组件分类id
const getDataById = (id) => {
  //id 分类id
  querData.id = id
  getPicList()
}
// 还需要通过defineExpose暴露据和方法让子组件许可和确认,接下来在父组件中就可以查看子组件中暴露的数据与方法
defineExpose({
  getDataById,
  openDialogUpload,
})
</script>
<style lang="less" scoped>
:deep(.el-card__body) {
  padding: 0px !important;
}
</style>

api.js

import request from '@/utils/request.js'

export const getPicCateFn=(page,limit=10)=>{
    return request({
        url:`admin/getPicsCateList/${page}`,
        method:'GET',
        params:{
            limit
        }
    })
}

//修改图库分类
export const editPicCateFn=(id,data)=>{
    return request({
        url:`admin/editPicsList/${id}`,
        method:'POST',
        data
    })
}

//删除图库分类
export const delCateFn=(id)=>{
    return request({
        url:`admin/delPicsCateList/${id}/delete`,
        method:'POST'
    })
}

//获取图库分类

export const getPicListByIdFn=(id,page,limit)=>{
    return request({
        url:`admin/getPicList/${id}/image/${page}`,
        method:'GET',
        params:{
            limit
        }
    })
}

//删除图片

export const delPicFn=(ids)=>{
    return request({
        url:"admin/delPic/delete_all",
        method:'POST',
        data:{
            ids
        }
    })
}

until/js

// 修改密码
import { editPasswordFn } from '@/api/login.js'
import { ref, reactive } from 'vue'
import { ElMessage } from 'element-plus'
export function useEditPassword() {
    //修改对话是否显示
    const dialogVisible = ref(false)
    //form表单dom元素
    const ruleFormRef = ref(null)
    //修改数据源
    const ruleForm = reactive({
        oldpassword: '',
        password: '',
        repassword: ''
    })
    //验证规则
    const rules = reactive({
        oldpassword: [
            { required: true, message: '请输入旧密码', trigger: 'blur' },
            { min: 5, max: 15, message: '请输入5到15个字符', trigger: 'blur' },
        ],
        password: [
            { required: true, message: '请输入新密码', trigger: 'blur' },
            { min: 5, max: 15, message: '请输入5到15个字符', trigger: 'blur' },
        ],
    })
    //关闭对话框的回调
    const closeHandle = () => {
        ruleFormRef.value.resetFields()
    }

    //确定修改密码
    const submitOk = () => {
        ruleFormRef.value.validate(async isValid => {
            console.log(isValid)
            if (!isValid) {
                return
            }
            const res = await editPasswordFn(ruleForm)
            console.log(res)
            if (res.msg && res.msg !== 'ok') {
                return ElMessage.error(res.msg)
            }
            ElMessage({
                message: '密码修改成功',
                type: 'success',
            })

            dialogVisible.value = false

        })
    }

    return {
        dialogVisible,
        ruleFormRef,
        ruleForm,
        rules,
        closeHandle,
        submitOk
    }
}

router.js

import {createRouter,createWebHashHistory} from 'vue-router'
import store from '@/store/index.js'
import np from 'nprogress'

//路由匹配规则
const routes=[
    {
        path:'/',
        redirect: '/home'
    },
    {
        path:'/home',
        component:()=>import('@/views/Home.vue'),
        children:[
            {
                path:'/home',
                name:'/home',
                component:()=>import('@/views/HomeIndex.vue'),
                meta:{
                    title:'后台首页'
                }
            },
            {
                path:'/notice/list',
                name:'/notice/list',
                component:()=>import('@/views/test.vue'),
                meta:{
                    title:'公告管理'
                }
            }
        ]
    },
    {
        path:'/login',
        component:()=>import('@/views/Login.vue')

    },
    //捕获404
    {
        path:'/:pathMatch(.*)*',
        name:'NotFound',
        component:()=>import('@/views/404.vue')

    }
]

const router=createRouter({
    history:createWebHashHistory(),
    routes
})

//全局路由守卫
router.beforeEach(async (to,from,next)=>{
    np.start()
    //获取token
    const tokenStr=window.sessionStorage.getItem('token')
    if(tokenStr){
        await store.dispatch('getUserInfo')
    }
    //如果没有登录
    if(!tokenStr&&to.path!=='/login') return next('/login')
    //如果已经登录路
    if(tokenStr&&to.path=='/login'){
        return next({path:from.path?from.path:'/'})
    }   
    next()
})

//后置全局路由守卫
router.afterEach((to,from,next)=>{
    np.done()

})
export default router

store.js

import { createStore } from 'vuex'
import { getUserInfoFn } from '@/api/login'

const store = createStore({
    state() {
        return {
            //管理员信息
            userInfo: {
            },
            //导航菜单
            menu:[],
            //控制导航是否隐藏
            isShow:false
        }
    },
    mutations: {
        setUserInfo(state, userInfo) {
            state.userInfo = userInfo
            state.menu=userInfo.menus
        },
        //修改isShow
        setShow(state){
            state.isShow=!state.isShow
        }
    },
    actions: {
        getUserInfo(context) {
            return new Promise((resolve, reject) => {
                getUserInfoFn().then(res => {  
                    console.log(res)                  
                    context.commit('setUserInfo', res.data)
                    resolve(res)
                }).catch(err => reject(err))
            })
        }
    }
})
export default store

App.vue

import { createApp } from 'vue'
import router from './router/index.js'
import './style.css'
import store from '@/store/index.js'
import 'nprogress/nprogress.css'

import ElementPlus from 'element-plus'
import 'element-plus/dist/index.css'

import App from './App.vue'
import * as ElementPlusIconsVue from '@element-plus/icons-vue'

const app = createApp(App)

for (const [key, component] of Object.entries(ElementPlusIconsVue)) {
    app.component(key, component)
}

app.use(ElementPlus)

app.use(router)

app.use(store)

app.mount('#app')

Header.vue

<template>
  <div class="header">
    <!-- 左列 -->
    <span class="logo"> 商城后台管理系统 </span>
    <el-icon class="icon" @click="setIsShow">
      <Fold />
    </el-icon>
    <!-- 右列 -->
    <div class="f_right">
      <el-tooltip
        effect="dark"
        content="刷新"
        :enterable="false"
        placement="bottom"
      >
        <el-icon class="icon" @click="refHandle">
          <Refresh />
        </el-icon>
      </el-tooltip>

      <el-tooltip
        v-if="!isFullscreen"
        effect="dark"
        content="全屏"
        :enterable="false"
        placement="bottom"
      >
        <el-icon class="icon" @click="toggle">
          <FullScreen />
        </el-icon>
      </el-tooltip>

      <el-tooltip
        v-else
        effect="dark"
        content="退出全屏"
        :enterable="false"
        placement="bottom"
      >
        <el-icon class="icon" @click="toggle">
          <FullScreen />
        </el-icon>
      </el-tooltip>

      <el-dropdown @command="commandHandle">
        <span>
          <el-avatar :size="30" :src="$store.state.userInfo.avatar" />
          {{ $store.state.userInfo.username }}
          <el-icon class="el-icon--right" style="margin-left: 10px">
            <arrow-down />
          </el-icon>
        </span>
        <template #dropdown>
          <el-dropdown-menu>
            <el-dropdown-item command="editPassword">修改密码</el-dropdown-item>
            <el-dropdown-item command="logout">退出登录</el-dropdown-item>
          </el-dropdown-menu>
        </template>
      </el-dropdown>
    </div>
    <!-- 修改密码对话框 -->
    <el-dialog
      v-model="dialogVisible"
      title="修改密码"
      width="40%"
      @close="closeHandle"
    >
      <el-form
        ref="ruleFormRef"
        :model="ruleForm"
        :rules="rules"
        label-width="100px"
      >
        <el-form-item label="原密码" prop="oldpassword">
          <el-input v-model="ruleForm.oldpassword" />
        </el-form-item>
        <el-form-item label="新密码" prop="password">
          <el-input v-model="ruleForm.password" />
        </el-form-item>
        <el-form-item label="确认密码" prop="repassword">
          <el-input v-model="ruleForm.repassword" />
        </el-form-item>
      </el-form>
      <template #footer>
        <span class="dialog-footer">
          <el-button @click="dialogVisible = false">取消</el-button>
          <el-button type="primary" @click="submitOk"> 确定 </el-button>
        </span>
      </template>
    </el-dialog>
  </div>
</template>

<script setup>
import { useEditPassword } from '@/utils/useEditPWP.js'
import { Fold, Refresh, FullScreen, ArrowDown } from '@element-plus/icons-vue'
import { useFullscreen } from '@vueuse/core'

import { useStore } from 'vuex'
import { useRouter } from 'vue-router'
import { ElMessageBox } from 'element-plus'

const store = useStore()
const router = useRouter()

const { toggle, isFullscreen } = useFullscreen()
const { dialogVisible, ruleFormRef, ruleForm, rules, closeHandle, submitOk } =
  useEditPassword()

//刷新
const refHandle = () => {
  location.reload()
}

//退出
const logout = async () => {
  const isLogout = await ElMessageBox.confirm('是否退出?', '提示', {
    confirmButtonText: '确定',
    cancelButtonText: '取消',
    type: 'warning',
  }).catch((err) => err)
  console.log(isLogout)
  if (isLogout !== 'confirm') {
    return
  }
  //清空本地存储
  window.sessionStorage.removeItem('token')
  //清空vuex数据
  store.commit('setUserInfo', {})
  router.push({ path: '/login' })
}

//下拉菜单事件
const commandHandle = (res) => {
  if (res == 'editPassword') {
    console.log('修改密码')
    dialogVisible.value = true
  } else if (res == 'logout') {
    console.log('退出')
    logout()
  }
}

//控制导航菜单的显示和隐藏
const setIsShow = () => {
  store.commit('setShow')
}
</script>

echarts.vue

<template>
    <div>
        <el-card>
            <div class="e_title">
                订单统计
                <span>
                    <el-check-tag @change="selectOp(item.value)" :checked="ops == item.value" v-for="(item, i) in option"
                        :key="i">
                        {{ item.text }}
                    </el-check-tag>
                </span>
            </div>
            <div id="e_main">
            </div>
        </el-card>
    </div>
</template>

<script setup>
import * as echarts from 'echarts';
import { getEchartsFn } from '@/api/home.js'
import { ref, onMounted,onBeforeUnmount } from 'vue'


var myChart
onMounted(() => {
    var chartDom = document.getElementById('e_main');
    myChart = echarts.init(chartDom);
    getEchartsData()    
})

const getEchartsData=async ()=>{

    var option;
    option = {
        xAxis: {
            type: 'category',
            data: []
        },
        yAxis: {
            type: 'value'
        },
        series: [
            {
                data: [],
                type: 'bar',
                showBackground: true,
                backgroundStyle: {
                    color: 'rgba(180, 180, 180, 0.2)'
                }
            }
        ]
    };
    
    myChart.showLoading()
    const res=await getEchartsFn(ops.value)
    myChart.hideLoading()
    console.log(res)
    if(res.msg&&res.msg!=='ok'){
        return
    }
    option.xAxis.data=res.data.x
    option.series[0].data=res.data.y

    option && myChart.setOption(option);

}

const ops = ref('week')
const option = [
    {
        text: '月',
        value: 'month'
    },
    {
        text: '周',
        value: 'week'
    },
    {
        text: '天',
        value: 'hour'
    }
]

//选择时间事件
const selectOp = (op) => {
    ops.value = op
    getEchartsData()
}

//销毁期间生命周期
onBeforeUnmount(()=>{
    if(myChart){
        echarts.dispose(myChart)
    }
})

const props=defineProps({
    value:{
        type:Number,
        default:0
    }
})
const data=reactive({
    num:0
})

function fn(){
    gsap.to(data,{
        //0.5毫秒之后 将初始数据 动画替换成父组件传递过来的数据
        duration:0.5,
        num:props.value
    })
}

fn()

watch(()=>props.value,()=>fn())

<el-form-item label="菜单图标" v-if="formData.menu == 1">
    <IconSelect v-model="formData.icon"></IconSelect>
</el-form-item>

//接收v-model的值
defineProps({
    modelValue: String
})

const emit = defineEmits(['update:modelValue'])

//选择图标事件
const changeHandle = (e) => {

    console.log(e)
    emit("update:modelValue", e)
}

const dialogVisible = ref(false)
const titleVal = ref('新增')
const skusId = ref(0)
//新增参数
const formData = reactive({
    name: '',
    default: '',
    order: 50,
    status: 1

})

const openDialog = () => {
    titleVal.value = '新增'
    formData.name = ''
    formData.default = ''
    formData.order = 50
    formData.status = 1
    dialogVisibl
</script>


本站提供的所有下载资源均来自互联网,仅提供学习交流使用,版权归原作者所有。如需商业使用,请联系原作者获得授权。 如您发现有涉嫌侵权的内容,请联系我们 邮箱:alixiixcom@163.com