案例管理模块

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

@ -7,14 +7,35 @@
:inline="true"
label-width="68px"
>
<el-form-item label="项目标题" prop="roleName">
<el-form-item label="项目标题" prop="title">
<el-input
v-model="queryParams.roleName"
v-model="queryParams.title"
placeholder="请输入项目标题"
clearable
style="width: 240px"
/>
</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-button type="primary" icon="Search" @click="handleQuery"
>搜索</el-button
@ -28,13 +49,14 @@
>新增</el-button
>
</el-col>
<el-col :span="1.5">
<el-button type="success" plain icon="Edit" :disabled="single"
>修改</el-button
>
</el-col>
<el-col :span="1.5">
<el-button type="danger" plain icon="Delete" :disabled="multiple"
<el-button
type="danger"
plain
icon="Delete"
:disabled="multiple"
@click="handlerDel"
>删除</el-button
>
</el-col>
@ -42,9 +64,17 @@
<!-- v-loading="loading" -->
<el-table :data="roleList" @selection-change="handleSelectionChange">
<el-table-column type="selection" width="55" align="center" />
<el-table-column label="项目标题" prop="roleId" />
<el-table-column label="项目类型" prop="roleId" />
<el-table-column label="后台是否关闭" prop="roleId" />
<el-table-column label="项目标题" prop="title" align="center" />
<el-table-column label="项目类型" prop="itemType" align="center">
<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
label="操作"
align="center"
@ -52,27 +82,43 @@
>
<template #default="scope">
<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 content="删除" placement="top">
<el-button link type="primary" icon="Delete"></el-button>
</el-tooltip>
<el-tooltip content="数据权限" placement="top">
<el-button link type="primary" icon="CircleCheck"></el-button>
</el-tooltip>
<el-tooltip content="分配用户" placement="top">
<el-button link type="primary" icon="User"></el-button>
<el-button
link
type="primary"
icon="Delete"
@click="handlerDel(scope.row)"
></el-button>
</el-tooltip>
</template>
</el-table-column>
</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-form ref="ruleFormRef" :model="form" label-width="100px">
<el-dialog :title="title" v-model="open" width="800px">
<el-form
ref="ruleFormRef"
:model="form"
:rules="rules"
label-width="100px"
>
<el-row>
<el-col :span="12">
<el-form-item label="项目类型">
<el-form-item label="项目类型" prop="itemType">
<el-select v-model="form.itemType">
<el-option
v-for="dict in jc_item_type"
@ -84,15 +130,15 @@
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="项目标题">
<el-form-item label="项目标题" prop="title">
<el-input v-model="form.title" placeholder="请输入项目标题" />
</el-form-item>
</el-col>
</el-row>
<el-row>
<el-col :span="12">
<el-form-item label="技术点">
<el-select v-model="form.technology">
<el-form-item label="技术点" prop="technology">
<el-select v-model="form.technology" multiple collapse-tags>
<el-option
v-for="dict in jc_technology"
:key="dict.value"
@ -103,7 +149,7 @@
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="后台关闭">
<el-form-item label="后台关闭" prop="isClose">
<el-select v-model="form.isClose">
<el-option
v-for="dict in sys_yes_no"
@ -120,8 +166,9 @@
label="项目集合(例如xxx项目的APP/pc/大屏端)"
class="block-form"
label-width="300px"
prop="itemJson"
>
<FormTable @childSub="childSub"></FormTable>
<FormTable v-model="form.itemJson"></FormTable>
</el-form-item>
</el-form>
<template #footer>
@ -137,6 +184,7 @@
<script setup>
import { ref, reactive, onMounted } from "vue";
import FormTable from "./table.vue";
import { getList, add, del, updata, getInfo } from "@/api/jichuang/model.js";
const { proxy } = getCurrentInstance();
const { jc_technology, jc_item_type, sys_yes_no } = proxy.useDict(
"jc_technology",
@ -144,7 +192,7 @@ const { jc_technology, jc_item_type, sys_yes_no } = proxy.useDict(
"sys_yes_no"
);
const showSearch = ref(true);
const single = ref(true);
const multiple = ref(true);
const loading = ref(true);
const roleList = ref([]);
@ -160,37 +208,141 @@ const data = reactive({
pageNum: 1,
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);
onMounted(() => {
getListData();
});
//
const handleAdd = () => {
reset();
open.value = true;
title.value = "新增案例";
};
const childSub = (e) => {
console.log(e);
//
const handlerUpdate = async (row) => {
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 = () => {
console.log(form.value, "提交数据");
const submitDataScope = async () => {
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() {
queryParams.value.pageNum = 1;
getListData();
}
function resetQuery() {
proxy.resetForm("queryRef");
handleQuery();
}
function reset() {
form.value = {
technology: [],
};
proxy.resetForm("ruleFormRef");
}
function handleSelectionChange(selection) {
ids.value = selection.map((item) => item.roleId);
single.value = selection.length != 1;
ids.value = selection.map((item) => item.id);
multiple.value = !selection.length;
}
</script>

@ -9,8 +9,24 @@
</el-row>
<el-table :data="itemGather">
<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="项目链接" 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
label="操作"
align="center"
@ -40,7 +56,7 @@
<el-dialog
v-model="innerVisible"
width="800px"
title="新增项目集合"
:title="title"
append-to-body
>
<el-form ref="formTable" :model="form" :rules="rules" label-width="100px">
@ -48,11 +64,19 @@
<el-input v-model="form.name" />
</el-form-item>
<el-form-item label="封面">
<el-form-item label="封面" prop="cover">
<ImageUpload v-model="form.cover" :limit="1"></ImageUpload>
</el-form-item>
<el-form-item label="项目链接" prop="link">
<el-input v-model="form.link" />
</el-form-item>
<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 label="账号">
<div
@ -96,7 +120,7 @@
<script setup>
import { ref, reactive, onMounted } from "vue";
const { proxy } = getCurrentInstance();
let $emit = defineEmits(["childSub"]);
let $emit = defineEmits();
import { v4 as uuidv4 } from "uuid";
const data = reactive({
form: {},
@ -115,13 +139,39 @@ const data = reactive({
trigger: "change",
},
],
link: [
{
required: true,
message: "请填写项目链接",
trigger: "blur",
},
],
},
formListJson: [{ userName: "", passWord: "" }],
});
let title = ref("");
const { form, rules, formListJson } = toRefs(data);
const props = defineProps({
modelValue: [Array],
});
let itemGather = reactive([]);
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 = () => {
formListJson.value.push({ userName: "", passWord: "" });
};
@ -132,6 +182,7 @@ const closeUserandPass = (index) => {
const handleUpdate = (row) => {
form.value = row;
formListJson.value = form.value.userData;
title.value = "修改项目集合";
innerVisible.value = true;
};
@ -159,7 +210,8 @@ const submitDataScope = () => {
itemGather.push(form.value);
}
innerVisible.value = false;
$emit("childSub", itemGather);
$emit("update:modelValue", itemGather);
}
});
};
@ -169,6 +221,7 @@ const cancelDataScope = () => {
const handlerAdd = () => {
form.value = {};
formListJson.value = [{ userName: "", passWord: "" }];
title.value = "新增项目集合";
innerVisible.value = true;
};
</script>

@ -37,11 +37,6 @@ export default defineConfig(({ mode, command }) => {
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
css: {

Loading…
Cancel
Save