4 changed files with 743 additions and 42 deletions
@ -1,56 +1,654 @@ |
|||
<!-- |
|||
@ 作者: 秦东 |
|||
@ 时间: 2024-05-13 16:10:18 |
|||
@ 备注: webservice服务 |
|||
* @作者: 袁纪菲 |
|||
* @时间: 2024-06-28 |
|||
* @备注: 恒信动态管理 |
|||
--> |
|||
<script lang='ts' setup> |
|||
const message = ref(''); |
|||
const ws = ref(null); |
|||
|
|||
onMounted(() => { |
|||
connect(); |
|||
<script setup lang="ts"> |
|||
import { UploadInstance } from 'element-plus'; |
|||
import { DocQuery,ZxxyNavis } from '@/api/knowledge/types' |
|||
import Editor from "@/components/WangEditor/index.vue"; |
|||
import type { UploadFile } from 'element-plus' |
|||
import * as pdfjsLib from 'pdfjs-dist'; |
|||
// 模拟列表数据 |
|||
let tableData = reactive([ |
|||
{ id: 1, name: '文章 1', column: '栏目 1', radius: '公开', accessdata: '数据 1', status: true }, |
|||
{ id: 2, name: '文章 2', column: '栏目 2', radius: '分厂', accessdata: '数据 2', status: false }, |
|||
]); |
|||
//列表数据 |
|||
// const tableList = ref<DocList[]>([]); |
|||
// 查询参数 |
|||
const queryParams = reactive<DocQuery>({ |
|||
page: 1, |
|||
pagesize: 10, |
|||
}); |
|||
|
|||
onUnmounted(() => { |
|||
if (ws.value) { |
|||
ws.value.close(); |
|||
} |
|||
// 富文本编辑器的值 |
|||
const editContvalue = ref(""); |
|||
// 用于存储 PDF 文档 |
|||
const pdfDocument = ref<null | pdfjsLib.PDFDocumentProxy>(null); |
|||
// 用于存储 PDF 页面的容器 |
|||
const pdfContainer = ref<HTMLElement | null>(null); |
|||
// 隐藏的文件输入 |
|||
const fileInput = ref<HTMLInputElement | null>(null); |
|||
// 选中的行 ID 数组 |
|||
const ids = ref([]); |
|||
// 加载状态 |
|||
const loading = ref(false); |
|||
// 总数据条数 |
|||
const total = ref(0); |
|||
// 弹窗相关 |
|||
const dialog = reactive({ |
|||
visible: false, |
|||
title: '', |
|||
}); |
|||
// 弹窗表单数据 |
|||
let formData = reactive<ZxxyNavis>({ |
|||
source: 'ORIGINAL', |
|||
accdownload: true, |
|||
review: true, |
|||
radius: '1', |
|||
}) |
|||
// 表单验证规则 |
|||
const rules = { |
|||
name: [{ required: true, message: '标题不能为空', trigger: 'blur' },], |
|||
// 其他字段的验证规则... |
|||
}; |
|||
|
|||
function connect() { |
|||
ws.value = new WebSocket('ws://120.0.0.1:14250'); |
|||
// 选中数据 |
|||
function handleSelectionChange(selection: any) { |
|||
ids.value = selection.map((item: any) => item.id); |
|||
} |
|||
|
|||
ws.value.onopen = function(event) { |
|||
console.log('WebSocket 连接已打开', event); |
|||
}; |
|||
// 重置查询 |
|||
function resetQuery() { |
|||
queryParams.branch = ''; |
|||
queryParams.section = ''; |
|||
queryParams.duty = ''; |
|||
queryParams.column = ''; |
|||
queryParams.name = ''; |
|||
} |
|||
|
|||
// 查询数据 |
|||
async function handleQuery() { |
|||
loading.value = true; |
|||
// 模拟发送请求获取数据 |
|||
setTimeout(() => { |
|||
loading.value = false; |
|||
// 假设每页 10 条数据,根据当前页码计算起始索引 |
|||
const start = (queryParams.page - 1) * queryParams.pagesize; |
|||
const end = start + queryParams.pagesize; |
|||
total.value = 20; // 假设总数据量为 20 |
|||
// 模拟分页数据 |
|||
const paginatedData = tableData.slice(start, end); |
|||
// 更新表格数据 |
|||
tableData = paginatedData; |
|||
}, 1000); |
|||
} |
|||
|
|||
ws.value.onerror = function(error) { |
|||
console.error('WebSocket 出错', error); |
|||
// 打开添加或编辑弹窗 |
|||
function openDialog(rowId?: number) { |
|||
dialog.visible = true; |
|||
if (rowId) { |
|||
dialog.title = '编辑'; |
|||
const row = tableData.find((item) => item.id === rowId); |
|||
formData = {...row }; |
|||
} else { |
|||
dialog.title = '添加'; |
|||
} |
|||
} |
|||
//上传封面 |
|||
const coverUrl = ref(''); |
|||
// 处理图片上传前的校验 |
|||
const beforeUploadCover = (file: { type: string; }) => { |
|||
const isImage = file.type.startsWith('image/'); |
|||
if (!isImage) { |
|||
ElMessage.error('请上传图片文件'); |
|||
return false; |
|||
} |
|||
return true; |
|||
}; |
|||
// 处理图片上传后的操作 |
|||
const handleCoverChange = (file: { raw: Blob; }) => { |
|||
const reader = new FileReader(); |
|||
reader.readAsDataURL(file.raw); |
|||
reader.onload = (e) => { |
|||
if (e.target && typeof e.target.result ==='string') { |
|||
coverUrl.value = e.target.result; |
|||
} |
|||
}; |
|||
}; |
|||
// 处理删除图片的操作 |
|||
const handleRemoveCover = () => { |
|||
coverUrl.value = ''; |
|||
}; |
|||
|
|||
// 加载 PDF 文件 |
|||
async function loadPdf(arrayBuffer: ArrayBuffer) { |
|||
const loadingTask = pdfjsLib.getDocument(arrayBuffer); |
|||
pdfDocument.value = await loadingTask.promise; |
|||
|
|||
// 渲染第一页 |
|||
renderPage(1); |
|||
} |
|||
|
|||
ws.value.onmessage = function(event) { |
|||
console.log('收到消息', event.data); |
|||
// 渲染 PDF 页面 |
|||
async function renderPage(pageNumber: number) { |
|||
const page = await pdfDocument.value!.getPage(pageNumber); |
|||
const scale = 1.5; |
|||
const viewport = page.getViewport({ scale }); |
|||
|
|||
const canvas = document.createElement('canvas'); |
|||
const context = canvas.getContext('2d')!; |
|||
canvas.height = viewport.height; |
|||
canvas.width = viewport.width; |
|||
|
|||
const renderContext = { |
|||
canvasContext: context, |
|||
viewport, |
|||
}; |
|||
|
|||
ws.value.onclose = function() { |
|||
console.log('WebSocket 连接已关闭'); |
|||
await page.render(renderContext).promise; |
|||
(pdfContainer.value as unknown as HTMLElement).appendChild(canvas); |
|||
} |
|||
|
|||
// 读取文件为 ArrayBuffer |
|||
async function readFileAsArrayBuffer(file: File): Promise<ArrayBuffer> { |
|||
return new Promise((resolve, reject) => { |
|||
const reader = new FileReader(); |
|||
reader.onloadend = () => resolve(reader.result as ArrayBuffer); |
|||
reader.onerror = reject; |
|||
reader.readAsArrayBuffer(file); |
|||
}); |
|||
} |
|||
|
|||
// 文件选择事件处理函数 |
|||
function handleFileChange(event: Event) { |
|||
const inputElement = event.target as HTMLInputElement; |
|||
const file = inputElement.files?.[0]; |
|||
|
|||
if (!file || !file.type.startsWith('application/pdf')) { |
|||
console.log('无效的文件类型:', file?.type); |
|||
ElMessage.error('请上传 PDF 文件'); |
|||
return; |
|||
} |
|||
|
|||
try { |
|||
const pdfData = readFileAsArrayBuffer(file); |
|||
pdfData.then(async (data) => { |
|||
await loadPdf(data); |
|||
// 清空富文本编辑器的内容 |
|||
editContvalue.value = ''; |
|||
// 设置 PDF 容器 |
|||
pdfContainer.value = document.querySelector('#pdf-container') as HTMLElement; |
|||
console.log('PDF 文件已加载'); |
|||
}); |
|||
} catch (error) { |
|||
console.error('Error loading PDF:', error); |
|||
} |
|||
} |
|||
// 在组件挂载后设置 fileInput |
|||
onMounted(() => { |
|||
fileInput.value = document.querySelector('#file-input') as HTMLInputElement; |
|||
// 设置 worker 脚本路径 |
|||
pdfjsLib.GlobalWorkerOptions.workerSrc = './node_modules/pdfjs-dist/build/pdf.worker.js'; |
|||
}); |
|||
|
|||
// 上传PDF并在富文本编辑器所在位置预览 |
|||
async function submitPdf() { |
|||
if (fileInput.value) { |
|||
fileInput.value.click(); // 触发文件选择对话框 |
|||
} |
|||
} |
|||
//上传附件 |
|||
const uploadRef = ref<UploadInstance>() |
|||
const submitUpload = () => { |
|||
uploadRef.value!.submit() |
|||
} |
|||
// 提交表单 |
|||
async function handleSubmit() { |
|||
const validateResult = validate(formData, rules); |
|||
if (validateResult) { |
|||
if (dialog.title === '添加') { |
|||
// 模拟添加数据 |
|||
const newData = { |
|||
...formData, |
|||
id: Date.now(), |
|||
accessdata: '', |
|||
status: true, |
|||
name: formData.name || '', // 确保 name 有值 |
|||
column: formData.column || '', |
|||
radius: formData.radius || '', |
|||
};// 设置默认的 accessdata 和 status 值 |
|||
tableData.push(newData); |
|||
ElMessage.success('添加成功'); |
|||
} else { |
|||
// 模拟编辑数据 |
|||
const index = tableData.findIndex((item) => item.id === formData.id); |
|||
const updatedData = { |
|||
id: formData.id!, |
|||
accdownload: formData.accdownload!, |
|||
sort: formData.sort!, |
|||
review: formData.review!, |
|||
name: formData.name!, |
|||
column: formData.column!, |
|||
accessdata: tableData[index].accessdata, // 从 tableData 中获取 |
|||
radius: tableData[index].radius, // 从 tableData 中获取 |
|||
status: tableData[index].status |
|||
}; |
|||
tableData[index] = updatedData; |
|||
ElMessage.success('编辑成功'); |
|||
} |
|||
dialog.visible = false; |
|||
} else { |
|||
ElMessage.error('表单填写有误,请检查!'); |
|||
} |
|||
} |
|||
|
|||
function sendMessage() { |
|||
if (ws.value && ws.value.readyState === WebSocket.OPEN) { |
|||
ws.value.send(message.value); |
|||
// 删除选中行 |
|||
type DataType = number[] | { id: number }; |
|||
|
|||
async function handleDelete(data: DataType) { |
|||
if (Array.isArray(data)) { |
|||
// 处理选中行删除 |
|||
if (data.length > 0) { |
|||
const confirmDelete = await ElMessageBox.confirm('确定删除选中的行吗?', '提示', { |
|||
confirmButtonText: '确定', |
|||
cancelButtonText: '取消', |
|||
type: 'warning', |
|||
}); |
|||
if (confirmDelete) { |
|||
data.forEach((id) => { |
|||
const index = tableData.findIndex((item) => item.id === id); |
|||
if (index!== -1) { |
|||
tableData.splice(index, 1); |
|||
} |
|||
}); |
|||
ids.value = []; |
|||
ElMessage.success('删除成功'); |
|||
} |
|||
} else { |
|||
console.error('WebSocket 连接未打开'); |
|||
ElMessage.warning('请先选择要删除的行'); |
|||
} |
|||
} else if (data && typeof data === 'object') { |
|||
// 处理单个行删除 |
|||
const confirmDelete = await ElMessageBox.confirm('确定删除当前行吗?', '提示', { |
|||
confirmButtonText: '确定', |
|||
cancelButtonText: '取消', |
|||
type: 'warning', |
|||
}); |
|||
if (confirmDelete) { |
|||
const index = tableData.findIndex((item) => item.id === data.id); |
|||
if (index!== -1) { |
|||
tableData.splice(index, 1); |
|||
ElMessage.success('删除成功'); |
|||
} |
|||
} |
|||
} |
|||
} |
|||
//自定义访问权限 |
|||
const userDialogEl = ref() |
|||
const showDialog = () => { |
|||
userDialogEl.value.open() |
|||
} |
|||
// 修改状态 |
|||
function editPostState(rowId: number, newStatus: boolean) { |
|||
const row = tableData.find((item) => item.id === rowId); |
|||
if (row) { // 增加对 row 是否存在的判断 |
|||
row.status = newStatus; |
|||
} |
|||
} |
|||
|
|||
// 表单验证函数 |
|||
function validate(formData: any, rules: any) { |
|||
let valid = true; |
|||
for (const key in rules) { |
|||
const rule = rules[key]; |
|||
const value = formData[key]; |
|||
for (const item of rule) { |
|||
if (item.required && (!value || value.trim() === '')) { |
|||
valid = false; |
|||
ElMessage.error(item.message); |
|||
break; |
|||
} |
|||
} |
|||
} |
|||
return valid; |
|||
} |
|||
|
|||
// 关闭弹窗 |
|||
function closeDialog() { |
|||
dialog.visible = false; |
|||
resetForm(); |
|||
} |
|||
const resetForm = () => { |
|||
formData = reactive<ZxxyNavis>({ |
|||
accdownload: true, |
|||
sort: 1, |
|||
review: true, |
|||
}) |
|||
coverUrl.value = ''; |
|||
} |
|||
</script> |
|||
|
|||
<template> |
|||
<div> |
|||
<input v-model="message" placeholder="输入消息" /> |
|||
<button @click="sendMessage">发送</button> |
|||
<div class="app-container"> |
|||
<!-- 查询 --> |
|||
<div class="search"> |
|||
<el-row> |
|||
<el-col :span="16"> |
|||
<el-form ref="queryFormRef" :model="queryParams" :inline="true"> |
|||
<el-form-item class="query" prop="branch"> |
|||
<el-select |
|||
v-model="queryParams.branch" |
|||
placeholder="请选分厂" |
|||
clearable |
|||
style="width: 120px"> |
|||
<el-option label="甲醇分厂" value="1"></el-option> |
|||
<el-option label="化产分厂" value="2"></el-option> |
|||
<el-option label="动力分厂" value="3"></el-option> |
|||
</el-select> |
|||
</el-form-item> |
|||
<el-form-item class="query" prop="section"> |
|||
<el-select |
|||
v-model="queryParams.section" |
|||
placeholder="请选工段" |
|||
clearable |
|||
style="width: 120px"> |
|||
<el-option label="工段1" value="1"></el-option> |
|||
<el-option label="工段2" value="2"></el-option> |
|||
</el-select> |
|||
</el-form-item> |
|||
<el-form-item class="query" prop="duty"> |
|||
<el-select |
|||
v-model="queryParams.duty" |
|||
placeholder="请选职务" |
|||
clearable |
|||
style="width: 120px"> |
|||
<el-option label="职务1" value="1"></el-option> |
|||
<el-option label="职务2" value="2"></el-option> |
|||
</el-select> |
|||
</el-form-item> |
|||
<el-form-item class="query" prop="column"> |
|||
<el-select |
|||
v-model="queryParams.column" |
|||
placeholder="请选栏目" |
|||
clearable |
|||
style="width: 120px"> |
|||
<el-option label="栏目1" value="1"></el-option> |
|||
<el-option label="栏目2" value="2"></el-option> |
|||
</el-select> |
|||
</el-form-item> |
|||
<el-form-item class="query" prop="name"> |
|||
<el-input |
|||
v-model="queryParams.name" |
|||
placeholder="请输入题目" |
|||
clearable |
|||
/> |
|||
</el-form-item> |
|||
</el-form> |
|||
</el-col> |
|||
<el-col :span="8" style="text-align: right;"> |
|||
<el-button |
|||
type="primary" |
|||
|
|||
@click="handleQuery" |
|||
>查询</el-button> |
|||
<el-button |
|||
@click="resetQuery"><i-ep-refresh />重置 |
|||
</el-button> |
|||
</el-col> |
|||
</el-row> |
|||
</div> |
|||
<div class="glm-btn-box"> |
|||
<el-button |
|||
type="primary" |
|||
@click="openDialog()" |
|||
><el-icon><Plus /></el-icon>添加</el-button> |
|||
<el-button |
|||
type="primary" |
|||
plain |
|||
:disabled="ids.length === 0" |
|||
@click="handleDelete(ids)" |
|||
><el-icon><Delete /></el-icon>删除</el-button> |
|||
</div> |
|||
<el-card shadow="never"> |
|||
<!-- 数据表格 --> |
|||
<el-table |
|||
v-loading="loading" |
|||
:data="tableData" |
|||
border |
|||
@selection-change="handleSelectionChange" |
|||
> |
|||
<el-table-column type="selection" width="50" /> |
|||
<el-table-column label="文章标题" prop="name" width="400" align="center"/> |
|||
<el-table-column label="所属栏目" prop="column" width="150" align="center"/> |
|||
<el-table-column label="可见范围" prop="radius" width="150" align="center" /> |
|||
<el-table-column label="访问数据" prop="accessdata" width="400" align="center"/> |
|||
<el-table-column label="状态" prop="status" width="100" align="center" > |
|||
<template #default="scope"> |
|||
<el-switch v-model="scope.row.status" class="ml-2" inline-prompt style="--el-switch-on-color: #ff4949; --el-switch-off-color: #13ce66" active-text="禁用" inactive-text="启用" @change="editPostState(scope.row.id,scope.row.status)" /> |
|||
</template> |
|||
</el-table-column> |
|||
<el-table-column fixed="right" label="编辑" align="center"> |
|||
<template #default="scope"> |
|||
<el-button |
|||
type="primary" |
|||
link |
|||
@click="openDialog(scope.row.id)" |
|||
><i-ep-edit />修改</el-button |
|||
> |
|||
<el-button |
|||
type="primary" |
|||
link |
|||
@click.stop="handleDelete(scope.row)" |
|||
><i-ep-delete />删除</el-button |
|||
> |
|||
</template> |
|||
</el-table-column> |
|||
</el-table> |
|||
<!-- 分页 --> |
|||
<pagination |
|||
v-if="total > 0" |
|||
v-model:total="total" |
|||
v-model:page="queryParams.page" |
|||
v-model:limit="queryParams.pagesize" |
|||
@pagination="handleQuery" |
|||
/> |
|||
</el-card> |
|||
<!-- 添加/修改弹窗 --> |
|||
<el-dialog |
|||
v-model="dialog.visible" |
|||
:title="dialog.title" |
|||
width="900px" |
|||
@close="closeDialog" |
|||
> |
|||
<el-form |
|||
ref="dataFormRef" |
|||
:model="formData" |
|||
:rules="rules" |
|||
label-width="100px" |
|||
> |
|||
<el-form-item label="标题" prop="name"> |
|||
<el-input v-model="formData.name" placeholder="请输入标题" /> |
|||
</el-form-item> |
|||
<el-form-item label="归属栏目" prop="column"> |
|||
<el-select |
|||
v-model="formData.column" |
|||
placeholder="请选择" |
|||
> |
|||
<el-option label="栏目1" value="1"></el-option> |
|||
<el-option label="栏目2" value="2"></el-option> |
|||
</el-select> |
|||
</el-form-item> |
|||
<el-form-item label="文档来源" prop="source"> |
|||
<el-radio-group v-model="formData.source" > |
|||
<el-radio label="ORIGINAL">原创</el-radio> |
|||
<el-radio label="RESHIP">转贴</el-radio> |
|||
</el-radio-group> |
|||
</el-form-item> |
|||
<el-form-item |
|||
v-if="formData.source == 'RESHIP'" |
|||
label="原文地址" |
|||
prop="path" |
|||
> |
|||
<el-input v-model="formData.path" placeholder="请输入原文地址" /> |
|||
</el-form-item> |
|||
<el-form-item label="上传封面" prop="cover"> |
|||
<div class="upload-cover custom-upload-box"> |
|||
<el-upload |
|||
class="cover-upload" |
|||
action="https://run.mocky.io/v3/9d059bf9-4660-45f2-925d-ce80ad6c4d15" |
|||
:show-file-list="false" |
|||
:on-change="handleCoverChange" |
|||
:before-upload="beforeUploadCover" |
|||
:drag="true" |
|||
> |
|||
<div v-if="!coverUrl"> |
|||
<i class="el-icon-upload"><el-icon class="el-icon--upload"><upload-filled /></el-icon></i> |
|||
<p>点击上传,或将文件拖拽到此处</p> |
|||
</div> |
|||
<img v-if="coverUrl" :src="coverUrl" style="width: 100%; height: auto; object-fit: cover;" @click="handleRemoveCover" /> |
|||
</el-upload> |
|||
</div> |
|||
</el-form-item> |
|||
<el-form-item label="文档标签" prop="tag"> |
|||
<el-input v-model="formData.tag" placeholder="请输入文档标签,每个标签请用,隔开!" /> |
|||
</el-form-item> |
|||
<el-form-item label="文档描述" prop="describe"> |
|||
<el-input v-model="formData.describe" placeholder="请输入文档简略描述" type="textarea"></el-input> |
|||
</el-form-item> |
|||
<el-form-item label="使用外链" prop="extlink"> |
|||
<el-input v-model="formData.extlink" placeholder="当使用外链的时候!(链接以http://或https://开头!)" ></el-input> |
|||
</el-form-item> |
|||
<el-form-item label="文档正文:" prop="text"> |
|||
<Editor v-model="editContvalue" style="height: calc(100vh - 124px)"/> |
|||
</el-form-item> |
|||
<el-form-item label="上传正文:"> |
|||
<el-button type="warning" @click="submitPdf"> |
|||
上传正文(只支持PDF文件) |
|||
</el-button> |
|||
</el-form-item> |
|||
<div id="pdf-container"></div> |
|||
<!-- 隐藏的文件输入 --> |
|||
<input ref="fileInput" type="file" accept=".pdf" style="display: none" @change="handleFileChange" /> |
|||
<el-form-item label="附件:" prop="accessory"> |
|||
<el-upload |
|||
ref="uploadRef" |
|||
v-model="formData.accessory" |
|||
class="upload-demo" |
|||
action="https://run.mocky.io/v3/9d059bf9-4660-45f2-925d-ce80ad6c4d15" |
|||
:auto-upload="false" |
|||
> |
|||
<template #trigger> |
|||
<el-button class="btn-fujian" type="primary">选择多文件</el-button> |
|||
</template> |
|||
<el-button class="ml-3" type="success" @click="submitUpload"> |
|||
开始上传 |
|||
</el-button> |
|||
</el-upload> |
|||
</el-form-item> |
|||
<el-form-item label="附件下载" prop="accdownload"> |
|||
<el-switch |
|||
v-model="formData.accdownload" |
|||
inline-prompt |
|||
class="ml-2" |
|||
style="--el-switch-on-color: #13ce66; --el-switch-off-color: #ff4949" |
|||
active-text="允许" |
|||
inactive-text="禁止" |
|||
/> |
|||
</el-form-item> |
|||
<el-form-item label="排序" prop="sort"> |
|||
<el-input v-model="formData.sort" placeholder="请输入文档序号" /> |
|||
</el-form-item> |
|||
<el-form-item label="评论设置" prop="review"> |
|||
<el-switch |
|||
v-model="formData.review" |
|||
inline-prompt |
|||
class="ml-2" |
|||
style="--el-switch-on-color: #13ce66; --el-switch-off-color: #ff4949" |
|||
active-text="允许" |
|||
inactive-text="禁止" |
|||
/> |
|||
</el-form-item> |
|||
<el-form-item label="访问权限" prop="radius"> |
|||
<el-radio-group v-model="formData.radius"> |
|||
<el-radio label="1">公开</el-radio> |
|||
<el-radio label="2">分厂</el-radio> |
|||
<el-radio label="3">工段</el-radio> |
|||
<el-radio label="4">自定义</el-radio> |
|||
</el-radio-group> |
|||
</el-form-item> |
|||
<el-form-item |
|||
v-if="formData.radius == '2'" |
|||
label="可见范围" |
|||
prop="gBfId" |
|||
label-width="100px" |
|||
> |
|||
<el-select v-model="formData.gBfId" placeholder="请选择分厂" class="compact-select"> |
|||
<el-option /> |
|||
</el-select> |
|||
</el-form-item> |
|||
<el-form-item |
|||
v-if="formData.radius == '3'" |
|||
label="可见范围" |
|||
prop="gBfId" |
|||
> |
|||
<el-select v-model="formData.gBfId" placeholder="请选择分厂" class="compact-select"> |
|||
<el-option /> |
|||
</el-select> |
|||
<el-select v-model="formData.gWsId" placeholder="请选择工段" class="compact-select"> |
|||
<el-option /> |
|||
</el-select> |
|||
</el-form-item> |
|||
<el-form-item |
|||
v-if="formData.radius == '4'" |
|||
label="可见范围" |
|||
prop="gBfId" |
|||
> |
|||
<el-input |
|||
v-bind="$props" |
|||
placeholder="请选择" |
|||
@click="showDialog" |
|||
> |
|||
<template #append> |
|||
<i class="icon-user" @click.stop="showDialog"></i> |
|||
</template> |
|||
</el-input> |
|||
</el-form-item> |
|||
</el-form> |
|||
<template #footer> |
|||
<div class="dialog-footer"> |
|||
<el-button type="primary" @click="handleSubmit">确 定</el-button> |
|||
<el-button type="success">暂 存</el-button> |
|||
<el-button @click="closeDialog">取 消</el-button> |
|||
</div> |
|||
</template> |
|||
</el-dialog> |
|||
</div> |
|||
</template> |
|||
<style lang='scss' scoped> |
|||
<style scoped> |
|||
.search { |
|||
padding: 20px; |
|||
} |
|||
|
|||
.query{ |
|||
margin: 0; |
|||
} |
|||
.custom-upload-box { |
|||
width: 30%; /* 您期望的宽度 */ |
|||
height: auto; /* 您期望的高度 */ |
|||
} |
|||
.cover-preview { |
|||
width: 100px; |
|||
height: 100px; |
|||
display: inline-block; |
|||
margin-right: 10px; |
|||
} |
|||
.btn-fujian{ |
|||
justify-content: space-between; |
|||
} |
|||
.compact-select { |
|||
width: 30%; |
|||
display: inline-block; |
|||
margin-right: 10px; /* 添加间距 */ |
|||
} |
|||
</style> |
|||
@ -0,0 +1,56 @@ |
|||
<!-- |
|||
@ 作者: 秦东 |
|||
@ 时间: 2024-05-13 16:10:18 |
|||
@ 备注: webservice服务 |
|||
--> |
|||
<script lang='ts' setup> |
|||
const message = ref(''); |
|||
const ws = ref(null); |
|||
|
|||
onMounted(() => { |
|||
connect(); |
|||
}); |
|||
|
|||
onUnmounted(() => { |
|||
if (ws.value) { |
|||
ws.value.close(); |
|||
} |
|||
}); |
|||
|
|||
function connect() { |
|||
ws.value = new WebSocket('ws://120.0.0.1:14250'); |
|||
|
|||
ws.value.onopen = function(event) { |
|||
console.log('WebSocket 连接已打开', event); |
|||
}; |
|||
|
|||
ws.value.onerror = function(error) { |
|||
console.error('WebSocket 出错', error); |
|||
}; |
|||
|
|||
ws.value.onmessage = function(event) { |
|||
console.log('收到消息', event.data); |
|||
}; |
|||
|
|||
ws.value.onclose = function() { |
|||
console.log('WebSocket 连接已关闭'); |
|||
}; |
|||
} |
|||
|
|||
function sendMessage() { |
|||
if (ws.value && ws.value.readyState === WebSocket.OPEN) { |
|||
ws.value.send(message.value); |
|||
} else { |
|||
console.error('WebSocket 连接未打开'); |
|||
} |
|||
} |
|||
</script> |
|||
<template> |
|||
<div> |
|||
<input v-model="message" placeholder="输入消息" /> |
|||
<button @click="sendMessage">发送</button> |
|||
</div> |
|||
</template> |
|||
<style lang='scss' scoped> |
|||
|
|||
</style> |
|||
Loading…
Reference in new issue