pms-aomei/src/views/atomViews/ListView.vue

562 lines
16 KiB
Vue
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<!-- 表格页加上搜索条件 -->
<template>
<div class="list-view">
<el-row>
<a
style="
margin: 0 0 16px 0;
color: #0b58ff;
display: flex;
align-items: center;
text-decoration: none;
cursor: pointer;
"
title="返回上一页"
@click.prevent="$router.go(-1)">
<span style="margin-right: 6px">
<svg
xmlns="http://www.w3.org/2000/svg"
fill="none"
viewBox="0 0 24 24"
stroke-width="1.5"
stroke="currentColor"
class="w-6 h-6">
<path stroke-linecap="round" stroke-linejoin="round" d="M9 15L3 9m0 0l6-6M3 9h12a6 6 0 010 12h-3" />
</svg>
</span>
<span style="line-height: 24px">返回</span>
</a>
</el-row>
<BaseListTable
v-loading="tableLoading"
:table-config="tableConfig.table"
:column-config="tableConfig.column"
:table-data="dataList"
@operate-event="handleOperate"
:current-page="page"
:current-size="size"
:refresh-layout-key="refreshLayoutKey" />
<el-pagination
class="mt-5 flex justify-end"
@size-change="handleSizeChange"
@current-change="handlePageChange"
:current-page.sync="page"
:page-sizes="[10, 20, 50, 100]"
:page-size="size"
:total="totalPage"
layout="total, sizes, prev, pager, next, jumper"></el-pagination>
<!-- :current-page.sync="currentPage"
:page-size.sync="pageSize" -->
<DialogWithMenu
ref="edit-dialog"
v-if="!!dialogConfigs && dialogType === DIALOG_WITH_MENU"
:dialog-visible.sync="dialogVisible"
:configs="dialogConfigs"
@refreshDataList="getList" />
<DialogJustForm
ref="edit-dialog"
v-if="!!dialogConfigs && dialogType === DIALOG_JUST_FORM"
:dialog-visible.sync="dialogVisible"
:configs="dialogConfigs"
@refreshDataList="getList" />
<Overlay v-if="overlayVisible" />
</div>
</template>
<script>
import BaseListTable from "@/components/BaseListTable.vue";
import DialogWithMenu from "@/components/DialogWithMenu.vue";
import DialogJustForm from "@/components/DialogJustForm.vue";
import Overlay from "@/components/Overlay.vue";
import moment from "moment";
const DIALOG_WITH_MENU = "DialogWithMenu";
const DIALOG_JUST_FORM = "DialogJustForm";
export default {
name: "ListView",
components: { BaseListTable, DialogWithMenu, DialogJustForm, Overlay },
props: {
tableConfig: {
type: Object,
default: () => ({
/** 列配置, 即 props **/ column: [],
/** 表格整体配置 */ table: undefined,
}),
},
/** 请求page接口的时候有些字段是必填的没有会报500把相关字段名传入这个prop: */
listQueryExtra: {
type: Array,
default: () => ["key"],
},
attachListQueryExtra: {
// 新增时,附带 listQueryExtra 里的哪些键和对应值
type: String,
default: "",
},
initDataWhenLoad: { type: Boolean, default: true },
/** dialog configs 或许可以从 tableConfig 计算出来 computed... */
dialogConfigs: {
type: Object,
default: () => null,
},
triggerUpdate: {
type: String,
default: "",
},
},
computed: {
dialogType() {
return this.dialogConfigs.menu ? DIALOG_WITH_MENU : DIALOG_JUST_FORM;
},
},
activated() {
console.log("list view with ehad activated..........");
this.refreshLayoutKey = this.layoutTable();
},
watch: {
triggerUpdate(val, oldVal) {
if (val && val !== oldVal) {
// get list
this.getList();
}
},
},
data() {
return {
DIALOG_WITH_MENU,
DIALOG_JUST_FORM,
dialogVisible: false,
topBtnConfig: null,
totalPage: 100,
page: 1,
size: 20, // 默认20
dataList: [],
tableLoading: false,
refreshLayoutKey: null,
overlayVisible: false,
};
},
inject: ["urls"],
mounted() {
this.initDataWhenLoad && this.getList();
},
methods: {
/** 获取 列表数据 */
getList(queryParams) {
this.tableLoading = true;
const params = queryParams
? { ...queryParams, page: this.page, limit: this.size }
: {
page: this.page,
limit: this.size,
};
if (!queryParams && this.listQueryExtra && this.listQueryExtra.length) {
this.listQueryExtra.map((nameOrObj) => {
if (typeof nameOrObj === "string") params[nameOrObj] = "";
else if (typeof nameOrObj === "object") {
Object.keys(nameOrObj).forEach((key) => {
params[key] = nameOrObj[key];
});
}
});
}
// if (this.urls.pageIsPostApi) {
// } else {
// 默认是 get 方式请求 page
this.$http[this.urls.pageIsPostApi ? "post" : "get"](
this.urls.page,
this.urls.pageIsPostApi
? {
...params,
}
: {
params,
}
)
.then(({ data: res }) => {
console.log("[http response] res is: ", res);
if (res.code === 0) {
// page 场景:
if ("list" in res.data) {
/** 破碎记录的特殊需求:数据要结合单位 material + materialUnitDictValue */
if ("attachDictValue" in this.tableConfig.column) {
this.dataList = res.data.list.map((row) => {
this.tableConfig.column.attachDictValue(row, "unit", "qty", "materialUnitDictValue");
return row;
});
} else this.dataList = res.data.list;
this.totalPage = res.data.total;
} else if ("records" in res.data) {
this.dataList = res.data.records.map((item) => ({
...item,
id: item._id ?? item.id,
}));
this.totalPage = res.data.total;
} else {
this.dataList.splice(0);
this.totalPage = 0;
}
} else {
this.$message({
message: `${res.code}: ${res.msg}`,
type: "error",
duration: 2000,
});
}
this.tableLoading = false;
})
.catch((err) => {
this.$message({
message: `${err}`,
type: "error",
duration: 2000,
});
this.tableLoading = false;
});
// }
},
layoutTable() {
return Math.random();
},
/** 处理 表格操作 */
handleOperate({ type, data }) {
console.log("payload", type, data);
// 编辑、删除、跳转路由、打开弹窗动态component都可以在配置里加上 url
// payload: { type: string, data: string | number | object }
switch (type) {
case "delete": {
let hintMsg = "name" in data ? `确定要删除记录 "${data.name}" 吗?` : "确定删除该记录?";
let currenPageListLength = this.dataList.length;
// 确认是否删除
return this.$confirm(hintMsg, "提示", {
confirmButtonText: "确认",
cancelButtonText: "我再想想",
type: "warning",
})
.then(() => {
// this.$http.delete(this.urls.base + `/${data}`).then((res) => {
this.$http({
url: this.urls.base,
method: "DELETE",
data: [`${data.id}`],
}).then(({ data: res }) => {
if (res.code === 0) {
this.$message.success("删除成功!");
// this.page = 1;
// this.size = 10;
if (currenPageListLength == 1) this.page = this.page > 1 ? this.page - 1 : 1;
this.getList();
} else {
this.$message({
message: `${res.code}: ${res.msg}`,
type: "error",
duration: 1500,
});
}
});
})
.catch((err) => {});
}
case "edit": {
this.openDialog(data); /** data is ==> id */
break;
}
case "view":
case "view-detail-action": {
this.openDialog(data, true);
break;
}
case "view-blender-batch-details": {
this.$router.push({
name: "pms-blenderBatchDetails",
query: {
batchId: data,
},
});
break;
}
case "status": {
console.log("status", data);
// TODO: 类似于这种字符串,可以统一集中到一个文件里
const { id, code } = data;
const queryCondition = { id, code };
if ("enabled" in data) queryCondition.enabled = data["enabled"];
if ("status" in data) queryCondition.status = data["status"];
// 更改状态,更改状态需要 id 和 code 然后是 状态 enabled
this.$http.put(this.urls.base, queryCondition).then(({ data: res }) => {
if (res.code === 0) {
// do nothing
} else {
this.$message({
message: `${res.code}: ${res.msg}`,
type: "error",
duration: 1500,
});
}
});
break;
}
case "view-attachment": {
this.openDialog(data, false, { key: "attachment" });
break;
}
case "view-recipe": {
this.openDialog(data, true, { key: "attr" });
break;
}
case "to-bom-detail": {
// console.log('to-bom-detail', data.name)
// 查看配方详情
return this.$router.push({
name: "pms-bomDetails",
query: {
name: data.name,
},
});
}
case "copy": {
return this.$http
.post(this.urls.copyUrl, data, {
headers: {
"Content-Type": "application/json",
},
})
.then(({ data: res }) => {
if (res.code === 0) {
this.$message({
message: "复制成功!",
type: "success",
duration: 1500,
});
this.getList();
} else {
this.$message({
message: `${res.code}: ${res.msg}`,
type: "error",
duration: 1500,
});
}
})
.catch((errMsg) => {
this.$message({
message: errMsg,
type: "error",
duration: 1500,
});
});
}
case "change-category": {
return this.$http.put(this.urls.base, data).then(({ data: res }) => {
if (res.code === 0) {
this.$message({
message: "修改成功",
type: "success",
duration: 1500,
onClose: () => {
this.getList();
},
});
} else {
this.$message({
message: `${res.code}: ${res.msg}`,
type: "error",
duration: 1500,
});
}
});
}
case "preview": {
console.log("[PREVIEW] data", data);
// report preview
return this.$router.push({
name: "pms-reportPreview",
query: {
name: data.name,
},
});
}
case "design": {
console.log("[DESIGN] data", data);
// report design
return this.$router.push({
name: "pms-reportDesign",
query: {
name: data.name,
},
});
}
case "detach": {
return this.$http
.post(this.urls.detach, data /* { id: data } */, { headers: { "Content-Type": "application/json" } })
.then(({ data: res }) => {
if (res.code === 0) {
this.$message({
message: "下发成功",
type: "success",
duration: 1500,
onClose: () => {
this.getList();
},
});
} else {
this.$message({
message: `${res.code}: ${res.msg}`,
type: "error",
duration: 1500,
});
}
});
}
case "sync": {
let shouldShowOverlay = false;
let payload = "";
console.log("sync...", type, data);
if (typeof data === "object") {
const head = data.head;
const syncOpt =
("options" in head && Array.isArray(head.options) && head.options.find((item) => item.name === "sync")) ||
null;
if (syncOpt && "showOverlay" in syncOpt && syncOpt.showOverlay) {
this.overlayVisible = true;
shouldShowOverlay = true;
payload = data.id;
}
} else payload = data;
this.$message({
message: "正在发起同步...",
type: "success",
});
// 同步单个料仓数据
this.$http
.post(this.urls.syncSingleUrl, payload, {
headers: {
"Content-Type": "application/json",
},
})
.then(({ data: res }) => {
this.$message({
message: res.msg,
type: res.code === 0 ? "success" : "error",
});
this.getList();
if (shouldShowOverlay) this.overlayVisible = false;
});
}
}
},
handleBtnClick({ btnName, payload }) {
console.log("[search] form handleBtnClick", btnName, payload);
switch (btnName) {
case "新增":
this.openDialog();
break;
case "查询": {
const params = {};
/** 处理 payload 里的数据 */
if (typeof payload === "object") {
// BaseSearchForm 给这个组件传递了数据
Object.assign(params, payload);
if ("timerange" in params && !!params.timerange) {
const [startTime, endTime] = params["timerange"];
delete params.timerange;
params.startTime = moment(startTime).format("YYYY-MM-DD HH:mm:ss");
params.endTime = moment(endTime).format("YYYY-MM-DD HH:mm:ss");
}
}
/** 处理 listQueryExtra 里的数据 */
this.listQueryExtra?.map((cond) => {
if (typeof cond === "string") {
if (!!payload[cond]) {
params[cond] = payload[cond];
} else {
params[cond] = "";
}
} else if (typeof cond === "object") {
Object.keys(cond).forEach((key) => {
params[key] = cond[key];
});
}
});
console.log("查询", params);
this.getList(params);
break;
}
case "同步":
this.$http.post(this.urls.syncUrl).then(({ data: res }) => {
if (res.code === 0) {
this.getList();
}
});
break;
}
},
/** 导航器的操作 */
handleSizeChange(val) {
// val 是新值
this.page = 1;
this.size = val;
this.getList();
},
handlePageChange(val) {
// val 是新值
this.getList();
},
/** 打开对话框 */
openDialog(row_id, detail_mode, tag_info) {
this.dialogVisible = true;
let extraParams = null;
if (this.attachListQueryExtra && this.listQueryExtra.length) {
this.listQueryExtra.forEach((item) => {
let found = item[this.attachListQueryExtra];
if (found !== null && found !== undefined) extraParams = item;
});
}
this.$nextTick(() => {
console.log(`[edit-dialog] extraParams: ${extraParams}`);
this.$refs["edit-dialog"].init(/** some args... */ row_id, detail_mode, tag_info, extraParams);
});
},
},
};
</script>
<style scoped>
.list-view {
background: white;
/* height: 100%; */
min-height: inherit;
border-radius: 6px;
padding: 16px;
box-shadow: 0 0 1.125px 0.125px rgba(0, 0, 0, 0.125);
}
.w-6 {
width: 16px;
}
.h-6 {
height: 16px;
}
</style>