案例管理模块

main
许宏杰 2 months ago
parent 8272f66faa
commit 40d680b6c6

@ -0,0 +1,42 @@
import request from "@/utils/request";
// 查询菜单列表
export function getList(query) {
return request({
url: "/jcModel",
method: "get",
params: query,
});
}
// 新增
export function add(data) {
return request({
url: "/jcModel",
method: "post",
data: data,
});
}
//删除
export function del(ids) {
return request({
url: "/jcModel/delete/" + ids,
method: "post",
});
}
//修改
export function updata(data) {
return request({
url: "/jcModel",
method: "put",
data: data,
});
}
//详情
export function getInfo(id) {
return request({
url: "/jcModel/" + id,
method: "get",
});
}

@ -35,7 +35,7 @@
tag="ul" tag="ul"
> >
<li <li
:key="index" :key="file.uid"
class="el-upload-list__item ele-upload-list__item-content" class="el-upload-list__item ele-upload-list__item-content"
v-for="(file, index) in fileList" v-for="(file, index) in fileList"
> >
@ -53,13 +53,12 @@
</div> </div>
</li> </li>
</transition-group> </transition-group>
<video hidden id="video" controls object-fill="fill"></video>
</div> </div>
</template> </template>
<script setup> <script setup>
import { getToken } from "@/utils/auth"; import { getToken } from "@/utils/auth";
import ffmpeg from "@/utils/ffmpeg";
const props = defineProps({ const props = defineProps({
modelValue: [String, Object, Array], modelValue: [String, Object, Array],
// //
@ -75,7 +74,7 @@ const props = defineProps({
// , ['png', 'jpg', 'jpeg'] // , ['png', 'jpg', 'jpeg']
fileType: { fileType: {
type: Array, type: Array,
default: () => ["mp4"], default: () => ["doc", "xls", "ppt", "txt", "pdf"],
}, },
// //
isShowTip: { isShowTip: {
@ -138,33 +137,19 @@ function handleBeforeUpload(file) {
proxy.$modal.msgError("文件名不正确,不能包含英文逗号!"); proxy.$modal.msgError("文件名不正确,不能包含英文逗号!");
return false; return false;
} }
// //
// if (props.fileSize) { if (props.fileSize) {
// const isLt = file.size / 1024 / 1024 < props.fileSize; const isLt = file.size / 1024 / 1024 < props.fileSize;
// if (!isLt) { if (!isLt) {
// // // proxy.$modal.msgError(` ${props.fileSize} MB!`); proxy.$modal.msgError(`上传文件大小不能超过 ${props.fileSize} MB!`);
// return ; return false;
// } }
// } }
proxy.$modal.loading("正在上传文件,请稍候..."); proxy.$modal.loading("正在上传文件,请稍候...");
number.value++; number.value++;
return uploadCompressVideo(file); return true;
} }
function uploadCompressVideo(file) {
if (file) {
let filename = file.name;
let filetype = file.type;
const videoUrl = ffmpeg.getObjectURL(file);
const video = document.getElementById("video");
video.src = videoUrl;
return ffmpeg.getVideoData().then((videoObj) => {
const { width, height } = videoObj;
return ffmpeg.squeezVideo(file, filename, filetype, width, height);
});
}
}
// //
function handleExceed() { function handleExceed() {
proxy.$modal.msgError(`上传文件数量不能超过 ${props.limit} 个!`); proxy.$modal.msgError(`上传文件数量不能超过 ${props.limit} 个!`);
@ -197,10 +182,6 @@ function handleDelete(index) {
// //
function uploadedSuccessfully() { function uploadedSuccessfully() {
console.log(
"sss",
number.value > 0 && uploadList.value.length === number.value
);
if (number.value > 0 && uploadList.value.length === number.value) { if (number.value > 0 && uploadList.value.length === number.value) {
fileList.value = fileList.value fileList.value = fileList.value
.filter((f) => f.url !== undefined) .filter((f) => f.url !== undefined)

@ -7,14 +7,35 @@
:inline="true" :inline="true"
label-width="68px" label-width="68px"
> >
<el-form-item label="项目标题" prop="roleName"> <el-form-item label="项目标题" prop="title">
<el-input <el-input
v-model="queryParams.roleName" v-model="queryParams.title"
placeholder="请输入项目标题" placeholder="请输入项目标题"
clearable clearable
style="width: 240px" style="width: 240px"
/> />
</el-form-item> </el-form-item>
<el-form-item label="项目类型" prop="itemType">
<el-select v-model="queryParams.itemType" style="width: 240px">
<el-option
v-for="dict in jc_item_type"
:key="dict.value"
:label="dict.label"
:value="dict.value"
></el-option>
</el-select>
</el-form-item>
<el-form-item label="后台关闭" prop="isClose">
<el-select v-model="queryParams.isClose" style="width: 240px">
<el-option
v-for="dict in sys_yes_no"
:key="dict.value"
:label="dict.label"
:value="dict.value"
></el-option>
</el-select>
</el-form-item>
<el-form-item> <el-form-item>
<el-button type="primary" icon="Search" @click="handleQuery" <el-button type="primary" icon="Search" @click="handleQuery"
>搜索</el-button >搜索</el-button
@ -28,13 +49,14 @@
>新增</el-button >新增</el-button
> >
</el-col> </el-col>
<el-col :span="1.5"> <el-col :span="1.5">
<el-button type="success" plain icon="Edit" :disabled="single" <el-button
>修改</el-button type="danger"
> plain
</el-col> icon="Delete"
<el-col :span="1.5"> :disabled="multiple"
<el-button type="danger" plain icon="Delete" :disabled="multiple" @click="handlerDel"
>删除</el-button >删除</el-button
> >
</el-col> </el-col>
@ -42,9 +64,17 @@
<!-- v-loading="loading" --> <!-- v-loading="loading" -->
<el-table :data="roleList" @selection-change="handleSelectionChange"> <el-table :data="roleList" @selection-change="handleSelectionChange">
<el-table-column type="selection" width="55" align="center" /> <el-table-column type="selection" width="55" align="center" />
<el-table-column label="项目标题" prop="roleId" /> <el-table-column label="项目标题" prop="title" align="center" />
<el-table-column label="项目类型" prop="roleId" /> <el-table-column label="项目类型" prop="itemType" align="center">
<el-table-column label="后台是否关闭" prop="roleId" /> <template #default="scope">
<dict-tag :options="jc_item_type" :value="scope.row.itemType" />
</template>
</el-table-column>
<el-table-column label="后台关闭" prop="isClose" align="center">
<template #default="scope">
<dict-tag :options="sys_yes_no" :value="scope.row.isClose" />
</template>
</el-table-column>
<el-table-column <el-table-column
label="操作" label="操作"
align="center" align="center"
@ -52,27 +82,43 @@
> >
<template #default="scope"> <template #default="scope">
<el-tooltip content="修改" placement="top"> <el-tooltip content="修改" placement="top">
<el-button link type="primary" icon="Edit"></el-button> <el-button
link
type="primary"
icon="Edit"
@click="handlerUpdate(scope.row)"
></el-button>
</el-tooltip> </el-tooltip>
<el-tooltip content="删除" placement="top"> <el-tooltip content="删除" placement="top">
<el-button link type="primary" icon="Delete"></el-button> <el-button
</el-tooltip> link
<el-tooltip content="数据权限" placement="top"> type="primary"
<el-button link type="primary" icon="CircleCheck"></el-button> icon="Delete"
</el-tooltip> @click="handlerDel(scope.row)"
<el-tooltip content="分配用户" placement="top"> ></el-button>
<el-button link type="primary" icon="User"></el-button>
</el-tooltip> </el-tooltip>
</template> </template>
</el-table-column> </el-table-column>
</el-table> </el-table>
<pagination
v-show="total > 0"
:total="total"
v-model:page="queryParams.pageNum"
v-model:limit="queryParams.pageSize"
@pagination="getListData"
/>
<!-- 添加或修改对话框 --> <!-- 添加或修改对话框 -->
<el-dialog :title="title" v-model="open" :rules="rules" width="800px"> <el-dialog :title="title" v-model="open" width="800px">
<el-form ref="ruleFormRef" :model="form" label-width="100px"> <el-form
ref="ruleFormRef"
:model="form"
:rules="rules"
label-width="100px"
>
<el-row> <el-row>
<el-col :span="12"> <el-col :span="12">
<el-form-item label="项目类型"> <el-form-item label="项目类型" prop="itemType">
<el-select v-model="form.itemType"> <el-select v-model="form.itemType">
<el-option <el-option
v-for="dict in jc_item_type" v-for="dict in jc_item_type"
@ -84,15 +130,15 @@
</el-form-item> </el-form-item>
</el-col> </el-col>
<el-col :span="12"> <el-col :span="12">
<el-form-item label="项目标题"> <el-form-item label="项目标题" prop="title">
<el-input v-model="form.title" placeholder="请输入项目标题" /> <el-input v-model="form.title" placeholder="请输入项目标题" />
</el-form-item> </el-form-item>
</el-col> </el-col>
</el-row> </el-row>
<el-row> <el-row>
<el-col :span="12"> <el-col :span="12">
<el-form-item label="技术点"> <el-form-item label="技术点" prop="technology">
<el-select v-model="form.technology"> <el-select v-model="form.technology" multiple collapse-tags>
<el-option <el-option
v-for="dict in jc_technology" v-for="dict in jc_technology"
:key="dict.value" :key="dict.value"
@ -103,7 +149,7 @@
</el-form-item> </el-form-item>
</el-col> </el-col>
<el-col :span="12"> <el-col :span="12">
<el-form-item label="后台关闭"> <el-form-item label="后台关闭" prop="isClose">
<el-select v-model="form.isClose"> <el-select v-model="form.isClose">
<el-option <el-option
v-for="dict in sys_yes_no" v-for="dict in sys_yes_no"
@ -120,8 +166,9 @@
label="项目集合(例如xxx项目的APP/pc/大屏端)" label="项目集合(例如xxx项目的APP/pc/大屏端)"
class="block-form" class="block-form"
label-width="300px" label-width="300px"
prop="itemJson"
> >
<FormTable @childSub="childSub"></FormTable> <FormTable v-model="form.itemJson"></FormTable>
</el-form-item> </el-form-item>
</el-form> </el-form>
<template #footer> <template #footer>
@ -137,6 +184,7 @@
<script setup> <script setup>
import { ref, reactive, onMounted } from "vue"; import { ref, reactive, onMounted } from "vue";
import FormTable from "./table.vue"; import FormTable from "./table.vue";
import { getList, add, del, updata, getInfo } from "@/api/jichuang/model.js";
const { proxy } = getCurrentInstance(); const { proxy } = getCurrentInstance();
const { jc_technology, jc_item_type, sys_yes_no } = proxy.useDict( const { jc_technology, jc_item_type, sys_yes_no } = proxy.useDict(
"jc_technology", "jc_technology",
@ -144,7 +192,7 @@ const { jc_technology, jc_item_type, sys_yes_no } = proxy.useDict(
"sys_yes_no" "sys_yes_no"
); );
const showSearch = ref(true); const showSearch = ref(true);
const single = ref(true);
const multiple = ref(true); const multiple = ref(true);
const loading = ref(true); const loading = ref(true);
const roleList = ref([]); const roleList = ref([]);
@ -160,37 +208,141 @@ const data = reactive({
pageNum: 1, pageNum: 1,
pageSize: 10, pageSize: 10,
}, },
rules: {}, rules: {
itemType: [
{
required: true,
message: "请选择项目类型",
trigger: "change",
},
],
title: [
{
required: true,
message: "请输入项目标题",
trigger: "blur",
},
],
technology: [
{
required: true,
message: "请选择技术点",
trigger: "change",
},
],
isClose: [
{
required: true,
message: "请选择后台是否关闭",
trigger: "change",
},
],
itemJson: [
{
required: true,
message: "请输入项目集合",
trigger: "change",
},
],
},
}); });
const { queryParams, form, rules } = toRefs(data); const { queryParams, form, rules } = toRefs(data);
onMounted(() => {
getListData();
});
// //
const handleAdd = () => { const handleAdd = () => {
reset();
open.value = true; open.value = true;
title.value = "新增案例"; title.value = "新增案例";
}; };
//
const childSub = (e) => { const handlerUpdate = async (row) => {
console.log(e); reset();
//
const info = await getInfo(row.id);
title.value = "修改案例";
info.data.technology = info.data.technology.split(",");
info.data.itemJson = JSON.parse(info.data.itemJson);
form.value = info.data;
open.value = true;
};
//
const handlerDel = (row) => {
const idlist = row.id || ids.value;
proxy.$modal
.confirm('是否确认删除编号为"' + idlist + '"的数据项?')
.then(function () {
return del(idlist);
})
.then(() => {
getListData();
proxy.$modal.msgSuccess("删除成功");
})
.catch(() => {});
};
//
const cancelDataScope = () => {
open.value = false;
}; };
const cancelDataScope = () => {}; const getListData = async () => {
loading.value = true;
const response = await getList(queryParams.value);
roleList.value = response.rows;
total.value = response.total;
loading.value = false;
};
// //
const submitDataScope = () => { const submitDataScope = async () => {
console.log(form.value, "提交数据"); proxy.$refs["ruleFormRef"].validate(async (valid) => {
form.value.technology = form.value.technology.toString();
form.value.itemJson = JSON.stringify(form.value.itemJson);
if (valid) {
if (form.value.id) {
await updata(form.value);
try {
proxy.$modal.msgSuccess("修改成功");
open.value = false;
getListData();
} catch {
form.value.technology = form.value.technology.split(",");
form.value.itemJson = JSON.parse(form.value.itemJson);
}
} else {
await add(form.value);
try {
proxy.$modal.msgSuccess("新增成功");
open.value = false;
getListData();
} catch {
form.value.technology = form.value.technology.split(",");
form.value.itemJson = JSON.parse(form.value.itemJson);
}
}
}
});
}; };
function handleQuery() { function handleQuery() {
queryParams.value.pageNum = 1; queryParams.value.pageNum = 1;
getListData();
} }
function resetQuery() { function resetQuery() {
proxy.resetForm("queryRef");
handleQuery(); handleQuery();
} }
function reset() {
form.value = {
technology: [],
};
proxy.resetForm("ruleFormRef");
}
function handleSelectionChange(selection) { function handleSelectionChange(selection) {
ids.value = selection.map((item) => item.roleId); ids.value = selection.map((item) => item.id);
single.value = selection.length != 1;
multiple.value = !selection.length; multiple.value = !selection.length;
} }
</script> </script>

@ -9,8 +9,24 @@
</el-row> </el-row>
<el-table :data="itemGather"> <el-table :data="itemGather">
<el-table-column label="序号" type="index" align="center" width="100" /> <el-table-column label="序号" type="index" align="center" width="100" />
<el-table-column label="封面" prop="cover" align="center" /> <el-table-column label="封面" prop="cover" align="center">
<template #default="scope">
<el-image
style="width: 100px; height: 100px"
:src="baseUrl + scope.row.cover"
fit="cover"
/>
</template>
</el-table-column>
<el-table-column label="项目端" prop="name" align="center" /> <el-table-column label="项目端" prop="name" align="center" />
<el-table-column label="项目链接" align="center" show-overflow-tooltip>
<template #default="scope">
<el-link type="primary" :href="scope.row.link" target="_blank">{{
scope.row.link
}}</el-link>
</template>
</el-table-column>
<el-table-column <el-table-column
label="操作" label="操作"
align="center" align="center"
@ -40,7 +56,7 @@
<el-dialog <el-dialog
v-model="innerVisible" v-model="innerVisible"
width="800px" width="800px"
title="新增项目集合" :title="title"
append-to-body append-to-body
> >
<el-form ref="formTable" :model="form" :rules="rules" label-width="100px"> <el-form ref="formTable" :model="form" :rules="rules" label-width="100px">
@ -48,11 +64,19 @@
<el-input v-model="form.name" /> <el-input v-model="form.name" />
</el-form-item> </el-form-item>
<el-form-item label="封面"> <el-form-item label="封面" prop="cover">
<ImageUpload v-model="form.cover" :limit="1"></ImageUpload> <ImageUpload v-model="form.cover" :limit="1"></ImageUpload>
</el-form-item> </el-form-item>
<el-form-item label="项目链接" prop="link">
<el-input v-model="form.link" />
</el-form-item>
<el-form-item label="录屏"> <el-form-item label="录屏">
<FileUpload v-model="form.video" :limit="1"></FileUpload> <FileUpload
v-model="form.video"
:limit="1"
:fileSize="40"
:fileType="['mp4', 'wmv']"
></FileUpload>
</el-form-item> </el-form-item>
<el-form-item label="账号"> <el-form-item label="账号">
<div <div
@ -96,7 +120,7 @@
<script setup> <script setup>
import { ref, reactive, onMounted } from "vue"; import { ref, reactive, onMounted } from "vue";
const { proxy } = getCurrentInstance(); const { proxy } = getCurrentInstance();
let $emit = defineEmits(["childSub"]); let $emit = defineEmits();
import { v4 as uuidv4 } from "uuid"; import { v4 as uuidv4 } from "uuid";
const data = reactive({ const data = reactive({
form: {}, form: {},
@ -115,13 +139,39 @@ const data = reactive({
trigger: "change", trigger: "change",
}, },
], ],
link: [
{
required: true,
message: "请填写项目链接",
trigger: "blur",
},
],
}, },
formListJson: [{ userName: "", passWord: "" }], formListJson: [{ userName: "", passWord: "" }],
}); });
let title = ref("");
const { form, rules, formListJson } = toRefs(data); const { form, rules, formListJson } = toRefs(data);
const props = defineProps({
modelValue: [Array],
});
let itemGather = reactive([]); let itemGather = reactive([]);
let innerVisible = ref(false); let innerVisible = ref(false);
const baseUrl = import.meta.env.VITE_APP_BASE_API;
watch(
() => props.modelValue,
(val) => {
if (val) {
//
const list = Array.isArray(val) ? val : [];
itemGather = list;
} else {
return [];
}
},
{ deep: true, immediate: true }
);
const addUserandPass = () => { const addUserandPass = () => {
formListJson.value.push({ userName: "", passWord: "" }); formListJson.value.push({ userName: "", passWord: "" });
}; };
@ -132,6 +182,7 @@ const closeUserandPass = (index) => {
const handleUpdate = (row) => { const handleUpdate = (row) => {
form.value = row; form.value = row;
formListJson.value = form.value.userData; formListJson.value = form.value.userData;
title.value = "修改项目集合";
innerVisible.value = true; innerVisible.value = true;
}; };
@ -159,7 +210,8 @@ const submitDataScope = () => {
itemGather.push(form.value); itemGather.push(form.value);
} }
innerVisible.value = false; innerVisible.value = false;
$emit("childSub", itemGather);
$emit("update:modelValue", itemGather);
} }
}); });
}; };
@ -169,6 +221,7 @@ const cancelDataScope = () => {
const handlerAdd = () => { const handlerAdd = () => {
form.value = {}; form.value = {};
formListJson.value = [{ userName: "", passWord: "" }]; formListJson.value = [{ userName: "", passWord: "" }];
title.value = "新增项目集合";
innerVisible.value = true; innerVisible.value = true;
}; };
</script> </script>

@ -37,11 +37,6 @@ export default defineConfig(({ mode, command }) => {
rewrite: (p) => p.replace(/^\/dev-api/, ""), rewrite: (p) => p.replace(/^\/dev-api/, ""),
}, },
}, },
headers: {
// 目的是为了消除浏览器报错: SharedArrayBufferis not defined
"Cross-Origin-Opener-Policy": "same-origin",
"Cross-Origin-Embedder-Policy": "require-corp",
},
}, },
//fix:error:stdin>:7356:1: warning: "@charset" must be the first rule in the file //fix:error:stdin>:7356:1: warning: "@charset" must be the first rule in the file
css: { css: {

Loading…
Cancel
Save