fix: 重写耗材模块

This commit is contained in:
2025-03-07 18:53:31 +08:00
parent 73057865da
commit 739f4a1062
67 changed files with 3610 additions and 1563 deletions

View File

@@ -48,6 +48,7 @@
"exceljs": "^4.4.0",
"js-cookie": "^3.0.5",
"jsencrypt": "^3.3.2",
"lodash": "^4.17.21",
"lodash-es": "^4.17.21",
"mitt": "^3.0.1",
"nprogress": "^0.2.0",

View File

@@ -1,104 +1,99 @@
// 代客下单
import request from "@/utils/request-php";
import { getToken } from '@/utils/auth'
import { getToken } from "@/utils/auth";
import { useUserStore } from "@/store";
const userStore = useUserStore();
function getLoginName() {
const obj = localStorage.getItem("userInfo") || '';
const { username } = obj ? JSON.parse(obj) : {};
return username
return userStore.userInfo.phone;
}
// 抖音团购核销准备
export function $douyin_fulfilmentcertificateprepare(data) {
return request({
url: 'douyin/fulfilmentcertificateprepare',
method: "post",
data: {
...data
}
});
return request({
url: "douyin/fulfilmentcertificateprepare",
method: "post",
data: {
...data,
},
});
}
// 抖音团购核销
export function $douyin_certificateprepare(data) {
return request({
url: 'douyin/certificateprepare',
method: "post",
data: {
...data
}
});
return request({
url: "douyin/certificateprepare",
method: "post",
data: {
...data,
},
});
}
// 抖音团购核销撤销
export function $douyin_fulfilmentcertificatecancel(data) {
return request({
url: 'douyin/fulfilmentcertificatecancel',
method: "post",
data: {
...data
}
});
return request({
url: "douyin/fulfilmentcertificatecancel",
method: "post",
data: {
...data,
},
});
}
// 抖音团购核销记录
export function $douyin_orderlist(data) {
return request({
url: 'douyin/orderlist',
method: "post",
data: {
...data
}
});
return request({
url: "douyin/orderlist",
method: "post",
data: {
...data,
},
});
}
// 抖音门店列表
export function $douyin_storelist(data) {
return request({
url: 'douyin/storelist',
method: "post",
data: {
...data
}
});
return request({
url: "douyin/storelist",
method: "post",
data: {
...data,
},
});
}
// 抖音绑定门店
export function $douyin_bindstore(data) {
return request({
url: 'douyin/bindstore',
method: "post",
data: {
...data
}
});
return request({
url: "douyin/bindstore",
method: "post",
data: {
...data,
},
});
}
// 抖音订单查询
export function $douyin_orderquery(data) {
return request({
url: 'douyin/orderquery',
method: "post",
data: {
...data
}
});
return request({
url: "douyin/orderquery",
method: "post",
data: {
...data,
},
});
}
//会员签入
export function $douyin_checkIn(data) {
return request({
url: 'douyin/checkIn',
method: "post",
data: {
clientType: 'ADMIN',
token: getToken(),
loginName: getLoginName(),
...data
}
});
return request({
url: "douyin/checkIn",
method: "post",
data: {
clientType: "ADMIN",
token: getToken(),
loginName: getLoginName(),
...data,
},
});
}
//美团
@@ -106,100 +101,89 @@ export function $douyin_checkIn(data) {
// 美团获取uisdk 绑定 链接
export function $meituan_getuisdkurl(data) {
return request({
url: 'meituan/getuisdkurl',
method: "post",
data: {
...data
}
});
return request({
url: "meituan/getuisdkurl",
method: "post",
data: {
...data,
},
});
}
// 美团获取uisdk 解绑 链接
export function $meituan_getuisdkuniurl(data) {
return request({
url: 'meituan/getuisdkuniurl',
method: "post",
data: {
...data
}
});
return request({
url: "meituan/getuisdkuniurl",
method: "post",
data: {
...data,
},
});
}
// 美团团购核销准备
export function $meituan_fulfilmentcertificateprepare(data) {
return request({
url: 'meituan/fulfilmentcertificateprepare',
method: "post",
data: {
...data
}
});
return request({
url: "meituan/fulfilmentcertificateprepare",
method: "post",
data: {
...data,
},
});
}
// 美团执行核销
export function $meituan_certificateprepare(data) {
return request({
url: 'meituan/certificateprepare',
method: "post",
data: {
...data
}
});
return request({
url: "meituan/certificateprepare",
method: "post",
data: {
...data,
},
});
}
// 美团团购核销记录
export function $meituan_orderlist(data) {
return request({
url: 'meituan/orderlist',
method: "post",
data: {
...data
}
});
return request({
url: "meituan/orderlist",
method: "post",
data: {
...data,
},
});
}
// 美团团购撤销
export function $meituan_fulfilmentcertificatecancel(data) {
return request({
url: 'meituan/fulfilmentcertificatecancel',
method: "post",
data: {
...data
}
});
return request({
url: "meituan/fulfilmentcertificatecancel",
method: "post",
data: {
...data,
},
});
}
// 美团查询绑定状态
export function $meituan_searchstorestatus(data) {
return request({
url: 'meituan/searchstorestatus',
method: "post",
data: {
...data
}
});
return request({
url: "meituan/searchstorestatus",
method: "post",
data: {
...data,
},
});
}
// 登出
export function $logout(data) {
return request({
url: 'user/logout',
method: "post",
data: {
...data
}
});
return request({
url: "user/logout",
method: "post",
data: {
...data,
},
});
}

View File

@@ -0,0 +1,58 @@
import request from "@/utils/request";
import { Product_BaseUrl } from "@/api/config";
const baseURL = Product_BaseUrl + "/admin/product/cons-group";
const Api = {
/** 分页*/
getList(params: any) {
return request<any>({
url: `${baseURL}/page`,
method: "get",
params,
});
},
/** 全部*/
getAllList(params: any) {
return request<any>({
url: `${baseURL}/list`,
method: "get",
params,
});
},
get(id: string | number) {
return request<any>({
url: `${baseURL}/` + id,
method: "get",
});
},
add(data: any) {
return request<any>({
url: `${baseURL}`,
method: "post",
data
});
},
edit(data: any) {
return request<any>({
url: `${baseURL}`,
method: "put",
data
});
},
disable(id: number | string) {
return request<any>({
url: `${baseURL}/disable/` + id,
method: "post",
});
},
enable(id: number | string) {
return request<any>({
url: `${baseURL}/enable/` + id,
method: "post",
});
},
};
export default Api;

70
src/api/product/cons.ts Normal file
View File

@@ -0,0 +1,70 @@
import request from "@/utils/request";
import { Product_BaseUrl } from "@/api/config";
const baseURL = Product_BaseUrl + "/admin/product/cons";
const Api = {
/** 分页*/
getList(params: any) {
return request<any>({
url: `${baseURL}/page`,
method: "get",
params,
});
},
/** 全部*/
getAllList(params: any) {
return request<any>({
url: `${baseURL}/list`,
method: "get",
params,
});
},
get(id: string | number) {
return request<any>({
url: `${baseURL}/` + id,
method: "get",
});
},
add(data: any) {
return request<any>({
url: `${baseURL}`,
method: "post",
data
});
},
edit(data: any) {
return request<any>({
url: `${baseURL}`,
method: "put",
data
});
},
disable(id: number | string) {
return request<any>({
url: `${baseURL}/disable/` + id,
method: "post",
});
},
enable(id: number | string) {
return request<any>({
url: `${baseURL}/enable/` + id,
method: "post",
});
},
onOff(id: number | string) {
return request<any>({
url: `${baseURL}/on-off/`,
method: "post",
});
},
modifySubUnit(id: number | string) {
return request<any>({
url: `${baseURL}/modifySubUnit`,
method: "post",
});
},
};
export default Api;

51
src/api/product/stock.ts Normal file
View File

@@ -0,0 +1,51 @@
import request from "@/utils/request";
import { Product_BaseUrl } from "@/api/config";
const baseURL = Product_BaseUrl + "/admin/product/stock";
// 耗材
const Api = {
/** 耗材入库*/
in(data: any) {
return request<any>({
url: `${baseURL}/in`,
method: "post",
data
});
},
//出库
out(data: any) {
return request<any>({
url: `${baseURL}/out`,
method: "post",
data
});
},
// 库存盘点记录
checkRecord(params: any) {
return request<any>({
url: `${baseURL}/check-record`,
method: "get",
params
});
},
//库存盘点
check(data: any) {
return request<any>({
url: `${baseURL}/check`,
method: "post",
data
});
},
//耗材报损
reportDamage(data: any) {
return request<any>({
url: `${baseURL}/reportDamage`,
method: "post",
data
});
},
};
export default Api;

53
src/api/product/vendor.ts Normal file
View File

@@ -0,0 +1,53 @@
import request from "@/utils/request";
import { Product_BaseUrl } from "@/api/config";
const baseURL = Product_BaseUrl + "/admin/product/vendor";
// 供应商
const Api = {
/** 分页*/
getList(params: any) {
return request<any>({
url: `${baseURL}/page`,
method: "get",
params,
});
},
/** 全部*/
getAllList(params: any) {
return request<any>({
url: `${baseURL}/list`,
method: "get",
params,
});
},
get(id: string | number) {
return request<any>({
url: `${baseURL}/` + id,
method: "get",
});
},
add(data: any) {
return request<any>({
url: `${baseURL}`,
method: "post",
data
});
},
edit(data: any) {
return request<any>({
url: `${baseURL}`,
method: "put",
data
});
},
delete(id: string | number) {
return request<any>({
url: `${baseURL}/` + id,
method: "delete",
});
},
};
export default Api;

View File

@@ -545,17 +545,17 @@ export const constantRoutes: RouteRecordRaw[] = [
children: [
{
path: "consumables",
component: () => import("@/views/inventory/consumables.vue"),
component: () => import("@/views/inventory/consumables/index.vue"),
name: "consumables",
meta: {
title: "耗材列表",
affix: false,
keepAlive: true,
},
},
{
path: "supplier",
component: () => import("@/views/inventory/supplier.vue"),
component: () => import("@/views/inventory/supplier/index.vue"),
name: "supplier",
meta: {
title: "供应商管理",
@@ -564,23 +564,35 @@ export const constantRoutes: RouteRecordRaw[] = [
},
},
{
path: "paymentRecord",
component: () => import("@/views/inventory/paymentRecord.vue"),
name: "paymentRecord",
path: "operation_in",
component: () => import("@/views/inventory/operation_in/index.vue"),
name: "operation_in",
meta: {
title: "结款记录",
title: "入库",
affix: false,
hidden: true
},
},
{
path: "paymentRecord",
component: () => import("@/views/inventory/payment-record.vue"),
name: "paymentRecord",
meta: {
title: "结款记录",
affix: false,
hidden: true,
},
},
{
path: "classification",
component: () => import("@/views/inventory/classification.vue"),
component: () => import("@/views/inventory/classification/index.vue"),
name: "classification",
meta: {
title: "分类管理",
affix: false,
hidden: true
hidden: true,
},
},

View File

@@ -412,6 +412,7 @@ export const useCartsStore = defineStore("carts", () => {
detailMap: returnDetailMap(data.detailMap)
}
}
/**
*
* @param initParams 购物车初始化参数
@@ -428,9 +429,12 @@ export const useCartsStore = defineStore("carts", () => {
setOldOrder($oldOrder)
}
console.log('oldOrder.detailMap', oldOrder.value.detailMap)
table_code.value = initParams && initParams.table_code ? initParams.table_code : '';
// console.log('oldOrder.detailMap', oldOrder.value.detailMap)
// const cache_table_code = localStorage.getItem('cache_table_code');
// const randomTableCode = cache_table_code ? cache_table_code : ('APC' + (1000 + Math.floor(Math.random() * 9000)))
initParams.table_code = initParams.table_code ? initParams.table_code : ''
table_code.value = initParams.table_code
// localStorage.setItem('cache_table_code', table_code.value);
WebSocketManager.subscribeToTopic(initParams, (msg) => {
console.log("收到消息:", msg);
@@ -444,6 +448,10 @@ export const useCartsStore = defineStore("carts", () => {
if (msg.data.table_code) {
table_code.value = table_code.value ? table_code.value : msg.data.table_code
}
if (msg.table_code) {
table_code.value = table_code.value ? table_code.value : msg.table_code
}
}

View File

@@ -34,11 +34,9 @@ export const usePermissionStore = defineStore("permission", () => {
if (!isTest) {
const dynamicRoutes = parseDynamicRoutes(data.filter(v => v.type == 0));
routes.value = [...constantRoutes, ...dynamicRoutes];
console.log(routes.value);
isRoutesLoaded.value = true;
resolve(dynamicRoutes);
} else {
isRoutesLoaded.value = true;
resolve(constantRoutes);
}

163
src/utils/limits.js Normal file
View File

@@ -0,0 +1,163 @@
import { ElMessage } from "element-plus";
function getHasPermission() {
return true;
}
const userInfo = JSON.parse(localStorage.getItem("userInfo"));
const $PermissionObj = {
data: [
{
key: "yun_xu_cha_kan_jing_ying_shu_ju",
text: "允许查看经营数据",
},
{
key: "yun_xu_cha_kan_suo_you_jiao_ban_ji_lu",
text: "允许查看所有交班记录",
},
],
default: [
{
key: "yun_xu_xia_dan",
text: "允许下单",
},
{
key: "yun_xu_shou_kuan",
text: "允许收款",
},
{
key: "yun_xu_tui_kuan",
text: "允许退款",
},
{
key: "yun_xu_jiao_ban",
text: "允许交班",
},
],
goods: [
{
key: "yun_xu_xiu_gai_shang_pin",
text: "允许修改商品",
},
{
key: "yun_xu_shang_xia_jia_shang_pin",
text: "允许上下架商品",
},
{
key: "yun_xu_xiu_gai_fen_lei",
text: "允许修改分类",
},
{
key: "yun_xu_xiu_gai_fen_zu",
text: "允许修改分组",
},
],
discount: [
{
key: "yun_xu_da_zhe",
text: "允许打折",
},
],
vip: [
{
key: "yun_xu_guan_li_hui_yuan_xin_xi",
text: "允许管理会员信息",
},
{
key: "yun_xu_xiu_gai_hui_yuan_yu_e",
text: "允许修改会员余额",
},
],
stock: [
{
text: "允许提交报损",
key: "yun_xu_ti_jiao_bao_sun",
},
{
text: "允许沽清",
key: "yun_xu_gu_qing",
},
{
text: "允许售罄商品",
key: "yun_xu_shou_qing_shang_pin",
},
{
text: "允许修改商品库存",
key: "yun_xu_xiu_gai_shang_pin_ku_cun",
},
{
text: "允许耗材入库",
key: "yun_xu_hao_cai_ru_ku",
},
{
text: "允许耗材出库",
key: "yun_xu_hao_cai_chu_ku",
},
{
text: "允许耗材盘点",
key: "yun_xu_hao_cai_pan_dian",
},
],
};
export async function hasPermission(params) {
//如果是商户默认拥有全部权限
const loginType = localStorage.getItem("loginType");
if (loginType == "merchant") {
return true;
}
params = returnFormatParams(params);
if (!params) {
return ElMessage.error(
"未找到相关权限请检查代码或在权限配置文件commons/utils/hasPermission.js文件进行修改或增加"
);
}
const option = Object.assign(
{
tips: true,
key: "",
text: "",
},
params
);
const res = await getHasPermission({
userId: userInfo.id,
code: params.key,
});
if (!res && option.tips) {
ElMessage.error({
title: "您没有" + params.text + "权限!",
duration: 5000,
});
}
return res;
}
export function isObjectButNotArray(value) {
return typeof value === "object" && Array.isArray(value) === false;
}
export function findPermissionObj(str) {
for (let i in $PermissionObj) {
const obj = $PermissionObj[i].find((v) => v.key == str || v.text == str);
if (obj) {
return obj;
}
}
console.error(
"未找到相关权限配置请检查权限配置文件commons/utils/hasPermission.js文件进行修改或增加"
);
return false;
}
export function returnFormatParams(params) {
if (typeof params === "string") {
return findPermissionObj(params);
} else {
if (isObjectButNotArray(params)) {
const obj = findPermissionObj(params.key || params.text);
return { ...params, ...obj };
} else {
console.error("参数只能是字符串或者对象,不能是数组");
}
}
}

View File

@@ -4,7 +4,7 @@ import { getToken } from "@/utils/auth";
// 创建axios实例
const service = axios.create({
baseURL: "https://czgdoumei.sxczgkj.com/index.php/api/", // api 的 base_url
baseURL: "https://newblockwlx.sxczgkj.cn/index.php/api/", // api 的 base_url
timeout: 1000 * 20, // 请求超时时间
});

View File

@@ -17,6 +17,9 @@ const contentConfig: IContentConfig<editRequest> = {
indexAction: function (params) {
return VersionApi.getList();
},
modifyAction: function (data: any) {
return VersionApi.edit(data);
},
deleteAction: VersionApi.delete,
// modifyAction: function (data) {
// // return VersionApi.edit(data);

View File

@@ -1,16 +0,0 @@
<template>
<!-- 结款记录 -->
<div style="padding: 15px;">结款记录
<!-- 搜索 -->
<!-- <Search></Search> -->
<!-- 数据统计 -->
<!-- <DataStatistics></DataStatistics> -->
<!-- 表格 -->
<!-- <Content></Content> -->
</div>
</template>
<script setup>
import Search from './paymentRecordconfig/Search.vue'
import DataStatistics from './paymentRecordconfig/DataStatistics.vue'
import Content from './paymentRecordconfig/Content.vue'
</script>

View File

@@ -1,10 +0,0 @@
<template>
<!-- 分类模块 -->
<div style="padding: 15px;">
<!-- 表格 -->
<Content></Content>
</div>
</template>
<script setup>
import Content from './classification/Content.vue'
</script>

View File

@@ -1,157 +0,0 @@
<template>
<div class="Table">
<!-- 按钮 -->
<AddButton @add="add"></AddButton>
<!-- 表格 -->
<Table :list="datas.tableData" @handleDelete="handleDelete" @handleEdit="handleEdit"
@handleStatusChange="handleStatusChange"></Table>
<!-- 分页 -->
<Paging :pagingConfig="datas.pagingConfig" @sizeChange="sizeChange" @currentChange="currentChange"></Paging>
<!-- 其他模板 -->
<!-- 新增/编辑 -->
<myDialog ref="myDialogRef" :title="datas.title" @confirm="confirm" width="30%">
<el-form ref="ruleFormRef" :rules="datas.rules" :model="datas.DialogForm" label-width="120px">
<el-form-item label="耗材类型名称" prop="name">
<el-input v-model="datas.DialogForm.name" placeholder="请输入供应商名称" />
</el-form-item>
<el-form-item label="是否禁用">
<el-switch v-model="datas.DialogForm.status" :active-value="1" :inactive-value="0" active-color="#13ce66"
inactive-color="#ff4949" />
</el-form-item>
</el-form>
</myDialog>
</div>
</template>
<script setup>
import AddButton from './component/AddButton.vue'
import Table from './component/Table.vue'
import Paging from './component/Paging.vue'
import myDialog from '@/components/mycomponents/myDialog.vue'
import eventBus from '@/utils/eventBus'
import API from './api'
const datas = reactive({
tableData: [], // 表格数据
title: '新增数据',
pagingConfig: {
total: 0, // 总数
pageSize: 10, // 每页数据数量
pageNumber: 1, // 当前页码
},
DialogForm: { // 弹窗表单数据
status: 1
},
rules: {
name: [
{ required: true, message: '请输入供应商名称', trigger: 'blur' },
], switch: [
{ required: true, message: ' ', trigger: 'blur' },
],
}
})
const myDialogRef = ref(null)
const ruleFormRef = ref(null)
onMounted(() => {
getList()
})
eventBus.on('search', (res) => {
getList(res)
})
async function getList(data = {}) {
const res = await API.getPage({ page: datas.pagingConfig.pageNumber, size: datas.pagingConfig.pageSize, ...data })
datas.tableData = res.records
datas.pagingConfig.total = res.totalRow
datas.pagingConfig.pageSize = res.pageSize
datas.pagingConfig.pageNumber = res.pageNumber
}
function add() {
rest()
datas.title = '新增数据'
myDialogRef.value.open()
}
async function handleEdit(row) {
datas.title = '编辑数据'
const res = await API.getinfo(row.id)
datas.DialogForm = res
myDialogRef.value.open()
}
// 修改状态
async function handleStatusChange(row) {
let res = null
if (row.status == 1) {
res = await API.onOff(row.id)
} else {
res = await API.onOff2(row.id)
}
if (res.code == 200) {
getList()
ElMessage({
message: '成功',
type: 'success',
})
}
}
async function confirm() {
ruleFormRef.value.validate(async valid => {
if (valid) {
let res = null
if (datas.title == '新增数据') {
res = await API.add(datas.DialogForm)
} else {
res = await API.update(datas.DialogForm)
}
if (res.code == 200) {
ElMessage({
message: '成功',
type: 'success',
})
rest()
getList()
myDialogRef.value.close()
}
}
})
}
// 重置
function rest() {
datas.DialogForm = { sort: "1" }
}
async function handleDelete(id) {
ElMessageBox.confirm("是否删除数据项?", "提示", {
confirmButtonText: "确定",
cancelButtonText: "取消",
type: "warning",
}).then(
async () => {
let res = await API.deleteByIds(id)
if (res.code == 200) {
ElMessage({
message: '删除成功',
type: 'success',
})
getList()
}
}
);
}
// 分页
function sizeChange(val) {
datas.pagingConfig.pageSize = val
getList()
}
function currentChange(val) {
datas.pagingConfig.pageNumber = val
getList()
}
</script>
<style scoped lang="scss">
.Table {
padding: 20px;
background-color: #fff;
border: 1px solid #e4e7ed;
margin-top: 20px;
border-radius: 4px;
}
</style>

View File

@@ -1,73 +0,0 @@
import request from "@/utils/request";
const baseURL = "/product/admin/product/cons-group";
// 耗材-配置
const AuthAPI = {
// 列表
getList(params: any) {
return request<any, Responseres>({
url: `${baseURL}/list`,
method: "get",
params,
});
},
/** 分页*/
getPage(params: any) {
return request<any, Responseres>({
url: `${baseURL}/page`,
method: "get",
params,
});
},
// 新增
add(data: any) {
return request<any, Responseres>({
url: `${baseURL}`,
method: "post",
data: { ...data },
});
},
// 详情
getinfo(id: number) {
return request<any, Responseres>({
url: `${baseURL}/${id}`,
method: "get",
});
},
// 编辑
update(data: Object) {
return request<any, Responseres>({
url: `${baseURL}`,
method: "put",
data,
});
},
// 删除
deleteByIds(id: number | String) {
return request<any, Responseres>({
url: `${baseURL}/${id}`,
method: "delete",
});
},
// 修改状态-启用
onOff(id: number | String) {
return request<any, Responseres>({
url: `${baseURL}/enable/${id}`,
method: "post",
});
},
// 修改状态-禁用
onOff2(id: number | String) {
return request<any, Responseres>({
url: `${baseURL}/disable/${id}`,
method: "post",
});
}
};
export interface Responseres {
code?: number | null;
data?: any;
msg?: null | string;
[property: string]: any;
}
export default AuthAPI;

View File

@@ -1,11 +0,0 @@
<template>
<el-button type="primary" icon="Plus" @click="addEvent">新增</el-button>
</template>
<script setup>
import { useRouter } from 'vue-router';
const router = useRouter();
const emit = defineEmits(['add']);
function addEvent() {
emit('add');
}
</script>

View File

@@ -1,24 +0,0 @@
<template>
<div style="margin-top: 10px;">
<el-pagination background :page-size="props.pagingConfig.pageSize" :page-sizes="[10, 20, 30, 40]"
layout="prev,pager,next,jumper,total,sizes" v-model:current-page="props.pagingConfig.pageNumber"
:total="props.pagingConfig.total" @size-change="handleSizeChange" @current-change="handleCurrentChange" />
</div>
</template>
<script setup>
const props = defineProps({
pagingConfig: {
type: Object,
default: () => { }
}
})
const emit = defineEmits(['sizeChange', 'currentChange'])
// 当前条改变
function handleSizeChange(val) {
emit('sizeChange', val)
}
// 当前页改变
function handleCurrentChange(val) {
emit('currentChange', val)
}
</script>

View File

@@ -1,42 +0,0 @@
<template>
<div style="margin-top: 10px;">
<el-table :data="props.list" border style="width: 100%">
<el-table-column prop="id" align="center" label="ID" />
<el-table-column prop="name" align="center" label="耗材类型名称" />
<el-table-column prop="status" align="center" label="状态">
<template #default="scope">
<el-switch v-model="scope.row.status" :active-value="1" :inactive-value="0" active-color="#13ce66"
inactive-color="#ff4949" @change="handleStatusChange(scope.row)" />
</template>
</el-table-column>
<el-table-column label="操作" align="center">
<template #default="scope">
<el-button size="small" type="primary" link icon="Edit" @click="handleEdit(scope.row)">编辑</el-button>
<!-- <el-button size="small" type="danger" link icon="Delete" style="color: #f89797;"
@click="handleDelete(scope.$index, scope.row)"> 删除 </el-button> -->
</template>
</el-table-column>
</el-table>
</div>
</template>
<script setup>
const emit = defineEmits(['handleDelete', 'handleEdit', 'handleStatusChange'])
const props = defineProps({
list: {
type: Array,
default: () => []
}
})
function handleEdit(row) {
emit('handleEdit', row)
}
function handleDelete(index, row) {
emit('handleDelete', row.id)
}
function handleStatusChange(row) {
emit('handleStatusChange', row)
}
</script>

View File

@@ -0,0 +1,53 @@
import Api from "@/api/product/cons-group";
import { returnOptions, switchAttr } from "./config";
import type { IModalConfig } from "@/components/CURD/types";
const modalConfig: IModalConfig = {
pageName: "sys:user",
dialog: {
title: "添加耗材分类",
width: 800,
draggable: true,
},
form: {
labelWidth: 140,
},
formAction: function (data) {
return Api.add({ ...data });
},
beforeSubmit(data) {
console.log("提交之前处理", data);
},
formItems: [
{
label: "耗材类型名称",
prop: "name",
rules: [{ required: true, message: "请输入耗材类型名称", trigger: "blur" }],
attrs: {
placeholder: "请输入耗材类型名称",
},
},
{
type: "switch",
label: "是否启用",
prop: "status",
attrs: {
activeValue: 1,
inactiveValue: 0
},
col: {
xs: 24,
sm: 12,
},
initialValue: 0
},
],
};
// 如果有异步数据会修改配置的推荐用reactive包裹而纯静态配置的可以直接导出
export default reactive(modalConfig);

View File

@@ -0,0 +1,48 @@
export interface options {
label: string;
value: string | number;
[property: string]: any;
}
export interface optionObject {
[property: string]: options[];
}
const options: optionObject = {
payType: [
{ label: "现金", value: "cash" },
{ label: "微信", value: "weixin" },
{ label: "银行卡", value: "bank" },
{ label: "会员支付", value: "member-account" },
{ label: "支付宝", value: "alipay" },
{ label: "刷卡", value: "deposit" },
{ label: "挂单", value: "arrears" },
{ label: "刷卡", value: "deposit" },
{ label: "储值", value: "member-account" },
{ label: "自定义", value: "virtual" },
],
isIdeal: [
{ label: "否", value: 0 },
{ label: "是", value: 1 },
]
};
export const switchAttr = {
"active-value": 1,
"inactive-value": 0,
}
export type optionsType = string;
export function returnOptions(type: optionsType) {
return options[type];
}
export function returnOptionsLabel(optionsType: optionsType, value: string | number) {
const options = returnOptions(optionsType);
if (!options) {
return "";
}
const option = options.find((item) => item.value === value);
return option ? option.label : "";
}

View File

@@ -0,0 +1,57 @@
import Api from "@/api/product/cons-group";
import type { IContentConfig } from "@/components/CURD/types";
const contentConfig: IContentConfig = {
pageName: "sys:user",
table: {
border: true,
highlightCurrentRow: true,
},
pagination: {
background: true,
layout: "prev,pager,next,jumper,total,sizes",
pageSize: 20,
pageSizes: [10, 20, 30, 50],
},
indexAction: function (params) {
return Api.getList({});
},
modifyAction: function (data) {
return Api.edit(data);
},
pk: "id",
toolbar: ["add"],
defaultToolbar: ["refresh", "filter", "search"],
cols: [
// { type: "selection", width: 50, align: "center" },
{
label: "ID",
align: "center",
prop: "id",
},
{
label: "耗材类型名称",
align: "center",
prop: "name",
},
{
label: "状态",
align: "center",
prop: "status",
templet: 'custom',
slotName: 'switch'
},
{
label: "操作",
align: "center",
fixed: "right",
width: 280,
templet: "tool",
operat: ["edit"],
},
],
};
export default contentConfig;

View File

@@ -0,0 +1,53 @@
import Api from "@/api/product/cons-group";
import { returnOptions, switchAttr } from "./config";
import type { IModalConfig } from "@/components/CURD/types";
const modalConfig: IModalConfig = {
pageName: "sys:user",
dialog: {
title: "编辑耗材分类",
width: 800,
draggable: true,
},
form: {
labelWidth: 140,
},
formAction: function (data) {
return Api.edit({ ...data, });
},
beforeSubmit(data) {
console.log("提交之前处理", data);
},
formItems: [
{
label: "耗材类型名称",
prop: "name",
rules: [{ required: true, message: "请输入耗材类型名称", trigger: "blur" }],
attrs: {
placeholder: "请输入耗材类型名称",
},
},
{
type: "switch",
label: "是否启用",
prop: "status",
attrs: {
activeValue: 1,
inactiveValue: 0
},
col: {
xs: 24,
sm: 12,
},
initialValue: 0
},
],
};
// 如果有异步数据会修改配置的推荐用reactive包裹而纯静态配置的可以直接导出
export default reactive(modalConfig);

View File

@@ -0,0 +1,21 @@
import type { ISearchConfig } from "@/components/CURD/types";
const searchConfig: ISearchConfig = {
pageName: "sys:user",
formItems: [
{
type: "input",
label: "版本号",
prop: "keywords",
attrs: {
placeholder: "请输入版本号",
clearable: true,
style: {
width: "200px",
},
},
},
],
};
export default searchConfig;

View File

@@ -0,0 +1,115 @@
<template>
<div class="app-container">
<!-- 列表 -->
<!-- 搜索 -->
<!-- <page-search
ref="searchRef"
:search-config="searchConfig"
@query-click="handleQueryClick"
@reset-click="handleResetClick"
/> -->
<!-- 列表 -->
<page-content
ref="contentRef"
:content-config="contentConfig"
@add-click="handleAddClick"
@edit-click="handleEditClick"
@export-click="handleExportClick"
@search-click="handleSearchClick"
@toolbar-click="handleToolbarClick"
@operat-click="handleOperatClick"
@filter-change="handleFilterChange"
>
<template #status="scope">
<el-tag :type="scope.row[scope.prop] == 1 ? 'success' : 'info'">
{{ scope.row[scope.prop] == 1 ? "启用" : "禁用" }}
</el-tag>
</template>
<template #options="scope">
{{ returnOptionsLabel(scope.prop, scope.row[scope.prop]) }}
</template>
<template #switch="scope">
<el-switch
v-model="scope.row[scope.prop]"
disabled
:active-value="1"
:inactive-value="0"
></el-switch>
</template>
<template #mobile="scope">
<el-text>{{ scope.row[scope.prop] }}</el-text>
<copy-button
v-if="scope.row[scope.prop]"
:text="scope.row[scope.prop]"
style="margin-left: 2px"
/>
</template>
</page-content>
<!-- 新增 -->
<page-modal
ref="addModalRef"
:modal-config="addModalConfig"
@submit-click="handleSubmitClick"
></page-modal>
<!-- 编辑 -->
<page-modal
ref="editModalRef"
:modal-config="editModalConfig"
@submit-click="handleSubmitClick"
></page-modal>
</div>
</template>
<script setup lang="ts">
import VersionApi from "@/api/system/version";
import type { IObject, IOperatData } from "@/components/CURD/types";
import usePage from "@/components/CURD/usePage";
import addModalConfig from "./config/add";
import contentConfig from "./config/content";
import editModalConfig from "./config/edit";
import searchConfig from "./config/search";
import { returnOptionsLabel } from "./config/config";
const {
searchRef,
contentRef,
addModalRef,
editModalRef,
handleQueryClick,
handleResetClick,
// handleAddClick,
// handleEditClick,
handleSubmitClick,
handleExportClick,
handleSearchClick,
handleFilterChange,
} = usePage();
// 新增
async function handleAddClick() {
addModalRef.value?.setModalVisible();
// addModalConfig.formItems[2]!.attrs!.data =
}
// 编辑
async function handleEditClick(row: IObject) {
editModalRef.value?.handleDisabled(false);
editModalRef.value?.setModalVisible();
// 根据id获取数据进行填充
console.log(row);
editModalRef.value?.setFormData({ ...row });
}
1;
// 其他工具栏
function handleToolbarClick(name: string) {
console.log(name);
if (name === "custom1") {
ElMessage.success("点击了自定义1按钮");
}
}
// 其他操作列
async function handleOperatClick(data: IOperatData) {
console.log(data);
}
</script>

View File

@@ -1,16 +0,0 @@
<template>
<div style="padding: 15px;">
<!-- 搜索 -->
<Search></Search>
<!-- 数据统计 -->
<DataStatistics></DataStatistics>
<!-- 表格 -->
<Content></Content>
<!-- 其他内容 -->
</div>
</template>
<script setup>
import Search from './consumablesconfig/Search.vue'
import DataStatistics from './consumablesconfig/DataStatistics.vue'
import Content from './consumablesconfig/Content.vue'
</script>

View File

@@ -0,0 +1,197 @@
<template>
<!-- 修改和增加 -->
<el-dialog :title="dialogtitle" v-model="show" width="85%">
<div v-if="dialogtitle != '编辑'">
<div v-for="(item, index) in forms" :key="index">
<el-form
:inline="true"
:ref="(el) => setFormRef(el, index)"
:model="item"
:rules="rules"
class="demo-form-inline"
>
<el-form-item label=" ">
<el-icon color="red" @click="formsReduce(index)"><Remove /></el-icon>
</el-form-item>
<el-form-item label="耗材名称" prop="conName">
<el-input v-model="item.conName" placeholder="请输入耗材信息名称"></el-input>
</el-form-item>
<el-form-item label="耗材类型" prop="conTypeId">
<el-select v-model="item.conTypeId" placeholder="请选择耗材类型" style="width: 200px">
<el-option
v-for="option in consGroups"
:key="option.conTypeId"
:label="option.conTypeName"
:value="option.id"
></el-option>
</el-select>
</el-form-item>
<el-form-item label="单位" prop="conUnit">
<el-input v-model="item.conUnit" placeholder="请输入单位"></el-input>
</el-form-item>
<el-form-item label="耗材价格">
<el-input v-model="item.price" placeholder="请输入耗材价格"></el-input>
</el-form-item>
<el-form-item label="预警值">
<el-input v-model="item.conWarning" placeholder="请输入耗材预警值"></el-input>
</el-form-item>
<el-form-item label=" ">
<el-icon color="green" @click="formsAdd(index)"><CirclePlus /></el-icon>
</el-form-item>
</el-form>
</div>
<div style="display: flex; justify-content: flex-end">
<el-button @click="dialogshow = false"> </el-button>
<el-button type="primary" @click="submitForms()"> </el-button>
</div>
</div>
<el-form
v-else
:inline="true"
ref="refform"
:model="form"
:rules="rules"
class="demo-form-inline"
>
{{ dialogtitle }}
<el-form-item label="耗材信息名称" prop="conName">
<el-input v-model="form.conName" placeholder="请输入耗材信息名称"></el-input>
</el-form-item>
<el-form-item label="耗材价格">
<el-input v-model="form.price" placeholder="请输入耗材价格"></el-input>
</el-form-item>
<el-form-item label="单位" prop="conUnit">
<el-input v-model="form.conUnit" placeholder="请输入单位"></el-input>
</el-form-item>
<el-form-item label="预警值">
<el-input v-model="form.conWarning" placeholder="请输入耗材预警值"></el-input>
</el-form-item>
<!-- <el-form-item label="状态" v-if="dialogtitle == '编辑'">
<el-switch v-model="form.status" active-value="1" inactive-value="0"></el-switch>
</el-form-item> -->
<!-- <el-form-item label="单位耗材值" prop="surplusStock">
<el-input v-model="form.surplusStock" placeholder="请输入单位耗材值"></el-input>
</el-form-item> -->
<el-form-item style="display: flex; justify-content: flex-end">
<el-button @click="dialogshow = false"> </el-button>
<el-button type="primary" @click="submitForm('refform')"> </el-button>
</el-form-item>
</el-form>
</el-dialog>
</template>
<script setup>
import consApi from "@/api/product/cons";
import consGroupApi from "@/api/product/cons-group";
import { ElMessage } from "element-plus";
const consGroups = ref([]);
const rules = {
conCode: [{ required: true, message: "请输入耗材信息代码", trigger: "blur" }],
conName: [{ required: true, message: "请输入耗材信息名称", trigger: "blur" }],
conTypeId: [{ required: true, message: "请选择耗材类型", trigger: "change" }],
price: [{ required: true, message: "请输入耗材价格", trigger: "blur" }],
conWarning: [{ required: true, message: "请输入耗材预警值", trigger: "blur" }],
conTypeId: [{ required: true, message: "请输入耗材类型id", trigger: "blur" }],
conUnit: [{ required: true, message: "请输入单位", trigger: "blur" }],
conWarning: [
{
required: true,
message: "请输入单位",
trigger: "blur",
},
],
};
function getConsGroups() {
consGroupApi.getAllList().then((res) => {
consGroups.value = res.map((v) => {
return {
...v,
label: v.name,
value: v.id,
};
});
});
}
getConsGroups();
const basicForm = {
conCode: "",
conName: "",
conTypeId: "",
price: "0",
conNames: "",
conUnit: "",
conWarning: "999",
shopId: localStorage.getItem("shopId"),
status: "",
};
const forms = ref([{ ...basicForm }]);
const form = reactive({
...basicForm,
});
const show = ref(false);
let dialogtitle = ref("");
function open(item) {
dialogtitle.value = item ? "编辑" : "新增";
show.value = true;
}
function formsAdd(index) {
forms.value.push({ ...basicForm });
}
function close() {
show.value = false;
}
const refForms = ref([]);
function setFormRef(el, index) {
if (el) {
refForms.value[index] = el;
}
}
function returnPromise(index, prosise) {
return new Promise((resolve, reject) => {
prosise
.then((res) => {
console.log(res);
resolve({ sucees: true });
})
.catch((err) => {
console.log(err);
resolve({ sucees: false });
});
});
}
async function submitForms() {
let isAllPassForm = 0;
for (let i in this.forms) {
console.log(refForms.value[i]);
const res = await returnPromise(i, refForms.value[i].validate());
console.log(res);
isAllPassForm += res.sucees ? 1 : 0;
}
//判断验证是否通过
if (isAllPassForm === this.forms.length) {
await consApi.add(this.forms);
ElMessage({ type: "success", message: "添加成功" });
// for(let i of this.forms){
// const res=await posttbConsInfo(i)
// this.$message({ type: "success", message: "添加成功" });
// }
this.dialogshow = false;
this.resetRuleForms();
this.ruleFormLoading = false;
this.getTableData();
}
}
defineExpose({
open,
close,
});
</script>

View File

@@ -0,0 +1,177 @@
<template>
<!-- 修改和增加 -->
<el-dialog :title="dialogtitle" v-model="show" width="800px" @close="reset">
<el-form :inline="false" ref="refform" :model="form" :rules="rules" class="demo-form-inline">
<el-form-item label="耗材名称" prop="conName">
<el-input v-model="form.conName" placeholder="请输入耗材名称"></el-input>
</el-form-item>
<el-form-item label="耗材分类" prop="consGroupId">
<el-select v-model="form.consGroupId" placeholder="请选择耗材分类" style="width: 200px">
<el-option
v-for="option in consGroups"
:key="option.conTypeId"
:label="option.label"
:value="option.id"
></el-option>
</el-select>
</el-form-item>
<el-form-item label="耗材价格" prop="price">
<el-input v-model="form.price" placeholder="请输入耗材价格"></el-input>
</el-form-item>
<el-form-item label="库存">
<el-input v-model="form.stockNumber" placeholder="请输入库存值"></el-input>
</el-form-item>
<el-form-item label="状态">
<el-switch v-model="form.status" :active-value="1" :inactive-value="0"></el-switch>
</el-form-item>
<el-form-item label="单位" prop="conUnit">
<el-input v-model="form.conUnit" placeholder="请输入单位"></el-input>
</el-form-item>
<el-form-item label="预警值">
<el-input v-model="form.conWarning" placeholder="请输入耗材预警值"></el-input>
</el-form-item>
<el-form-item label="是否检测耗材">
<el-switch v-model="form.status" :active-value="1" :inactive-value="0"></el-switch>
</el-form-item>
<el-form-item label="第二单位" prop="conUnitTwo">
<el-input v-model="form.conUnitTwo" placeholder="请输入第二单位"></el-input>
</el-form-item>
<el-form-item label="第二单位转换数量" prop="conUnitTwoConvert">
<el-input-number
v-model="form.conUnitTwoConvert"
placeholder="第二单位转换数量"
></el-input-number>
</el-form-item>
<el-form-item label="默认入库单位" prop="defaultUnit">
<el-input v-model="form.defaultUnit" placeholder="请输入默认入库单位"></el-input>
</el-form-item>
<el-form-item style="display: flex; justify-content: flex-end">
<el-button @click="close"> </el-button>
<el-button type="primary" @click="submitForm('refform')"> </el-button>
</el-form-item>
</el-form>
</el-dialog>
</template>
<script setup>
import consApi from "@/api/product/cons";
import consGroupApi from "@/api/product/cons-group";
import { ElMessage } from "element-plus";
const consGroups = ref([]);
const rules = {
conName: [{ required: true, message: "请输入耗材名称", trigger: "blur" }],
consGroupId: [{ required: true, message: "请选择耗材类型", trigger: "change" }],
price: [{ required: true, message: "请输入耗材价格", trigger: "blur" }],
conWarning: [{ required: true, message: "请输入耗材预警值", trigger: "blur" }],
conUnit: [{ required: true, message: "请输入耗材单位", trigger: "blur" }],
conWarning: [
{
required: true,
message: "请输入单位",
trigger: "blur",
},
],
};
function getConsGroups() {
consGroupApi.getAllList().then((res) => {
consGroups.value = res.map((v) => {
return {
...v,
label: v.name,
value: v.id,
};
});
});
}
getConsGroups();
const basicForm = {
conName: "",
consGroupId: "",
conUnit: "",
price: "",
conWarning: "",
};
const forms = ref([{ ...basicForm }]);
const form = reactive({
...basicForm,
});
const show = ref(false);
let dialogtitle = ref("");
function open(item) {
dialogtitle.value = item ? "编辑" : "新增";
Object.assign(form, item);
show.value = true;
}
function formsAdd(index) {
forms.value.push({ ...basicForm });
}
function close() {
show.value = false;
}
const refform = ref();
const refForms = ref([]);
function setFormRef(el, index) {
if (el) {
refForms.value[index] = el;
}
}
function returnPromise(index, prosise) {
return new Promise((resolve, reject) => {
prosise
.then((res) => {
console.log(res);
resolve({ sucees: true });
})
.catch((err) => {
console.log(err);
resolve({ sucees: false });
});
});
}
const emits = defineEmits(["refresh"]);
async function submitForm() {
refform.value.validate(async (valid) => {
if (valid) {
const res =
dialogtitle.value == "新增" ? await consApi.add(this.form) : await consApi.edit(this.form);
ElMessage({ type: "success", message: dialogtitle.value + "成功" });
emits("refresh");
close();
}
});
}
async function submitForms() {
let isAllPassForm = 0;
for (let i in this.forms) {
console.log(refForms.value[i]);
const res = await returnPromise(i, refForms.value[i].validate());
console.log(res);
isAllPassForm += res.sucees ? 1 : 0;
}
//判断验证是否通过
if (isAllPassForm === this.forms.length) {
await consApi.add(this.forms);
ElMessage({ type: "success", message: "添加成功" });
// for(let i of this.forms){
// const res=await posttbConsInfo(i)
// this.$message({ type: "success", message: "添加成功" });
// }
this.dialogshow = false;
this.resetRuleForms();
this.ruleFormLoading = false;
this.getTableData();
}
}
function reset() {
form.value = { ...basicForm };
}
defineExpose({
open,
close,
});
</script>

View File

@@ -0,0 +1,240 @@
<!-- 耗材列表的新增耗材盘点 -->
<template>
<el-dialog title="耗材盘点" v-model="dialogVisible" width="80%">
<el-form ref="form" :model="form" :rules="rules" label-position="left" inline>
<el-form-item label="账存数量">
<el-input v-model="form.balance" readonly style="width: 180px"></el-input>
</el-form-item>
<el-form-item label="实际数量">
<el-input-number
v-model="form.stockNumber"
:min="0"
:step="1"
step-strictly
style="width: 180px"
></el-input-number>
</el-form-item>
<el-form-item label="盈亏数量">
<el-input
v-model="profitNumber"
readonly
:class="{ lose: profitNumber < 0 }"
style="width: 180px"
></el-input>
</el-form-item>
<el-form-item label="单价">
<el-input v-model="form.price" readonly></el-input>
</el-form-item>
<el-form-item label="盈亏金额">
<el-input
v-model="profitPrice"
readonly
:class="{ lose: profitNumber < 0 }"
style="width: 180px"
></el-input>
</el-form-item>
<el-form-item label="备注">
<el-input v-model="form.remark" placeholder="请输入备注" style="width: 300px"></el-input>
</el-form-item>
<el-form-item>
<el-button @click="dialogVisible = false"> </el-button>
<el-button type="primary" :loading="loading" @click="onSubmitHandle"> </el-button>
</el-form-item>
</el-form>
<div class="head-container">
<el-table ref="table" :data="tableData.list" v-loading="tableData.loading" border stripe>
<el-table-column label="商品信息" width="150px">
<template v-slot="scope">
<div class="shop_info">
<el-image :src="scope.row.coverImg" style="width: 30px; height: 30px">
<template #error>
<div class="img_error">
<i class="icon el-icon-document-delete"></i>
</div>
</template>
</el-image>
<span>{{ scope.row.conName }}</span>
</div>
</template>
</el-table-column>
<el-table-column label="售价" prop="price">
<template v-slot="scope">{{ scope.row.price }}</template>
</el-table-column>
<el-table-column label="账存数量" prop="stockNumber"></el-table-column>
<el-table-column label="盈亏数量" prop="lpNum"></el-table-column>
<el-table-column label="盈亏金额" prop="lpAmount">
<template v-slot="scope">{{ scope.row.lpAmount }}</template>
</el-table-column>
<el-table-column label="实际库存" prop="acStockNumber"></el-table-column>
<el-table-column label="盘点时间" prop="createTime"></el-table-column>
<el-table-column label="盘点备注" prop="remark"></el-table-column>
</el-table>
</div>
<el-pagination
:total="tableData.total"
:current-page="tableData.page + 1"
:page-sizes="[5, 10, 30, 50]"
:page-size="tableData.size"
@current-change="paginationChange"
@size-change="sizeChange"
layout="total, sizes, prev, pager, next, jumper"
></el-pagination>
</el-dialog>
</template>
<script>
import { formatDecimal } from "@/utils/tools.js";
import { hasPermission } from "@/utils/limits.js";
import stockApi from "@/api/product/stock";
export default {
data() {
return {
dialogVisible: false,
loading: false,
form: {
skuId: "", // sku商品必传
productId: "", // 必传
stocktakinNum: "", // 必传
price: "", // 商品价格 非必传 为空盘点价格为商品价格
remark: "", // 盘点备注 非必传
stockNumber: 0,
balance: "",
},
rules: {
stocktakinNum: [
{
required: true,
message: "请输入盘点数量",
trigger: "blur",
},
],
},
resetForm: "",
searhForm: {
name: "",
skuId: "",
productId: "",
},
tableData: {
page: 0,
size: 5,
total: 0,
loading: false,
list: [],
},
};
},
mounted() {
this.resetForm = { ...this.form };
},
computed: {
profitNumber() {
if (this.form.balance == undefined) {
return this.form.stockNumber - 0;
} else {
return this.form.stockNumber - this.form.balance;
}
},
profitPrice() {
return formatDecimal((this.form.stockNumber - this.form.balance) * this.form.price);
},
},
methods: {
onSubmitHandle() {
this.$refs.form.validate(async (valid) => {
if (valid) {
try {
this.form.lpNum = this.profitNumber;
this.form.balance = this.form.stockNumber;
this.loading = true;
this.form.conInfoId = this.form.id;
delete this.form["id"];
console.log(this.form);
let res = await tbConCheck(this.form);
console.log(this.form);
this.$emit("success", res);
this.dialogVisible = false;
this.loading = false;
this.$notify({
title: "注意",
message: `添加成功`,
type: "success",
});
this.getTableData();
} catch (error) {
this.loading = false;
console.log(error);
}
}
});
},
async show(obj) {
console.log(obj, 111);
let res = await hasPermission("允许耗材盘点");
if (!res) {
return;
}
this.form.remark = "";
this.form.stocktakinNum = 0;
this.form.lpNum = 0;
// this.form.stockNumber = 0
this.form = Object.assign(this.form, obj);
this.dialogVisible = true;
this.form.conInfoId = obj.consId;
this.form.stockNumber = obj.balance < 0 ? 0 : obj.balance;
// this.form.balance = obj.stockNumber
this.form.balance = obj.balance;
this.form.price == null ? 0 : this.form.price;
this.searhForm.productId = obj.id;
this.getTableData();
},
// 分页大小改变
sizeChange(e) {
this.tableData.size = e;
this.getTableData();
},
// 分页回调
paginationChange(e) {
this.tableData.page = e - 1;
this.getTableData();
},
// 商品列表
async getTableData() {
try {
this.tableData.loading = true;
const res = await stockApi.checkRecord({
page: this.tableData.page,
size: this.tableData.size,
conId: this.searhForm.productId,
sort: "id,desc",
});
this.tableData.list = res.content;
this.tableData.total = res.totalElements;
setTimeout(() => {
this.tableData.loading = false;
}, 500);
} catch (error) {
console.log(error);
}
},
},
};
</script>
<style scoped lang="scss">
.lose {
&::v-deep .el-input__inner {
color: rgb(238, 29, 29);
}
}
.shop_info {
display: flex;
align-items: center;
span {
margin-left: 10px;
}
}
</style>

View File

@@ -0,0 +1,88 @@
import Api from "@/api/product/vendor";
import type { IModalConfig } from "@/components/CURD/types";
const modalConfig: IModalConfig = {
pageName: "sys:user",
dialog: {
title: "新增耗材",
width: 800,
draggable: true,
},
form: {
labelWidth: 140,
},
formAction: function (data) {
return Api.add({ ...data });
},
beforeSubmit(data) {
console.log("提交之前处理", data);
},
formItems: [
{
label: "渠道",
prop: "source",
rules: [{ required: true, message: "请选择渠道", trigger: "blur" }],
type: "select",
attrs: {
placeholder: "请选择渠道",
},
options: [],
},
{
label: "类型",
prop: "type",
rules: [{ required: true, message: "请选择类型", trigger: "blur" }],
type: "select",
attrs: {
placeholder: "请选择类型",
},
col: {
xs: 24,
sm: 12,
},
options: [],
},
{
type: "input",
label: "版本号",
prop: "version",
rules: [{ required: true, message: "请输入版本号", trigger: "blur" }],
attrs: {
placeholder: "请输入版本号",
},
},
{
type: "radio",
label: "是否强制更新",
prop: "isForce",
rules: [{ required: true, message: "请输入版本号", trigger: "blur" }],
attrs: {
placeholder: "请输入版本号",
},
initialValue: 0,
options: [],
},
{
type: "textarea",
label: "更新提示内容",
prop: "message",
rules: [{ required: true, message: "请输入更新提示内容", trigger: "blur" }],
attrs: {
placeholder: "请输入更新提示内容",
},
},
{
type: "custom",
label: "版本文件",
prop: "url",
rules: [{ required: true, message: "请上传版本文件", trigger: "blur" }],
attrs: {
placeholder: "请上传版本文件",
},
initialValue: [],
},
],
};
// 如果有异步数据会修改配置的推荐用reactive包裹而纯静态配置的可以直接导出
export default reactive(modalConfig);

View File

@@ -0,0 +1,43 @@
import type { statusType } from "@/api/order/order";
export const options: { [key in optionsType]: options[] } = {
}
export type optionsType = string;
export function returnOptions(type: optionsType) {
return options[type];
}
export function returnOptionsLabel(optionsType: optionsType, value: string | number) {
const options = returnOptions(optionsType);
if (!options) {
return "";
}
const option = options.find((item) => item.value === value);
return option ? option.label : "";
}
export interface options {
label: string;
value: string | number;
[property: string]: any;
}
export interface statusOptions extends options {
value: statusType;
}
export type payTypeValue =
| ""
| "cash"
| "bank"
| "scanCode"
| "deposit"
| "vipPay"
| "arrears"
| "virtual"
| "arrears";
export interface payTypeOptions extends options {
value: payTypeValue;
}

View File

@@ -0,0 +1,94 @@
import Api from "@/api/product/cons";
import type { IContentConfig } from "@/components/CURD/types";
const contentConfig: IContentConfig = {
pageName: "sys:user",
table: {
border: true,
highlightCurrentRow: true,
},
pagination: {
background: true,
layout: "prev,pager,next,jumper,total,sizes",
pageSize: 10,
pageSizes: [10, 20, 30, 50],
},
indexAction: function (params) {
return Api.getList(params);
},
// deleteAction: Api.delete,
// modifyAction: function (data) {
// // return Api.edit(data);
// },
pk: "id",
toolbar: [
"add",
{
text: "入库",
name: 'ruku',
auth: 'ruku'
},
{
text: "出库",
name: 'chuku',
auth: ''
},
{
text: "分类管理",
name: 'category',
auth: ''
},
{
text: "供应商管理",
name: 'gongyinsahng',
auth: ''
},
],
defaultToolbar: ["refresh", "filter", "search"],
cols: [
{ type: "selection", width: 50, align: "center" },
// { label: "id", align: "center", prop: "id", width: 100, show: true },
{
label: "耗材名称",
align: "center",
prop: "conName",
},
{
label: "单位",
align: "center",
prop: "conUnit",
},
{
label: "所属商品",
align: "center",
templet: 'custom',
slotName: 'goods'
},
{
label: "库存数量",
align: "center",
prop: "stockNumber",
},
{
label: "预警值",
align: "center",
prop: "conWarning",
},
{
label: "是否启用",
align: "center",
prop: "status",
templet: "custom",
slotName: "status",
},
{
label: "操作",
align: "center",
fixed: "right",
width: 150,
templet: "custom",
slotName: 'operate'
},
],
};
export default contentConfig;

View File

@@ -0,0 +1,51 @@
import VersionApi, { type editRequest } from "@/api/system/version";
import type { IModalConfig } from "@/components/CURD/types";
const modalConfig: IModalConfig<editRequest> = {
pageName: "sys:user",
dialog: {
title: "编辑版本",
width: 800,
draggable: true,
},
pk: "id",
formAction: function (data) {
return VersionApi.edit({ ...data, url: typeof data.url === "string" ? data.url : data.url[0] });
},
beforeSubmit(data) {
console.log("提交之前处理", data);
},
formItems: [
{
type: "input",
label: "版本号",
prop: "version",
rules: [{ required: true, message: "请输入版本号", trigger: "blur" }],
attrs: {
placeholder: "请输入版本号",
},
},
{
type: "textarea",
label: "更新提示内容",
prop: "message",
rules: [{ required: true, message: "请输入更新提示内容", trigger: "blur" }],
attrs: {
placeholder: "请输入更新提示内容",
},
},
{
type: "custom",
label: "版本文件",
prop: "url",
rules: [{ required: true, message: "请上传版本文件", trigger: "blur" }],
attrs: {
placeholder: "请上传版本文件",
},
initialValue: [],
},
],
};
export default reactive(modalConfig);

View File

@@ -0,0 +1,64 @@
import type { ISearchConfig } from "@/components/CURD/types";
import consGroupApi from '@/api/product/cons-group'
import { statusOptions, payTypeOptions } from "./config";
const searchConfig: ISearchConfig = {
pageName: "sys:user",
inline: true,
isExpandable: false,
formItems: [
{
type: "select",
label: "耗材分类",
prop: "consGroupId",
attrs: {
placeholder: "请选择耗材分类",
clearable: true,
style: {
width: "200px",
},
},
initialValue: "",
initFn(formItem) {
console.log(formItem);
consGroupApi.getAllList({}).then(res => {
formItem.options = res.map((item: { name: any; id: any; }) => {
return {
label: item?.name,
value: item?.id
}
})
})
},
},
{
type: "input",
label: "耗材名称",
prop: "conName",
attrs: {
placeholder: "请输入耗材名称",
clearable: true,
style: {
width: "200px",
},
},
},
{
type: "date-picker",
label: "创建时间",
prop: "createAt",
attrs: {
type: "daterange",
"range-separator": "~",
"start-placeholder": "开始时间",
"end-placeholder": "截止时间",
"value-format": "YYYY-MM-DD",
style: {
width: "240px",
},
},
},
],
};
export default searchConfig;

View File

@@ -0,0 +1,186 @@
<template>
<div class="app-container">
<!-- 列表 -->
<!-- 搜索 -->
<page-search
ref="searchRef"
:search-config="searchConfig"
@query-click="handleQueryClick"
@reset-click="handleResetClick"
/>
<!-- 列表 -->
<page-content
ref="contentRef"
:content-config="contentConfig"
@add-click="handleAddClick"
@edit-click="handleEditClick"
@export-click="handleExportClick"
@search-click="handleSearchClick"
@toolbar-click="handleToolbarClick"
@operat-click="handleOperatClick"
@filter-change="handleFilterChange"
>
<template #status="scope">
<el-tag :type="scope.row[scope.prop] == 1 ? 'success' : 'info'">
{{ scope.row[scope.prop] == 1 ? "启用" : "禁用" }}
</el-tag>
</template>
<template #goods="scope">
<div class="goods_info">
<div class="row" v-for="item in scope.row.productList" :key="item.id">
<el-image :src="item.productImg" class="cover" lazy></el-image>
<div class="info">
<div class="name">
<span :class="[item.isVip == 1 ? 'colorStyle' : '']">
{{ item.productName }}
</span>
<span class="refund" v-if="item.refundNumber">(退 - {{ item.refundNumber }})</span>
</div>
<div class="sku">{{ item.productSkuName }}</div>
</div>
</div>
</div>
</template>
<template #options="scope">
{{ returnOptionsLabel(scope.prop, scope.row[scope.prop]) }}
</template>
<template #state="scope">
<el-tag :type="returnStateType(scope.row[scope.prop])">
{{ returnOptionsLabel(scope.prop, scope.row[scope.prop]) }}
</el-tag>
</template>
<template #mobile="scope">
<el-text>{{ scope.row[scope.prop] }}</el-text>
<copy-button
v-if="scope.row[scope.prop]"
:text="scope.row[scope.prop]"
style="margin-left: 2px"
/>
</template>
<template #operate="scope">
<div>
<el-button @click="refAddHaocaiOpen(scope.row)" type="primary" link>编辑</el-button>
<el-button @click="refAddHaocaiTakinShow(scope.row)" link type="primary">
耗材盘点
</el-button>
</div>
</template>
</page-content>
<!-- 耗材添加编辑 -->
<add-haocai ref="refAddHaocai" @refresh="refresh"></add-haocai>
<!-- 耗材盘点 -->
<addConsTakin ref="refAddHaocaiTakin" @refresh="refresh"></addConsTakin>
</div>
</template>
<script setup lang="ts">
import addHaocai from "./components/add-haocai.vue";
import addConsTakin from "./components/addConsTakin.vue";
import orderApi, { type getListResponse, OrderInfoVo } from "@/api/order/order";
import type { IObject, IOperatData } from "@/components/CURD/types";
import usePage from "@/components/CURD/usePage";
import contentConfig from "./config/content";
import editModalConfig from "./config/edit";
import searchConfig from "./config/search";
import { returnOptionsLabel } from "./config/config";
const router = useRouter();
const {
searchRef,
contentRef,
editModalRef,
handleQueryClick,
handleResetClick,
handleSubmitClick,
handleExportClick,
handleSearchClick,
handleFilterChange,
} = usePage();
//耗材盘点
const refAddHaocaiTakin = ref();
function refAddHaocaiTakinShow(item: any) {
refAddHaocaiTakin.value.show(item);
}
function refresh() {
console.log("refresh");
contentRef.value?.fetchPageData();
}
const refAddHaocai = ref();
function refAddHaocaiOpen(item) {
refAddHaocai.value.open(item);
}
// 新增
async function handleAddClick() {
refAddHaocaiOpen();
}
// 编辑
async function handleEditClick(row: IObject) {
editModalRef.value?.handleDisabled(false);
editModalRef.value?.setModalVisible();
console.log({ ...row });
editModalRef.value?.setFormData({ ...row, url: [row.url] });
}
1;
// 其他工具栏
function handleToolbarClick(name: string) {
console.log(name);
if (name === "category") {
router.push({ path: "/inventory/classification" });
return;
}
if (name == "gongyinsahng") {
router.push({ path: "/inventory/supplier" });
return;
}
if (name == "ruku") {
router.push({ path: "/inventory/operation_in" });
return;
}
}
// 其他操作列
async function handleOperatClick(data: IOperatData) {
console.log(data);
if (data.name === "detail") {
return;
}
if (data.name === "printer") {
}
}
function returnStateType(status: string) {
if (status === "unpaid") {
return "warning";
}
if (status === "done") {
return "primary";
}
if (status === "cancelled") {
return "info";
}
if (status === "refund") {
return "danger";
}
}
const route = useRouter();
// 结账
function toPayOrder(order: getListResponse) {
route.push({
path: "/tool/index",
query: {
id: order.id,
},
});
}
//详情
const refDetail = ref();
function showdetail(row: OrderInfoVo) {
refDetail.value.show(row);
}
</script>
<style scoped lang="scss">
</style>

View File

@@ -1,24 +0,0 @@
<template>
<div class="Table">
<!-- 按钮 -->
<AddButton></AddButton>
<!-- 表格 -->
<Table></Table>
<!-- 分页 -->
<Paging></Paging>
</div>
</template>
<script setup>
import AddButton from './component/AddButton.vue'
import Table from './component/Table.vue'
import Paging from './component/Paging.vue'
</script>
<style scoped lang="scss">
.Table {
padding: 20px;
background-color: #fff;
border: 1px solid #e4e7ed;
margin-top: 20px;
border-radius: 4px;
}
</style>

View File

@@ -1,103 +0,0 @@
<template>
<div class="DataStatistics">
<div style="width: 200px;">
<el-icon class="iconStyle">
<UserFilled />
</el-icon>
<span>耗材种数</span>
<span>{{ datas.totalRow }}</span>
</div>
<div style="width: 300px;">
<el-icon class="iconStyle">
<UserFilled />
</el-icon>
<div>
<div><span>增加数量</span><span>0</span></div>
<div style="display: flex;">
<div>
<span>手动增加</span><span>0</span>
</div>
<span style="margin: 0 20px;color: #ccc;">|</span>
<div>
<span>入库</span><span>0</span>
</div>
</div>
</div>
</div>
<div style="width: 500px;">
<el-icon class="iconStyle">
<UserFilled />
</el-icon>
<div>
<div><span>减少数量</span><span>0</span></div>
<div style="display: flex;">
<div>
<span>手动减少</span><span>0</span>
</div>
<span style="margin: 0 20px;color: #ccc;">|</span>
<div>
<span>消耗</span><span>0</span>
</div>
<span style="margin: 0 20px;color: #ccc;">|</span>
<div>
<span>报损</span><span>0</span>
</div><span style="margin: 0 20px;color: #ccc;">|</span>
<div>
<span>出库</span><span>0</span>
</div>
</div>
</div>
</div>
</div>
</template>
<script setup>
import API from "@/api/product/index";
import { onMounted, reactive } from "vue";
onMounted(() => {
getPage();
})
let datas = reactive({
totalRow: 0
})
async function getPage() {
let res = await API.getPage();
datas.totalRow = res.totalRow
}
</script>
<style scoped lang="scss">
.DataStatistics {
border: 1px solid #e4e7ed;
background-color: #fff;
border-radius: 4px;
margin-top: 20px;
padding: 20px;
display: flex;
align-items: center;
justify-content: space-around;
>div {
height: 80px;
background-color: #f4f9ff;
display: flex;
align-items: center;
justify-content: space-around;
padding: 20px;
.iconStyle {
background-color: #d4e9fe;
border-radius: 50%;
padding: 6px;
font-size: 36px;
color: #3f9eff;
}
span {
color: #666;
font-size: 14px;
}
}
}
</style>

View File

@@ -1,61 +0,0 @@
<template>
<div class="Search">
<el-form :inline="true" :model="formInline" class="demo-form-inline">
<el-form-item label="耗材分类">
<el-select v-model="formInline.region" placeholder="请选择耗材分类" clearable>
<el-option label="Zone one" value="shanghai" />
<el-option label="Zone two" value="beijing" />
</el-select>
</el-form-item>
<el-form-item label="耗材名称">
<el-input v-model="formInline.user" placeholder="请输入耗材名称" clearable />
</el-form-item>
<el-form-item label="日期">
<el-date-picker v-model="formInline.value1" type="daterange" range-separator="-" start-placeholder="开始日期"
end-placeholder="结束日期" />
</el-form-item>
<el-form-item label="排列方式">
<el-select v-model="formInline.region" placeholder="请选择排列方式" clearable>
<el-option label="创建时间" value="shanghai" />
<el-option label="数量由低到高" value="beijing" />
</el-select>
</el-form-item>
<el-form-item>
<el-button type="primary" icon="Search" @click="onSubmit">搜索</el-button>
<el-button icon="Refresh" @click="onSubmit">重置</el-button>
</el-form-item>
</el-form>
</div>
</template>
<script lang="ts" setup>
import { reactive } from 'vue'
const formInline = reactive({
user: '',
region: '',
date: '',
value1: ""
})
const onSubmit = () => {
console.log('submit!')
}
</script>
<style scoped lang="scss">
.Search {
padding: 20px;
background-color: #fff;
border: 1px solid #e4e7ed;
border-radius: 4px;
}
.demo-form-inline .el-input {
--el-input-width: 220px;
}
.demo-form-inline .el-select {
--el-select-width: 220px;
}
</style>

View File

@@ -1,14 +0,0 @@
<template>
<el-button type="success" icon="Plus">新增</el-button>
<el-button>入库</el-button>
<el-button>出库</el-button>
<el-button @click="toUrl('classification')">分类管理</el-button>
<el-button @click="toUrl('supplier')">供应商管理</el-button>
</template>
<script setup>
import { useRouter } from 'vue-router';
const router = useRouter();
function toUrl(name) {
router.push({ name });
}
</script>

View File

@@ -1,22 +0,0 @@
<template>
<div style="margin-top: 10px;">
<el-pagination background :page-size="20" :page-sizes="[10, 20, 30, 40]" layout="prev,pager,next,jumper,total,sizes"
v-model:current-page="datas.currentPage" :total="datas.total" @size-change="handleSizeChange"
@current-change="handleCurrentChange" />
</div>
</template>
<script setup>
let datas = reactive({
currentPage: 1,
pageSize: 20,
total: 20,
})
// 当前条改变
function handleSizeChange(val) {
console.log(`每页 ${val}`);
}
// 当前页改变
function handleCurrentChange(val) {
console.log(`当前页: ${val}`);
}
</script>

View File

@@ -1,34 +0,0 @@
<template>
<div style="margin-top: 10px;">
<el-table :data="tableData" border style="width: 100%">
<el-table-column prop="date" label="Date" width="180" />
<el-table-column prop="name" label="Name" width="180" />
<el-table-column prop="address" label="Address" />
</el-table>
</div>
</template>
<script lang="ts" setup>
const tableData = [
{
date: '2016-05-03',
name: 'Tom',
address: 'No. 189, Grove St, Los Angeles',
},
{
date: '2016-05-02',
name: 'Tom',
address: 'No. 189, Grove St, Los Angeles',
},
{
date: '2016-05-04',
name: 'Tom',
address: 'No. 189, Grove St, Los Angeles',
},
{
date: '2016-05-01',
name: 'Tom',
address: 'No. 189, Grove St, Los Angeles',
},
]
</script>

View File

@@ -0,0 +1,207 @@
<!-- 耗材列表 -->
<template>
<el-dialog title="选择耗材" v-model="dialogVisible">
<el-form :model="searchForm" inline>
<el-form-item>
<el-input
v-model="searchForm.conTypeName"
placeholder="耗材类型名称"
@input="onInput"
></el-input>
</el-form-item>
<el-form-item>
<el-input v-model="searchForm.conName" placeholder="耗材名称" @input="onInput"></el-input>
</el-form-item>
<el-form-item>
<el-button type="primary" @click="getTableData">查询</el-button>
<el-button @click="resetHandle">重置</el-button>
</el-form-item>
</el-form>
<div class="head-container">
<el-table
ref="table"
:data="tableData.list"
v-loading="tableData.loading"
@select="firstSelectChange"
:row-key="getRowKey"
@selection-change="onSelectionChange"
>
<el-table-column type="selection" width="55" align="center"></el-table-column>
<el-table-column label="耗材名称" prop="conName"></el-table-column>
<el-table-column label="价格" prop="price"></el-table-column>
<el-table-column label="耗材代码" prop="conCode"></el-table-column>
<el-table-column label="耗材类型名称" prop="conTypeName"></el-table-column>
<el-table-column label="单位" prop="conUnit"></el-table-column>
<el-table-column label="最近入库量" prop="lasterInStock"></el-table-column>
<el-table-column label="库存数量" prop="stockNumber">
<template v-slot="scope">
{{ formatDecimal(scope.row.stockNumber, 2, true) }}
</template>
</el-table-column>
<!-- <el-table-column label="操作" fixed="right">
<template v-slot="scope">
<el-button type="primary" size="mini" @click="confirmHandle(scope.row)">选择</el-button>
</template>
</el-table-column> -->
</el-table>
</div>
<el-pagination
:total="tableData.total"
:current-page="tableData.page + 1"
:page-size="tableData.size"
@current-change="paginationChange"
@size-change="sizeChange"
layout="total, sizes, prev, pager, next, jumper"
></el-pagination>
<template #footer>
<span class="dialog-footer">
<el-button @click="dialogVisible = false"> </el-button>
<el-button type="primary" @click="confirmHandle"> </el-button>
</span>
</template>
</el-dialog>
</template>
<script>
import consApi from "@/api/product/cons";
import { formatDecimal } from "@/utils/tools.js";
import _ from "lodash";
export default {
data() {
return {
formatDecimal,
dialogVisible: false,
searchForm: {
conTypeId: "",
conTypeName: "",
conCode: "",
conName: "",
},
resetSearchForm: "",
tableData: {
page: 0,
size: 10,
total: 0,
loading: false,
list: [],
},
goods: [],
stayselection: [],
};
},
mounted() {
this.resetSearchForm = { ...this.searchForm };
},
methods: {
reset() {
this.$refs.table.clearSelection();
},
onInput: _.debounce(function (event) {
//防抖请求
this.getTableData();
}, 500),
onSelectionChange(selection) {
this.stayselection = selection;
},
getRowKey(row) {
return row.id;
},
firstSelectChange() {
// console.log(selection)
let selection = this.$refs.table.selection || [];
if (selection.length > 1 && this.isselect) {
const del_row = selection.shift();
this.$refs.table.toggleRowSelection(del_row, false);
}
},
// 确定选商品
confirmHandle() {
// let res = this.$refs.table.selection
// let res = this.stayselection
// this.$emit('success', res)
var uniqueArray = this.stayselection.filter(
(item1) => !this.goods.some((item2) => item2.productId == item1.id)
);
this.$emit("success", uniqueArray);
this.close();
},
// 重置查询
resetHandle() {
this.searchForm = { ...this.resetSearchForm };
this.tableData.page = 0;
this.tableData.size = 10;
this.tableData.list = [];
this.getTableData();
},
// 分页大小改变
sizeChange(e) {
this.tableData.size = e;
this.getTableData();
},
// 分页回调
paginationChange(e) {
this.tableData.page = e - 1;
this.getTableData();
},
// 耗材列表
async getTableData() {
this.tableData.loading = true;
try {
const res = await consApi.getList({
page: this.tableData.page,
size: this.tableData.size,
...this.searchForm,
});
this.tableData.list = res.records;
this.tableData.total = res.totalRow;
if (this.goods.length) {
this.$nextTick(() => {
this.selection();
});
}
setTimeout(() => {
this.tableData.loading = false;
}, 500);
} catch (error) {
console.log(error);
}
},
show(goods) {
this.dialogVisible = true;
if (goods && goods.length) {
this.goods = goods;
} else {
this.goods = [];
}
this.resetHandle();
},
close() {
this.dialogVisible = false;
},
selection() {
this.goods.forEach((row) => {
this.tableData.list.forEach((item, index) => {
if (row.id == item.id) {
this.$refs.table.toggleRowSelection(this.tableData.list[index]);
}
});
});
},
},
};
</script>
<style scoped lang="scss">
.shop_info {
display: flex;
align-items: center;
span {
margin-left: 10px;
}
}
</style>

View File

@@ -0,0 +1,250 @@
<template>
<el-dialog title="选择商品" v-model="dialogVisible" @close="reset" top="5vh">
<el-form :model="searhForm" inline>
<el-form-item>
<el-input v-model="searhForm.name" placeholder="商品名称" @input="onInput"></el-input>
</el-form-item>
<el-form-item>
<el-select v-model="searhForm.category" placeholder="商品分类">
<el-option
:label="item.name"
:value="item.id"
v-for="item in categoryList"
:key="item.id"
></el-option>
</el-select>
</el-form-item>
<el-form-item>
<el-button type="primary" @click="getTableData">查询</el-button>
<el-button @click="resetHandle">重置</el-button>
</el-form-item>
</el-form>
<div class="head-container">
<el-table
ref="table"
:data="tableData.list"
@select="firstSelectChange"
v-loading="tableData.loading"
:row-key="getRowKey"
@selection-change="onSelectionChange"
>
<el-table-column
type="selection"
width="55"
align="center"
:reserve-selection="true"
></el-table-column>
<el-table-column label="商品信息">
<template v-slot="scope">
<div class="shop_info">
<el-image :src="scope.row.coverImg" style="width: 30px; height: 30px">
<div class="img_error" slot="error">
<i class="icon el-icon-document-delete"></i>
</div>
</el-image>
<span>{{ scope.row.name }}</span>
</div>
</template>
</el-table-column>
<el-table-column label="规格">
<template v-slot="scope">
{{ scope.row.typeEnum }}
</template>
</el-table-column>
<el-table-column label="是否售罄">
<template v-slot="scope">
{{ scope.row.isPauseSale == 1 ? "" : "" }}
</template>
</el-table-column>
<el-table-column label="是否分销">
<template v-slot="scope">
{{ scope.row.isDistribute == 1 ? "" : "" }}
</template>
</el-table-column>
<el-table-column label="售价">
<template v-slot="scope">{{ scope.row.lowPrice }}</template>
</el-table-column>
<el-table-column label="销量/库存">
<template v-slot="scope">
{{ scope.row.realSalesNumber }}/{{ scope.row.stockNumber }}
</template>
</el-table-column>
<el-table-column label="分类名称" prop="categoryName"></el-table-column>
</el-table>
</div>
<el-pagination
:total="tableData.total"
:current-page="tableData.page + 1"
:page-size="tableData.size"
@current-change="paginationChange"
@size-change="sizeChange"
layout="total, sizes, prev, pager, next, jumper"
></el-pagination>
<template #footer>
<span class="dialog-footer">
<el-button @click="dialogVisible = false"> </el-button>
<el-button type="primary" @click="confirmHandle"> </el-button>
</span>
</template>
</el-dialog>
</template>
<script>
import _ from "lodash";
import consApi from "@/api/product/cons";
export default {
data() {
return {
dialogVisible: false,
searhForm: {
name: "",
category: "",
},
categoryList: [],
tableData: {
page: 0,
size: 10,
total: 0,
loading: false,
list: [],
},
goods: [],
// 是否单选
isselect: false,
stayselection: [], //待确认
};
},
methods: {
reset() {
this.$refs.table.clearSelection();
},
onInput: _.debounce(function (event) {
//防抖请求
this.getTableData();
}, 500),
onSelectionChange(selection) {
this.stayselection = selection;
},
getRowKey(row) {
return row.id;
},
firstSelectChange() {
let selection = this.$refs.table.selection;
if (selection.length > 1 && this.isselect) {
const del_row = selection.shift();
this.$refs.table.toggleRowSelection(del_row, false);
}
},
// 确定选商品
confirmHandle() {
// let res = this.$refs.table.selection
var uniqueArray = this.stayselection.filter(
(item1) => !this.goods.some((item2) => item2.productId == item1.id)
);
this.$emit("success", uniqueArray);
this.close();
},
// 是否单选
isselectEvent() {
this.isselect = true;
},
// 重置查询
resetHandle() {
this.searhForm.name = "";
this.searhForm.category = "";
this.tableData.page = 0;
this.tableData.size = 10;
this.tableData.list = [];
this.getTableData();
},
// 分页大小改变
sizeChange(e) {
this.tableData.size = e;
this.getTableData();
},
// 分页回调
paginationChange(e) {
this.tableData.page = e - 1;
this.getTableData();
},
// 商品列表
async getTableData() {
this.tableData.loading = true;
try {
const res = await consApi.getpage({
page: this.tableData.page,
size: this.tableData.size,
name: this.searhForm.name,
categoryId: this.searhForm.category,
sort: "id",
});
this.tableData.list = res.content;
this.tableData.total = res.totalElements;
if (this.goods.length) {
this.$nextTick(() => {
this.selection();
});
}
setTimeout(() => {
this.tableData.loading = false;
}, 500);
} catch (error) {
console.log(error);
}
},
// 商品分类
async tbShopCategoryGet() {
try {
const res = await tbShopCategoryGet({
page: 0,
size: 100,
sort: "id",
shopId: localStorage.getItem("shopId"),
});
this.categoryList = res.content;
} catch (error) {
console.log(error);
}
},
show(goods) {
this.dialogVisible = true;
if (goods && goods.length) {
this.goods = goods;
} else {
this.goods = [];
}
this.tbShopCategoryGet();
this.resetHandle();
},
close() {
this.dialogVisible = false;
},
selection() {
this.goods.forEach((row) => {
this.tableData.list.forEach((item, index) => {
if (row.id == item.id) {
this.$refs.table.toggleRowSelection(this.tableData.list[index]);
}
});
});
},
},
};
</script>
<style scoped lang="scss">
.head-container {
max-height: 60vh;
overflow-y: scroll;
}
.shop_info {
display: flex;
align-items: center;
span {
margin-left: 10px;
}
}
</style>

View File

@@ -0,0 +1,687 @@
<template>
<div class="app-container bg-fff u-m-20">
<div class="head-container">
<el-form
ref="queryForm"
:model="queryForm"
:rules="queryRules"
label-position="left"
label-width="80px"
>
<el-row>
<el-col :span="8">
<el-form-item label="供应商">
<el-select
v-model="queryForm.purveyorId"
placeholder="请选择供应商"
clearable
style="width: 220px"
@change="changeTypeEnum"
>
<el-option
:label="item.name"
:value="item.id"
v-for="item in purveyorList"
:key="item.id"
></el-option>
</el-select>
{{ queryForm.waitAmount }}
</el-form-item>
</el-col>
<el-col :span="8">
<el-form-item label="入库时间" prop="time">
<el-date-picker
v-model="queryForm.time"
type="date"
format="YYYY-MM-DD"
value-format="YYYY-MM-DD"
placeholder="选择日期"
style="width: 220px"
></el-date-picker>
</el-form-item>
</el-col>
</el-row>
<el-row v-if="shopTypes[shopTypesActive].value == 'purveyor'">
<el-col :span="8">
<el-form-item label="应付金额">
<el-input
v-model="queryForm.totalAmount"
placeholder="请输入应收金额"
style="width: 220px"
></el-input>
</el-form-item>
</el-col>
<el-col :span="8">
<el-form-item label="实付金额">
<el-input
v-model="queryForm.paidAmount"
placeholder="请输入实收金额"
style="width: 220px"
></el-input>
</el-form-item>
</el-col>
</el-row>
<el-row v-if="shopTypes[shopTypesActive].value == 'purveyor'">
<el-col :span="8">
<el-form-item label="付款时间">
<el-date-picker
v-model="queryForm.paidAt"
type="date"
format="yyyy-MM-dd"
value-format="yyyy-MM-dd"
placeholder="选择日期"
style="width: 220px"
></el-date-picker>
</el-form-item>
</el-col>
<el-col :span="8">
<el-form-item label="批号">
<el-input
v-model="queryForm.batchNumber"
placeholder="请输入批号"
style="width: 220px"
></el-input>
</el-form-item>
</el-col>
</el-row>
<el-row>
<el-col :span="8">
<el-form-item label="备注">
<el-input
v-model="queryForm.remark"
placeholder="请输入备注"
style="width: 220px"
></el-input>
</el-form-item>
</el-col>
</el-row>
<el-form-item>
<el-button type="primary" @click="showHaocai" v-if="inTabValue == 'consumable'">
选择耗材
</el-button>
<el-button type="primary" @click="$refs.shopList.show(tableData.list)" v-else>
选择商品
</el-button>
</el-form-item>
<el-autocomplete
v-model="autocompletename"
:fetch-suggestions="querySearchAsync"
:value-key="inTabValue == 'goods' ? 'name' : 'conName'"
:placeholder="inTabValue == 'goods' ? '商品搜索' : '耗材搜索'"
@select="handleSelect"
style="width: 500px"
></el-autocomplete>
</el-form>
</div>
<div class="head-container">
<el-button type="primary" plain v-if="inTabValue == 'consumable'">
{{ tableData.list.length }}种耗材金额合计
<span style="color: red">{{ queryForm.totalAmount }}</span>
</el-button>
<el-button type="primary" plain v-else>
{{ tableData.list.length }}种商品金额合计
<span style="color: red">{{ queryForm.totalAmount }}</span>
</el-button>
</div>
<div class="head-container">
<el-table :data="tableData.list" v-if="inTabValue == 'consumable'">
<el-table-column label="耗材名称" prop="conName">
<template v-slot="scope">
{{ scope.row.conName }}
</template>
</el-table-column>
<el-table-column label="进价">
<template v-slot="scope">
<el-input-number
v-model="scope.row.price"
:min="0"
controls-position="right"
@change="consCountTotal($event, scope.row, 'price')"
></el-input-number>
<div class="tips" style="font-size: 16px">
原价
<!-- {{ scope.row.costPrice }}/{{ scope.row.conUnit }} -->
{{
!scope.row.unit
? scope.row.defaultUnit
? scope.row.defaultUnit == scope.row.conUnitTwo
? (scope.row.costPrice * scope.row.conUnitTwoConvert).toFixed(2)
: scope.row.costPrice
: scope.row.costPrice
: scope.row.unit == scope.row.conUnitTwo
? (scope.row.costPrice * scope.row.conUnitTwoConvert).toFixed(2)
: scope.row.costPrice
}}
/
{{
!scope.row.unit
? scope.row.defaultUnit
? scope.row.defaultUnit
: scope.row.conUnit
: scope.row.unit
}}
</div>
</template>
</el-table-column>
<el-table-column label="单位">
<template v-slot="scope">
<el-select
@change="consCountTotal($event, scope.row, 'unit')"
v-model="scope.row.unit"
:placeholder="scope.row.defaultUnit ? scope.row.defaultUnit : scope.row.conUnit"
>
<el-option :label="scope.row.conUnit" :value="scope.row.conUnit"></el-option>
<el-option
:label="scope.row.conUnitTwo"
:value="scope.row.conUnitTwo"
v-if="scope.row.conUnitTwo"
></el-option>
</el-select>
<div class="tips">&nbsp;</div>
</template>
</el-table-column>
<el-table-column label="数量">
<template v-slot="scope">
<el-input-number
v-model="scope.row.stockNumber"
:min="0"
:step="1"
step-strictly
controls-position="right"
@change="consCountTotal($event, scope.row, 'stockNumber')"
></el-input-number>
<div class="tips" style="font-size: 16px">入库前</div>
</template>
</el-table-column>
<el-table-column label="小计">
<template v-slot="scope">
<!-- <el-input-number v-model="scope.row.totalAmount" :min="0" scope.row.price , scope.row.stockNumber
controls-position="right"></el-input-number> -->
<el-input :value="formatDecimal(testform(scope.row))" readonly style="width: 100px" />
</template>
</el-table-column>
<!-- <el-table-column label="变动后剩余库存">
<template v-slot="scope">
{{ scope.row.stockNumber + scope.row.number }}{{ scope.row.conUnit }}
</template>
</el-table-column> -->
<el-table-column label="操作" width="80">
<template v-slot="scope">
<el-button link @click="tableData.list.splice(scope.$index, 1), spliceclick()">
删除
</el-button>
</template>
</el-table-column>
</el-table>
<el-table :data="tableData.list" v-else>
<el-table-column type="index" width="50"></el-table-column>
<el-table-column label="商品名称" prop="name">
<template v-slot="scope">
<div class="name_wrap">
<span class="name">{{ scope.row.name }}</span>
<span v-if="scope.row.specSnap">({{ scope.row.specSnap }})</span>
<!-- <el-tag type="info" v-if="scope.row.specSnap" size="mini">{{ scope.row.specSnap }}</el-tag> -->
</div>
</template>
</el-table-column>
<el-table-column label="进价">
<template v-slot="scope">
<el-input-number
v-model="scope.row.costPrice"
:min="0"
controls-position="right"
@change="modifyPrice($event, scope.row, 'costPrice')"
></el-input-number>
<div class="tips">成本价{{ scope.row.costPrice }}/{{ scope.row.unitName }}</div>
</template>
</el-table-column>
<el-table-column label="数量">
<template v-slot="scope">
<el-input-number
v-model="scope.row.number"
:min="0"
:step="1"
step-strictly
controls-position="right"
@change="modifyPrice($event, scope.row, 'number', 'totalAmount')"
></el-input-number>
<div class="tips" style="font-size: 16px">
入库前
{{
!scope.row.unit
? scope.row.defaultUnit
? scope.row.defaultUnit == scope.row.conUnitTwo
? scope.row.number / scope.row.conUnitTwoConvert
: scope.row.number
: scope.row.number
: scope.row.unit == scope.row.conUnitTwo
? scope.row.number / scope.row.conUnitTwoConvert
: scope.row.number
}}
{{
!scope.row.unit
? scope.row.defaultUnit
? scope.row.defaultUnit
: scope.row.conUnit
: scope.row.unit
}}
</div>
</template>
</el-table-column>
<el-table-column label="小计">
<template v-slot="scope">
<!-- <el-input-number v-model="scope.row.totalAmount" :min="0"
controls-position="right"></el-input-number> -->
<el-input
:value="scope.row.costPrice * scope.row.number"
readonly
style="width: 100px"
/>
</template>
</el-table-column>
<el-table-column label="变动后剩余库存">
<template v-slot="scope">
{{ scope.row.stockNumber + scope.row.number }}{{ scope.row.unitName }}
</template>
</el-table-column>
<el-table-column label="操作" width="80">
<template v-slot="scope">
<el-button type="text" @click="tableData.list.splice(scope.$index, 1), spliceclick()">
删除
</el-button>
</template>
</el-table-column>
</el-table>
</div>
<div>
<el-button type="primary" @click="submitHandle" :loading="queryFormLoading">确定</el-button>
</div>
<!-- 选择商品 -->
<shopList ref="shopList" @success="selectShop" />
<!-- 选择耗材 -->
<ConsumableList ref="ConsumableList" @success="selectConsumable" />
<el-dialog
v-model="showResult"
:show-close="false"
:close-on-press-escape="false"
:close-on-click-modal="false"
>
<el-result
icon="success"
title="入库提交成功"
:subTitle="`共操作${tableData.list.length}件商品`"
>
<template #extra>
<template>
<el-button type="primary" size="medium" @click="resetHandle">创建新的入库单</el-button>
<router-link to="/invoicing/operating_record">
<el-button size="medium">历史提交</el-button>
</router-link>
</template>
</template>
</el-result>
</el-dialog>
</div>
</template>
<script>
import vendorApi from "@/api/product/vendor";
import stockApi from "@/api/product/stock";
import dayjs from "dayjs";
import shopList from "./components/shopList.vue";
import ConsumableList from "./components/consumableList.vue";
import { formatDecimal } from "@/utils/tools.js";
export default {
name: "operation_in",
components: {
shopList,
ConsumableList,
},
data() {
return {
formatDecimal,
inTabValue: "consumable",
inTabs: [
{
label: "商品入库",
value: "goods",
type: "purveyor",
},
{
label: "耗材入库",
value: "consumable",
type: "in",
},
],
shopTypesActive: 0,
shopTypes: [
{
label: "供应商入库",
value: "purveyor",
},
{
label: "其他入库",
value: "purchase",
},
],
shopTypes2: [
{
label: "供应商入库",
value: "purveyor",
},
],
resetForm: "",
queryFormLoading: false,
queryForm: {
batchNumber: "",
list: [],
paidAmount: 0,
paidAt: "",
purveyorId: "",
purveyorName: "",
remark: "",
time: dayjs().format("YYYY-MM-DD"),
totalAmount: 0,
type: "in",
shopId: localStorage.getItem("shopId"),
},
queryRules: {
purveyorId: [
{
required: true,
message: "请选择供应商",
trigger: "change",
},
],
time: [
{
required: true,
message: " ",
trigger: "change",
},
],
},
purveyorList: [],
tableData: {
list: [],
},
showResult: false,
autocompletename: "",
restaurants: [],
timeout: null,
};
},
mounted() {
this.resetForm = { ...this.queryForm };
this.tbShopPurveyorGet();
},
methods: {
showHaocai() {
this.$refs.ConsumableList.show(this.tableData.list);
},
async querySearchAsync(queryString, cb) {
//快捷搜索
let res = null;
if (this.inTabValue == "goods") {
res = await tbProductlist({
page: 0,
size: 20,
name: queryString ? queryString : "",
shopId: localStorage.getItem("shopId"),
sort: "id",
});
} else {
res = await tbConsInfoGet({
page: 0,
size: 20,
shopId: localStorage.getItem("shopId"),
conName: queryString ? queryString : "",
});
}
this.restaurants = res.content;
if (res.content.length == 0) {
//给个提示没有搜到
this.$message("无此商品");
return false;
}
var uniqueArray = this.restaurants.filter(
(item1) => !this.tableData.list.some((item2) => item2.productId == item1.id)
);
clearTimeout(this.timeout);
this.timeout = setTimeout(() => {
cb(uniqueArray);
}, 1000 * Math.random());
},
testform(d) {
let p = 1;
if (d.unit && d.unit == d.conUnitTwo) {
p = d.conUnitTwoConvert;
}
return d.price * d.stockNumber * p;
},
handleSelect(item) {
//选定后清空
this.autocompletename = "";
if (this.inTabValue == "goods") {
this.selectShop([item]);
} else {
this.selectConsumable([item]);
}
},
//删除计算
spliceclick() {
var zong = 0;
if (this.inTabValue == "goods") {
this.tableData.list.forEach((ele) => {
zong += ele.costPrice * ele.number;
});
} else {
this.tableData.list.forEach((ele) => {
let p = 1;
if (ele.unit && ele.conUnitTwo == ele.unit) {
p = ele.conUnitTwoConvert;
}
zong += ele.price * ele.stockNumber * p;
});
}
this.queryForm.totalAmount = formatDecimal(zong);
},
// 选择商品
selectShop(res) {
let arr = [];
res.forEach((item) => {
item.skuList.forEach((i) => {
arr.push({
name: item.name,
unitName: item.unitName,
productId: item.id,
number: 0,
totalAmount: "",
...i,
});
});
});
this.tableData.list = [...this.tableData.list, ...arr];
},
// 切换入库内容
tabChange(value, type) {
this.shopTypesActive = type == "in" ? 0 : 1;
this.inTabValue = value;
this.resetHandle();
this.$refs.shopList.reset(); //清除选项
this.$refs.ConsumableList.reset(); //清除选项
},
// 切换类型
changeTypeEnum(index) {
let filterd = this.purveyorList.filter((ele) => ele.id == index);
this.queryForm.waitAmount = filterd[0].waitAmount;
this.inTabs.forEach((i) => {
if (i.value == this.inTabValue) {
this.queryForm.type = i.type;
}
});
if (this.inTabValue == "consumable") {
return false;
}
//商品入库是否显示应付实付
if (this.queryForm.purveyorId) {
this.shopTypesActive = 0;
} else {
this.shopTypesActive = 1;
}
},
// 计算耗材总价
consCountTotal(cvalue, row, key1, key2 = undefined) {
if (cvalue == undefined) {
setTimeout(() => {
row[key1] = 0;
let zong = 0;
this.tableData.list.forEach((ele) => {
zong += ele.price * ele.stockNumber;
});
this.queryForm.totalAmount = formatDecimal(zong);
}, 10);
} else {
row[key1] = cvalue;
let zong = 0;
this.tableData.list.forEach((ele) => {
let p = 1;
if (ele.unit && ele.conUnitTwo == ele.unit) {
p = ele.conUnitTwoConvert;
}
zong += ele.price * ele.stockNumber * p;
});
this.queryForm.totalAmount = formatDecimal(zong);
}
},
// 计算商品总价
modifyPrice(cvalue, row, key1, key2 = undefined) {
if (cvalue == undefined) {
setTimeout(() => {
row[key1] = 0;
row[key2] = 0;
let zong = 0;
this.tableData.list.forEach((ele) => {
zong += ele.costPrice * ele.number;
});
this.queryForm.totalAmount = formatDecimal(zong);
}, 10);
} else {
row[key1] = cvalue;
row[key2] = cvalue;
let zong = 0;
this.tableData.list.forEach((ele) => {
zong += ele.costPrice * ele.number;
});
this.queryForm.totalAmount = formatDecimal(zong);
}
},
// 提交
submitHandle() {
if (this.tableData.list.length == 0) {
switch (this.inTabValue) {
case "goods":
this.$message("请先选择商品!");
break;
case "consumable":
this.$message("请先选择耗材!");
break;
default:
break;
}
return false;
}
this.$refs.queryForm.validate(async (valid) => {
if (valid) {
try {
this.queryFormLoading = true;
switch (this.inTabValue) {
case "goods":
this.queryForm.list = this.tableData.list;
await tbProductStockOperateOutAndOn(this.queryForm);
break;
case "consumable":
this.queryForm.accountsPayable = this.queryForm.totalAmount;
this.queryForm.actualPayment = this.queryForm.paidAmount;
this.queryForm.paymentTime = this.queryForm.paidAt;
this.queryForm.supplierId = this.queryForm.purveyorId;
this.queryForm.list = this.tableData.list;
await stockApi.in(this.queryForm);
break;
default:
break;
}
this.queryFormLoading = false;
this.$message({
message: "入库提交成功",
type: "success",
});
this.resetHandle(); //初始化
// this.showResult = true
// this.$refs.shopList.reset()//清除选项
// this.$refs.ConsumableList.reset()//清除选项
} catch (error) {
console.log(error);
this.queryFormLoading = false;
}
}
});
},
// 选择耗材
selectConsumable(res) {
console.log(res);
let arr = res.map((item) => {
item.number = formatDecimal(item.stockNumber - item.stockConsume, 2, true);
item.stockNumber = 0;
item.costPrice = item.price;
item.conInfoId = item.id;
return item;
});
this.tableData.list = [...this.tableData.list, ...arr];
},
// 初始化
resetHandle() {
this.showResult = false;
this.queryForm = { ...this.resetForm };
if (this.inTabValue == "goods") {
this.queryForm.type = "purveyor";
} else {
this.queryForm.type = this.inTabs.find((item) => item.value == this.inTabValue).type;
}
this.tableData.list = [];
this.$refs.queryForm.resetFields();
this.$refs.queryForm.resetFields();
},
// 获取供应商列表
async tbShopPurveyorGet() {
try {
const res = await vendorApi.getList({});
this.purveyorList = res.records;
} catch (error) {
console.log(error);
}
},
},
};
</script>
<style scoped lang="scss">
.name_wrap {
display: flex;
align-items: center;
.name {
margin-right: 10px;
}
}
.app-container {
}
</style>

View File

@@ -0,0 +1,6 @@
<template>
<!-- 结款记录 -->
<div style="padding: 15px">结款记录</div>
</template>
<script setup>
</script>

View File

@@ -1,146 +0,0 @@
<template>
<div class="Table">
<!-- 按钮 -->
<AddButton @add="add"></AddButton>
<!-- 表格 -->
<Table :list="datas.tableData" @handleDelete="handleDelete" @handleEdit="handleEdit"></Table>
<!-- 分页 -->
<Paging :pagingConfig="datas.pagingConfig" @sizeChange="sizeChange" @currentChange="currentChange"></Paging>
<!-- 其他模板 -->
<!-- 新增/编辑 -->
<myDialog ref="myDialogRef" :title="datas.title" @confirm="confirm" width="30%">
<el-form ref="ruleFormRef" :rules="datas.rules" :model="datas.DialogForm" label-width="80px">
<el-form-item label="供应商" prop="name">
<el-input v-model="datas.DialogForm.name" placeholder="请输入供应商名称" />
</el-form-item>
<el-form-item label="联系电话">
<el-input v-model="datas.DialogForm.telephone" placeholder="请输入联系电话" />
</el-form-item>
<el-form-item label="地址">
<el-input v-model="datas.DialogForm.address" placeholder="请输入地址" type="textarea" />
</el-form-item>
<el-form-item label="备注">
<el-input v-model="datas.DialogForm.remark" placeholder="请输入备注" type="textarea" />
</el-form-item>
</el-form>
</myDialog>
</div>
</template>
<script setup>
import AddButton from './component/AddButton.vue'
import Table from './component/Table.vue'
import Paging from './component/Paging.vue'
import myDialog from '@/components/mycomponents/myDialog.vue'
import eventBus from '@/utils/eventBus'
import API from './api'
const datas = reactive({
tableData: [], // 表格数据
title: '新增数据',
pagingConfig: {
total: 0, // 总数
pageSize: 10, // 每页数据数量
pageNumber: 1, // 当前页码
},
DialogForm: { // 弹窗表单数据
name: "",
telephone: "",
address: "",
remark: ""
},
rules: {
name: [
{ required: true, message: '请输入供应商名称', trigger: 'blur' },
{ min: 3, max: 5, message: 'Length should be 3 to 5', trigger: 'blur' },
],
}
})
const myDialogRef = ref(null)
const ruleFormRef = ref(null)
onMounted(() => {
getList()
})
eventBus.on('search', (res) => {
getList(res)
})
async function getList(data = {}) {
const res = await API.getPage({ page: datas.pagingConfig.pageNumber, size: datas.pagingConfig.pageSize, ...data })
datas.tableData = res.records
datas.pagingConfig.total = res.totalRow
datas.pagingConfig.pageSize = res.pageSize
datas.pagingConfig.pageNumber = res.pageNumber
}
function add() {
rest()
datas.title = '新增数据'
myDialogRef.value.open()
}
async function handleEdit(row) {
datas.title = '编辑数据'
const res = await API.getinfo(row.id)
datas.DialogForm = res
myDialogRef.value.open()
}
async function confirm() {
ruleFormRef.value.validate(async valid => {
if (valid) {
let res = null
if (datas.title == '新增数据') {
res = await API.add(datas.DialogForm)
} else {
res = await API.update(datas.DialogForm)
}
if (res.code == 200) {
ElMessage({
message: '成功',
type: 'success',
})
rest()
getList()
myDialogRef.value.close()
}
}
})
}
// 重置
function rest() {
datas.DialogForm = { sort: "1" }
}
async function handleDelete(id) {
ElMessageBox.confirm("是否删除数据项?", "提示", {
confirmButtonText: "确定",
cancelButtonText: "取消",
type: "warning",
}).then(
async () => {
let res = await API.deleteByIds(id)
if (res.code == 200) {
ElMessage({
message: '删除成功',
type: 'success',
})
getList()
}
}
);
}
// 分页
function sizeChange(val) {
datas.pagingConfig.pageSize = val
getList()
}
function currentChange(val) {
datas.pagingConfig.pageNumber = val
getList()
}
</script>
<style scoped lang="scss">
.Table {
padding: 20px;
background-color: #fff;
border: 1px solid #e4e7ed;
margin-top: 20px;
border-radius: 4px;
}
</style>

View File

@@ -1,103 +0,0 @@
<template>
<div class="DataStatistics">
<div style="width: 200px;">
<el-icon class="iconStyle">
<UserFilled />
</el-icon>
<span>耗材种数</span>
<span>{{ datas.totalRow }}</span>
</div>
<div style="width: 300px;">
<el-icon class="iconStyle">
<UserFilled />
</el-icon>
<div>
<div><span>增加数量</span><span>0</span></div>
<div style="display: flex;">
<div>
<span>手动增加</span><span>0</span>
</div>
<span style="margin: 0 20px;color: #ccc;">|</span>
<div>
<span>入库</span><span>0</span>
</div>
</div>
</div>
</div>
<div style="width: 500px;">
<el-icon class="iconStyle">
<UserFilled />
</el-icon>
<div>
<div><span>减少数量</span><span>0</span></div>
<div style="display: flex;">
<div>
<span>手动减少</span><span>0</span>
</div>
<span style="margin: 0 20px;color: #ccc;">|</span>
<div>
<span>消耗</span><span>0</span>
</div>
<span style="margin: 0 20px;color: #ccc;">|</span>
<div>
<span>报损</span><span>0</span>
</div><span style="margin: 0 20px;color: #ccc;">|</span>
<div>
<span>出库</span><span>0</span>
</div>
</div>
</div>
</div>
</div>
</template>
<script setup>
import API from "@/api/product/index";
import { onMounted, reactive } from "vue";
onMounted(() => {
getPage();
})
let datas = reactive({
totalRow: 0
})
async function getPage() {
let res = await API.getPage();
datas.totalRow = res.totalRow
}
</script>
<style scoped lang="scss">
.DataStatistics {
border: 1px solid #e4e7ed;
background-color: #fff;
border-radius: 4px;
margin-top: 20px;
padding: 20px;
display: flex;
align-items: center;
justify-content: space-around;
>div {
height: 80px;
background-color: #f4f9ff;
display: flex;
align-items: center;
justify-content: space-around;
padding: 20px;
.iconStyle {
background-color: #d4e9fe;
border-radius: 50%;
padding: 6px;
font-size: 36px;
color: #3f9eff;
}
span {
color: #666;
font-size: 14px;
}
}
}
</style>

View File

@@ -1,66 +0,0 @@
<template>
<div class="Search">
<el-form :inline="true" :model="formInline" class="demo-form-inline">
<el-form-item label="耗材分类">
<el-select v-model="formInline.region" placeholder="请选择耗材分类" clearable>
<el-option label="Zone one" value="shanghai" />
<el-option label="Zone two" value="beijing" />
</el-select>
</el-form-item>
<el-form-item label="耗材名称">
<el-input v-model="formInline.user" placeholder="请输入耗材名称" clearable />
</el-form-item>
<el-form-item label="日期">
<el-date-picker v-model="formInline.value1" type="daterange" range-separator="-" start-placeholder="开始日期"
end-placeholder="结束日期" />
</el-form-item>
<el-form-item label="排列方式">
<el-select v-model="formInline.region" placeholder="请选择排列方式" clearable>
<el-option label="创建时间" value="shanghai" />
<el-option label="数量由低到高" value="beijing" />
</el-select>
</el-form-item>
<el-form-item>
<el-button type="primary" icon="Search" @click="onSubmit">搜索</el-button>
<el-button icon="Refresh" @click="reset">重置</el-button>
</el-form-item>
</el-form>
</div>
</template>
<script setup>
import eventBus from '@/utils/eventBus'
const formInline = reactive({
user: '',
region: '',
date: '',
value1: ""
})
const onSubmit = () => {
eventBus.emit('search', formInline)
}
const reset = () => {
formInline.user = ''
formInline.region = ''
formInline.date = ''
formInline.value1 = ''
eventBus.emit('search', formInline)
}
</script>
<style scoped lang="scss">
.Search {
padding: 20px;
background-color: #fff;
border: 1px solid #e4e7ed;
border-radius: 4px;
}
.demo-form-inline .el-input {
--el-input-width: 220px;
}
.demo-form-inline .el-select {
--el-select-width: 220px;
}
</style>

View File

@@ -1,60 +0,0 @@
import request from "@/utils/request";
const baseURL = "/product/admin/prod/group";
// XXX-配置
const AuthAPI = {
// 列表
getList(params: any) {
return request<any, Responseres>({
url: `${baseURL}/list`,
method: "get",
params,
});
},
/** 分页*/
getPage(params: any) {
return request<any, Responseres>({
url: `${baseURL}/page`,
method: "get",
params,
});
},
// 新增
add(data: any) {
return request<any, Responseres>({
url: `${baseURL}`,
method: "post",
data: { ...data },
});
},
// 详情
getinfo(id: number) {
return request<any, Responseres>({
url: `${baseURL}/${id}`,
method: "get",
});
},
// 编辑
update(data: Object) {
return request<any, Responseres>({
url: `${baseURL}`,
method: "put",
data,
});
},
// 删除
deleteByIds(id: number | String) {
return request<any, Responseres>({
url: `${baseURL}/${id}`,
method: "delete",
});
},
};
export interface Responseres {
code?: number | null;
data?: any;
msg?: null | string;
[property: string]: any;
}
export default AuthAPI;

View File

@@ -1,15 +0,0 @@
<template>
<el-button type="primary" icon="Plus" @click="addEvent">新增</el-button>
<el-button @click="toUrl('supplier')">其他按钮</el-button>
</template>
<script setup>
import { useRouter } from 'vue-router';
const router = useRouter();
const emit = defineEmits(['add']);
function toUrl(name) {
router.push({ name });
}
function addEvent() {
emit('add');
}
</script>

View File

@@ -1,24 +0,0 @@
<template>
<div style="margin-top: 10px;">
<el-pagination background :page-size="props.pagingConfig.pageSize" :page-sizes="[10, 20, 30, 40]"
layout="prev,pager,next,jumper,total,sizes" v-model:current-page="props.pagingConfig.pageNumber"
:total="props.pagingConfig.total" @size-change="handleSizeChange" @current-change="handleCurrentChange" />
</div>
</template>
<script setup>
const props = defineProps({
pagingConfig: {
type: Object,
default: () => { }
}
})
const emit = defineEmits(['sizeChange', 'currentChange'])
// 当前条改变
function handleSizeChange(val) {
emit('sizeChange', val)
}
// 当前页改变
function handleCurrentChange(val) {
emit('currentChange', val)
}
</script>

View File

@@ -1,34 +0,0 @@
<template>
<div style="margin-top: 10px;">
<el-table :data="props.list" border style="width: 100%">
<el-table-column prop="date" label="Date" width="180" />
<el-table-column prop="name" label="Name" width="180" />
<el-table-column prop="address" label="Address" />
<el-table-column label="操作">
<template #default="scope">
<el-button size="small" type="primary" link icon="Edit" @click="handleEdit(scope.row)">编辑</el-button>
<el-button size="small" type="danger" link icon="Delete" style="color: #f89797;"
@click="handleDelete(scope.$index, scope.row)"> 删除 </el-button>
</template>
</el-table-column>
</el-table>
</div>
</template>
<script setup>
const emit = defineEmits(['handleDelete'])
const props = defineProps({
list: {
type: Array,
default: () => []
}
})
function handleEdit(row) {
emit('handleEdit', row)
}
async function handleDelete(index, row) {
emit('handleDelete', row.id)
}
</script>

View File

@@ -1,14 +0,0 @@
<template>
<!-- 供应商管理模块 -->
<div style="padding: 15px;">
<!-- 搜索 -->
<Search></Search>
<!-- 表格 -->
<Content></Content>
<!-- 其他内容 -->
</div>
</template>
<script setup>
import Search from './supplierconfig/Search.vue'
import Content from './supplierconfig/Content.vue'
</script>

View File

@@ -0,0 +1,77 @@
import Api from "@/api/product/vendor";
import { returnOptions, switchAttr } from "./config";
import type { IModalConfig } from "@/components/CURD/types";
const modalConfig: IModalConfig = {
pageName: "sys:user",
dialog: {
title: "添加供应商",
width: 800,
draggable: true,
},
form: {
labelWidth: 140,
},
formAction: function (data) {
return Api.add({ ...data });
},
beforeSubmit(data) {
console.log("提交之前处理", data);
},
formItems: [
{
label: "名称",
prop: "name",
rules: [{ required: true, message: "请输入名称", trigger: "blur" }],
attrs: {
placeholder: "请输入名称",
},
},
{
label: "联系人名字",
prop: "contactName",
rules: [{ required: false, message: "请输入联系人名字", trigger: "blur" }],
attrs: {
placeholder: "请输入联系人名字",
},
},
{
label: "联系人电话",
prop: "telephone",
rules: [{ required: false, message: "请输入联系人名字", trigger: "blur" }],
attrs: {
placeholder: "请输入联系人名字",
},
},
{
label: "供应商地址",
prop: "address",
rules: [{ required: false, message: "请输入供应商地址", trigger: "blur" }],
attrs: {
placeholder: "请输入供应商地址",
},
},
{
label: "备注",
prop: "remark",
rules: [{ required: false, message: "请输入备注", trigger: "blur" }],
attrs: {
placeholder: "请输入备注",
},
},
{
label: "排序",
prop: "sort",
rules: [{ required: true, message: "请输入排序", trigger: "blur" }],
type: "input-number",
attrs: {
placeholder: "请输入排序",
},
},
],
};
// 如果有异步数据会修改配置的推荐用reactive包裹而纯静态配置的可以直接导出
export default reactive(modalConfig);

View File

@@ -0,0 +1,48 @@
export interface options {
label: string;
value: string | number;
[property: string]: any;
}
export interface optionObject {
[property: string]: options[];
}
const options: optionObject = {
payType: [
{ label: "现金", value: "cash" },
{ label: "微信", value: "weixin" },
{ label: "银行卡", value: "bank" },
{ label: "会员支付", value: "member-account" },
{ label: "支付宝", value: "alipay" },
{ label: "刷卡", value: "deposit" },
{ label: "挂单", value: "arrears" },
{ label: "刷卡", value: "deposit" },
{ label: "储值", value: "member-account" },
{ label: "自定义", value: "virtual" },
],
isIdeal: [
{ label: "否", value: 0 },
{ label: "是", value: 1 },
]
};
export const switchAttr = {
"active-value": 1,
"inactive-value": 0,
}
export type optionsType = string;
export function returnOptions(type: optionsType) {
return options[type];
}
export function returnOptionsLabel(optionsType: optionsType, value: string | number) {
const options = returnOptions(optionsType);
if (!options) {
return "";
}
const option = options.find((item) => item.value === value);
return option ? option.label : "";
}

View File

@@ -0,0 +1,79 @@
import Api from "@/api/product/vendor";
import type { IContentConfig } from "@/components/CURD/types";
const contentConfig: IContentConfig = {
pageName: "sys:user",
table: {
border: true,
highlightCurrentRow: true,
},
pagination: {
background: true,
layout: "prev,pager,next,jumper,total,sizes",
pageSize: 20,
pageSizes: [10, 20, 30, 50],
},
indexAction: function (params) {
return Api.getList({});
},
deleteAction: function (id) {
return Api.delete(id);
},
modifyAction: function (data) {
return Api.edit(data);
},
pk: "id",
toolbar: ["add"],
defaultToolbar: ["refresh", "filter", "search"],
cols: [
// { type: "selection", width: 50, align: "center" },
{
label: "供应商",
align: "center",
prop: "name",
},
{
label: "联系人",
align: "center",
prop: "contactName",
},
{
label: "联系人电话",
align: "center",
prop: "telephone",
},
{
label: "地址",
align: "center",
prop: "address",
},
{
label: "备注",
align: "center",
prop: "remark",
},
{
label: "创建时间",
align: "center",
prop: "createTime",
},
{
label: "状态",
align: "center",
prop: "status",
templet: 'custom',
slotName: 'switch'
},
{
label: "操作",
align: "center",
fixed: "right",
width: 280,
templet: "tool",
operat: ["edit", 'delete'],
},
],
};
export default contentConfig;

View File

@@ -0,0 +1,77 @@
import Api from "@/api/product/vendor";
import { returnOptions, switchAttr } from "./config";
import type { IModalConfig } from "@/components/CURD/types";
const modalConfig: IModalConfig = {
pageName: "sys:user",
dialog: {
title: "编辑供应商",
width: 800,
draggable: true,
},
form: {
labelWidth: 140,
},
formAction: function (data) {
return Api.edit({ ...data });
},
beforeSubmit(data) {
console.log("提交之前处理", data);
},
formItems: [
{
label: "名称",
prop: "name",
rules: [{ required: true, message: "请输入名称", trigger: "blur" }],
attrs: {
placeholder: "请输入名称",
},
},
{
label: "联系人名字",
prop: "contactName",
rules: [{ required: false, message: "请输入联系人名字", trigger: "blur" }],
attrs: {
placeholder: "请输入联系人名字",
},
},
{
label: "联系人电话",
prop: "telephone",
rules: [{ required: false, message: "请输入联系人名字", trigger: "blur" }],
attrs: {
placeholder: "请输入联系人名字",
},
},
{
label: "供应商地址",
prop: "address",
rules: [{ required: false, message: "请输入供应商地址", trigger: "blur" }],
attrs: {
placeholder: "请输入供应商地址",
},
},
{
label: "备注",
prop: "remark",
rules: [{ required: false, message: "请输入备注", trigger: "blur" }],
attrs: {
placeholder: "请输入备注",
},
},
{
label: "排序",
prop: "sort",
rules: [{ required: true, message: "请输入排序", trigger: "blur" }],
type: "input-number",
attrs: {
placeholder: "请输入排序",
},
},
],
};
// 如果有异步数据会修改配置的推荐用reactive包裹而纯静态配置的可以直接导出
export default reactive(modalConfig);

View File

@@ -0,0 +1,21 @@
import type { ISearchConfig } from "@/components/CURD/types";
const searchConfig: ISearchConfig = {
pageName: "sys:user",
formItems: [
{
type: "input",
label: "版本号",
prop: "keywords",
attrs: {
placeholder: "请输入版本号",
clearable: true,
style: {
width: "200px",
},
},
},
],
};
export default searchConfig;

View File

@@ -0,0 +1,115 @@
<template>
<div class="app-container">
<!-- 列表 -->
<!-- 搜索 -->
<!-- <page-search
ref="searchRef"
:search-config="searchConfig"
@query-click="handleQueryClick"
@reset-click="handleResetClick"
/> -->
<!-- 列表 -->
<page-content
ref="contentRef"
:content-config="contentConfig"
@add-click="handleAddClick"
@edit-click="handleEditClick"
@export-click="handleExportClick"
@search-click="handleSearchClick"
@toolbar-click="handleToolbarClick"
@operat-click="handleOperatClick"
@filter-change="handleFilterChange"
>
<template #status="scope">
<el-tag :type="scope.row[scope.prop] == 1 ? 'success' : 'info'">
{{ scope.row[scope.prop] == 1 ? "启用" : "禁用" }}
</el-tag>
</template>
<template #options="scope">
{{ returnOptionsLabel(scope.prop, scope.row[scope.prop]) }}
</template>
<template #switch="scope">
<el-switch
v-model="scope.row[scope.prop]"
disabled
:active-value="1"
:inactive-value="0"
></el-switch>
</template>
<template #mobile="scope">
<el-text>{{ scope.row[scope.prop] }}</el-text>
<copy-button
v-if="scope.row[scope.prop]"
:text="scope.row[scope.prop]"
style="margin-left: 2px"
/>
</template>
</page-content>
<!-- 新增 -->
<page-modal
ref="addModalRef"
:modal-config="addModalConfig"
@submit-click="handleSubmitClick"
></page-modal>
<!-- 编辑 -->
<page-modal
ref="editModalRef"
:modal-config="editModalConfig"
@submit-click="handleSubmitClick"
></page-modal>
</div>
</template>
<script setup lang="ts">
import VersionApi from "@/api/system/version";
import type { IObject, IOperatData } from "@/components/CURD/types";
import usePage from "@/components/CURD/usePage";
import addModalConfig from "./config/add";
import contentConfig from "./config/content";
import editModalConfig from "./config/edit";
import searchConfig from "./config/search";
import { returnOptionsLabel } from "./config/config";
const {
searchRef,
contentRef,
addModalRef,
editModalRef,
handleQueryClick,
handleResetClick,
// handleAddClick,
// handleEditClick,
handleSubmitClick,
handleExportClick,
handleSearchClick,
handleFilterChange,
} = usePage();
// 新增
async function handleAddClick() {
addModalRef.value?.setModalVisible();
// addModalConfig.formItems[2]!.attrs!.data =
}
// 编辑
async function handleEditClick(row: IObject) {
editModalRef.value?.handleDisabled(false);
editModalRef.value?.setModalVisible();
// 根据id获取数据进行填充
console.log(row);
editModalRef.value?.setFormData({ ...row });
}
1;
// 其他工具栏
function handleToolbarClick(name: string) {
console.log(name);
if (name === "custom1") {
ElMessage.success("点击了自定义1按钮");
}
}
// 其他操作列
async function handleOperatClick(data: IOperatData) {
console.log(data);
}
</script>

View File

@@ -1,147 +0,0 @@
<template>
<div class="Table">
<!-- 按钮 -->
<AddButton @add="add"></AddButton>
<!-- 表格 -->
<Table :list="datas.tableData" @handleDelete="handleDelete" @handleEdit="handleEdit"></Table>
<!-- 分页 -->
<Paging :pagingConfig="datas.pagingConfig" @sizeChange="sizeChange" @currentChange="currentChange"></Paging>
<!-- 其他模板 -->
<!-- 新增/编辑 -->
<myDialog ref="myDialogRef" :title="datas.title" @confirm="confirm" width="30%">
<el-form ref="ruleFormRef" :rules="datas.rules" :model="datas.DialogForm" label-width="80px">
<el-form-item label="供应商" prop="name">
<el-input v-model="datas.DialogForm.name" placeholder="请输入供应商名称" />
</el-form-item>
<el-form-item label="联系电话">
<el-input v-model="datas.DialogForm.telephone" placeholder="请输入联系电话" />
</el-form-item>
<el-form-item label="地址">
<el-input v-model="datas.DialogForm.address" placeholder="请输入地址" type="textarea" />
</el-form-item>
<el-form-item label="备注">
<el-input v-model="datas.DialogForm.remark" placeholder="请输入备注" type="textarea" />
</el-form-item>
</el-form>
</myDialog>
</div>
</template>
<script setup>
import AddButton from './component/AddButton.vue'
import Table from './component/Table.vue'
import Paging from './component/Paging.vue'
import myDialog from '@/components/mycomponents/myDialog.vue'
import eventBus from '@/utils/eventBus'
import API from './api'
const datas = reactive({
tableData: [], // 表格数据
title: '新增数据',
pagingConfig: {
total: 0, // 总数
pageSize: 10, // 每页数据数量
pageNumber: 1, // 当前页码
},
DialogForm: { // 弹窗表单数据
name: "",
telephone: "",
address: "",
remark: "",
sort: "1",
},
rules: {
name: [
{ required: true, message: '请输入供应商名称', trigger: 'blur' }
],
}
})
const myDialogRef = ref(null)
const ruleFormRef = ref(null)
onMounted(() => {
getList()
})
eventBus.on('search', (res) => {
getList(res)
})
async function getList(data = {}) {
const res = await API.getPage({ page: datas.pagingConfig.pageNumber, size: datas.pagingConfig.pageSize, ...data })
datas.tableData = res.records
datas.pagingConfig.total = res.totalRow
datas.pagingConfig.pageSize = res.pageSize
datas.pagingConfig.pageNumber = res.pageNumber
}
function add() {
rest()
datas.title = '新增数据'
myDialogRef.value.open()
}
async function handleEdit(row) {
datas.title = '编辑数据'
const res = await API.getinfo(row.id)
datas.DialogForm = res
myDialogRef.value.open()
}
async function confirm() {
ruleFormRef.value.validate(async valid => {
if (valid) {
let res = null
if (datas.title == '新增数据') {
res = await API.add(datas.DialogForm)
} else {
res = await API.update(datas.DialogForm)
}
if (res.code == 200) {
ElMessage({
message: '成功',
type: 'success',
})
getList()
rest()
myDialogRef.value.close()
}
}
})
}
// 重置
function rest() {
datas.DialogForm = { sort: "1" }
}
async function handleDelete(id) {
ElMessageBox.confirm("是否删除数据项?", "提示", {
confirmButtonText: "确定",
cancelButtonText: "取消",
type: "warning",
}).then(
async () => {
let res = await API.deleteByIds(id)
if (res.code == 200) {
ElMessage({
message: '删除成功',
type: 'success',
})
getList()
}
}
);
}
// 分页
function sizeChange(val) {
datas.pagingConfig.pageSize = val
getList()
}
function currentChange(val) {
datas.pagingConfig.pageNumber = val
getList()
}
</script>
<style scoped lang="scss">
.Table {
padding: 20px;
background-color: #fff;
border: 1px solid #e4e7ed;
margin-top: 20px;
border-radius: 4px;
}
</style>

View File

@@ -1,52 +0,0 @@
<template>
<div class="Search">
<el-form :inline="true" :model="formInline" class="demo-form-inline">
<el-form-item label="供应商:">
<el-input v-model="formInline.name" placeholder="请输入供应商" clearable />
</el-form-item>
<el-form-item label="类型:">
<el-select v-model="formInline.region" placeholder="请选择类型" clearable>
<el-option label="进货" value="shanghai" />
<el-option label="退货" value="beijing" />
</el-select>
</el-form-item>
<el-form-item>
<el-button type="primary" icon="Search" @click="onSubmit">搜索</el-button>
<el-button icon="Refresh" @click="reset">重置</el-button>
</el-form-item>
</el-form>
</div>
</template>
<script setup>
import eventBus from '@/utils/eventBus'
const formInline = reactive({
name: '',
region: '',
})
const onSubmit = () => {
eventBus.emit('search', formInline)
}
const reset = () => {
formInline.name = ''
formInline.region = ''
eventBus.emit('search', formInline)
}
</script>
<style scoped lang="scss">
.Search {
padding: 20px;
background-color: #fff;
border: 1px solid #e4e7ed;
border-radius: 4px;
}
.demo-form-inline .el-input {
--el-input-width: 220px;
}
.demo-form-inline .el-select {
--el-select-width: 220px;
}
</style>

View File

@@ -1,60 +0,0 @@
import request from "@/utils/request";
const baseURL = "/product/admin/product/vendor";
// 供应商管理
const AuthAPI = {
// 列表
getList(params: any) {
return request<any, Responseres>({
url: `${baseURL}/list`,
method: "get",
params,
});
},
/** 分页*/
getPage(params: any) {
return request<any, Responseres>({
url: `${baseURL}/page`,
method: "get",
params,
});
},
// 新增
add(data: any) {
return request<any, Responseres>({
url: `${baseURL}`,
method: "post",
data: { ...data },
});
},
// 详情
getinfo(id: number) {
return request<any, Responseres>({
url: `${baseURL}/${id}`,
method: "get",
});
},
// 编辑
update(data: Object) {
return request<any, Responseres>({
url: `${baseURL}`,
method: "put",
data,
});
},
// 删除
deleteByIds(id: number | String) {
return request<any, Responseres>({
url: `${baseURL}/${id}`,
method: "delete",
});
},
};
export interface Responseres {
code?: number | null;
data?: any;
msg?: null | string;
[property: string]: any;
}
export default AuthAPI;

View File

@@ -1,9 +0,0 @@
<template>
<el-button type="primary" icon="Plus" @click="addEvent">新增</el-button>
</template>
<script setup>
const emit = defineEmits(['add']);
function addEvent() {
emit('add');
}
</script>

View File

@@ -1,24 +0,0 @@
<template>
<div style="margin-top: 10px;">
<el-pagination background :page-size="props.pagingConfig.pageSize" :page-sizes="[10, 20, 30, 40]"
layout="prev,pager,next,jumper,total,sizes" v-model:current-page="props.pagingConfig.pageNumber"
:total="props.pagingConfig.total" @size-change="handleSizeChange" @current-change="handleCurrentChange" />
</div>
</template>
<script setup>
const props = defineProps({
pagingConfig: {
type: Object,
default: () => { }
}
})
const emit = defineEmits(['sizeChange', 'currentChange'])
// 当前条改变
function handleSizeChange(val) {
emit('sizeChange', val)
}
// 当前页改变
function handleCurrentChange(val) {
emit('currentChange', val)
}
</script>

View File

@@ -1,48 +0,0 @@
<template>
<div style="margin-top: 10px;">
<el-table :data="props.list" border style="width: 100%">
<el-table-column prop="name" label="供应商" />
<el-table-column prop="telephone" label="联系电话" />
<el-table-column prop="address" label="地址" />
<el-table-column prop="remark" label="备注" />
<el-table-column prop="date" label="剩余付款金额" />
<el-table-column prop="date" label="待付款笔数" />
<el-table-column prop="date" label="状态" />
<el-table-column prop="lastTransactTime" label="上笔进货日期" />
<el-table-column label="操作" width="250">
<template #default="scope">
<el-button size="small" type="primary" link icon="Edit" @click="handleEdit(scope.row)">编辑</el-button>
<el-button size="small" type="danger" link icon="Delete" style="color: #f89797;"
@click="handleDelete(scope.$index, scope.row)"> 删除 </el-button>
<el-button size="small" type="primary" link @click="PaymentRecord()">结款记录</el-button>
</template>
</el-table-column>
</el-table>
</div>
</template>
<script setup>
import { useRouter } from 'vue-router';
const router = useRouter()
const emit = defineEmits(['handleDelete'])
const props = defineProps({
list: {
type: Array,
default: () => []
}
})
function handleEdit(row) {
emit('handleEdit', row)
}
async function handleDelete(index, row) {
emit('handleDelete', row.id)
}
function PaymentRecord() {
router.push({ name: 'paymentRecord' });
}
</script>

View File

@@ -192,6 +192,7 @@ function handleLogin() {
.login(user)
.then(async (res) => {
await userStore.getUserInfo();
await $douyin_checkIn();
const { path, queryParams } = parseRedirect();
console.log(res, "Denglv返回");

View File

@@ -38,12 +38,12 @@
<el-input v-model="form.alipayAppToken" placeholder="请输入支付宝商户密钥"></el-input>
</el-form-item> -->
<el-form-item label="状态">
<!-- <el-form-item label="状态">
<el-radio-group v-model="form.status">
<el-radio :value="1">启用</el-radio>
<el-radio :value="-1">禁用</el-radio>
</el-radio-group>
</el-form-item>
</el-form-item> -->
</el-form>
</el-tab-pane>
</el-tabs>