Browse Source

no message

yjf_v1
DESKTOP-CUI7KST\HXGK 1 year ago
parent
commit
9227a6de66
  1. 1
      package.json
  2. 46
      src/api/knowledge/types.ts
  3. 664
      src/views/sysworkflow/codepage/page.vue
  4. 56
      src/views/sysworkflow/codepage/page0628.vue

1
package.json

@ -63,6 +63,7 @@
"nprogress": "^0.2.0",
"path-browserify": "^1.0.1",
"path-to-regexp": "^6.2.0",
"pdfjs-dist": "^4.5.136",
"pinia": "^2.1.6",
"quill-image-resize-custom-module": "^4.1.7",
"quill-image-uploader": "^1.3.0",

46
src/api/knowledge/types.ts

@ -169,3 +169,49 @@ export interface ShowTitle {
hasCard:Boolean;//是否展示
}
//知行学院恒信动态管理
// 查询参数
export interface DocQuery {
branch?: string,
section?: string,
duty?: string,
column?: string,
name?: string,
page: number,
pagesize: number,
}
export interface ZxxyNavis {
id?: number;
//文章标题
name?: string;
//归属栏目
column?: string;
//文档来源
source?: string;
//原文地址
path?: string;
//封面
cover?: string;
//文档标签
tag?: string;
//文档描述
describe?: string;
//外链
extlink?: string;
//附件
accessory?: string;
//附件下载
accdownload?: boolean;
//排序
sort?: number;
//评论
review?: boolean;
//访问权限
radius?: string;
//分厂
gBfId?: string;
//工段
gWsId?: string;
}

664
src/views/sysworkflow/codepage/page.vue

@ -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>

56
src/views/sysworkflow/codepage/page0628.vue

@ -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…
Cancel
Save