This commit is contained in:
zpc 2025-08-07 19:55:38 +08:00
parent 636d10fe53
commit fa61d0f70e
29 changed files with 356 additions and 3499 deletions

2
.env
View File

@ -1,3 +1,3 @@
# 页面标题
VITE_APP_TITLE = '申请礼物后台管理'
VITE_APP_TITLE = '光缆资源管理系统'

View File

@ -1,10 +1,10 @@
# 生产环境配置
ENV = 'production'
VITE_APP_API_HOST = 'https://gift.zpc-xy.com/'
VITE_APP_API_HOST = 'https://odf.zpc-xy.com/'
# 生产环境
VITE_APP_BASE_API = 'https://gift.zpc-xy.com/'
VITE_APP_BASE_API = 'https://odf.zpc-xy.com/'
# 路由前缀
VITE_APP_ROUTER_PREFIX = '/'
@ -13,7 +13,7 @@ VITE_APP_ROUTER_PREFIX = '/'
VITE_APP_UPLOAD_URL = 'Common/UploadFile'
#socket API
VITE_APP_SOCKET_API = 'https://gift.zpc-xy.com/msghub'
VITE_APP_SOCKET_API = 'https://odf.zpc-xy.com/msghub'
# 是否在打包时开启压缩,支持 gzip 和 brotli
VITE_BUILD_COMPRESS = gzip

BIN
dist.zip

Binary file not shown.

View File

@ -6,8 +6,8 @@
<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
<meta name="renderer" content="webkit">
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no">
<link rel="icon" href="/favicon.ico">
<title>申请礼物管理系统</title>
<link rel="icon" href="/favicon.jpg">
<title>光缆资源管理系统</title>
<!--[if lt IE 11]><script>window.location.href='/html/ie.html';</script><![endif]-->
<style>
html,

Binary file not shown.

Before

Width:  |  Height:  |  Size: 66 KiB

BIN
public/favicon.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 260 KiB

View File

@ -1,96 +0,0 @@
import request from '@/utils/request'
// 查询列表
export function listArticle(query) {
return request({
url: '/Article/list',
method: 'get',
params: query
})
}
// 查询最新列表
export function listNewArticle(query) {
return request({
url: '/Article/newList',
method: 'get',
params: query
})
}
// 查询详细
export function getArticle(Id) {
return request({
url: '/Article/' + Id,
method: 'get'
})
}
// 新增
export function addArticle(data) {
return request({
url: '/Article/add',
method: 'post',
data: data
})
}
// 修改
export function updateArticle(data) {
return request({
url: '/Article/edit',
method: 'put',
data: data
})
}
// 删除文章
export function delArticle(id) {
return request({
url: '/Article/' + id,
method: 'delete'
})
}
// 查询目录
export function listArticleCategory() {
return request({
url: '/Article/CategoryList',
method: 'get'
})
}
// 查询文章目录树
export function listArticleCategoryTree() {
return request({
url: '/Article/CategoryTreeList',
menubar: 'get'
})
}
// 置顶
export function topArticle(data) {
return request({
url: '/Article/top',
method: 'put',
data: data
})
}
// 修改是否公开
export function changeArticlePublic(data) {
return request({
url: '/Article/ChangePublic',
method: 'put',
data: data
})
}
/**
* 审核
* @param type 审核类型 pass ,reject
* @param ids id
*/
export function auditArticle(type, ids, data) {
return request({
url: `article/${type}/${ids}`,
method: 'PUT',
params: data
})
}

View File

@ -1,88 +0,0 @@
import request from '@/utils/request'
/**
* 文章目录分页查询
* @param {查询条件} data
*/
export function listArticleCategory(query) {
return request({
url: 'article/ArticleCategory/list',
method: 'get',
params: query
})
}
/**
* 文章目录tree查询
* @param {查询条件} data
*/
export function treelistArticleCategory(query) {
return request({
url: 'article/ArticleCategory/treelist',
method: 'get',
params: query
})
}
/**
* 新增文章目录
* @param data
*/
export function addArticleCategory(data) {
return request({
url: 'article/ArticleCategory',
method: 'post',
data: data
})
}
/**
* 修改文章目录
* @param data
*/
export function updateArticleCategory(data) {
return request({
url: 'article/ArticleCategory',
method: 'PUT',
data: data
})
}
/**
* 获取文章目录详情
* @param {Id}
*/
export function getArticleCategory(id) {
return request({
url: 'article/ArticleCategory/' + id,
method: 'get'
})
}
/**
* 删除文章目录
* @param {主键} pid
*/
export function delArticleCategory(pid) {
return request({
url: 'article/ArticleCategory/' + pid,
method: 'delete'
})
}
// 导出文章目录
export function exportArticleCategory(query) {
return request({
url: 'article/ArticleCategory/export',
method: 'get',
params: query
})
}
export function changeSort(data) {
return request({
url: 'article/ArticleCategory/ChangeSort',
method: 'get',
params: data
})
}

View File

@ -1,62 +0,0 @@
import request from '@/utils/request'
import { downFile } from '@/utils/request'
/**
* 话题分页查询
* @param {查询条件} data
*/
export function listArticleTopic(query) {
return request({
url: 'article/ArticleTopic/list',
method: 'get',
params: query
})
}
/**
* 新增话题
* @param data
*/
export function addArticleTopic(data) {
return request({
url: 'article/ArticleTopic',
method: 'post',
data: data
})
}
/**
* 修改话题
* @param data
*/
export function updateArticleTopic(data) {
return request({
url: 'article/ArticleTopic',
method: 'PUT',
data: data
})
}
/**
* 获取话题详情
* @param {Id}
*/
export function getArticleTopic(id) {
return request({
url: 'article/ArticleTopic/' + id,
method: 'get'
})
}
/**
* 删除话题
* @param {主键} pid
*/
export function delArticleTopic(pid) {
return request({
url: 'article/ArticleTopic/delete/' + pid,
method: 'delete'
})
}
// 导出话题
export async function exportArticleTopic(query) {
await downFile('article/ArticleTopic/export', { ...query })
}

View File

@ -1,79 +0,0 @@
import request from '@/utils/request'
import { downFile } from '@/utils/request'
/**
* 礼品申领表分页查询
* @param {查询条件} data
*/
export function listGiftClaim(query) {
return request({
url: 'business/GiftClaim/list',
method: 'get',
params: query,
})
}
export function getGiftClaimSatistics() {
return request({
url: 'business/GiftClaim/statistics',
method: 'get',
})
}
/**
* 新增礼品申领表
* @param data
*/
export function addGiftClaim(data) {
return request({
url: 'business/GiftClaim',
method: 'post',
data: data,
})
}
/**
* 修改礼品申领表
* @param data
*/
export function updateGiftClaim(data) {
return request({
url: 'business/GiftClaim',
method: 'PUT',
data: data,
})
}
/**
* 获取礼品申领表详情
* @param {Id}
*/
export function getGiftClaim(id) {
return request({
url: 'business/GiftClaim/' + id,
method: 'get'
})
}
/**
* 删除礼品申领表
* @param {主键} pid
*/
export function delGiftClaim(pid) {
return request({
url: 'business/GiftClaim/delete/' + pid,
method: 'POST'
})
}
// 导出礼品申领表
export async function exportGiftClaim(query) {
await downFile('business/GiftClaim/export', { ...query })
}
/**
* 新增礼品申领表
* @param data
*/
export function updateGiftClaimStatus(id, status) {
return request({
url: 'business/GiftClaim/editStatus?id=' + id + "&status=" + status,
method: 'post',
})
}

View File

@ -1,57 +0,0 @@
import request from '@/utils/request'
/**
* 礼品小程序分页查询
* @param {查询条件} data
*/
export function listGiftConfig(query) {
return request({
url: 'business/GiftConfig/list',
method: 'get',
params: query,
})
}
/**
* 新增礼品小程序
* @param data
*/
export function addGiftConfig(data) {
return request({
url: 'business/GiftConfig',
method: 'post',
data: data,
})
}
/**
* 修改礼品小程序
* @param data
*/
export function updateGiftConfig(data) {
return request({
url: 'business/GiftConfig',
method: 'PUT',
data: data,
})
}
/**
* 获取礼品小程序详情
* @param {Id}
*/
export function getGiftConfig(id) {
return request({
url: 'business/GiftConfig/' + id,
method: 'get'
})
}
/**
* 删除礼品小程序
* @param {主键} pid
*/
export function delGiftConfig(pid) {
return request({
url: 'business/GiftConfig/delete/' + pid,
method: 'POST'
})
}

View File

@ -1,62 +0,0 @@
import request from '@/utils/request'
import { downFile } from '@/utils/request'
/**
* 微信用户表分页查询
* @param {查询条件} data
*/
export function listGiftUser(query) {
return request({
url: 'business/GiftUser/list',
method: 'get',
params: query,
})
}
/**
* 新增微信用户表
* @param data
*/
export function addGiftUser(data) {
return request({
url: 'business/GiftUser',
method: 'post',
data: data,
})
}
/**
* 修改微信用户表
* @param data
*/
export function updateGiftUser(data) {
return request({
url: 'business/GiftUser',
method: 'PUT',
data: data,
})
}
/**
* 获取微信用户表详情
* @param {Id}
*/
export function getGiftUser(id) {
return request({
url: 'business/GiftUser/' + id,
method: 'get'
})
}
/**
* 删除微信用户表
* @param {主键} pid
*/
export function delGiftUser(pid) {
return request({
url: 'business/GiftUser/delete/' + pid,
method: 'POST'
})
}
// 导出微信用户表
export async function exportGiftUser(query) {
await downFile('business/GiftUser/export', { ...query })
}

View File

@ -12,7 +12,17 @@ export function listOdfPorts(query) {
params: query,
})
}
/**
* 端口分页查询
* @param {查询条件} data
*/
export function listOdfPortss(query) {
return request({
url: 'business/OdfPorts/lists',
method: 'get',
params: query,
})
}
/**
* 新增端口
* @param data

Binary file not shown.

Before

Width:  |  Height:  |  Size: 10 KiB

After

Width:  |  Height:  |  Size: 260 KiB

View File

@ -67,7 +67,7 @@ export default {
/**
* 水印文案
*/
watermarkText: 'ZRAdmin.NET',
watermarkText: '光缆资源管理系统',
/**
* 是否显示其他登录
*/
@ -107,5 +107,5 @@ export default {
/**
* 前往通知地址
*/
noticeUrl: 'https://gitee.com/izory/ZrAdminNetCore'
noticeUrl: ''
}

View File

@ -1,442 +0,0 @@
<!--
* @Descripttion: (文章目录/articleCategory)
* @version: (1.0)
* @Author: (zr)
* @Date: (2022-05-13)
* @LastEditors: (zr)
* @LastEditTime: (2022-05-13)
-->
<template>
<div class="app-container">
<el-form :model="queryParams" label-position="right" inline ref="queryRef" v-show="showSearch" @submit.prevent>
<el-form-item>
<el-radio-group v-model="queryParams.categoryType" @change="handleQuery()">
<el-radio-button value="">全部</el-radio-button>
<el-radio-button v-for="item in categoryTypeOptions" :key="item.dictValue" :value="item.dictValue">
{{ item.dictLabel }}
</el-radio-button>
</el-radio-group>
</el-form-item>
<!-- <el-form-item>
<el-button icon="search" type="primary" @click="handleQuery">{{ $t('btn.search') }}</el-button>
<el-button icon="refresh" @click="resetQuery">{{ $t('btn.reset') }}</el-button>
</el-form-item> -->
</el-form>
<el-row :gutter="10" class="mb8">
<el-col :span="1.5">
<el-button type="primary" v-hasPermi="['articlecategory:add']" plain icon="plus" @click="handleAdd">
{{ $t('btn.add') }}
</el-button>
</el-col>
<el-col :span="1.5">
<el-button type="info" plain icon="sort" @click="toggleExpandAll">展开/折叠</el-button>
</el-col>
<el-col :span="1.5">
<el-button type="danger" :disabled="multiple" v-hasPermi="['articlecategory:delete']" plain icon="delete" @click="handleDelete">
{{ $t('btn.delete') }}
</el-button>
</el-col>
<el-col :span="1.5">
<el-button type="warning" plain icon="download" @click="handleExport" v-hasPermi="['articlecategory:export']">
{{ $t('btn.export') }}
</el-button>
</el-col>
<right-toolbar v-model:showSearch="showSearch" @queryTable="getList"></right-toolbar>
</el-row>
<!-- 数据区域 -->
<el-table
v-if="refreshTable"
:data="dataList"
v-loading="loading"
ref="tableRef"
border
highlight-current-row
@sort-change="sortChange"
@selection-change="handleSelectionChange"
:default-expand-all="isExpandAll"
row-key="categoryId"
:tree-props="{ children: 'children', hasChildren: 'hasChildren' }">
<el-table-column type="selection" width="50" />
<el-table-column prop="name" label="目录名" :show-overflow-tooltip="true" />
<el-table-column prop="icon" label="图标" :show-overflow-tooltip="true">
<template #default="{ row }">
<svg-icon :name="row.icon" v-if="row.icon"></svg-icon>
{{ row.icon }}
</template>
</el-table-column>
<el-table-column prop="bgImg" label="背景" :show-overflow-tooltip="true">
<template #default="{ row }">
<image-preview :src="row.bgImg" split=","></image-preview>
</template>
</el-table-column>
<el-table-column prop="categoryType" label="分类" align="center">
<template #default="{ row }">
<dict-tag :options="categoryTypeOptions" :value="row.categoryType"></dict-tag>
</template>
</el-table-column>
<el-table-column prop="categoryId" label="目录id" sortable align="center" />
<el-table-column prop="orderNum" label="排序" sortable align="center">
<template #default="scope">
<span v-show="editIndex != scope.row.categoryId" @click="editCurrRow(scope.row.categoryId)">{{ scope.row.orderNum }}</span>
<el-input
:ref="setColumnsRef"
v-show="editIndex == scope.row.categoryId"
v-model="scope.row.orderNum"
@blur="handleChangeSort(scope.row)"></el-input>
</template>
</el-table-column>
<el-table-column prop="introduce" label="介绍" :show-overflow-tooltip="true" />
<el-table-column prop="createTime" label="添加时间" align="center" :show-overflow-tooltip="true" />
<el-table-column prop="parentId" label="父级id" align="center" />
<el-table-column label="操作" align="center" width="140">
<template #default="scope">
<el-button v-hasPermi="['articlecategory:edit']" type="success" icon="edit" title="编辑" @click="handleUpdate(scope.row)"></el-button>
<el-button v-hasPermi="['articlecategory:delete']" type="danger" icon="delete" title="删除" @click="handleDelete(scope.row)"></el-button>
</template>
</el-table-column>
</el-table>
<!-- 添加或修改文章目录对话框 -->
<el-dialog :title="title" :lock-scroll="false" v-model="open" width="550px">
<el-form ref="formRef" :model="form" :rules="rules" label-width="80px">
<el-row :gutter="20">
<el-col :lg="24">
<el-form-item label="父级id" prop="parentId">
<el-cascader
class="w100"
:options="dataList"
:props="{ checkStrictly: true, value: 'categoryId', label: 'name', emitPath: false }"
placeholder="请选择上级菜单"
clearable
v-model="form.parentId">
<template #default="{ node, data }">
<span>{{ data.name }}</span>
<span v-if="!node.isLeaf"> ({{ data.children.length }}) </span>
</template>
</el-cascader>
</el-form-item>
</el-col>
<el-col :lg="24">
<el-form-item label="目录分类" prop="categoryType">
<el-select v-model="form.categoryType" placeholder="请选择分类" clearable>
<el-option v-for="dict in categoryTypeOptions" :key="dict.dictValue" :label="dict.dictLabel" :value="parseInt(dict.dictValue)" />
</el-select>
</el-form-item>
</el-col>
<el-col :lg="24">
<el-form-item label="目录名" prop="name">
<el-input v-model="form.name" placeholder="请输入目录名" />
</el-form-item>
</el-col>
<el-col :lg="24">
<el-form-item label="图标" prop="icon">
<el-popover placement="bottom" :width="540" trigger="click">
<template #reference>
<el-input v-model="form.icon" placeholder="点击选择图标" readonly>
<template #prefix>
<svg-icon v-if="form.icon" :name="form.icon" />
<el-icon v-else>
<search />
</el-icon>
</template>
</el-input>
</template>
<icon-select ref="iconSelectRef" @selected="iconSelected" />
</el-popover>
</el-form-item>
</el-col>
<el-col :lg="24">
<el-form-item label="排序" prop="orderNum">
<el-input-number v-model="form.orderNum" placeholder="请输入排序值" />
</el-form-item>
</el-col>
<el-col :lg="24">
<el-form-item label="介绍" prop="introduce">
<el-input v-model="form.introduce" placeholder="请输入介绍" />
</el-form-item>
</el-col>
<el-col :lg="24">
<el-form-item label="背景图" prop="bgImg">
<UploadImage ref="uploadRef" v-model="form.bgImg" :limit="1" :fileSize="15"> </UploadImage>
</el-form-item>
</el-col>
</el-row>
</el-form>
<template #footer>
<div class="dialog-footer">
<el-button text @click="cancel">{{ $t('btn.cancel') }}</el-button>
<el-button type="primary" @click="submitForm">{{ $t('btn.submit') }}</el-button>
</div>
</template>
</el-dialog>
</div>
</template>
<script setup name="articlecategory">
import {
treelistArticleCategory,
addArticleCategory,
delArticleCategory,
updateArticleCategory,
getArticleCategory,
exportArticleCategory,
changeSort
} from '@/api/article/articlecategory.js'
import IconSelect from '@/components/IconSelect'
const { proxy } = getCurrentInstance()
//
const isExpandAll = ref(false)
const refreshTable = ref(true)
///
function toggleExpandAll() {
refreshTable.value = false
isExpandAll.value = !isExpandAll.value
nextTick(() => {
refreshTable.value = true
})
}
// categoryId
const ids = ref([])
//
const single = ref(true)
//
const multiple = ref(true)
//
const loading = ref(false)
//
const showSearch = ref(true)
//
const queryParams = reactive({
pageNum: 1,
pageSize: 10,
sort: undefined,
sortType: undefined,
categoryType: ''
})
//
const title = ref('')
// 1add 2edit
const opertype = ref(0)
//
const open = ref(false)
//
const state = reactive({
form: {},
rules: {
name: [{ required: true, message: '目录名不能为空', trigger: 'blur' }],
categoryType: [{ required: true, message: '目录分类不能为空', trigger: 'blur' }]
}
})
const { form, rules } = toRefs(state)
//
const total = ref(0)
const dataList = ref([])
const queryRef = ref()
const formRef = ref()
var dictParams = []
function getList() {
loading.value = true
treelistArticleCategory(queryParams).then((res) => {
if (res.code == 200) {
//dataList.value = res.data.result
//total.value = res.data.totalNum
dataList.value = res.data
loading.value = false
}
})
}
// dialog
function cancel() {
open.value = false
reset()
}
//
function reset() {
form.value = {
name: undefined,
parentId: 0,
icon: '',
orderNum: 0,
categoryType: undefined
}
proxy.resetForm('formRef')
}
//
function handleQuery() {
queryParams.pageNum = 1
getList()
}
//
function handleAdd() {
reset()
open.value = true
title.value = '添加'
opertype.value = 1
if (queryParams.categoryType) {
form.value.categoryType = parseInt(queryParams.categoryType)
}
}
//
function handleDelete(row) {
const Ids = row.categoryId || ids.value
proxy
.$confirm('是否确认删除参数编号为"' + Ids + '"的数据项?')
.then(function () {
return delArticleCategory(Ids)
})
.then(() => {
handleQuery()
proxy.$modal.msgSuccess('删除成功')
})
.catch(() => {})
}
//
function handleUpdate(row) {
reset()
const id = row.categoryId || ids.value
getArticleCategory(id).then((res) => {
const { code, data } = res
if (code == 200) {
open.value = true
title.value = '修改数据'
opertype.value = 2
form.value = {
...data
}
}
})
}
//
function submitForm() {
proxy.$refs['formRef'].validate((valid) => {
if (valid) {
if (form.value.categoryId != undefined && opertype.value === 2) {
updateArticleCategory(form.value)
.then((res) => {
proxy.$modal.msgSuccess('修改成功')
open.value = false
getList()
})
.catch(() => {})
} else {
addArticleCategory(form.value)
.then((res) => {
proxy.$modal.msgSuccess('新增成功')
open.value = false
getList()
})
.catch((err) => {
//TODO
})
}
}
})
}
//
function resetQuery() {
proxy.resetForm('queryRef')
handleQuery()
}
//
function handleExport() {
proxy
.$confirm('是否确认导出所有文章目录数据项?', '警告', {
confirmButtonText: '确定',
cancelButtonText: '取消',
type: 'warning'
})
.then(function () {
return exportArticleCategory(queryParams)
})
.then((response) => {
proxy.download(response.data.path)
})
}
//
function handleSelectionChange(selection) {
ids.value = selection.map((item) => item.categoryId)
single.value = selection.length != 1
multiple.value = !selection.length
}
//
function sortChange(column) {
if (column.prop == null || column.order == null) {
queryParams.sort = undefined
queryParams.sortType = undefined
} else {
queryParams.sort = column.prop
queryParams.sortType = column.order
}
handleQuery()
}
function iconSelected(name) {
form.value.icon = name
document.body.click()
}
// ****************** start **********************
// ref
const columnRefs = ref([])
const setColumnsRef = (el) => {
if (el) {
columnRefs.value.push(el)
}
}
const editIndex = ref(-1)
//
function editCurrRow(rowId) {
editIndex.value = rowId
setTimeout(() => {
columnRefs.value[rowId].focus()
}, 100)
}
//
function handleChangeSort(info) {
editIndex.value = -1
proxy
.$confirm('是否保存数据?')
.then(function () {
return changeSort({ value: info.orderNum, id: info.categoryId })
})
.then(() => {
handleQuery()
proxy.$modal.msgSuccess('修改成功')
})
.catch(() => {
handleQuery()
})
}
// ****************** end **********************
const categoryTypeOptions = ref([])
proxy.getDicts('article_category_type').then((response) => {
categoryTypeOptions.value = response.data
})
handleQuery()
</script>

View File

@ -1,272 +0,0 @@
<!--
* @Descripttion: (文章话题/article_topic)
* @Author: (admin)
* @Date: (2024-05-24)
-->
<template>
<div>
<el-form :model="queryParams" label-position="right" inline ref="queryRef" v-show="showSearch" @submit.prevent>
<el-form-item>
<el-button icon="search" type="primary" @click="handleQuery">{{ $t('btn.search') }}</el-button>
<el-button icon="refresh" @click="resetQuery">{{ $t('btn.reset') }}</el-button>
</el-form-item>
</el-form>
<!-- 工具区域 -->
<el-row :gutter="15" class="mb10">
<el-col :span="1.5">
<el-button type="primary" v-hasPermi="['articletopic:add']" plain icon="plus" @click="handleAdd">
{{ $t('btn.add') }}
</el-button>
</el-col>
<el-col :span="1.5">
<el-button type="warning" plain icon="download" @click="handleExport" v-hasPermi="['articletopic:export']">
{{ $t('btn.export') }}
</el-button>
</el-col>
<right-toolbar v-model:showSearch="showSearch" @queryTable="getList" :columns="columns"></right-toolbar>
</el-row>
<el-table
:data="dataList"
v-loading="loading"
ref="table"
border
header-cell-class-name="el-table-header-cell"
highlight-current-row
@sort-change="sortChange">
<el-table-column prop="topicId" label="话题ID" align="center" v-if="columns.showColumn('topicId')" />
<el-table-column prop="topicName" label="话题名" align="center" :show-overflow-tooltip="true" v-if="columns.showColumn('topicName')" />
<el-table-column
prop="topicDescription"
label="话题描述"
align="center"
:show-overflow-tooltip="true"
v-if="columns.showColumn('topicDescription')" />
<el-table-column prop="joinNum" label="参与次数" align="center" v-if="columns.showColumn('joinNum')" />
<el-table-column prop="addTime" label="创建时间" :show-overflow-tooltip="true" v-if="columns.showColumn('addTime')" />
<el-table-column label="操作" width="160">
<template #default="scope">
<el-button
type="success"
size="small"
icon="edit"
title="编辑"
v-hasPermi="['articletopic:edit']"
@click="handleUpdate(scope.row)"></el-button>
<el-button
type="danger"
size="small"
icon="delete"
title="删除"
v-hasPermi="['articletopic:delete']"
@click="handleDelete(scope.row)"></el-button>
</template>
</el-table-column>
</el-table>
<pagination :total="total" v-model:page="queryParams.pageNum" v-model:limit="queryParams.pageSize" @pagination="getList" />
<el-dialog :title="title" :lock-scroll="false" v-model="open" width="400">
<el-form ref="formRef" :model="form" :rules="rules" label-width="90px">
<el-row :gutter="20">
<el-col :lg="24">
<el-form-item label="话题名" prop="topicName">
<el-input v-model="form.topicName" placeholder="请输入话题名" :disabled="opertype == 2" />
</el-form-item>
</el-col>
<el-col :lg="24">
<el-form-item label="话题描述" prop="topicDescription">
<el-input type="textarea" v-model="form.topicDescription" placeholder="请输入话题描述" />
</el-form-item>
</el-col>
</el-row>
</el-form>
<template #footer v-if="opertype != 3">
<el-button text @click="cancel">{{ $t('btn.cancel') }}</el-button>
<el-button type="primary" @click="submitForm">{{ $t('btn.submit') }}</el-button>
</template>
</el-dialog>
</div>
</template>
<script setup name="articletopic">
import { listArticleTopic, addArticleTopic, delArticleTopic, updateArticleTopic, getArticleTopic } from '@/api/article/articletopic.js'
const { proxy } = getCurrentInstance()
const ids = ref([])
const loading = ref(false)
const showSearch = ref(true)
const queryParams = reactive({
pageNum: 1,
pageSize: 10,
sort: 'topicid',
sortType: 'desc'
})
const columns = ref([
{ visible: true, align: 'left', type: '', prop: 'topicId', label: '话题ID' },
{ visible: true, align: 'left', type: '', prop: 'topicName', label: '话题名', showOverflowTooltip: true },
{ visible: true, align: 'left', type: '', prop: 'topicDescription', label: '话题描述', showOverflowTooltip: true },
{ visible: true, align: 'left', type: '', prop: 'joinNum', label: '参与次数' },
{ visible: true, align: 'left', type: '', prop: 'addTime', label: '创建时间', showOverflowTooltip: true }
//{ visible: false, prop: 'actions', label: '', type: 'slot', width: '160' }
])
const total = ref(0)
const dataList = ref([])
const queryRef = ref()
const defaultTime = ref([new Date(2000, 1, 1, 0, 0, 0), new Date(2000, 2, 1, 23, 59, 59)])
var dictParams = []
function getList() {
loading.value = true
listArticleTopic(queryParams).then((res) => {
const { code, data } = res
if (code == 200) {
dataList.value = data.result
total.value = data.totalNum
loading.value = false
}
})
}
//
function handleQuery() {
queryParams.pageNum = 1
getList()
}
//
function resetQuery() {
proxy.resetForm('queryRef')
handleQuery()
}
//
function sortChange(column) {
var sort = undefined
var sortType = undefined
if (column.prop != null && column.order != null) {
sort = column.prop
sortType = column.order
}
queryParams.sort = sort
queryParams.sortType = sortType
handleQuery()
}
/*************** form操作 ***************/
const formRef = ref()
const title = ref('')
// 1add 2edit 3view
const opertype = ref(0)
const open = ref(false)
const state = reactive({
single: true,
multiple: true,
form: {},
rules: {
topicId: [{ required: true, message: '话题ID不能为空', trigger: 'blur', type: 'number' }],
topicName: [{ required: true, message: '话题名不能为空', trigger: 'blur' }]
},
options: {}
})
const { form, rules, options, single, multiple } = toRefs(state)
// dialog
function cancel() {
open.value = false
reset()
}
//
function reset() {
form.value = {
topicId: null,
topicName: null,
topicDescription: null,
joinNum: null,
addTime: null
}
proxy.resetForm('formRef')
}
//
function handleAdd() {
reset()
open.value = true
title.value = '添加文章话题'
opertype.value = 1
}
//
function handleUpdate(row) {
reset()
const id = row.topicId || ids.value
getArticleTopic(id).then((res) => {
const { code, data } = res
if (code == 200) {
open.value = true
title.value = '修改文章话题'
opertype.value = 2
form.value = {
...data
}
}
})
}
// &
function submitForm() {
proxy.$refs['formRef'].validate((valid) => {
if (valid) {
if (form.value.topicId != undefined && opertype.value === 2) {
updateArticleTopic(form.value).then((res) => {
proxy.$modal.msgSuccess('修改成功')
open.value = false
getList()
})
} else {
addArticleTopic(form.value).then((res) => {
proxy.$modal.msgSuccess('新增成功')
open.value = false
getList()
})
}
}
})
}
//
function handleDelete(row) {
const Ids = row.topicId || ids.value
proxy
.$confirm('是否确认删除参数编号为"' + Ids + '"的数据项?', '警告', {
confirmButtonText: proxy.$t('common.ok'),
cancelButtonText: proxy.$t('common.cancel'),
type: 'warning'
})
.then(function () {
return delArticleTopic(Ids)
})
.then(() => {
getList()
proxy.$modal.msgSuccess('删除成功')
})
}
//
function handleExport() {
proxy
.$confirm('是否确认导出文章话题数据项?', '警告', {
confirmButtonText: '确定',
cancelButtonText: '取消',
type: 'warning'
})
.then(async () => {
await proxy.downFile('/article/ArticleTopic/export', { ...queryParams })
})
}
handleQuery()
</script>

View File

@ -1,389 +0,0 @@
<template>
<div class="app-container">
<el-form :model="queryParams" label-position="left" inline ref="queryForm" v-show="showSearch" @submit.prevent>
<el-form-item label="标题" prop="title">
<el-input v-model="queryParams.title" placeholder="请输入标题" />
</el-form-item>
<el-form-item label="摘要" prop="abstractText">
<el-input v-model="queryParams.abstractText" placeholder="请输入摘要" />
</el-form-item>
<el-form-item label="分类" prop="categoryId">
<el-cascader
class="w100"
:options="categoryOptions"
:props="{ checkStrictly: true, value: 'categoryId', label: 'name', emitPath: false }"
placeholder="请选择分类"
clearable
v-model="queryParams.categoryId" />
</el-form-item>
<el-form-item label="审核状态" prop="auditStatus">
<el-radio-group v-model="queryParams.auditStatus" @change="handleQuery()">
<el-radio-button value="">全部</el-radio-button>
<el-radio-button v-for="item in options.auditOptions" :key="item.dictValue" :value="item.dictValue">
{{ item.dictLabel }}
</el-radio-button>
</el-radio-group>
</el-form-item>
<el-form-item prop="status">
<el-radio-group v-model="queryParams.status" @change="handleQuery()">
<el-radio-button value="">全部</el-radio-button>
<el-radio-button v-for="item in options.sys_article_status" :key="item.dictValue" :value="item.dictValue">
{{ item.dictLabel }}
</el-radio-button>
</el-radio-group>
</el-form-item>
<el-form-item prop="articleType">
<el-radio-group v-model="queryParams.articleType" @change="handleQuery()">
<el-radio-button value="">全部</el-radio-button>
<el-radio-button v-for="item in options.sys_article_type" :key="item.dictValue" :value="item.dictValue">
{{ item.dictLabel }}
</el-radio-button>
</el-radio-group>
</el-form-item>
<el-form-item label="是否公开" prop="isPublic">
<el-radio-group v-model="queryParams.isPublic" @change="handleQuery()">
<el-radio-button value="">全部</el-radio-button>
<el-radio-button v-for="item in options.isPublicOptions" :key="item.dictValue" :value="item.dictValue">
{{ item.dictLabel }}
</el-radio-button>
</el-radio-group>
</el-form-item>
<el-form-item label="是否置顶" prop="isTop">
<el-radio-group v-model="queryParams.isTop" @change="handleQuery()">
<el-radio-button value="">全部</el-radio-button>
<el-radio-button v-for="item in options.isPublicOptions" :key="item.dictValue" :value="item.dictValue">
{{ item.dictLabel }}
</el-radio-button>
</el-radio-group>
</el-form-item>
<el-form-item>
<el-button type="primary" icon="search" @click="handleQuery">搜索</el-button>
<el-button icon="refresh" @click="resetQuery">重置</el-button>
</el-form-item>
</el-form>
<el-row :gutter="10" class="mb8">
<el-col :span="1.5">
<el-button type="success" :disabled="multiple" v-hasPermi="['article:audit']" plain icon="check" size="small" @click="handleAuditPass">
通过
</el-button>
</el-col>
<el-col :span="1.5">
<el-button type="danger" :disabled="multiple" v-hasPermi="['article:audit']" plain icon="close" size="small" @click="handleAuditReject">
拒绝
</el-button>
</el-col>
<el-col :span="1.5">
<el-button type="primary" plain icon="plus" v-hasPermi="['system:article:add']" size="small" @click="handleAdd">发布文章</el-button>
</el-col>
<el-col :span="1.5">
<el-button type="danger" plain icon="plus" v-hasPermi="['system:article:add']" size="small" @click="handleMonents">发布动态</el-button>
</el-col>
<right-toolbar v-model:showSearch="showSearch" @queryTable="getList" :columns="columns"></right-toolbar>
</el-row>
<el-table
:data="dataList"
height="600px"
v-loading="loading"
@selection-change="handleSelectionChange"
highlight-current-row
@sort-change="sortChange"
ref="table">
<el-table-column type="selection" width="50" align="center" :selectable="checkSelectable" />
<el-table-column prop="cid" label="文章信息" width="130">
<template #default="{ row }">
<div @click="handleView(row)">内容id{{ row.cid }}</div>
<div>作者{{ row.authorName }}</div>
<div>标签{{ row.tags }}</div>
</template>
</el-table-column>
<el-table-column label="分类">
<template #default="{ row }">
<div v-if="row.articleCategoryNav">{{ row.articleCategoryNav.name }}</div>
</template>
</el-table-column>
<el-table-column prop="title" label="标题" width="120" :show-overflow-tooltip="true">
<template #default="scope">
<el-button link type="primary" @click="handleView(scope.row)">{{ scope.row.title }}</el-button>
</template>
</el-table-column>
<el-table-column prop="coverUrl" label="封面" width="90" :show-overflow-tooltip="true">
<template #default="{ row }">
<image-preview :src="row.coverUrl" split="," style="width: 40px" v-if="row.coverUrl"></image-preview>
</template>
</el-table-column>
<!-- <el-table-column prop="authorName" label="作者" width="80"> </el-table-column> -->
<!-- <el-table-column prop="fmt_type" label="编辑器类型" width="100"> </el-table-column> -->
<!-- <el-table-column prop="tags" label="标签" width="100" :show-overflow-tooltip="true"> </el-table-column> -->
<el-table-column prop="hits" label="浏览" width="80" align="center" sortable> </el-table-column>
<el-table-column prop="praiseNum" label="赞" width="80" align="center" sortable> </el-table-column>
<el-table-column prop="commentNum" label="评论" width="80" align="center" sortable> </el-table-column>
<el-table-column prop="abstractText" label="摘要" v-if="columns.showColumn('abstractText')"> </el-table-column>
<el-table-column prop="status" align="center" label="状态" width="90">
<template #default="scope">
<el-tag :type="scope.row.status == '2' ? 'danger' : 'success'">{{ scope.row.status == '2' ? '草稿' : '已发布' }} </el-tag>
</template>
</el-table-column>
<el-table-column prop="auditStatus" align="center" label="审核" width="90">
<template #default="scope">
<dict-tag :options="options.auditOptions" :value="scope.row.auditStatus"> </dict-tag>
</template>
</el-table-column>
<el-table-column label="置顶" prop="isTop" width="90" align="center" v-if="columns.showColumn('isTop')" sortable>
<template #default="scope">
<el-switch
v-model="scope.row.isTop"
inline-prompt
disabled
active-text="是"
inactive-text="否"
:active-value="1"
:inactive-value="0"></el-switch>
</template>
</el-table-column>
<el-table-column label="公开" align="center" prop="isPublic" width="90">
<template #default="scope">
<el-switch
v-model="scope.row.isPublic"
inline-prompt
active-text="是"
inactive-text="否"
:active-value="1"
:inactive-value="0"
disabled></el-switch>
</template>
</el-table-column>
<el-table-column prop="createTime" label="发布时间" width="128" :show-overflow-tooltip="true">
<template #default="scope">
{{ showTime(scope.row.createTime) }}
</template>
</el-table-column>
<el-table-column label="操作" width="130" fixed="right">
<template #default="scope">
<el-button-group>
<el-button size="small" icon="view" @click="handleView(scope.row)"> </el-button>
<el-button
size="small"
icon="edit"
@click="handleUpdate(scope.row)"
v-hasPermi="['system:article:update']"
v-if="scope.row.articleType == 0">
</el-button>
<el-popconfirm title="确定删除吗?" @confirm="handleDelete(scope.row)" style="margin-left: 10px">
<template #reference>
<el-button size="small" type="danger" icon="delete" v-hasPermi="['system:article:delete']"></el-button>
</template>
</el-popconfirm>
</el-button-group>
</template>
</el-table-column>
</el-table>
<pagination :total="total" v-model:page="queryParams.pageNum" v-model:limit="queryParams.pageSize" @pagination="getList" />
<el-dialog :title="previewInfo.title" v-model="showPreview">
<image-preview :src="previewInfo.coverUrl" split="," style="height: 140px" v-if="previewInfo.coverUrl"></image-preview>
<MdPreview show-code-row-number editorId="id1" :theme="settingsStore.codeMode" :modelValue="previewInfo.content" />
</el-dialog>
</div>
</template>
<script setup name="index">
import { listArticle, delArticle, auditArticle, getArticle } from '@/api/article/article.js'
import { treelistArticleCategory } from '@/api/article/articlecategory.js'
import { MdPreview } from 'md-editor-v3'
import { showTime } from '@/utils/index'
import 'md-editor-v3/lib/preview.css'
import useSettingsStore from '@/store/modules/settings'
const settingsStore = useSettingsStore()
const { proxy } = getCurrentInstance()
const router = useRouter()
// mid
const ids = ref([])
//
const single = ref(true)
//
const multiple = ref(true)
//
const showSearch = ref(true)
//
const dataList = ref([])
//
const total = ref(0)
//
const categoryOptions = ref([])
const loading = ref(false)
const data = reactive({
form: {},
queryParams: {
sort: 'cid',
sortType: 'desc',
status: '',
isPublic: '',
isTop: '',
articleType: '',
auditStatus: ''
},
options: {
isPublicOptions: [
{ dictLabel: '是', dictValue: '1' },
{ dictLabel: '否', dictValue: '0', listClass: 'info' }
],
auditOptions: [
{ dictLabel: '通过', dictValue: '1' },
{ dictLabel: '待审核', dictValue: '0', listClass: 'info' },
{ dictLabel: '不通过', dictValue: '2', listClass: 'danger' }
],
//
sys_comment_permi: [],
//
sys_article_status: [],
//
sys_article_type: []
}
})
const columns = ref([
{ visible: false, prop: 'abstractText', label: '摘要' },
{ visible: false, prop: 'isTop', label: '置顶' }
])
const queryForm = ref()
const { queryParams, options } = toRefs(data)
//
function sortChange(column) {
if (column.prop == null || column.order == null) {
queryParams.sort = undefined
queryParams.sortType = undefined
} else {
queryParams.sort = column.prop
queryParams.sortType = column.order
}
handleQuery()
}
proxy.getDicts(['sys_article_status', 'sys_article_type', 'sys_comment_permi']).then((response) => {
response.data.forEach((element) => {
data.options[element.dictType] = element.list
})
})
/** 查询菜单下拉树结构 */
function getCategoryTreeselect() {
treelistArticleCategory().then((res) => {
if (res.code == 200) {
categoryOptions.value = res.data
}
})
}
//
function getList() {
loading.value = true
listArticle(queryParams.value).then((res) => {
loading.value = false
if (res.code == 200) {
dataList.value = res.data.result
total.value = res.data.totalNum
}
})
}
/** 重置查询操作 */
function resetQuery() {
proxy.resetForm('queryForm')
handleQuery()
}
/** 搜索按钮操作 */
function handleQuery() {
getList()
}
/** 新增按钮操作 */
function handleAdd() {
router.push({ path: '/article/publish' })
}
function handleMonents() {
router.push({ path: '/article/publishMoments' })
}
/** 删除按钮操作 */
function handleDelete(row) {
delArticle(row.cid).then((res) => {
if (res.code == 200) {
proxy.$modal.msgSuccess('删除成功')
handleQuery()
}
})
}
/** 修改按钮操作 */
function handleUpdate(row) {
router.push({ path: '/article/publish', query: { cid: row.cid } })
}
//
const previewInfo = ref({})
function handleView(row) {
getArticle(row.cid).then((res) => {
previewInfo.value = res.data
showPreview.value = true
})
}
// function handleTopChange(row) {
// topArticle({ cid: row.cid, isTop: row.isTop }).then((res) => {
// handleQuery()
// })
// }
// function handleChangePublic(row) {
// changeArticlePublic({ cid: row.cid, isPublic: row.isPublic }).then((res) => {
// handleQuery()
// })
// }
function checkSelectable(row) {
return row.auditStatus == 0 ? true : false
}
/**
* 审核通过
* @param {审核} row
*/
function handleAuditPass(row) {
const id = row.cid || ids.value
auditArticle('pass', id).then((res) => {
const { code } = res
if (code == 200) {
proxy.$modal.msgSuccess('通过成功')
}
getList()
})
}
/**
* 拒绝
* @param {*} row
*/
function handleAuditReject(row) {
const id = row.cid || ids.value
proxy.$prompt('请输入拒绝原因', 'Tip', {}).then(({ value }) => {
auditArticle('reject', id, { reason: value }).then((res) => {
const { code } = res
if (code == 200) {
proxy.$modal.msgSuccess('拒绝成功')
}
getList()
})
})
}
//
function handleSelectionChange(selection) {
ids.value = selection.map((item) => item.cid)
single.value = selection.length != 1
multiple.value = !selection.length
}
const showPreview = ref(false)
getCategoryTreeselect()
handleQuery()
</script>

View File

@ -1,262 +0,0 @@
<template>
<div class="app-container">
<el-form :model="form" ref="formRef" :rules="rules" @submit.prevent>
<el-row class="mb10">
<el-col :lg="24">
<el-form-item label="" prop="title">
<el-input v-model="form.title" placeholder="请输入文章标题(必须)" />
</el-form-item>
</el-col>
<el-col :lg="24">
<el-form-item prop="content" label="">
<MdEditor v-model="form.content" :showToolbarName="true" :theme="settingsStore.codeMode" :onUploadImg="onUploadImg" />
</el-form-item>
</el-col>
<el-col :lg="24">
<el-form-item prop="abstractText">
<el-input v-model="form.abstractText" type="textarea" show-word-limit maxlength="100" placeholder="请输入文章摘要(必须)" />
</el-form-item>
</el-col>
<el-col :lg="5">
<el-form-item prop="categoryId" label="分类" label-position="100px">
<el-cascader
class="w100"
:options="categoryOptions"
:props="{ checkStrictly: true, value: 'categoryId', label: 'name', emitPath: false }"
placeholder="请选择文章分类"
clearable
v-model="form.categoryId" />
</el-form-item>
</el-col>
<el-col :lg="24">
<el-form-item label="标签">
<el-tag v-for="tag in form.dynamicTags" :key="tag" class="mr10" closable :disable-transitions="false" @close="handleCloseTag(tag)">
{{ tag }}
</el-tag>
<el-input
size="small"
v-if="inputVisible"
style="width: 150px"
ref="inputRef"
v-model="inputValue"
maxLength="8"
placeholder="最多8个字符"
@keyup.enter="handleInputConfirm"
@blur="handleInputConfirm" />
<el-button v-else class="button-new-tag" size="small" icon="plus" text @click="showInput">文章标签</el-button>
</el-form-item>
</el-col>
<el-col :lg="8">
<el-form-item>
<template #label>
<span>
<el-tooltip content="不公开只有自己会看到" placement="top">
<el-icon :size="15">
<questionFilled />
</el-icon>
</el-tooltip>
是否公开
</span>
</template>
<el-switch v-model="form.isPublic" inline-prompt :active-value="1" :in-active-value="0" active-text="" inactive-text="" />
</el-form-item>
</el-col>
<el-col :lg="24">
<el-form-item>
<UploadImage ref="uploadRef" v-model="form.coverUrl" :limit="1" :fileSize="15" style="width: 90px">
<template #icon>
<div class="upload-wrap">
<el-icon class="avatar-uploader-icon"><plus /></el-icon>
<div>请选择封面</div>
</div>
</template>
</UploadImage>
</el-form-item>
</el-col>
</el-row>
</el-form>
<div class="btn-wrap">
<el-button type="success" @click="handlePublish('1')">发布文章</el-button>
<el-button @click="handlePublish('2')" v-if="!info || info.status == 2">存为草稿</el-button>
</div>
</div>
</template>
<script setup name="articlepublish">
import { addArticle, updateArticle, getArticle } from '@/api/article/article.js'
import { treelistArticleCategory } from '@/api/article/articlecategory.js'
import useSettingsStore from '@/store/modules/settings'
import { upload } from '@/api/common.js'
import { MdEditor } from 'md-editor-v3'
import 'md-editor-v3/lib/style.css'
const settingsStore = useSettingsStore()
const { proxy } = getCurrentInstance()
const route = useRoute()
//
const categoryOptions = ref([])
const inputVisible = ref(false)
const inputValue = ref('')
const formRef = ref()
const inputRef = ref()
const data = reactive({
form: {
dynamicTags: [],
fmtType: 'markdown',
tags: undefined,
cid: undefined,
content: undefined,
status: undefined,
categoryId: undefined,
isPublic: 1,
abstractText: undefined,
editorType: 'markdown'
},
rules: {
title: [{ required: true, message: '标题不能为空', trigger: 'blur' }],
content: [{ required: true, message: '内容不能为空', trigger: 'blur' }],
abstractText: [{ required: true, message: '摘要不能为空', trigger: 'blur' }]
}
})
const { form, rules } = toRefs(data)
const cid = route.query.cid
form.value.cid = cid
/** 查询菜单下拉树结构 */
function getCategoryTreeselect() {
treelistArticleCategory({}).then((res) => {
if (res.code == 200) {
categoryOptions.value = res.data
}
})
}
// md
async function onUploadImg(files, callback) {
const res = await Promise.all(
Array.from(files).map((file) => {
return new Promise((rev, rej) => {
const form = new FormData()
form.append('file', file)
upload(form)
.then((res) => rev(res))
.catch((error) => rej(error))
})
})
)
callback(res.map((item) => item.data.url))
}
/** 提交按钮 */
function handlePublish(status) {
form.value.status = status
form.value.tags = form.value.dynamicTags.toString()
proxy.$refs['formRef'].validate((valid) => {
if (valid) {
if (form.value.cid != undefined) {
updateArticle(form.value).then((res) => {
if (res.code == 200) {
if (status == 1) {
proxy.$modal.msgSuccess('发布文章成功')
proxy.$tab.closeOpenPage({ path: '/article/index' })
} else {
proxy.$modal.msgSuccess('保存成功')
}
} else {
proxy.$modal.msgError('修改文章失败')
}
})
} else {
addArticle(form.value).then((res) => {
if (res.code == 200) {
form.value.cid = res.data
if (status == 1) {
proxy.$modal.msgSuccess('发布文章成功')
proxy.$tab.closeOpenPage({ path: '/article/index' })
} else {
proxy.$modal.msgSuccess('保存成功')
}
} else {
proxy.$modal.msgError('发布文章失败')
}
})
}
}
})
}
function handleCloseTag(tag) {
form.value.dynamicTags.splice(form.value.dynamicTags.indexOf(tag), 1)
}
const showInput = () => {
if (form.value.dynamicTags.length >= 5) {
proxy.$modal.msgError('最多5个标签')
return
}
inputVisible.value = true
nextTick(() => {
inputRef.value.input.focus()
})
}
//
function handleInputConfirm() {
if (inputValue.value) {
form.value.dynamicTags.push(inputValue.value)
}
inputVisible.value = false
inputValue.value = ''
}
const info = ref()
function getInfo(cid) {
if (!cid || cid == undefined) return
getArticle(cid).then((res) => {
if (res.code == 200) {
var data = res.data
info.value = data
form.value = {
...data,
dynamicTags: data.tags != null && data.tags.length > 0 ? data.tags.split(',') : []
}
}
})
}
getInfo(cid)
getCategoryTreeselect()
</script>
<style scoped>
.app-container {
position: relative;
}
.button-new-tag {
padding-top: 0;
padding-bottom: 0;
width: 90px;
margin-right: 10px;
vertical-align: bottom;
}
.upload-wrap {
display: flex;
align-items: center;
flex-direction: column;
color: #ccc;
}
.btn-wrap {
z-index: 10;
width: 100%;
/* top: 0; */
background: #fff;
padding: 3px 20px;
display: flex;
align-items: center;
position: fixed;
bottom: var(--base-footer-height);
}
</style>

View File

@ -1,163 +0,0 @@
<template>
<div class="app-container">
<el-form :model="form" ref="formRef" :rules="rules" @submit.prevent>
<el-row class="mb10">
<el-col :lg="24">
<el-form-item label="" prop="title">
<el-input v-model="form.title" placeholder="请输入标题" />
</el-form-item>
</el-col>
<el-col :lg="24">
<el-form-item prop="content" label="">
<el-input type="textarea" rows="10" placeholder="说点什么吧" show-word-limit v-model="form.content"></el-input>
</el-form-item>
</el-col>
<el-col :lg="12">
<el-form-item prop="categoryId" label="选择圈子">
<el-select v-model="form.categoryId" clearable>
<el-option v-for="item in categoryOptions" :key="item.categoryId" :label="item.name" :value="item.categoryId"> </el-option>
</el-select>
</el-form-item>
</el-col>
<el-col :lg="24">
<el-form-item prop="commentSwitch" label="评论权限">
<el-select clearable v-model="form.commentSwitch">
<el-option v-for="item in options.sys_comment_permi" :label="item.dictLabel" :value="parseInt(item.dictValue)"> </el-option>
</el-select>
</el-form-item>
</el-col>
<el-col :lg="24">
<el-form-item prop="topicId" label="选择话题">
<el-select clearable v-model="form.topicId">
<el-option v-for="item of topicList" :label="item.topicName" :value="item.topicId"> </el-option>
<!-- <template #footer>
<el-button v-if="!isAdding" text bg size="small" @click="isAdding = true"> 添加话题 </el-button>
<template v-else>
<el-input v-model="topicName" class="option-input" placeholder="输入话题名" size="small" />
<el-button type="primary" size="small" @click="onAddTopic"> 确定 </el-button>
<el-button size="small" @click="isAdding = false">取消</el-button>
</template>
</template> -->
</el-select>
</el-form-item>
</el-col>
<el-col :lg="8">
<el-form-item>
<template #label>
<span>
<el-tooltip content="不公开只有自己会看到" placement="top">
<el-icon :size="15">
<questionFilled />
</el-icon>
</el-tooltip>
是否公开
</span>
</template>
<el-switch v-model="form.isPublic" inline-prompt :active-value="1" :in-active-value="0" active-text="" inactive-text="" />
</el-form-item>
</el-col>
<el-col :lg="24">
<el-form-item>
<UploadImage ref="uploadRef" v-model="form.coverUrl" :limit="9" :fileSize="15" style="width: 90px">
<template #icon>
<div class="upload-wrap">
<el-icon><plus /></el-icon>
<div>请选择</div>
</div>
</template>
</UploadImage>
</el-form-item>
</el-col>
<el-col :lg="24">
<el-button type="success" icon="upload" @click="handlePublish('1')">立即发布</el-button>
</el-col>
</el-row>
</el-form>
</div>
</template>
<script setup name="articlepublish">
import { addArticle } from '@/api/article/article.js'
import { listArticleCategory } from '@/api/article/articlecategory.js'
import { listArticleTopic } from '@/api/article/articletopic'
const { proxy } = getCurrentInstance()
//
const categoryOptions = ref([])
const topicName = ref('')
const isAdding = ref(false)
const formRef = ref()
const data = reactive({
form: {
title: undefined,
cid: undefined,
content: undefined,
status: undefined,
categoryId: undefined,
isPublic: 1,
articleType: 2,
topicId: undefined,
tags: '',
commentSwitch: 0
},
rules: {
title: [{ required: false, message: '标题不能为空', trigger: 'blur' }],
content: [{ required: true, message: '内容不能为空', trigger: 'blur' }]
},
options: {
sys_comment_permi: []
}
})
const { form, rules, options } = toRefs(data)
proxy.getDicts(['sys_comment_permi']).then((response) => {
response.data.forEach((element) => {
data.options[element.dictType] = element.list
})
})
/** 查询菜单下拉树结构 */
function getCategoryTreeselect() {
listArticleCategory({ categoryType: 1, pageSize: 100 }).then((res) => {
if (res.code == 200) {
categoryOptions.value = res.data.result
}
})
}
const topicList = ref([])
listArticleTopic().then((res) => {
topicList.value = res.data.result
})
/** 提交按钮 */
function handlePublish(status) {
form.value.status = status
form.value.tags = topicList.value.find((x) => x.topicId == form.value.topicId)?.topicName
proxy.$refs['formRef'].validate((valid) => {
if (valid) {
addArticle(form.value).then((res) => {
if (res.code == 200) {
proxy.$modal.msgSuccess('发布成功')
proxy.$tab.closeOpenPage({ path: '/article/index' })
} else {
proxy.$modal.msgError('发布失败')
}
})
}
})
}
function onAddTopic() {}
getCategoryTreeselect()
</script>
<style scoped>
.app-container {
position: relative;
}
.upload-wrap {
display: flex;
align-items: center;
flex-direction: column;
color: #ccc;
}
</style>

View File

@ -1,622 +0,0 @@
<!--
* @Descripttion: (礼品申领表/gift_claim)
* @Author: (admin)
* @Date: (2025-07-30)
-->
<template>
<div>
<el-form :model="queryParams" label-position="right" inline ref="queryRef" v-show="showSearch" @submit.prevent>
<el-form-item label="姓名" prop="name">
<el-input v-model="queryParams.name" placeholder="请输入姓名" />
</el-form-item>
<el-form-item label="联系方式" prop="phone">
<el-input v-model="queryParams.phone" placeholder="请输入联系方式" />
</el-form-item>
<el-form-item label="工作单位" prop="company">
<el-input v-model="queryParams.company" placeholder="请输入工作单位" />
</el-form-item>
<el-form-item label="收货地址" prop="address">
<el-input v-model="queryParams.address" placeholder="请输入收货地址" />
</el-form-item>
<el-form-item label="产品型号" prop="productModel">
<el-input v-model="queryParams.productModel" placeholder="请输入产品型号" />
</el-form-item>
<el-form-item label="出品编号" prop="productSerialNumber">
<el-input v-model="queryParams.productSerialNumber" placeholder="请输入出品编号" />
</el-form-item>
<el-form-item label="微信openId" prop="userWxOpenId">
<el-input v-model="queryParams.userWxOpenId" placeholder="请输入微信openId" />
</el-form-item>
<el-form-item label="审核状态" prop="status">
<el-select clearable v-model="queryParams.status" placeholder="请选择审核状态">
<el-option v-for="item in options.gift_request_claim" :key="item.dictValue" :label="item.dictLabel" :value="item.dictValue">
<span class="fl">{{ item.dictLabel }}</span>
<span class="fr" style="color: var(--el-text-color-secondary)">{{ item.dictValue }}</span>
</el-option>
</el-select>
</el-form-item>
<el-form-item>
<el-button icon="search" type="primary" @click="handleQuery">{{ $t('btn.search') }}</el-button>
<el-button icon="refresh" @click="resetQuery">{{ $t('btn.reset') }}</el-button>
</el-form-item>
</el-form>
<!-- 工具区域 -->
<el-row :gutter="15" class="mb10">
<el-col :span="1.5">
<el-button type="primary" v-hasPermi="['giftclaim:add']" plain icon="plus" @click="handleAdd">
{{ $t('btn.add') }}
</el-button>
</el-col>
<el-col :span="1.5">
<el-button type="warning" plain icon="download" @click="handleExport" v-hasPermi="['giftclaim:export']">
{{ $t('btn.export') }}
</el-button>
</el-col>
<right-toolbar v-model:showSearch="showSearch" @queryTable="getList" :columns="columns"></right-toolbar>
</el-row>
<el-table
:data="dataList"
v-loading="loading"
ref="table"
border
header-cell-class-name="el-table-header-cell"
highlight-current-row
@sort-change="sortChange">
<el-table-column prop="id" label="序号" align="center" width="80">
<template #default="scope">
{{ (queryParams.pageNum - 1) * queryParams.pageSize + scope.$index + 1 }}
</template>
</el-table-column>
<el-table-column prop="id" label="id" align="center" width="70" v-if="columns.showColumn('id')"> </el-table-column>
<el-table-column prop="userId" label="用户信息" align="center" width="300">
<template #default="scope">
<div class="user-info-container">
<div class="user-info-item">
<span class="info-label">openId</span>
<span class="info-value">{{ scope.row.userWxOpenId }}</span>
</div>
<div class="user-info-item">
<span class="info-label">姓名</span>
<span class="info-value">{{ scope.row.name }}</span>
</div>
<div class="user-info-item">
<span class="info-label">联系方式</span>
<span class="info-value">{{ scope.row.phone }}</span>
</div>
<div class="user-info-item">
<span class="info-label">工作单位</span>
<span class="info-value">{{ scope.row.company }}</span>
</div>
<div class="user-info-item">
<span class="info-label">收货地址</span>
<span class="info-value">{{ scope.row.address }}</span>
</div>
</div>
</template>
</el-table-column>
<el-table-column prop="productModel" label="产品信息" align="center" width="400" v-if="columns.showColumn('productModel')">
<template #default="scope">
<div class="product-info-container">
<div class="product-image">
<ImagePreview style="width: 80px; height: 80px; border-radius: 8px" :src="scope.row.productImage"></ImagePreview>
</div>
<div class="product-details">
<div class="product-info-item">
<span class="info-label">产品型号</span>
<span class="info-value">{{ scope.row.productModel }}</span>
</div>
<div class="product-info-item">
<span class="info-label">出品编号</span>
<span class="info-value">{{ scope.row.productSerialNumber }}</span>
</div>
<div class="product-info-item">
<span class="info-label">出品年月</span>
<span class="info-value">{{ scope.row.productDate }}</span>
</div>
</div>
</div>
</template>
</el-table-column>
<el-table-column prop="createdAt" label="时间信息" :show-overflow-tooltip="true" width="220">
<template #default="scope">
<div class="user-info-container">
<div class="user-info-item">
<span class="info-label" style="font-size: 12px; min-width: 50px">申请时间</span>
<span class="info-value" style="font-size: 12px">{{ scope.row.createdAt }}</span>
</div>
<div class="user-info-item">
<span class="info-label" style="font-size: 12px; min-width: 50px">审核时间</span>
<span class="info-value" style="font-size: 12px">{{ scope.row.reviewAt }}</span>
</div>
</div>
</template>
</el-table-column>
<el-table-column prop="status" label="审核状态" align="center" width="150">
<template #default="scope">
<div class="status-column">
<div class="status-tag-wrapper">
<dict-tag :options="options.gift_request_claim" :value="scope.row.status" />
</div>
<div class="audit-buttons" v-if="scope.row.status === 0">
<el-button size="small" type="success" plain @click="handleAudit(scope.row, 1)" v-hasPermi="['giftclaim:audit']"> 通过 </el-button>
<el-button size="small" type="danger" plain @click="handleAudit(scope.row, 2)" v-hasPermi="['giftclaim:audit']"> 拒绝 </el-button>
</div>
</div>
</template>
</el-table-column>
<el-table-column label="操作" width="120">
<template #default="scope">
<el-button
type="success"
size="small"
icon="edit"
title="编辑"
v-hasPermi="['giftclaim:edit']"
@click="handleUpdate(scope.row)"></el-button>
<el-button
type="danger"
size="small"
icon="delete"
title="删除"
v-hasPermi="['giftclaim:delete']"
@click="handleDelete(scope.row)"></el-button>
</template>
</el-table-column>
</el-table>
<pagination :total="total" v-model:page="queryParams.pageNum" v-model:limit="queryParams.pageSize" @pagination="getList" />
<el-dialog :title="title" :lock-scroll="false" v-model="open">
<el-form ref="formRef" :model="form" :rules="rules" label-width="100px">
<el-row :gutter="20">
<el-col :lg="12">
<el-form-item label="姓名" prop="name">
<el-input v-model="form.name" placeholder="请输入姓名" />
</el-form-item>
</el-col>
<el-col :lg="12">
<el-form-item label="联系方式" prop="phone">
<el-input v-model="form.phone" placeholder="请输入联系方式" />
</el-form-item>
</el-col>
<el-col :lg="12">
<el-form-item label="工作单位" prop="company">
<el-input v-model="form.company" placeholder="请输入工作单位" />
</el-form-item>
</el-col>
<el-col :lg="12">
<el-form-item label="收货地址" prop="address">
<el-input v-model="form.address" placeholder="请输入收货地址" />
</el-form-item>
</el-col>
<el-col :lg="12">
<el-form-item label="产品型号" prop="productModel">
<el-input v-model="form.productModel" placeholder="请输入产品型号" />
</el-form-item>
</el-col>
<el-col :lg="12">
<el-form-item label="出品编号" prop="productSerialNumber">
<el-input v-model="form.productSerialNumber" placeholder="请输入出品编号" />
</el-form-item>
</el-col>
<el-col :lg="12">
<el-form-item label="出品年月" prop="productDate">
<el-input v-model="form.productDate" placeholder="请输入出品年月" />
</el-form-item>
</el-col>
<el-col :lg="24">
<el-form-item label="出品图片" prop="productImage">
<UploadImage v-model="form.productImage" :data="{ uploadType: 1 }" />
</el-form-item>
</el-col>
<el-col :lg="12">
<el-form-item label="提交时间" prop="createdAt">
<el-date-picker v-model="form.createdAt" type="datetime" placeholder="选择日期时间" value-format="YYYY-MM-DD HH:mm:ss">
</el-date-picker>
</el-form-item>
</el-col>
<el-col :lg="12">
<el-form-item label="审核状态" prop="status">
<el-select v-model="form.status" placeholder="请选择审核状态">
<el-option
v-for="item in options.gift_request_claim"
:key="item.dictValue"
:label="item.dictLabel"
:value="parseInt(item.dictValue)"></el-option>
</el-select>
</el-form-item>
</el-col>
</el-row>
</el-form>
<template #footer v-if="opertype != 3">
<el-button text @click="cancel">{{ $t('btn.cancel') }}</el-button>
<el-button type="primary" :loading="state.submitLoading" @click="submitForm">{{ $t('btn.submit') }}</el-button>
</template>
</el-dialog>
</div>
</template>
<script setup name="giftclaim">
import { listGiftClaim, addGiftClaim, delGiftClaim, updateGiftClaim, getGiftClaim, updateGiftClaimStatus } from '@/api/business/giftclaim.js'
const { proxy } = getCurrentInstance()
const ids = ref([])
const loading = ref(false)
const showSearch = ref(true)
const queryParams = reactive({
pageNum: 1,
pageSize: 10,
sort: 'Id',
sortType: 'desc',
name: undefined,
phone: undefined,
company: undefined,
address: undefined,
productModel: undefined,
productSerialNumber: undefined,
userWxOpenId: undefined,
status: undefined
})
const columns = ref([
{ visible: true, align: 'center', type: '', prop: 'id', label: '序号' },
{ visible: true, align: 'center', type: '', prop: 'id', label: 'id' },
{ visible: true, align: 'center', type: '', prop: 'userId', label: '用户信息' },
{ visible: true, align: 'center', type: '', prop: 'productModel', label: '产品信息', showOverflowTooltip: true },
{ visible: true, align: 'center', type: '', prop: 'createdAt', label: '申请时间', showOverflowTooltip: true },
{ visible: true, align: 'center', type: 'dict', prop: 'status', label: '审核状态', dictType: 'gift_request_claim', showOverflowTooltip: true }
//{ visible: false, prop: 'actions', label: '', type: 'slot', width: '160' }
])
const total = ref(0)
const dataList = ref([])
const queryRef = ref()
const defaultTime = ref([new Date(2000, 1, 1, 0, 0, 0), new Date(2000, 2, 1, 23, 59, 59)])
var dictParams = ['gift_request_claim']
proxy.getDicts(dictParams).then((response) => {
response.data.forEach((element) => {
state.options[element.dictType] = element.list
})
})
function getList() {
loading.value = true
listGiftClaim(queryParams).then((res) => {
const { code, data } = res
if (code == 200) {
dataList.value = data.result
total.value = data.totalNum
loading.value = false
}
})
}
//
function handleQuery() {
queryParams.pageNum = 1
getList()
}
//
function resetQuery() {
proxy.resetForm('queryRef')
handleQuery()
}
//
function sortChange(column) {
var sort = undefined
var sortType = undefined
if (column.prop != null && column.order != null) {
sort = column.prop
sortType = column.order
}
queryParams.sort = sort
queryParams.sortType = sortType
handleQuery()
}
//
async function handleAudit(row, status) {
console.log(row, status)
var id = row.id
const res = await updateGiftClaimStatus(id, status)
if (res.code == 200) {
proxy.$modal.msgSuccess(status == 1 ? '审核成功' : '审核不通过')
getList()
}
}
/*************** form操作 ***************/
const formRef = ref()
const title = ref('')
// 1add 2edit 3view
const opertype = ref(0)
const open = ref(false)
const state = reactive({
single: true,
multiple: true,
submitLoading: false,
form: {},
rules: {
userId: [{ required: true, message: '用户ID不能为空', trigger: 'blur', type: 'number' }],
name: [{ required: true, message: '姓名不能为空', trigger: 'blur' }],
phone: [{ required: true, message: '联系方式不能为空', trigger: 'blur' }],
address: [{ required: true, message: '收货地址不能为空', trigger: 'blur' }],
productModel: [{ required: true, message: '产品型号不能为空', trigger: 'blur' }],
productSerialNumber: [{ required: true, message: '出品编号不能为空', trigger: 'blur' }],
productDate: [{ required: true, message: '出品年月不能为空', trigger: 'blur' }],
status: [{ required: true, message: '审核状态不能为空', trigger: 'change', type: 'number' }]
},
options: {
// eg:{ dictLabel: '', dictValue: '0'}
gift_request_claim: []
}
})
const { form, rules, options, single, multiple } = toRefs(state)
// dialog
function cancel() {
open.value = false
reset()
}
//
function reset() {
form.value = {
id: null,
userId: null,
name: null,
phone: null,
company: null,
address: null,
productModel: null,
productSerialNumber: null,
productDate: null,
productImage: null,
createdAt: null,
status: null
}
proxy.resetForm('formRef')
}
//
function handleAdd() {
reset()
open.value = true
state.submitLoading = false
title.value = '添加礼品申领表'
opertype.value = 1
}
//
function handleUpdate(row) {
reset()
state.submitLoading = false
const id = row.id || ids.value
getGiftClaim(id).then((res) => {
const { code, data } = res
if (code == 200) {
open.value = true
title.value = '修改礼品申领表'
opertype.value = 2
form.value = {
...data
}
}
})
}
// &
function submitForm() {
proxy.$refs['formRef'].validate((valid) => {
if (valid) {
state.submitLoading = true
if (form.value.id != undefined && opertype.value === 2) {
updateGiftClaim(form.value).then((res) => {
proxy.$modal.msgSuccess('修改成功')
open.value = false
getList()
})
} else {
addGiftClaim(form.value)
.then((res) => {
proxy.$modal.msgSuccess('新增成功')
open.value = false
getList()
})
.finally(() => {
setTimeout(() => {
state.submitLoading = false
}, 800)
})
}
}
})
}
//
function handleDelete(row) {
const Ids = row.id || ids.value
proxy
.$confirm('是否确认删除参数编号为"' + Ids + '"的数据项?', '警告', {
confirmButtonText: proxy.$t('common.ok'),
cancelButtonText: proxy.$t('common.cancel'),
type: 'warning'
})
.then(function () {
return delGiftClaim(Ids)
})
.then(() => {
getList()
proxy.$modal.msgSuccess('删除成功')
})
}
//
function handleExport() {
proxy
.$confirm('是否确认导出礼品申领表数据项?', '警告', {
confirmButtonText: '确定',
cancelButtonText: '取消',
type: 'warning'
})
.then(async () => {
await proxy.downFile('/business/GiftClaim/export', { ...queryParams })
})
}
handleQuery()
</script>
<style scoped>
/* 用户信息样式 */
.user-info-container {
padding: 8px;
text-align: left;
}
.user-info-item {
margin-bottom: 6px;
display: flex;
align-items: flex-start;
line-height: 1.4;
}
.user-info-item:last-child {
margin-bottom: 0;
}
/* 产品信息样式 */
.product-info-container {
display: flex;
align-items: flex-start;
gap: 12px;
padding: 8px;
text-align: left;
}
.product-image {
flex-shrink: 0;
display: flex;
align-items: center;
justify-content: center;
}
.product-details {
flex: 1;
min-width: 0;
}
.product-info-item {
margin-bottom: 6px;
display: flex;
align-items: flex-start;
line-height: 1.4;
}
.product-info-item:last-child {
margin-bottom: 0;
}
/* 通用信息样式 */
.info-label {
font-weight: 500;
color: #606266;
white-space: nowrap;
margin-right: 4px;
min-width: 70px;
}
.info-value {
color: #303133;
word-break: break-all;
flex: 1;
}
/* 审核状态列样式 */
.status-column {
display: flex;
align-items: center;
justify-content: center;
gap: 10px; /* 标签和按钮之间的间距 */
flex-wrap: wrap; /* 允许换行 */
padding: 4px;
}
.status-tag-wrapper {
flex-shrink: 0; /* 防止标签收缩 */
margin-bottom: 4px;
}
.audit-buttons {
display: flex;
gap: 6px; /* 按钮之间的间距 */
flex-wrap: wrap; /* 小屏幕时允许按钮换行 */
}
.audit-buttons .el-button {
padding: 4px 8px; /* 紧凑的按钮内边距 */
font-size: 12px; /* 稍小的字体 */
border-radius: 4px;
transition: all 0.2s ease;
}
.audit-buttons .el-button:hover {
transform: translateY(-1px); /* 悬停时轻微上移效果 */
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.15);
}
/* 响应式调整 */
@media (max-width: 768px) {
.product-info-container {
flex-direction: column;
align-items: center;
gap: 8px;
}
.product-image {
align-self: center;
}
.user-info-container,
.product-details {
font-size: 12px;
}
.info-label {
min-width: 60px;
font-size: 12px;
}
.status-column {
flex-direction: column; /* 小屏幕时垂直排列 */
gap: 6px;
}
.audit-buttons {
gap: 4px;
}
.audit-buttons .el-button {
padding: 2px 6px;
font-size: 11px;
}
/* 调整表格列宽度 */
.el-table-column[prop='status'] {
min-width: 140px;
}
}
</style>

View File

@ -1,395 +0,0 @@
<!--
* @Descripttion: (微信用户表/gift_user)
* @Author: (admin)
* @Date: (2025-07-30)
-->
<template>
<div>
<el-form :model="queryParams" label-position="right" inline ref="queryRef" v-show="showSearch" @submit.prevent>
<el-form-item label="昵称" prop="nickname">
<el-input v-model="queryParams.nickname" placeholder="请输入昵称" />
</el-form-item>
<el-form-item>
<el-button icon="search" type="primary" @click="handleQuery">{{ $t('btn.search') }}</el-button>
<el-button icon="refresh" @click="resetQuery">{{ $t('btn.reset') }}</el-button>
</el-form-item>
</el-form>
<!-- 工具区域 -->
<el-row :gutter="15" class="mb10">
<el-col :span="1.5">
<el-button type="primary" v-hasPermi="['giftuser:add']" plain icon="plus" @click="handleAdd">
{{ $t('btn.add') }}
</el-button>
</el-col>
<el-col :span="1.5">
<el-button type="warning" plain icon="download" @click="handleExport" v-hasPermi="['giftuser:export']">
{{ $t('btn.export') }}
</el-button>
</el-col>
<right-toolbar v-model:showSearch="showSearch" @queryTable="getList" :columns="columns"></right-toolbar>
</el-row>
<el-table
:data="dataList"
v-loading="loading"
ref="table"
border
header-cell-class-name="el-table-header-cell"
highlight-current-row
@sort-change="sortChange">
<el-table-column prop="id" label="主键ID" align="center" sortable v-if="columns.showColumn('id')" />
<el-table-column prop="openid" label="微信openid" align="center" :show-overflow-tooltip="true" v-if="columns.showColumn('openid')" />
<el-table-column prop="unionid" label="微信unionid" align="center" :show-overflow-tooltip="true" v-if="columns.showColumn('unionid')" />
<el-table-column prop="nickname" label="昵称" align="center" :show-overflow-tooltip="true" v-if="columns.showColumn('nickname')" />
<el-table-column prop="avatarUrl" label="头像URL" align="center" v-if="columns.showColumn('avatarUrl')">
<template #default="scope">
<ImagePreview :src="scope.row.avatarUrl"></ImagePreview>
</template>
</el-table-column>
<el-table-column prop="gender" label="性别" align="center" v-if="columns.showColumn('gender')">
<template #default="scope">
<dict-tag :options="options.sys_user_sex" :value="scope.row.gender" />
</template>
</el-table-column>
<el-table-column prop="phone" label="手机号" align="center" :show-overflow-tooltip="true" v-if="columns.showColumn('phone')" />
<el-table-column prop="status" label="状态" align="center" v-if="columns.showColumn('status')">
<template #default="scope">
<dict-tag :options="options.sys_normal_disable" :value="scope.row.status" />
</template>
</el-table-column>
<el-table-column
prop="lastLoginTime"
label="最后登录时间"
:show-overflow-tooltip="true"
sortable
v-if="columns.showColumn('lastLoginTime')" />
<el-table-column label="操作" width="160">
<template #default="scope">
<el-button type="primary" size="small" icon="view" title="详情" @click="handlePreview(scope.row)"></el-button>
<el-button
type="success"
size="small"
icon="edit"
title="编辑"
v-hasPermi="['giftuser:edit']"
@click="handleUpdate(scope.row)"></el-button>
<el-button
type="danger"
size="small"
icon="delete"
title="删除"
v-hasPermi="['giftuser:delete']"
@click="handleDelete(scope.row)"></el-button>
</template>
</el-table-column>
</el-table>
<pagination :total="total" v-model:page="queryParams.pageNum" v-model:limit="queryParams.pageSize" @pagination="getList" />
<el-dialog :title="title" :lock-scroll="false" v-model="open">
<el-form ref="formRef" :model="form" :rules="rules" label-width="100px">
<el-row :gutter="20">
<el-col :lg="24">
<el-form-item label="微信openid" prop="openid">
<el-input v-model="form.openid" placeholder="请输入微信openid" />
</el-form-item>
</el-col>
<el-col :lg="24">
<el-form-item label="微信unionid" prop="unionid">
<el-input v-model="form.unionid" placeholder="请输入微信unionid" />
</el-form-item>
</el-col>
<el-col :lg="24">
<el-form-item label="昵称" prop="nickname">
<el-input v-model="form.nickname" placeholder="请输入昵称" />
</el-form-item>
</el-col>
<el-col :lg="24">
<el-form-item label="头像URL" prop="avatarUrl">
<UploadImage v-model="form.avatarUrl" :data="{ uploadType: 1 }" />
</el-form-item>
</el-col>
<el-col :lg="24">
<el-form-item label="性别" prop="gender">
<el-select v-model="form.gender" placeholder="请选择性别">
<el-option v-for="item in options.sys_user_sex" :key="item.dictValue" :label="item.dictLabel" :value="item.dictValue"></el-option>
</el-select>
</el-form-item>
</el-col>
<el-col :lg="24">
<el-form-item label="手机号" prop="phone">
<el-input v-model="form.phone" placeholder="请输入手机号" />
</el-form-item>
</el-col>
<el-col :lg="24">
<el-form-item label="状态" prop="status">
<el-radio-group v-model="form.status">
<el-radio v-for="item in options.sys_normal_disable" :key="item.dictValue" :value="item.dictValue">
{{ item.dictLabel }}
</el-radio>
</el-radio-group>
</el-form-item>
</el-col>
<el-col :lg="24">
<el-form-item label="最后登录时间" prop="lastLoginTime">
<el-date-picker v-model="form.lastLoginTime" type="datetime" placeholder="选择日期时间" value-format="YYYY-MM-DD HH:mm:ss">
</el-date-picker>
</el-form-item>
</el-col>
</el-row>
</el-form>
<template #footer v-if="opertype != 3">
<el-button text @click="cancel">{{ $t('btn.cancel') }}</el-button>
<el-button type="primary" :loading="state.submitLoading" @click="submitForm">{{ $t('btn.submit') }}</el-button>
</template>
</el-dialog>
</div>
</template>
<script setup name="giftuser">
import { listGiftUser, addGiftUser, delGiftUser, updateGiftUser, getGiftUser } from '@/api/business/giftuser.js'
const { proxy } = getCurrentInstance()
const ids = ref([])
const loading = ref(false)
const showSearch = ref(true)
const queryParams = reactive({
pageNum: 1,
pageSize: 10,
sort: 'Id',
sortType: 'desc',
nickname: undefined
})
const columns = ref([
{ visible: true, align: 'center', type: '', prop: 'id', label: '主键ID' },
{ visible: true, align: 'center', type: '', prop: 'openid', label: '微信openid', showOverflowTooltip: true },
{ visible: true, align: 'center', type: '', prop: 'unionid', label: '微信unionid', showOverflowTooltip: true },
{ visible: true, align: 'center', type: '', prop: 'nickname', label: '昵称', showOverflowTooltip: true },
{ visible: true, align: 'center', type: 'img', prop: 'avatarUrl', label: '头像URL', showOverflowTooltip: true },
{ visible: true, align: 'center', type: 'dict', prop: 'gender', label: '性别', showOverflowTooltip: true, dictType: 'sys_user_sex' },
{ visible: true, align: 'center', type: '', prop: 'phone', label: '手机号', showOverflowTooltip: true },
{ visible: true, align: 'center', type: 'dict', prop: 'status', label: '状态', showOverflowTooltip: true, dictType: 'sys_normal_disable' },
{ visible: false, align: 'center', type: '', prop: 'lastLoginTime', label: '最后登录时间', showOverflowTooltip: true }
//{ visible: false, prop: 'actions', label: '', type: 'slot', width: '160' }
])
const total = ref(0)
const dataList = ref([])
const queryRef = ref()
const defaultTime = ref([new Date(2000, 1, 1, 0, 0, 0), new Date(2000, 2, 1, 23, 59, 59)])
var dictParams = ['sys_user_sex', 'sys_normal_disable']
proxy.getDicts(dictParams).then((response) => {
response.data.forEach((element) => {
state.options[element.dictType] = element.list
})
})
function getList() {
loading.value = true
listGiftUser(queryParams).then((res) => {
const { code, data } = res
if (code == 200) {
dataList.value = data.result
total.value = data.totalNum
loading.value = false
}
})
}
//
function handleQuery() {
queryParams.pageNum = 1
getList()
}
//
function resetQuery() {
proxy.resetForm('queryRef')
handleQuery()
}
//
function sortChange(column) {
var sort = undefined
var sortType = undefined
if (column.prop != null && column.order != null) {
sort = column.prop
sortType = column.order
if (column.prop == 'lastLoginTime') {
sort = 'last_login_time'
}
if (column.prop == 'createTime') {
sort = 'create_time'
}
}
queryParams.sort = sort
queryParams.sortType = sortType
handleQuery()
}
/*************** form操作 ***************/
const formRef = ref()
const title = ref('')
// 1add 2edit 3view
const opertype = ref(0)
const open = ref(false)
const state = reactive({
single: true,
multiple: true,
submitLoading: false,
form: {},
rules: {
openid: [{ required: true, message: '微信openid不能为空', trigger: 'blur' }],
status: [{ required: true, message: '状态不能为空', trigger: 'blur' }]
},
options: {
// eg:{ dictLabel: '', dictValue: '0'}
sys_user_sex: [],
// eg:{ dictLabel: '', dictValue: '0'}
sys_normal_disable: []
}
})
const { form, rules, options, single, multiple } = toRefs(state)
// dialog
function cancel() {
open.value = false
reset()
}
//
function reset() {
form.value = {
id: null,
openid: null,
unionid: null,
nickname: null,
avatarUrl: null,
gender: null,
phone: null,
status: null,
lastLoginTime: null,
createTime: null,
updateTime: null
}
proxy.resetForm('formRef')
}
/**
* 查看
* @param {*} row
*/
function handlePreview(row) {
reset()
const id = row.id
getGiftUser(id).then((res) => {
const { code, data } = res
if (code == 200) {
open.value = true
title.value = '查看'
opertype.value = 3
form.value = {
...data
}
}
})
}
//
function handleAdd() {
reset()
open.value = true
state.submitLoading = false
title.value = '添加微信用户表'
opertype.value = 1
}
//
function handleUpdate(row) {
reset()
state.submitLoading = false
const id = row.id || ids.value
getGiftUser(id).then((res) => {
const { code, data } = res
if (code == 200) {
open.value = true
title.value = '修改微信用户表'
opertype.value = 2
form.value = {
...data
}
}
})
}
// &
function submitForm() {
proxy.$refs['formRef'].validate((valid) => {
if (valid) {
state.submitLoading = true
if (form.value.id != undefined && opertype.value === 2) {
updateGiftUser(form.value).then((res) => {
proxy.$modal.msgSuccess('修改成功')
open.value = false
getList()
})
} else {
addGiftUser(form.value)
.then((res) => {
proxy.$modal.msgSuccess('新增成功')
open.value = false
getList()
})
.finally(() => {
setTimeout(() => {
state.submitLoading = false
}, 800)
})
}
}
})
}
//
function handleDelete(row) {
const Ids = row.id || ids.value
proxy
.$confirm('是否确认删除参数编号为"' + Ids + '"的数据项?', '警告', {
confirmButtonText: proxy.$t('common.ok'),
cancelButtonText: proxy.$t('common.cancel'),
type: 'warning'
})
.then(function () {
return delGiftUser(Ids)
})
.then(() => {
getList()
proxy.$modal.msgSuccess('删除成功')
})
}
//
function handleExport() {
proxy
.$confirm('是否确认导出微信用户表数据项?', '警告', {
confirmButtonText: '确定',
cancelButtonText: '取消',
type: 'warning'
})
.then(async () => {
await proxy.downFile('/business/GiftUser/export', { ...queryParams })
})
}
handleQuery()
</script>

View File

@ -1,221 +0,0 @@
<!--
* @Descripttion: (-信息/odf_frames)
* @Author: (admin)
* @Date: (2025-08-05)
-->
<template>
<div>
<el-form :model="queryParams" label-position="right" inline ref="queryRef" v-show="showSearch" @submit.prevent>
<el-form-item label="ODF机架ID" prop="rackId">
<el-input v-model.number="queryParams.rackId" placeholder="请输入ODF机架ID" />
</el-form-item>
<el-form-item label="名称" prop="portsName">
<el-input v-model="queryParams.portsName" placeholder="请输入名称" />
</el-form-item>
<el-form-item>
<el-button icon="search" type="primary" @click="handleQuery">{{ $t('btn.search') }}</el-button>
<el-button icon="refresh" @click="resetQuery">{{ $t('btn.reset') }}</el-button>
</el-form-item>
</el-form>
<!-- 工具区域 -->
<el-row :gutter="15" class="mb10">
<el-col :span="1.5">
<el-button type="primary" v-hasPermi="['odfframes:add']" plain icon="plus" @click="handleAdd">
{{ $t('btn.add') }}
</el-button>
</el-col>
<el-col :span="1.5">
<el-button type="success" :disabled="single" v-hasPermi="['odfframes:edit']" plain icon="edit" @click="handleUpdate">
{{ $t('btn.edit') }}
</el-button>
</el-col>
<el-col :span="1.5">
<el-button type="danger" :disabled="multiple" v-hasPermi="['odfframes:delete']" plain icon="delete" @click="handleDelete">
{{ $t('btn.delete') }}
</el-button>
</el-col>
<right-toolbar v-model:showSearch="showSearch" @queryTable="getList" :columns="columns"></right-toolbar>
</el-row>
<el-table
:data="dataList"
v-loading="loading"
ref="table"
border
header-cell-class-name="el-table-header-cell"
highlight-current-row
@sort-change="sortChange"
@selection-change="handleSelectionChange">
<el-table-column type="selection" width="50" align="center" />
<el-table-column prop="id" label="Id" align="center" v-if="columns.showColumn('id')" />
<el-table-column prop="rackId" label="ODF机架ID" align="center" v-if="columns.showColumn('rackId')" />
<el-table-column prop="portsName" label="名称" align="center" :show-overflow-tooltip="true" v-if="columns.showColumn('portsName')" />
<el-table-column prop="sequenceNumber" label="序号" align="center" v-if="columns.showColumn('sequenceNumber')" />
<el-table-column prop="createdAt" label="创建时间" :show-overflow-tooltip="true" v-if="columns.showColumn('createdAt')" />
<el-table-column prop="updateAt" label="修改时间" :show-overflow-tooltip="true" v-if="columns.showColumn('updateAt')" />
<el-table-column label="操作" width="160">
<template #default="scope">
<el-button type="primary" size="small" icon="view" title="详情" @click="handlePreview(scope.row)"></el-button>
<el-button
type="success"
size="small"
icon="edit"
title="编辑"
v-hasPermi="['odfframes:edit']"
@click="handleUpdate(scope.row)"></el-button>
<el-button
type="danger"
size="small"
icon="delete"
title="删除"
v-hasPermi="['odfframes:delete']"
@click="handleDelete(scope.row)"></el-button>
</template>
</el-table-column>
</el-table>
<pagination :total="total" v-model:page="queryParams.pageNum" v-model:limit="queryParams.pageSize" @pagination="getList" />
<!-- ODF框表单组件 -->
<OdfFrameForm v-model:visible="formVisible" :id="currentId" :mode="formMode" @success="handleFormSuccess" />
</div>
</template>
<script setup name="odfframes">
import { listOdfFrames, delOdfFrames } from '@/api/business/odfframes.js'
import OdfFrameForm from '@/components/business/OdfFrameForm.vue'
const { proxy } = getCurrentInstance()
const ids = ref([])
const loading = ref(false)
const showSearch = ref(true)
const formVisible = ref(false)
const currentId = ref(null)
const formMode = ref('edit') // 'add', 'edit', 'view'
const queryParams = reactive({
pageNum: 1,
pageSize: 10,
sort: 'SequenceNumber',
sortType: 'asc',
rackId: undefined,
portsName: undefined
})
const columns = ref([
{ visible: true, align: 'center', type: '', prop: 'id', label: 'Id' },
{ visible: true, align: 'center', type: '', prop: 'rackId', label: 'ODF机架ID', dictType: 'sql_odf_room' },
{ visible: true, align: 'center', type: '', prop: 'portsName', label: '名称', showOverflowTooltip: true },
{ visible: true, align: 'center', type: '', prop: 'sequenceNumber', label: '序号' },
{ visible: false, align: 'center', type: '', prop: 'createdAt', label: '创建时间', showOverflowTooltip: true },
{ visible: false, align: 'center', type: '', prop: 'updateAt', label: '修改时间', showOverflowTooltip: true }
//{ visible: false, prop: 'actions', label: '', type: 'slot', width: '160' }
])
const total = ref(0)
const dataList = ref([])
const queryRef = ref()
const defaultTime = ref([new Date(2000, 1, 1, 0, 0, 0), new Date(2000, 2, 1, 23, 59, 59)])
const state = reactive({
single: true,
multiple: true
})
const { single, multiple } = toRefs(state)
function getList() {
loading.value = true
listOdfFrames(queryParams).then((res) => {
const { code, data } = res
if (code == 200) {
dataList.value = data.result
total.value = data.totalNum
loading.value = false
}
})
}
//
function handleQuery() {
queryParams.pageNum = 1
getList()
}
//
function resetQuery() {
proxy.resetForm('queryRef')
handleQuery()
}
//
function handleSelectionChange(selection) {
ids.value = selection.map((item) => item.id)
state.single = selection.length != 1
state.multiple = !selection.length
}
//
function sortChange(column) {
var sort = undefined
var sortType = undefined
if (column.prop != null && column.order != null) {
sort = column.prop
sortType = column.order
}
queryParams.sort = sort
queryParams.sortType = sortType
handleQuery()
}
/**
* 查看
* @param {*} row
*/
function handlePreview(row) {
currentId.value = row.id
formMode.value = 'view'
formVisible.value = true
}
//
function handleAdd() {
currentId.value = null
formMode.value = 'add'
formVisible.value = true
}
//
function handleUpdate(row) {
const id = row?.id || ids.value[0]
currentId.value = id
formMode.value = 'edit'
formVisible.value = true
}
//
function handleFormSuccess() {
getList()
}
//
function handleDelete(row) {
const Ids = row.id || ids.value
proxy
.$confirm('是否确认删除参数编号为"' + Ids + '"的数据项?', '警告', {
confirmButtonText: proxy.$t('common.ok'),
cancelButtonText: proxy.$t('common.cancel'),
type: 'warning'
})
.then(function () {
return delOdfFrames(Ids)
})
.then(() => {
getList()
proxy.$modal.msgSuccess('删除成功')
})
}
handleQuery()
</script>

View File

@ -42,6 +42,9 @@
<span>{{ node.label }}</span>
</div>
<div class="tree-node-actions">
<el-tooltip v-if="selectedNodeId === data.id" class="box-item" effect="dark" content="已选中">
<el-icon class="selected-icon"><Check /></el-icon>
</el-tooltip>
<el-tooltip v-if="data.level > 0 && data.level < 4" class="box-item" effect="dark" :content="getAddNodeTooltip(node, data)">
<el-icon v-if="data.level > 0 && data.level < 4" @click.stop="handleAddNode(node, data)"><CirclePlus /></el-icon>
</el-tooltip>
@ -94,7 +97,7 @@
<el-dropdown-item command="upload">
<importData
templateUrl="business/OdfPorts/importTemplate"
importUrl="/business/OdfPorts/importData"
importUrl="business/OdfPorts/importData"
@success="handleFileSuccess"></importData>
</el-dropdown-item>
</el-dropdown-menu>
@ -238,7 +241,7 @@
</template>
<script setup name="odfIndex">
import { CirclePlus, EditPen, Refresh, DeleteFilled } from '@element-plus/icons-vue'
import { CirclePlus, EditPen, Refresh, DeleteFilled, Check } from '@element-plus/icons-vue'
import { getOdfRoomsTreeList } from '@/api/business/odfindex'
import OdfPortForm from '@/components/business/OdfPortForm.vue'
import OdfRoomForm from '@/components/business/OdfRoomExpertForm.vue'
@ -253,6 +256,7 @@ const deptOptions = ref([])
const selectedDept = ref(null)
const formVisible = ref(false)
const currentId = ref(null)
const selectedNodeId = ref(null) // ID
let selectFrom = ref({
deptId: '',
selectName: ''
@ -263,6 +267,7 @@ const roomForm = ref({
mode: 'edit',
currentNode: null, //
handleFormSuccess: () => {
handleSearch()
//
refreshCurrentRoomNode()
}
@ -298,6 +303,8 @@ const defaultExpandedKeys = ref(['all-rooms'])
const handleSearch = () => {
// key
treeKey.value++
//
selectedNodeId.value = null
}
//
@ -485,6 +492,7 @@ const refreshParentNode = (node) => {
}
//
function handleFormSuccess() {
handleSearch()
getList()
}
const getAddNodeTooltip = (node, data) => {
@ -689,6 +697,8 @@ function getTreeselect() {
/** 节点单击事件 */
function handleNodeClick(data) {
console.log(data)
// ID
selectedNodeId.value = data.id
queryParams.roomId = data.roomId
queryParams.racksId = data.racksId
queryParams.framesId = data.framesId
@ -899,8 +909,11 @@ function handleDelete(row) {
.catch(() => {})
}
function handleFileSuccess() {
console.log('文件上传成功')
function handleFileSuccess(response) {
proxy.$alert('<p>' + response.data + '</p>', '导入结果', {
dangerouslyUseHTMLString: true
})
handleSearch()
getList()
}
@ -1038,6 +1051,28 @@ handleQuery()
transform: scale(1.1);
}
/* 选中图标样式 */
.tree-node-actions .selected-icon {
color: #67c23a !important;
font-weight: bold;
animation: pulse 1.5s ease-in-out infinite;
}
@keyframes pulse {
0% {
opacity: 1;
transform: scale(1);
}
50% {
opacity: 0.7;
transform: scale(1.1);
}
100% {
opacity: 1;
transform: scale(1);
}
}
/* 刷新图标样式 */
/* .tree-node-actions .el-icon:last-child {
color: #409eff;

View File

@ -1,11 +1,35 @@
<!--
* @Descripttion: (端口/odf_ports)
* @Descripttion: (端口数据列表/odf_ports)
* @Author: (admin)
* @Date: (2025-08-06)
-->
<template>
<div>
<el-form :model="queryParams" label-position="right" inline ref="queryRef" v-show="showSearch" @submit.prevent>
<el-form-item label="机房名称" prop="roomName">
<el-input v-model="queryParams.roomName" placeholder="请输入机房名称" />
</el-form-item>
<el-form-item label="机架名称" prop="rackName">
<el-input v-model="queryParams.rackName" placeholder="请输入机架名称" />
</el-form-item>
<el-form-item label="机框名称" prop="frameName">
<el-input v-model="queryParams.frameName" placeholder="请输入机框名称" />
</el-form-item>
<el-form-item label="连接状态" prop="status">
<el-radio-group v-model="queryParams.status">
<el-radio>全部</el-radio>
<el-radio v-for="item in options.odf_ports_status" :key="item.dictValue" :value="item.dictValue">{{ item.dictLabel }}</el-radio>
</el-radio-group>
</el-form-item>
<el-form-item label="备注" prop="remarks">
<el-input v-model="queryParams.remarks" placeholder="请输入备注" />
</el-form-item>
<el-form-item label="光衰值dB" prop="opticalAttenuation">
<el-input v-model="queryParams.opticalAttenuation" placeholder="请输入光衰值dB" />
</el-form-item>
<el-form-item label="历史故障记录" prop="historyRemarks">
<el-input v-model="queryParams.historyRemarks" placeholder="请输入历史故障记录" />
</el-form-item>
<el-form-item>
<el-button icon="search" type="primary" @click="handleQuery">{{ $t('btn.search') }}</el-button>
<el-button icon="refresh" @click="resetQuery">{{ $t('btn.reset') }}</el-button>
@ -13,38 +37,6 @@
</el-form>
<!-- 工具区域 -->
<el-row :gutter="15" class="mb10">
<el-col :span="1.5">
<el-button type="primary" v-hasPermi="['odfports:add']" plain icon="plus" @click="handleAdd">
{{ $t('btn.add') }}
</el-button>
</el-col>
<el-col :span="1.5">
<el-button type="success" :disabled="single" v-hasPermi="['odfports:edit']" plain icon="edit" @click="handleUpdate">
{{ $t('btn.edit') }}
</el-button>
</el-col>
<el-col :span="1.5">
<el-button type="danger" :disabled="multiple" v-hasPermi="['odfports:delete']" plain icon="delete" @click="handleDelete">
{{ $t('btn.delete') }}
</el-button>
</el-col>
<el-col :span="1.5">
<el-dropdown trigger="click" v-hasPermi="['odfports:import']">
<el-button type="primary" plain icon="Upload">
{{ $t('btn.import') }}<el-icon class="el-icon--right"><arrow-down /></el-icon>
</el-button>
<template #dropdown>
<el-dropdown-menu>
<el-dropdown-item command="upload">
<importData
templateUrl="business/OdfPorts/importTemplate"
importUrl="/business/OdfPorts/importData"
@success="handleFileSuccess"></importData>
</el-dropdown-item>
</el-dropdown-menu>
</template>
</el-dropdown>
</el-col>
<el-col :span="1.5">
<el-button type="warning" plain icon="download" @click="handleExport" v-hasPermi="['odfports:export']">
{{ $t('btn.export') }}
@ -60,9 +52,7 @@
border
header-cell-class-name="el-table-header-cell"
highlight-current-row
@sort-change="sortChange"
@selection-change="handleSelectionChange">
<el-table-column type="selection" width="50" align="center" />
@sort-change="sortChange">
<el-table-column prop="id" label="Id" align="center" v-if="columns.showColumn('id')" />
<el-table-column prop="name" label="端口名称" align="center" :show-overflow-tooltip="true" v-if="columns.showColumn('name')" />
<el-table-column prop="roomId" label="机房ID" align="center" v-if="columns.showColumn('roomId')" />
@ -70,8 +60,9 @@
<el-table-column prop="rackId" label="机架ID" align="center" v-if="columns.showColumn('rackId')" />
<el-table-column prop="rackName" label="机架名称" align="center" :show-overflow-tooltip="true" v-if="columns.showColumn('rackName')" />
<el-table-column prop="frameId" label="框ID" align="center" v-if="columns.showColumn('frameId')" />
<el-table-column prop="frameName" label="框名称" align="center" :show-overflow-tooltip="true" v-if="columns.showColumn('frameName')" />
<el-table-column prop="frameName" label="框名称" align="center" :show-overflow-tooltip="true" v-if="columns.showColumn('frameName')" />
<el-table-column prop="deptId" label="部门ID" align="center" v-if="columns.showColumn('deptId')" />
<el-table-column prop="deptName" label="DeptName" align="center" :show-overflow-tooltip="true" v-if="columns.showColumn('deptName')" />
<el-table-column prop="rowNumber" label="行号1-6" align="center" v-if="columns.showColumn('rowNumber')" />
<el-table-column prop="portNumber" label="端口号1-12" align="center" v-if="columns.showColumn('portNumber')" />
<el-table-column prop="status" label="连接状态0正常1断开" align="center" v-if="columns.showColumn('status')">
@ -79,21 +70,24 @@
<dict-tag :options="options.odf_ports_status" :value="scope.row.status" />
</template>
</el-table-column>
<el-table-column prop="remarks" label="备注" align="center" :show-overflow-tooltip="true" v-if="columns.showColumn('remarks')" />
<el-table-column
prop="opticalAttenuation"
label="光衰值dB"
align="center"
:show-overflow-tooltip="true"
v-if="columns.showColumn('opticalAttenuation')" />
<el-table-column prop="remarks" label="备注" align="center" :show-overflow-tooltip="true" v-if="columns.showColumn('remarks')" />
<el-table-column
prop="historyRemarks"
label="历史故障"
label="历史故障记录"
align="center"
:show-overflow-tooltip="true"
v-if="columns.showColumn('historyRemarks')" />
<el-table-column prop="createdAt" label="创建时间" :show-overflow-tooltip="true" v-if="columns.showColumn('createdAt')" />
<el-table-column prop="updatedAt" label="修改时间" :show-overflow-tooltip="true" v-if="columns.showColumn('updatedAt')" />
<el-table-column label="操作" width="160">
<template #default="scope">
<el-button type="primary" size="small" icon="view" title="详情" @click="handlePreview(scope.row)"></el-button>
<el-button
type="success"
size="small"
@ -101,61 +95,171 @@
title="编辑"
v-hasPermi="['odfports:edit']"
@click="handleUpdate(scope.row)"></el-button>
<el-button
type="danger"
size="small"
icon="delete"
title="删除"
v-hasPermi="['odfports:delete']"
@click="handleDelete(scope.row)"></el-button>
</template>
</el-table-column>
</el-table>
<pagination :total="total" v-model:page="queryParams.pageNum" v-model:limit="queryParams.pageSize" @pagination="getList" />
<!-- ODF端口表单组件 -->
<OdfPortForm v-model:visible="formVisible" :id="currentId" @success="handleFormSuccess" />
<el-dialog :title="title" :lock-scroll="false" v-model="open">
<el-form ref="formRef" :model="form" :rules="rules" label-width="100px">
<el-row :gutter="20">
<el-col :lg="12">
<el-form-item label="端口名称" prop="name">
<el-input v-model="form.name" placeholder="请输入端口名称" />
</el-form-item>
</el-col>
<el-col :lg="12">
<el-form-item label="机房ID" prop="roomId">
<el-input v-model.number="form.roomId" placeholder="请输入机房ID" />
</el-form-item>
</el-col>
<el-col :lg="12">
<el-form-item label="机房名称" prop="roomName">
<el-input v-model="form.roomName" placeholder="请输入机房名称" />
</el-form-item>
</el-col>
<el-col :lg="12">
<el-form-item label="机架ID" prop="rackId">
<el-input v-model.number="form.rackId" placeholder="请输入机架ID" />
</el-form-item>
</el-col>
<el-col :lg="12">
<el-form-item label="机架名称" prop="rackName">
<el-input v-model="form.rackName" placeholder="请输入机架名称" />
</el-form-item>
</el-col>
<el-col :lg="12">
<el-form-item label="框ID" prop="frameId">
<el-input v-model.number="form.frameId" placeholder="请输入框ID" />
</el-form-item>
</el-col>
<el-col :lg="12">
<el-form-item label="机框名称" prop="frameName">
<el-input v-model="form.frameName" placeholder="请输入机框名称" />
</el-form-item>
</el-col>
<el-col :lg="12">
<el-form-item label="部门ID" prop="deptId">
<el-input v-model.number="form.deptId" placeholder="请输入部门ID" />
</el-form-item>
</el-col>
<el-col :lg="12">
<el-form-item label="DeptName" prop="deptName">
<el-input v-model="form.deptName" placeholder="请输入DeptName" />
</el-form-item>
</el-col>
<el-col :lg="12">
<el-form-item label="行号1-6" prop="rowNumber">
<el-input v-model.number="form.rowNumber" placeholder="请输入行号1-6" />
</el-form-item>
</el-col>
<el-col :lg="12">
<el-form-item label="端口号1-12" prop="portNumber">
<el-input v-model.number="form.portNumber" placeholder="请输入端口号1-12" />
</el-form-item>
</el-col>
<el-col :lg="12">
<el-form-item label="连接状态0正常1断开" prop="status">
<el-radio-group v-model="form.status">
<el-radio v-for="item in options.odf_ports_status" :key="item.dictValue" :value="parseInt(item.dictValue)">
{{ item.dictLabel }}
</el-radio>
</el-radio-group>
</el-form-item>
</el-col>
<el-col :lg="12">
<el-form-item label="备注" prop="remarks">
<el-input v-model="form.remarks" placeholder="请输入备注" />
</el-form-item>
</el-col>
<el-col :lg="12">
<el-form-item label="光衰值dB" prop="opticalAttenuation">
<el-input v-model="form.opticalAttenuation" placeholder="请输入光衰值dB" />
</el-form-item>
</el-col>
<el-col :lg="12">
<el-form-item label="历史故障记录" prop="historyRemarks">
<el-input v-model="form.historyRemarks" placeholder="请输入历史故障记录" />
</el-form-item>
</el-col>
<el-col :lg="12">
<el-form-item label="创建时间" prop="createdAt">
<el-date-picker v-model="form.createdAt" type="datetime" placeholder="选择日期时间" value-format="YYYY-MM-DD HH:mm:ss">
</el-date-picker>
</el-form-item>
</el-col>
<el-col :lg="12">
<el-form-item label="修改时间" prop="updatedAt">
<el-date-picker v-model="form.updatedAt" type="datetime" placeholder="选择日期时间" value-format="YYYY-MM-DD HH:mm:ss">
</el-date-picker>
</el-form-item>
</el-col>
</el-row>
</el-form>
<template #footer v-if="opertype != 3">
<el-button text @click="cancel">{{ $t('btn.cancel') }}</el-button>
<el-button type="primary" :loading="state.submitLoading" @click="submitForm">{{ $t('btn.submit') }}</el-button>
</template>
</el-dialog>
</div>
</template>
<script setup name="odfports">
import { listOdfPorts, delOdfPorts } from '@/api/business/odfports.js'
import importData from '@/components/ImportData'
import OdfPortForm from '@/components/business/OdfPortForm.vue'
import { listOdfPortss, updateOdfPorts, getOdfPorts } from '@/api/business/odfports.js'
const { proxy } = getCurrentInstance()
const ids = ref([])
const loading = ref(false)
const showSearch = ref(true)
const formVisible = ref(false)
const currentId = ref(null)
const queryParams = reactive({
pageNum: 1,
pageSize: 10,
sort: 'Id',
sortType: 'asc'
sortType: 'desc',
roomName: undefined,
rackName: undefined,
frameName: undefined,
status: undefined,
remarks: undefined,
opticalAttenuation: undefined,
historyRemarks: undefined
})
const columns = ref([
{ visible: true, align: 'center', type: '', prop: 'id', label: 'Id' },
{ visible: true, align: 'center', type: '', prop: 'name', label: '端口名称', showOverflowTooltip: true },
{ visible: true, align: 'center', type: '', prop: 'roomId', label: '机房ID' },
{ visible: false, align: 'center', type: '', prop: 'roomId', label: '机房ID' },
{ visible: true, align: 'center', type: '', prop: 'roomName', label: '机房名称', showOverflowTooltip: true },
{ visible: true, align: 'center', type: '', prop: 'rackId', label: '机架ID' },
{ visible: false, align: 'center', type: '', prop: 'rackId', label: '机架ID' },
{ visible: true, align: 'center', type: '', prop: 'rackName', label: '机架名称', showOverflowTooltip: true },
{ visible: true, align: 'center', type: '', prop: 'frameId', label: '框ID' },
{ visible: true, align: 'center', type: '', prop: 'frameName', label: '框名称', showOverflowTooltip: true },
{ visible: false, align: 'center', type: '', prop: 'frameId', label: '框ID' },
{ visible: true, align: 'center', type: '', prop: 'frameName', label: '框名称', showOverflowTooltip: true },
{ visible: false, align: 'center', type: '', prop: 'deptId', label: '部门ID' },
{ visible: false, align: 'center', type: '', prop: 'rowNumber', label: '行号1-6' },
{ visible: false, align: 'center', type: '', prop: 'portNumber', label: '端口号1-12' },
{ visible: false, align: 'center', type: 'dict', prop: 'status', label: '连接状态0正常1断开', dictType: 'odf_ports_status' },
{ visible: false, align: 'center', type: '', prop: 'opticalAttenuation', label: '光衰值dB', showOverflowTooltip: true },
{ visible: false, align: 'center', type: '', prop: 'remarks', label: '备注', showOverflowTooltip: true },
{ visible: false, align: 'center', type: '', prop: 'historyRemarks', label: '历史故障表', showOverflowTooltip: true }
{ visible: false, align: 'center', type: '', prop: 'deptName', label: '所属部门', showOverflowTooltip: true },
{ visible: false, align: 'center', type: '', prop: 'rowNumber', label: '行号' },
{ visible: false, align: 'center', type: '', prop: 'portNumber', label: '端口号' },
{ visible: true, align: 'center', type: 'dict', prop: 'status', label: '连接状态', dictType: 'odf_ports_status' },
{ visible: true, align: 'center', type: '', prop: 'remarks', label: '备注', showOverflowTooltip: true },
{ visible: true, align: 'center', type: '', prop: 'opticalAttenuation', label: '光衰值dB', showOverflowTooltip: true },
{ visible: true, align: 'center', type: '', prop: 'historyRemarks', label: '历史故障记录', showOverflowTooltip: true },
{ visible: false, align: 'center', type: '', prop: 'createdAt', label: '创建时间', showOverflowTooltip: true },
{ visible: false, align: 'center', type: '', prop: 'updatedAt', label: '修改时间', showOverflowTooltip: true }
//{ visible: false, prop: 'actions', label: '', type: 'slot', width: '160' }
])
const total = ref(0)
const dataList = ref([])
const queryRef = ref()
@ -163,16 +267,6 @@ const defaultTime = ref([new Date(2000, 1, 1, 0, 0, 0), new Date(2000, 2, 1, 23,
var dictParams = ['odf_ports_status']
const state = reactive({
single: true,
multiple: true,
options: {
odf_ports_status: []
}
})
const { single, multiple, options } = toRefs(state)
proxy.getDicts(dictParams).then((response) => {
response.data.forEach((element) => {
state.options[element.dictType] = element.list
@ -181,7 +275,7 @@ proxy.getDicts(dictParams).then((response) => {
function getList() {
loading.value = true
listOdfPorts(queryParams).then((res) => {
listOdfPortss(queryParams).then((res) => {
const { code, data } = res
if (code == 200) {
dataList.value = data.result
@ -202,14 +296,6 @@ function resetQuery() {
proxy.resetForm('queryRef')
handleQuery()
}
//
function handleSelectionChange(selection) {
ids.value = selection.map((item) => item.id)
state.single = selection.length != 1
state.multiple = !selection.length
}
//
function sortChange(column) {
var sort = undefined
@ -224,68 +310,138 @@ function sortChange(column) {
handleQuery()
}
//
function handleAdd() {
currentId.value = null
formVisible.value = true
/*************** form操作 ***************/
const formRef = ref()
const title = ref('')
// 1add 2edit 3view
const opertype = ref(0)
const open = ref(false)
const state = reactive({
single: true,
multiple: true,
submitLoading: false,
form: {},
rules: {
name: [{ required: true, message: '端口名称不能为空', trigger: 'blur' }],
roomId: [{ required: true, message: '机房ID不能为空', trigger: 'blur', type: 'number' }],
roomName: [{ required: true, message: '机房名称不能为空', trigger: 'blur' }],
rackId: [{ required: true, message: '机架ID不能为空', trigger: 'blur', type: 'number' }],
rackName: [{ required: true, message: '机架名称不能为空', trigger: 'blur' }],
frameId: [{ required: true, message: '框ID不能为空', trigger: 'blur', type: 'number' }],
frameName: [{ required: true, message: '机框名称不能为空', trigger: 'blur' }],
deptId: [{ required: true, message: '部门ID不能为空', trigger: 'blur', type: 'number' }],
rowNumber: [{ required: true, message: '行号1-6不能为空', trigger: 'blur', type: 'number' }],
portNumber: [{ required: true, message: '端口号1-12不能为空', trigger: 'blur', type: 'number' }],
status: [{ required: true, message: '连接状态0正常1断开不能为空', trigger: 'blur', type: 'number' }],
createdAt: [{ required: true, message: '创建时间不能为空', trigger: 'blur' }],
updatedAt: [{ required: true, message: '修改时间不能为空', trigger: 'blur' }]
},
options: {
// 01 eg:{ dictLabel: '', dictValue: '0'}
odf_ports_status: []
}
})
const { form, rules, options, single, multiple } = toRefs(state)
// dialog
function cancel() {
open.value = false
reset()
}
//
function reset() {
form.value = {
id: null,
name: null,
roomId: null,
roomName: null,
rackId: null,
rackName: null,
frameId: null,
frameName: null,
deptId: null,
deptName: null,
rowNumber: null,
portNumber: null,
status: null,
remarks: null,
opticalAttenuation: null,
historyRemarks: null,
createdAt: null,
updatedAt: null
}
proxy.resetForm('formRef')
}
/**
* 查看
* @param {*} row
*/
function handlePreview(row) {
reset()
const id = row.id
getOdfPorts(id).then((res) => {
const { code, data } = res
if (code == 200) {
open.value = true
title.value = '查看'
opertype.value = 3
form.value = {
...data
}
}
})
}
//
function handleUpdate(row) {
const id = row?.id || ids.value[0]
currentId.value = id
formVisible.value = true
}
reset()
state.submitLoading = false
const id = row.id || ids.value
getOdfPorts(id).then((res) => {
const { code, data } = res
if (code == 200) {
open.value = true
title.value = '修改端口数据列表'
opertype.value = 2
//
function handleFormSuccess() {
getList()
}
//
function handleDelete(row) {
const Ids = row.id || ids.value
proxy
.$confirm('是否确认删除参数编号为"' + Ids + '"的数据项?', '警告', {
confirmButtonText: proxy.$t('common.ok'),
cancelButtonText: proxy.$t('common.cancel'),
type: 'warning'
})
.then(function () {
return delOdfPorts(Ids)
})
.then(() => {
getList()
proxy.$modal.msgSuccess('删除成功')
})
}
//
const handleFileSuccess = (response) => {
const { item1, item2 } = response.data
var error = ''
item2.forEach((item) => {
error += item.storageMessage + ','
form.value = {
...data
}
}
})
proxy.$alert(item1 + '<p>' + error + '</p>', '导入结果', {
dangerouslyUseHTMLString: true
})
getList()
}
// &
function submitForm() {
proxy.$refs['formRef'].validate((valid) => {
if (valid) {
state.submitLoading = true
if (form.value.id != undefined && opertype.value === 2) {
updateOdfPorts(form.value).then((res) => {
proxy.$modal.msgSuccess('修改成功')
open.value = false
getList()
})
} else {
}
}
})
}
//
function handleExport() {
proxy
.$confirm('是否确认导出端口数据项?', '警告', {
.$confirm('是否确认导出端口数据列表数据项?', '警告', {
confirmButtonText: '确定',
cancelButtonText: '取消',
type: 'warning'
})
.then(async () => {
await proxy.downFile('/business/OdfPorts/export', { ...queryParams })
await proxy.downFile('/business/OdfPorts/exports', { ...queryParams })
})
}
handleQuery()
</script>

View File

@ -39,28 +39,7 @@
{{ $t('btn.delete') }}
</el-button>
</el-col>
<el-col :span="1.5">
<el-dropdown trigger="click" v-hasPermi="['odfracks:import']">
<el-button type="primary" plain icon="Upload">
{{ $t('btn.import') }}<el-icon class="el-icon--right"><arrow-down /></el-icon>
</el-button>
<template #dropdown>
<el-dropdown-menu>
<el-dropdown-item command="upload">
<importData
templateUrl="business/OdfRacks/importTemplate"
importUrl="/business/OdfRacks/importData"
@success="handleFileSuccess"></importData>
</el-dropdown-item>
</el-dropdown-menu>
</template>
</el-dropdown>
</el-col>
<el-col :span="1.5">
<el-button type="warning" plain icon="download" @click="handleExport" v-hasPermi="['odfracks:export']">
{{ $t('btn.export') }}
</el-button>
</el-col>
<right-toolbar v-model:showSearch="showSearch" @queryTable="getList" :columns="columns"></right-toolbar>
</el-row>

View File

@ -47,7 +47,7 @@
<el-dropdown-item command="upload">
<importData
templateUrl="business/OdfRooms/importTemplate"
importUrl="/business/OdfRooms/importData"
importUrl="business/OdfRooms/importData"
@success="handleFileSuccess"></importData>
</el-dropdown-item>
</el-dropdown-menu>
@ -250,12 +250,12 @@ function handleDelete(row) {
//
const handleFileSuccess = (response) => {
const { item1, item2 } = response.data
var error = ''
item2.forEach((item) => {
error += item.storageMessage + ','
})
proxy.$alert(item1 + '<p>' + error + '</p>', '导入结果', {
// const { item1, item2 } = response.data
// var error = ''
// item2.forEach((item) => {
// error += item.storageMessage + ','
// })
proxy.$alert('<p>' + response.data + '</p>', '导入结果', {
dangerouslyUseHTMLString: true
})
getList()

View File

@ -2,7 +2,7 @@
<div class="home">
<!-- 用户信息 -->
<el-row :gutter="15">
<el-col :md="24" :lg="16" :xl="24" class="mb10">
<el-col :md="24" :lg="24" :xl="24" class="mb10">
<el-card shadow="hover">
<div class="user-item">
<div class="user-item-left">
@ -27,17 +27,6 @@
</div>
</el-card>
</el-col>
<el-col :lg="8" class="mb10">
<el-card style="height: 100%">
<div class="text-warning mb10">{{ currentTime }} {{ weekName }}</div>
<div class="work-wrap">
<el-statistic title="申请数量" :value="statistics.nowCount" />
<el-statistic title="待审核数量" :value="statistics.shenhe" />
<el-statistic title="审核通过" :value="statistics.shenhe1" />
<el-statistic title="审核未通过" :value="statistics.shenhe2" />
</div>
</el-card>
</el-col>
</el-row>
<el-row :gutter="15">
@ -61,7 +50,7 @@
<script setup name="index">
import PanelGroup from './dashboard/PanelGroup'
import CommonMenu from './components/CommonMenu'
import { getGiftClaimSatistics } from '@/api/business/giftclaim.js'
import dayjs from 'dayjs'
//
import duration from 'dayjs/plugin/duration'
@ -99,14 +88,6 @@ function handleAdd() {
proxy.$modal.msg('请通过搜索添加')
}
getGiftClaimSatistics().then((res) => {
console.log(res)
statistics.value.nowCount = res.data.nowCount
statistics.value.shenhe = res.data.shenheCount
statistics.value.shenhe1 = res.data.shenheCount1
statistics.value.shenhe2 = res.data.shenheCount2
})
function workTimeFormatter(val) {
return dayjs.duration(val * 60, 'second').format('HH时mm分')
}

View File

@ -1,94 +0,0 @@
<template>
<div class="app-container">
<el-form :model="form" ref="formRef" @submit.prevent>
<el-row class="mb10">
<el-col :lg="24">
<el-form-item>
<UploadImage ref="uploadRef" v-model="form.homeImage" :limit="1" :fileSize="15" style="width: 100px" :data="{ storeType: 2 }">
<template #icon>
<div class="upload-wrap">
<el-icon class="avatar-uploader-icon"><plus /></el-icon>
<div>首页宣传图片</div>
</div>
</template>
</UploadImage>
</el-form-item>
</el-col>
<el-col :lg="24">
<el-form-item>
<UploadImage ref="uploadRef" v-model="form.extend" :limit="1" :fileSize="15" style="width: 100px" :data="{ storeType: 2 }">
<template #icon>
<div class="upload-wrap">
<el-icon class="avatar-uploader-icon"><plus /></el-icon>
<div>首页礼品图片</div>
</div>
</template>
</UploadImage>
</el-form-item>
</el-col>
</el-row>
</el-form>
<div class="btn-wrap">
<el-button type="success" @click="handlePublish">保存</el-button>
</div>
</div>
</template>
<script setup name="mp_settings">
import useSettingsStore from '@/store/modules/settings'
import { getGiftConfig, updateGiftConfig } from '@/api/business/giftconfig.js'
const settingsStore = useSettingsStore()
const { proxy } = getCurrentInstance()
const formRef = ref()
const uploadRef = ref()
const form = reactive({
homeImage: '',
extend: '',
extend1: '',
id: 0
})
/** 提交按钮 */
async function handlePublish() {
await updateGiftConfig(form)
proxy.$modal.msgSuccess('保存成功')
}
function getList() {
getGiftConfig(0).then((res) => {
const { code, data } = res
if (code == 200) {
console.log(data)
form.homeImage = data.homeImage ?? ''
form.id = data.id
form.extend = data.extend
}
})
}
getList()
</script>
<style scoped>
.app-container {
position: relative;
}
.upload-wrap {
display: flex;
align-items: center;
flex-direction: column;
color: #ccc;
}
.btn-wrap {
z-index: 10;
width: 100%;
background: #fff;
padding: 3px 20px;
display: flex;
align-items: center;
position: fixed;
bottom: var(--base-footer-height);
}
</style>