532 lines
11 KiB
Vue
532 lines
11 KiB
Vue
<style scoped>
|
||
.n-card {
|
||
max-width: 350px;
|
||
height: 280px;
|
||
margin: auto;
|
||
}
|
||
.n-card .name {
|
||
font-size: large;
|
||
float: left;
|
||
}
|
||
.n-card .pay {
|
||
font-size: large;
|
||
color: red;
|
||
float: right;
|
||
}
|
||
@media screen and (min-width: 200px) and (max-width: 1200px) {
|
||
.n-card-box {
|
||
max-width: 100%;
|
||
height: 50%;
|
||
margin: auto;
|
||
}
|
||
}
|
||
@media screen and (min-width: 1200px) {
|
||
.n-card-box {
|
||
max-width: 50%;
|
||
height: 50%;
|
||
margin: auto;
|
||
}
|
||
}
|
||
.n-card-box .name {
|
||
font-size: large;
|
||
float: left;
|
||
}
|
||
.n-card-box .pay {
|
||
font-size: large;
|
||
color: red;
|
||
float: right;
|
||
}
|
||
</style>
|
||
<template>
|
||
<div style="width: 90%; margin: 10px auto">
|
||
<n-grid y-gap="20" x-gap="10" cols="1 200:2 600:4">
|
||
<n-gi span="1">
|
||
<n-select
|
||
placeholder="区域"
|
||
class="selection"
|
||
v-model:value="select_area"
|
||
:options="options_area"
|
||
@update:value="GetJob"
|
||
/>
|
||
</n-gi>
|
||
<n-gi span="1">
|
||
<n-select
|
||
placeholder="时间"
|
||
max-tag-count="responsive"
|
||
class="selection"
|
||
v-model:value="select_time"
|
||
:options="options_time"
|
||
@update:value="GetJob"
|
||
/>
|
||
</n-gi>
|
||
<n-gi span="1">
|
||
<n-select
|
||
placeholder="类型"
|
||
class="selection"
|
||
v-model:value="select_type"
|
||
:options="options_type"
|
||
@update:value="GetJob"
|
||
/>
|
||
</n-gi>
|
||
<n-gi span="1">
|
||
<n-select
|
||
placeholder="时薪"
|
||
class="selection"
|
||
v-model:value="select_pay"
|
||
:options="options_pay"
|
||
@update:value="GetJob"
|
||
/>
|
||
</n-gi>
|
||
<!--数据表格-->
|
||
</n-grid>
|
||
<n-grid y-gap="20" style="margin: 20px 0" x-gap="10" cols="1 200:2 600:9">
|
||
<n-gi span="2">
|
||
<div>
|
||
<n-select
|
||
placeholder="最大行数"
|
||
style="float: left; margin-right: 10px; width: 50%"
|
||
v-model:value="maxrows"
|
||
:options="rows"
|
||
/>
|
||
<n-button type="error" @click="deleteMany">删除选中</n-button>
|
||
</div>
|
||
</n-gi>
|
||
<n-gi span="6" style="float: left">
|
||
<div>
|
||
<n-auto-complete
|
||
:style="{ float: 'left', width: '75%', padding: '4px' }"
|
||
type="text"
|
||
placeholder="搜索兼职名称、id"
|
||
>
|
||
</n-auto-complete>
|
||
<n-button
|
||
:style="{ float: 'left', margin: '4px 10px' }"
|
||
strong
|
||
secondary
|
||
circle
|
||
type="info"
|
||
>
|
||
<template #icon>
|
||
<n-icon><Search /></n-icon>
|
||
</template>
|
||
</n-button>
|
||
</div>
|
||
</n-gi>
|
||
<n-gi span="1">
|
||
<CreateBox @create="GetJob" />
|
||
</n-gi>
|
||
</n-grid>
|
||
|
||
<n-data-table
|
||
:single-line="false"
|
||
:style="{ margin: '10px auto' }"
|
||
:columns="columns"
|
||
:data="data"
|
||
:row-key="rowKey"
|
||
:pagination="{ pageSize: maxrows }"
|
||
@update:checked-row-keys="tableSelect"
|
||
:bordered="true"
|
||
:row-props="rowProps"
|
||
/>
|
||
</div>
|
||
<n-dropdown
|
||
placement="bottom-start"
|
||
trigger="manual"
|
||
:x="xRef"
|
||
:y="yRef"
|
||
:options="options"
|
||
:show="showDropdownRef"
|
||
:on-clickoutside="onClickoutside"
|
||
@select="handleSelect"
|
||
/>
|
||
<n-modal v-model:show="showModal">
|
||
<n-card
|
||
style="width: 600px"
|
||
:title="select?.name"
|
||
preset="card"
|
||
size="huge"
|
||
role="dialog"
|
||
aria-modal="true"
|
||
class="n-card-box"
|
||
>
|
||
<template #header-extra>
|
||
<text class="pay">{{ select?.data.pay }}¥/天</text>
|
||
</template>
|
||
<template #default>
|
||
<p v-html="select?.data.desc"></p>
|
||
</template>
|
||
<template #cover>
|
||
<n-image
|
||
object-fit="contain"
|
||
:src="select?.data.img"
|
||
preview-disabled
|
||
lazy
|
||
/>
|
||
</template>
|
||
<template #footer>
|
||
工作时间:{{ select?.data.time }}
|
||
<n-button
|
||
type="error"
|
||
style="float: right"
|
||
@click="showModal = false"
|
||
ghost
|
||
round
|
||
>关闭</n-button
|
||
>
|
||
</template>
|
||
</n-card>
|
||
</n-modal>
|
||
</template>
|
||
|
||
<script setup lang="ts">
|
||
import type { DataTableColumns, DataTableRowKey } from "naive-ui";
|
||
import { useMessage, NButton, NIcon, NCard } from "naive-ui";
|
||
import { defineComponent, h, ref, nextTick, type VNodeChild } from "vue";
|
||
import { Search, CloseCircleOutline } from "@vicons/ionicons5";
|
||
import type { Job, Respoense } from "@/types";
|
||
import CreateBox from "./CreateBox.vue";
|
||
import UpdateBox from "./UpdateBox.vue";
|
||
//筛选器
|
||
|
||
const config = useRuntimeConfig();
|
||
const select_area = ref("");
|
||
const select_time = ref("");
|
||
const select_type = ref("");
|
||
const select_pay = ref(0);
|
||
const options_area = ref([
|
||
{
|
||
label: "全部",
|
||
value: "",
|
||
disabled: false,
|
||
},
|
||
{
|
||
label: "校内",
|
||
value: "in",
|
||
disabled: false,
|
||
},
|
||
{
|
||
label: "校外",
|
||
value: "out",
|
||
},
|
||
]);
|
||
const options_time = ref([
|
||
{
|
||
label: "全天",
|
||
value: "",
|
||
disabled: false,
|
||
},
|
||
{
|
||
label: "中午",
|
||
value: "noon",
|
||
disabled: false,
|
||
},
|
||
{
|
||
label: "上午",
|
||
value: "moning",
|
||
disabled: false,
|
||
},
|
||
{
|
||
label: "下午",
|
||
value: "afnon",
|
||
disabled: false,
|
||
},
|
||
{
|
||
label: "晚上",
|
||
value: "night",
|
||
},
|
||
]);
|
||
const options_type = ref([
|
||
{
|
||
label: "全部",
|
||
value: "",
|
||
disabled: false,
|
||
},
|
||
{
|
||
label: "室内",
|
||
value: "in",
|
||
disabled: false,
|
||
},
|
||
{
|
||
label: "室外",
|
||
value: "out",
|
||
},
|
||
]);
|
||
const options_pay = ref([
|
||
{
|
||
label: "全部",
|
||
value: 0,
|
||
disabled: false,
|
||
},
|
||
{
|
||
label: ">50¥/D",
|
||
value: 50,
|
||
disabled: false,
|
||
},
|
||
{
|
||
label: ">100¥/D",
|
||
value: 100,
|
||
},
|
||
]);
|
||
//数据表格
|
||
const options = [
|
||
{
|
||
label: () => h("span", { style: { color: "gray" } }, "查看"),
|
||
key: "view",
|
||
},
|
||
{
|
||
label: () => h("span", { style: { color: "green" } }, "编辑"),
|
||
key: "edit",
|
||
},
|
||
{
|
||
label: () => h("span", { style: { color: "red" } }, "删除"),
|
||
key: "delete",
|
||
},
|
||
];
|
||
const showModal = ref(false);
|
||
const message = useMessage();
|
||
const showDropdownRef = ref(false);
|
||
const xRef = ref(0);
|
||
const yRef = ref(0);
|
||
const select = ref<Job>();
|
||
function handleSelect(value: string) {
|
||
showDropdownRef.value = false;
|
||
message.success(value + ":" + select.value?.name);
|
||
if ((value = "view")) {
|
||
showModal.value = true;
|
||
}
|
||
}
|
||
function onClickoutside() {
|
||
showDropdownRef.value = false;
|
||
}
|
||
function rowProps(row: Job) {
|
||
return {
|
||
onContextmenu: (e: MouseEvent) => {
|
||
e.preventDefault();
|
||
showDropdownRef.value = false;
|
||
nextTick().then(() => {
|
||
showDropdownRef.value = true;
|
||
xRef.value = e.clientX;
|
||
yRef.value = e.clientY;
|
||
select.value = row;
|
||
});
|
||
},
|
||
};
|
||
}
|
||
function deleteMany() {
|
||
checkedRowKeys.value.forEach(async (RowKey) => {
|
||
const row = RowKey.toString();
|
||
const result: string = await $fetch("/api/job/delete", {
|
||
method: "post",
|
||
body: {
|
||
id: row,
|
||
},
|
||
});
|
||
const res = JSON.parse(result);
|
||
if (res.code) {
|
||
message.info("Deleted " + RowKey + " " + res.status);
|
||
GetJob();
|
||
} else {
|
||
message.error("Faild delete" + row + ".Because " + res.reason);
|
||
}
|
||
});
|
||
}
|
||
const maxrows = ref(10);
|
||
const rows = ref([
|
||
{
|
||
label: "10行",
|
||
value: 10,
|
||
},
|
||
{
|
||
label: "30行",
|
||
value: 30,
|
||
},
|
||
{
|
||
label: "50行",
|
||
value: 50,
|
||
},
|
||
{
|
||
label: "100行",
|
||
value: 100,
|
||
},
|
||
{
|
||
label: "1000行",
|
||
value: 1000,
|
||
},
|
||
]);
|
||
const checkedRowKeysRef = ref<DataTableRowKey[]>([]);
|
||
const checkedRowKeys = checkedRowKeysRef;
|
||
function rowKey(row: Job) {
|
||
return row.id;
|
||
}
|
||
function tableSelect(rowKeys: DataTableRowKey[]) {
|
||
checkedRowKeysRef.value = rowKeys;
|
||
}
|
||
const columns = [
|
||
{
|
||
type: "selection",
|
||
},
|
||
{
|
||
title: "id",
|
||
key: "id",
|
||
align: "center",
|
||
},
|
||
{
|
||
title: "兼职名称",
|
||
key: "name",
|
||
align: "center",
|
||
},
|
||
{
|
||
title: "创建时间",
|
||
key: "createTime",
|
||
align: "center",
|
||
},
|
||
{
|
||
title: "更新时间",
|
||
key: "updateTime",
|
||
align: "center",
|
||
},
|
||
{
|
||
title: "操作",
|
||
key: "actions",
|
||
align: "center",
|
||
width: "20%",
|
||
render(row: Job) {
|
||
return [
|
||
/* h(
|
||
NButton,
|
||
{
|
||
style: "margin: auto 1%;",
|
||
type: "info",
|
||
size: "medium",
|
||
onClick: () => {
|
||
alert(JSON.stringify(row));
|
||
},
|
||
},
|
||
{ default: () => "查看" }
|
||
),*/
|
||
h(
|
||
NButton,
|
||
{
|
||
style: "margin: auto 1%;",
|
||
type: "info",
|
||
size: "medium",
|
||
onClick: () => {
|
||
select.value = row;
|
||
showModal.value = true;
|
||
},
|
||
},
|
||
{ default: () => "查看" }
|
||
),
|
||
h(UpdateBox, {
|
||
Job: row,
|
||
onChanged: () => {
|
||
GetJob();
|
||
},
|
||
}),
|
||
h(
|
||
NButton,
|
||
{
|
||
style: "margin: auto 1%;",
|
||
type: "primary",
|
||
size: "medium",
|
||
onClick: async () => {
|
||
const result: string = await $fetch("/api/job/pin", {
|
||
method: "post",
|
||
body: {
|
||
id: row.id,
|
||
},
|
||
});
|
||
const res = JSON.parse(result);
|
||
if (res.code) {
|
||
if (row.pin) {
|
||
message.success(
|
||
"Unpin " +
|
||
row.id +
|
||
" " +
|
||
res.status +
|
||
" .Now is " +
|
||
res.job.pin
|
||
);
|
||
} else {
|
||
message.success(
|
||
"Pin " +
|
||
row.id +
|
||
" " +
|
||
res.status +
|
||
" .Now is " +
|
||
res.job.pin
|
||
);
|
||
}
|
||
|
||
GetJob();
|
||
} else {
|
||
message.error("Faild" + row.name + ".Because " + res);
|
||
}
|
||
},
|
||
},
|
||
{
|
||
default: () => {
|
||
if (row.pin) {
|
||
return "取置";
|
||
} else {
|
||
return "置顶";
|
||
}
|
||
},
|
||
}
|
||
),
|
||
h(
|
||
NButton,
|
||
{
|
||
style: "margin: auto 1%;",
|
||
type: "error",
|
||
size: "medium",
|
||
onClick: async () => {
|
||
const result: string = await $fetch("api/job/delete", {
|
||
method: "post",
|
||
body: {
|
||
id: row.id,
|
||
},
|
||
});
|
||
const res = JSON.parse(result);
|
||
if (res.code) {
|
||
message.info("Deleted " + row.name + " " + res.status);
|
||
GetJob();
|
||
} else {
|
||
message.error("Faild delete" + row.name + ".Because " + res);
|
||
}
|
||
},
|
||
},
|
||
{ default: () => "删除" }
|
||
),
|
||
];
|
||
},
|
||
},
|
||
];
|
||
|
||
const Jobs: string = await $fetch(
|
||
"/api/job?area=" +
|
||
select_area.value +
|
||
"&type=" +
|
||
select_type.value +
|
||
"&time=" +
|
||
select_time.value +
|
||
"&pay=" +
|
||
select_pay.value
|
||
);
|
||
async function GetJob() {
|
||
const Jobs: string = await $fetch(
|
||
"/api/job?area=" +
|
||
select_area.value +
|
||
"&type=" +
|
||
select_type.value +
|
||
"&time=" +
|
||
select_time.value +
|
||
"&pay=" +
|
||
select_pay.value
|
||
);
|
||
job.value = JSON.parse(Jobs);
|
||
}
|
||
const job = ref(JSON.parse(Jobs));
|
||
const data = job;
|
||
</script>
|