Compare commits

...

9 Commits

Author SHA1 Message Date
Alex Ant 72674cba10 chore(release): publish
- coopback@1.7.28
 - terminal@0.1.31
2024-07-26 18:42:47 +05:00
Alex Ant 495a8e2d1e chore(release): publish
- coopback@1.7.28-alpha.0
 - terminal@0.1.31-alpha.0
2024-07-26 18:41:33 +05:00
Alex Ant 95ae221d60 Добавление платежных реквизитов | удаление | просмотр | свайп в рамках страницы 2024-07-26 18:38:14 +05:00
Alex Ant 857f746da1 bug fix 2024-07-26 11:03:52 +05:00
Alex Ant 0e2e3052b1 works 2024-07-25 21:00:04 +05:00
Alex Ant 167c04cc3f commit 2024-07-25 20:47:42 +05:00
Alex Ant 043f51479a looking for bug #2 2024-07-25 20:30:56 +05:00
Alex Ant 921282df81 looking for bug 2024-07-25 20:20:44 +05:00
Alex Ant b3c641501c migration 2024-07-25 20:07:44 +05:00
42 changed files with 10700 additions and 12878 deletions
+8
View File
@@ -3,6 +3,14 @@
All notable changes to this project will be documented in this file.
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
## [1.7.28](https://github.com/hagopj13/node-express-boilerplate/compare/coopback@1.7.28-alpha.0...coopback@1.7.28) (2024-07-26)
**Note:** Version bump only for package coopback
## [1.7.27](https://github.com/hagopj13/node-express-boilerplate/compare/coopback@1.7.27-alpha.5...coopback@1.7.27) (2024-07-25)
**Note:** Version bump only for package coopback
+2 -2
View File
@@ -1,12 +1,12 @@
{
"name": "create-nodejs-express-app",
"version": "1.7.27",
"version": "1.7.28",
"lockfileVersion": 3,
"requires": true,
"packages": {
"": {
"name": "create-nodejs-express-app",
"version": "1.7.27",
"version": "1.7.28",
"license": "MIT",
"dependencies": {
"@a2seven/yoo-checkout": "^1.1.4",
+1 -1
View File
@@ -1,6 +1,6 @@
{
"name": "coopback",
"version": "1.7.27",
"version": "1.7.28",
"description": "",
"private": true,
"bin": "bin/createNodejsApp.js",
@@ -0,0 +1,43 @@
import config from '../../src/config/config';
import { User } from '../../src/models';
import { tokenService } from '../../src/services';
import { userService } from '../../src/services';
import mongoose from 'mongoose';
import { connectGenerator } from '../../src/services/document.service';
import crypto from 'crypto';
import bcryptjs from 'bcryptjs';
const { compare, hash } = bcryptjs;
async function init() {
try {
await connectGenerator();
await mongoose.connect(config.mongoose.url, config.mongoose.options);
const orgs_collection = mongoose.connection.collection('OrgData');
const bankData_collection = mongoose.connection.collection('PaymentData');
const orgs = await orgs_collection.find().toArray();
for (const org of orgs) {
await bankData_collection.insertOne({
_created_at: org._created_at,
username: org.username,
method_id: 1,
user_type: 'organization',
method_type: 'bank_transfer',
is_default: true,
data: org.bank_account,
deleted: false,
block_num: org.block_num,
});
}
} catch (e: any) {
console.log('Ошибка: ', e);
}
process.exit(0);
}
init();
@@ -80,6 +80,14 @@ export const addPaymentMethod = catchAsync(async (req: RSavePaymentMethod, res)
const user = await getUserByUsername(req.body.username);
const method = req.body as any;
if (method.method_type === 'sbp' && !method.data.phone)
throw new ApiError(httpStatus.BAD_REQUEST, 'Не указан телефон для метода СБП');
if (method.method_type === 'bank_transfer' && !method.data.account_number)
throw new ApiError(httpStatus.BAD_REQUEST, 'Не верно указаны реквизиты для банковского платежа');
const paymentData: Cooperative.Payments.IPaymentData = {
username: req.body.username,
method_id: req.body.method_id,
@@ -40,23 +40,16 @@ export const getUsers = catchAsync(async (req, res) => {
const filter = pick(req.query, ['username', 'role']);
const options = pick(req.query, ['sortBy', 'limit', 'page']);
Object.keys(filter).forEach((key) => {
if (filter[key] !== undefined) {
filter[key] = { $eq: filter[key], $ne: 'service' };
} else {
filter[key] = { $ne: 'service' };
}
});
const users = await userService.queryUsers(filter, options);
const result = {} as IGetResponse<IUser>;
//TODO wrong format answer
const data = [] as any;
for await (let user of users.results) {
const json = user.toJSON();
json.private_data = (await user.getPrivateData()) || {};
data.push(json);
if (user.type != 'service') {
json.private_data = (await user.getPrivateData()) || {};
data.push(json);
}
}
result.results = data;
+8
View File
@@ -3,6 +3,14 @@
All notable changes to this project will be documented in this file.
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
## [0.1.31](https://github.com/coopenomics/monocoop/compare/terminal@0.1.31-alpha.0...terminal@0.1.31) (2024-07-26)
**Note:** Version bump only for package terminal
## [0.1.30](https://github.com/coopenomics/monocoop/compare/terminal@0.1.30-alpha.4...terminal@0.1.30) (2024-07-25)
**Note:** Version bump only for package terminal
+2 -1
View File
@@ -1,6 +1,6 @@
{
"name": "terminal",
"version": "0.1.30",
"version": "0.1.31",
"description": "A Terminal Project",
"productName": "Terminal App",
"author": "Alex Ant <dacom.dark.sun@gmail.com>",
@@ -44,6 +44,7 @@
"pinia-plugin-persistedstate": "^3.2.1",
"pug": "^3.0.3",
"quasar": "^2.16.0",
"swiper": "^11.1.7",
"vite": "2.9.16",
"vue": "^3.4.18",
"vue-i18n": "^9.2.2",
+2
View File
@@ -3,6 +3,8 @@ router-view(v-if="isLoaded")
</template>
<script setup lang="ts">
console.log('on start')
import { onMounted, ref } from 'vue'
import { FailAlert } from 'src/shared/api/alerts'
import { handleException } from 'src/shared/api';
@@ -45,6 +45,7 @@ export default route(function (/* { store, ssrContext } */) {
from: RouteLocationNormalizedGeneric,
next: any
) => {
const currentUser = useCurrentUserStore();
const session = useSessionStore();
@@ -63,14 +64,17 @@ export default route(function (/* { store, ssrContext } */) {
menuStore.setRoutes(routes)
if (to.name == 'index') {
if (session.isAuth)
console.log('7')
if (session.isAuth){
next({ name: AUTHORIZED_HOME_PAGE, params: { coopname: COOPNAME } });
else
return
} else {
next({
name: NOT_AUTHORIZED_HOME_PAGE,
params: { coopname: COOPNAME },
});
return;
return;
}
}
if (hasAccess(to, currentUser.userAccount)) {
@@ -1,24 +0,0 @@
import { sendGET, sendPOST } from 'src/shared/api';
import { IAddPaymentMethod, IDeletePaymentMethod, IGetPaymentMethods, IPaymentData } from '../model';
async function loadMethods(params: IGetPaymentMethods): Promise<IPaymentData> {
const {username} = params
const methods = (await sendGET('/v1/payments/methods', {username})) as IPaymentData;
return methods;
}
async function addMethod(params: IAddPaymentMethod): Promise<void> {
await sendPOST(`/v1/payments/methods/${params.username}/add`, params)
}
async function deleteMethod(params: IDeletePaymentMethod): Promise<void>{
const {username, method_id} = params
await sendPOST(`/v1/payments/methods/${username}/delete`, {method_id})
}
export const api = {
loadMethods,
addMethod,
deleteMethod
}
@@ -1,2 +0,0 @@
export * from './stores'
export * from './types'
@@ -1,40 +0,0 @@
import { defineStore } from 'pinia';
import { ref, Ref } from 'vue';
import { api } from '../api';
import { IAddPaymentMethod, IDeletePaymentMethod, IGetPaymentMethods, IPaymentData } from './types';
interface IPaymentStore {
//методы
loadMethods(params: IGetPaymentMethods): Promise<void>;
addMethod(params: IAddPaymentMethod): Promise<void>
deleteMethod(params: IDeletePaymentMethod): Promise<void>
paymentMethods: Ref<IPaymentData | null>
}
const namespace = 'payments';
export const useCurrentUserStore = defineStore(
namespace,
(): IPaymentStore => {
const loadMethods = async(params: IGetPaymentMethods): Promise<void> => {
paymentMethods.value = await api.loadMethods(params)
}
const addMethod = async(params: IAddPaymentMethod): Promise<void> => {
await api.addMethod(params)
}
const deleteMethod = async(params: IDeletePaymentMethod): Promise<void> => {
await api.deleteMethod(params)
}
const paymentMethods = ref<IPaymentData | null>(null)
return {
loadMethods,
addMethod,
deleteMethod,
paymentMethods
}
})
@@ -1,31 +0,0 @@
import { Cooperative } from 'cooptypes';
export type IPaymentData = Cooperative.Documents.IGetResponse<Cooperative.Payments.IPaymentData>
export interface IGetPaymentMethods {
username?: number
}
export interface IDeletePaymentMethod {
username: number;
method_id: number;
}
export interface IAddPaymentMethod {
username: string;
method_id: number;
method_type: 'sbp' | 'bank_transfer';
data: {
phone: string;
} | ({
account_number: string;
bank_name: string;
card_number?: string;
currency: 'RUB' | 'Other';
details: {
bik: string;
corr: string;
kpp: string;
};
});
}
@@ -1,4 +1,4 @@
import { fetchTable } from '../../../shared/api';
import { fetchTable, sendGET } from '../../../shared/api';
import {
ContractsList,
@@ -14,6 +14,9 @@ import {
IProgramWalletData,
ICoopMarketProgramData,
ExtendedProgramWalletData,
IGetPaymentMethods,
IGetResponsePaymentMethodData,
IPaymentMethodData,
} from '../model';
import {
@@ -153,6 +156,14 @@ async function loadUserProgramWalletsData(
return extendedProgramWallets;
}
async function loadMethods(params: IGetPaymentMethods): Promise<IPaymentMethodData[]> {
const {username} = params
const methods = (await sendGET(`/v1/payments/methods/${username}`)) as IGetResponsePaymentMethodData;
return methods.results;
}
export const api = {
loadSingleUserWalletData,
loadSingleUserDepositData,
@@ -161,4 +172,5 @@ export const api = {
loadUserDepositsData,
loadUserWithdrawsData,
loadUserProgramWalletsData,
loadMethods
};
@@ -7,6 +7,7 @@ import {
IPaymentOrder,
ExtendedProgramWalletData,
ICreateWithdraw,
IPaymentMethodData,
} from './types';
import { ILoadUserWallet, ICreateDeposit } from './types';
import { Ref, ref } from 'vue';
@@ -21,16 +22,28 @@ interface IWalletStore {
program_wallets: Ref<ExtendedProgramWalletData[]>;
deposits: Ref<IDepositData[]>;
withdraws: Ref<IWithdrawData[]>;
methods: Ref<IPaymentMethodData[]>;
update: (params: ILoadUserWallet) => Promise<void>;
//TODO move to Features
createDeposit: (params: ICreateDeposit) => Promise<IPaymentOrder>;
createWithdraw: (params: ICreateWithdraw) => Promise<void>;
}
export const useWalletStore = defineStore(namespace, (): IWalletStore => {
const wallet = ref({} as IWalletData);
const deposits = ref([] as IDepositData[]);
const withdraws = ref([] as IWithdrawData[]);
const program_wallets = ref([] as ExtendedProgramWalletData[]);
const wallet = ref<IWalletData>({
username: '',
coopname: '',
available: `0.0000 ${CURRENCY}`,
blocked: `0.0000 ${CURRENCY}`,
minimum: `0.0000 ${CURRENCY}`,
});
const deposits = ref<IDepositData[]>([]);
const withdraws = ref<IWithdrawData[]>([]);
const program_wallets = ref<ExtendedProgramWalletData[]>([]);
const methods = ref<IPaymentMethodData[]>([]);
const createEmptyWallet = (): IWalletData => ({
username: '',
@@ -40,6 +53,7 @@ export const useWalletStore = defineStore(namespace, (): IWalletStore => {
minimum: `0.0000 ${CURRENCY}`,
});
const update = async (params: ILoadUserWallet) => {
try {
const data = await Promise.all([
@@ -47,11 +61,14 @@ export const useWalletStore = defineStore(namespace, (): IWalletStore => {
api.loadUserDepositsData(params),
api.loadUserWithdrawsData(params),
api.loadUserProgramWalletsData(params),
api.loadMethods(params)
]);
wallet.value = data[0] ?? createEmptyWallet();
deposits.value = data[1] ?? [];
withdraws.value = data[2] ?? [];
program_wallets.value = data[3] ?? [];
methods.value = data[4] ?? [];
} catch (e: any) {
console.log(e);
}
@@ -72,6 +89,7 @@ export const useWalletStore = defineStore(namespace, (): IWalletStore => {
program_wallets,
deposits,
withdraws,
methods,
update,
createDeposit,
createWithdraw,
@@ -74,3 +74,17 @@ export interface IPaymentOrder {
export interface ICreateWithdraw {
quantity: string;
}
import { Cooperative } from 'cooptypes';
export type IPaymentMethodData = Cooperative.Payments.IPaymentData
export type IGetResponsePaymentMethodData = Cooperative.Documents.IGetResponse<IPaymentMethodData>
export interface IGetPaymentMethods {
username?: string
}
export interface IDeletePaymentMethod {
username: string;
method_id: number;
}
@@ -4,13 +4,13 @@ const walletStore = useWalletStore()
</script>
<template lang="pug">
div.row.flex.justify-between.q-pa-sm
div
div.row.flex.justify-around.q-pa-sm
div.q-mt-md
span.text-grey Паевый счёт
p {{ walletStore.wallet.available }}
p.text-h3 {{ walletStore.wallet.available }}
div.text-right
div.q-mt-md.text-right
span.text-grey Членский счёт
p {{ walletStore.wallet.blocked }}
p.text-h3 {{ walletStore.wallet.blocked }}
</template>
@@ -0,0 +1,2 @@
export * as AddPaymentMethodModel from './model'
export * from './ui'
@@ -0,0 +1,54 @@
import { useSessionStore } from 'src/entities/Session'
import { useWalletStore } from 'src/entities/Wallet'
import { sendPOST } from 'src/shared/api';
import { COOPNAME } from 'src/shared/config'
export interface ISBPData {
phone: string;
}
export interface IBankTransferData {
account_number: string;
bank_name: string;
card_number?: string;
currency: string;
details: {
bik: string;
corr: string;
kpp: string;
};
}
export interface IAddPaymentMethod {
username: string;
method_id: number;
method_type: 'sbp' | 'bank_transfer';
data: ISBPData | IBankTransferData;
}
export function useAddPaymentMethod() {
const store = useWalletStore()
const session = useSessionStore()
async function addPaymentMethod(params: IAddPaymentMethod) {
await store.update({
coopname: COOPNAME,
username: params.username,
})
params.method_id = store.methods.length + 1
await sendPOST(`/v1/payments/methods/${params.username}/add`, params)
await store.update({
coopname: COOPNAME,
username: session.username
})
}
return {
addPaymentMethod
}
}
@@ -0,0 +1,161 @@
<template lang="pug">
div
q-btn(@click="showDialog=true" outline) добавить метод
q-dialog(v-model="showDialog" @hide="clear")
ModalBase(:title='"Добавить метод платежа"' )
Form(:handler-submit="handlerSubmit" :is-submitting="isSubmitting" :button-cancel-txt="'Отменить'" :button-submit-txt="'Продолжить'" @cancel="clear").q-pa-sm
q-select(v-model="methodType" filled :options="methods" map-options emit-value option-label="title" option-value="value" label="Выберите способ получения платежа" :rules="[val => notEmpty(val)]")
div(v-if="methodType=='sbp'")
q-input(v-model="sbp.phone" filled mask="+7 (###) ###-##-##" fill-mask label="Номер телефона" hint="Имя и фамилия получателя должны совпадать с теми, которые указаны в Удостоверении." :rules="[val => notEmpty(val)]" autocomplete="off").q-mb-lg
div(v-if="methodType=='bank_transfer'")
q-select(
v-model="bank_transfer.currency"
label="Валюта счёта"
filled
:options="[{ label: 'RUB', value: 'RUB' }]"
emit-value
:rules="[val => notEmpty(val)]"
map-options
)
q-input(
v-model="bank_transfer.bank_name"
filled
label="Наименование банка"
:rules="[val => notEmpty(val)]"
autocomplete="off"
)
q-input(
v-model="bank_transfer.details.corr"
filled
mask="####################"
label="Корреспондентский счет"
:rules="[val => notEmpty(val), val => val.length === 20 || 'ожидаем 20 цифр']"
autocomplete="off"
)
q-input(
v-model="bank_transfer.details.bik"
filled
mask="#########"
label="БИК"
:rules="[val => notEmpty(val), val => val.length === 9 || 'ожидаем 9 цифр']"
autocomplete="off"
)
q-input(
v-model="bank_transfer.details.kpp"
filled
mask="#########"
label="КПП"
:rules="[val => notEmpty(val), val => val.length === 9 || 'ожидаем 9 цифр']"
autocomplete="off"
)
q-input(
v-model="bank_transfer.account_number"
filled
mask="####################"
label="Номер счета"
:rules="[val => notEmpty(val), val => val.length === 20 || 'ожидаем 20 цифр']"
autocomplete="off"
hint="Имя и фамилия получателя должны совпадать с теми, которые указаны в Удостоверении."
).q-mb-lg
</template>
<script lang="ts" setup>
import { computed, ref } from 'vue';
import { useAddPaymentMethod } from '../model';
import { FailAlert } from 'src/shared/api';
import { ModalBase } from 'src/shared/ui/ModalBase';
import { Form } from 'src/shared/ui/Form';
const props = defineProps({
username: {
type: String,
required: true,
},
})
const username = computed(() => props.username)
const methodType = ref()
const methods = ref([{
title: 'Система Быстрых Платежей (СБП)',
value: 'sbp'
}, {
title: 'Банковский перевод',
value: 'bank_transfer'
}])
const notEmpty = (val: any) => {
return !!val || 'Это поле обязательно для заполнения'
}
const showDialog = ref(false)
const isSubmitting = ref(false)
const sbp = ref({ phone: '' })
const bank_transfer = ref({
account_number: '',
bank_name: '',
currency: 'RUB',
details: {
bik: '',
corr: '',
kpp: '',
}
})
const clear = (): void => {
showDialog.value = false
sbp.value = { phone: '' }
bank_transfer.value = {
account_number: '',
bank_name: '',
currency: 'RUB',
details: {
bik: '',
corr: '',
kpp: '',
}
}
}
const { addPaymentMethod } = useAddPaymentMethod()
const handlerSubmit = async (): Promise<void> => {
isSubmitting.value = true
try {
let data = null
if (methodType.value === 'sbp')
data = sbp.value
else if (methodType.value === 'bank_transfer')
data = bank_transfer.value
if (data != null)
await addPaymentMethod({
username: username.value,
method_id: 0, //autogenerate
method_type: methodType.value,
data
})
showDialog.value = false
isSubmitting.value = false
clear()
} catch (e: any) {
showDialog.value = false
isSubmitting.value = false
FailAlert(e.message)
}
}
</script>
@@ -0,0 +1 @@
export {default as AddPaymentMethodButton } from './AddPaymentButton.vue'
@@ -1,2 +1 @@
export * from './api'
export * from './model'
@@ -0,0 +1,29 @@
import { useSessionStore } from 'src/entities/Session'
import { useWalletStore } from 'src/entities/Wallet'
import { sendPOST } from 'src/shared/api';
import { COOPNAME } from 'src/shared/config'
export interface IDeletePaymentMethod {
username: string;
method_id: number;
}
export function useDeletePaymentMethod() {
const store = useWalletStore()
const session = useSessionStore()
async function deletePaymentMethod(params: IDeletePaymentMethod) {
const {username, method_id} = params
await sendPOST(`/v1/payments/methods/${username}/delete`, {method_id})
await store.update({
coopname: COOPNAME,
username: session.username
})
}
return {
deletePaymentMethod
}
}
@@ -0,0 +1,67 @@
<template lang="pug">
div
q-btn(@click="showDialog=true" :size="size" flat) удалить
q-icon(name="close")
q-dialog(v-model="showDialog" @hide="clear")
ModalBase(:title='"Удалить метод платежа"' )
Form(:handler-submit="handlerSubmit" :is-submitting="isSubmitting" :button-cancel-txt="'Отменить'" :button-submit-txt="'Продолжить'" @cancel="clear").q-pa-sm
p Вы уверены, что хотите удалить метод платежа?
</template>
<script lang="ts" setup>
import { computed, ref } from 'vue';
import { useDeletePaymentMethod } from '../model';
import { FailAlert, SuccessAlert } from 'src/shared/api';
import { ModalBase } from 'src/shared/ui/ModalBase';
import { Form } from 'src/shared/ui/Form';
const props = defineProps({
username: {
type: String,
required: true,
},
method_id: {
type: Number,
required: true,
},
size: {
type: String,
required: false,
default: 'md'
}
})
const username = computed(() => props.username)
const showDialog = ref(false)
const isSubmitting = ref(false)
const clear = (): void => {
showDialog.value = false
}
const { deletePaymentMethod } = useDeletePaymentMethod()
const handlerSubmit = async (): Promise<void> => {
isSubmitting.value = true
try {
await deletePaymentMethod({
username: username.value,
method_id: props.method_id
})
showDialog.value = false
isSubmitting.value = false
SuccessAlert('Метод платежа успешно удалён')
} catch (e: any) {
showDialog.value = false
isSubmitting.value = false
FailAlert(e.message)
}
}
</script>
@@ -0,0 +1 @@
export {default as DeletePaymentButton} from './DeletePaymentMethodButton.vue'
@@ -1,6 +1,6 @@
<template lang="pug">
div.DepositPreparator
q-btn(color="primary" @click="showDialog=true") Совершить взнос
q-btn(@click="showDialog=true" outline) Совершить взнос
q-dialog(v-model="showDialog" @hide="clear")
ModalBase(v-if="!paymentOrder" :title='"Введите сумму"' )
Form(:handler-submit="handlerSubmit" :is-submitting="isSubmitting" :button-cancel-txt="'Отменить'" :button-submit-txt="'Продолжить'" @cancel="clear").q-pa-sm
@@ -1,6 +1,6 @@
<template lang="pug">
div
q-btn(color="primary" @click="showDialog = true") получить возврат
q-btn(@click="showDialog = true" outline) получить возврат
q-dialog(v-model="showDialog" @hide="clear")
ModalBase( :title='"Введите сумму"' )
@@ -1,7 +1,6 @@
<template lang="pug">
div.row.justify-center
div.col-md-6.col-xs-12.q-mt-lg
p.text-h6.text-center Контакты
div.col-md-6.col-xs-12
CooperativeContacts.full-width
@@ -1,26 +1,41 @@
<template lang="pug">
div
q-tabs( v-model="tab" dense switch-indicator inline-label outside-arrows mobile-arrows align="justify" active-bg-color="teal" active-color="white" indicator-color="secondary" style="border-bottom: 1px solid teal;")
q-tab(name="Удостоверение" label="Удостоверение")
q-tab(name="Кошелёк" label="Кошелёк")
q-tab(name="Реквизиты" label="Реквизиты")
q-tab-panels(
swipeable
v-model="tab"
animated
transition-prev="fade"
transition-next="fade"
style="background: none !important;"
style="background: none !important; min-height: 85vh;"
)
q-tab-panel(name="Удостоверение")
PersonalCard(:username="username")
q-tab-panel(name="Кошелёк")
CompositeWalletCard
WalletCard(:username="username")
q-tab-panel(name="Реквизиты")
PaymentMethodsCard(:username="username")
</template>
<script lang="ts" setup>
import { CompositeWalletCard } from 'src/widgets/Wallet';
// import { CompositeWalletCard } from 'src/widgets/Wallet';
import { PaymentMethodsCard } from 'src/widgets/Wallet/PaymentMethods';
import { PersonalCard } from 'src/widgets/Wallet/PersonalCard/ui'
import { WalletCard } from 'src/widgets/Wallet/WalletCard'
import { ref } from 'vue';
import { computed, ref } from 'vue';
import { useCurrentUserStore } from 'src/entities/User';
const tab = ref('Кошелёк')
const currentUser = useCurrentUserStore()
const username = computed(() => currentUser.username)
const tab = ref('Удостоверение')
</script>
@@ -24,7 +24,7 @@ const cancel = (): void => {
q-form(@submit.prevent="handlerSubmit")
template(#default)
slot
div.flex.q-mt-sm
div.flex.q-mt-md
q-btn(v-if="showCancel" flat @click="cancel") {{ buttonCancelTxt }}
q-btn(:class="{'full-width': !showCancel}" type="submit" :loading="isSubmitting" color="primary") {{ buttonSubmitTxt }}
@@ -1,6 +1,7 @@
<template lang="pug">
div
q-card(v-if="contacts && contacts.details" flat bordered).q-pa-sm
//- p.text-h6.text-center Контакты
q-input(type="textarea" autogrow readonly label="Наименование организации" v-model="contacts.full_name")
q-input(type="textarea" autogrow readonly label="ИНН" v-model="contacts.details.inn")
q-input(type="textarea" autogrow readonly label="ОГРН" v-model="contacts.details.ogrn")
@@ -12,12 +13,12 @@ div
</template>
<script lang="ts" setup>
import { useCooperativeStore } from 'src/entities/Cooperative';
import { computed } from 'vue';
import { useCooperativeStore } from 'src/entities/Cooperative';
import { computed } from 'vue';
const cooperative = useCooperativeStore()
cooperative.loadContacts()
const cooperative = useCooperativeStore()
cooperative.loadContacts()
const contacts = computed(() => cooperative.contacts)
const chairman = computed(() => `${contacts.value?.chairman?.last_name} ${contacts.value?.chairman?.first_name} ${contacts.value?.chairman?.middle_name}`)
const contacts = computed(() => cooperative.contacts)
const chairman = computed(() => `${contacts.value?.chairman?.last_name} ${contacts.value?.chairman?.first_name} ${contacts.value?.chairman?.middle_name}`)
</script>
@@ -19,7 +19,7 @@ const localCoop = ref({
})
const save = async () => {
const {updateCoop} = useUpdateCoop()
const { updateCoop } = useUpdateCoop()
const session = useSessionStore()
if (coop.publicCooperativeData)
try {
@@ -36,7 +36,7 @@ const save = async () => {
await coop.loadPublicCooperativeData(COOPNAME)
SuccessAlert('Размеры взносов успешно обновлены')
} catch(e: any){
} catch (e: any) {
FailAlert(`${e.message}`)
}
else {
@@ -75,5 +75,6 @@ div.q-pa-md
q-input(filled v-model="localCoop.org_minimum" label="Минимальный паевый взнос")
template(#append)
p.q-pa-sm {{ CURRENCY }}
q-btn(@click="save") Сохранить
q-btn(@click="save" outline) Сохранить
</template>
@@ -16,7 +16,7 @@ div
).full-height
template(#top)
q-btn(icon="add" @click="showAdd = true") добавить участника
q-btn(icon="add" @click="showAdd = true" outline) добавить участника
template(#header="props")
@@ -124,7 +124,7 @@ const addMember = async () => {
try {
await updateBoard(members_for_send)
} catch(e:any){
} catch (e: any) {
}
@@ -147,7 +147,7 @@ const removeMember = async (username: string) => {
try {
await updateBoard(members_for_send)
} catch(e:any){
} catch (e: any) {
}
showLoading.value = false
@@ -1 +1 @@
export { default as CompositeWalletCard } from './WalletPage.vue'
export { default as CompositeWalletCard } from './CompositeWalletCard.vue'
@@ -0,0 +1 @@
export * from './ui'
@@ -0,0 +1,110 @@
<template lang="pug">
q-card(flat bordered).q-pa-md
AddPaymentMethodButton(:username="username")
q-list.full-width.q-mt-lg
q-item(v-for="method in wallet.methods" :key="method.method_id").q-mt-md.full-width
q-card(flat).full-width.row.justify-center
div(v-if="method.method_type ==='sbp' && isSBPData(method.data)").col-md-10.col-xs-12
div.flex.justify-between
q-badge
span {{ method.method_id }}
span(v-if="method.method_type ==='sbp'").q-pl-xs СБП
DeletePaymentButton(:size="'xs'" :username="username" :method_id="method.method_id")
q-input(v-model="method.data.phone" label="Номер телефона" filled readonly)
div(v-if="method.method_type ==='bank_transfer' && isBankTransferData(method.data)").col-md-10.col-xs-12
div.flex.justify-between
q-badge
span {{ method.method_id }}
span(v-if="method.method_type ==='bank_transfer'").q-pl-xs Банковский перевод
DeletePaymentButton(:size="'xs'" :username="username" :method_id="method.method_id")
q-select(
v-model="method.data.currency"
readonly
label="Валюта счёта"
filled
:options="[{ label: 'RUB', value: 'RUB' }]"
emit-value
map-options
)
q-input(
v-model="method.data.bank_name"
readonly
filled
label="Наименование банка"
autocomplete="off"
)
q-input(
v-model="method.data.details.corr"
filled
readonly
mask="####################"
label="Корреспондентский счет"
autocomplete="off"
)
q-input(
v-model="method.data.details.bik"
readonly
filled
mask="#########"
label="БИК"
autocomplete="off"
)
q-input(
v-model="method.data.details.kpp"
readonly
filled
mask="#########"
label="КПП"
autocomplete="off"
)
q-input(
v-model="method.data.account_number"
filled
readonly
mask="####################"
label="Номер счета"
autocomplete="off"
)
</template>
<script lang="ts" setup>
import { useWalletStore } from 'src/entities/Wallet';
import { COOPNAME } from 'src/shared/config';
import { computed } from 'vue';
import { AddPaymentMethodButton } from 'src/features/Wallet/AddPaymentMethod';
import type { IBankTransferData, ISBPData } from 'src/features/Wallet/AddPaymentMethod/model';
import { DeletePaymentButton } from 'src/features/Wallet/DeletePaymentMethod/ui';
const props = defineProps({
username: {
type: String,
required: true,
},
})
const wallet = useWalletStore()
const username = computed(() => props.username)
wallet.update({ coopname: COOPNAME, username: username.value })
function isSBPData(data: ISBPData | IBankTransferData): data is ISBPData {
return (data as ISBPData).phone !== undefined;
}
function isBankTransferData(data: ISBPData | IBankTransferData): data is IBankTransferData {
return (data as IBankTransferData).account_number !== undefined;
}
</script>
@@ -0,0 +1 @@
export {default as PaymentMethodsCard} from './PaymentMethods.vue'
@@ -2,7 +2,8 @@
q-card(v-if="currentUser?.username" flat bordered).q-pa-md.digital-certificate
div.row
div.col-md-4.col-xs-12
p.text-bold.full-width.text-sm.text-center УДОСТОВЕРЕНИЕ ПАЙЩИКА
//- p.text-bold.full-width.text-sm.text-center УДОСТОВЕРЕНИЕ ПАЙЩИКА
div(style="flex-grow: 1; display: flex; justify-content: center;")
AutoAvatar(style="width: 125px;" :username="currentUser.username").q-pa-sm.q-pt-lg
div.col-md-8.col-xs-12
@@ -61,39 +62,39 @@ q-card(v-if="currentUser?.username" flat bordered).q-pa-md.digital-certificate
</template>
<script lang="ts" setup>
import type { IEntrepreneurData, IIndividualData, IOrganizationData } from 'src/entities/User'
import { AutoAvatar } from '.';
import { useCurrentUserStore } from 'src/entities/User'
import { computed } from 'vue';
const currentUser = useCurrentUserStore()
import type { IEntrepreneurData, IIndividualData, IOrganizationData } from 'src/entities/User'
import { AutoAvatar } from '.';
import { useCurrentUserStore } from 'src/entities/User'
import { computed } from 'vue';
const currentUser = useCurrentUserStore()
const userType = computed(() => currentUser.userAccount?.type)
const userType = computed(() => currentUser.userAccount?.type)
const individualProfile = computed(() => {
if (userType.value === 'individual') {
return currentUser.userAccount?.private_data as IIndividualData
}
return null
})
const individualProfile = computed(() => {
if (userType.value === 'individual') {
return currentUser.userAccount?.private_data as IIndividualData
}
return null
})
const entrepreneurProfile = computed(() => {
if (userType.value === 'entrepreneur') {
return currentUser.userAccount?.private_data as IEntrepreneurData
}
return null
})
const entrepreneurProfile = computed(() => {
if (userType.value === 'entrepreneur') {
return currentUser.userAccount?.private_data as IEntrepreneurData
}
return null
})
const organizationProfile = computed(() => {
if (userType.value === 'organization') {
return currentUser.userAccount?.private_data as IOrganizationData
}
return null
})
const organizationProfile = computed(() => {
if (userType.value === 'organization') {
return currentUser.userAccount?.private_data as IOrganizationData
}
return null
})
const userProfile = computed(() => {
if (userType.value === 'individual' || userType.value === 'entrepreneur') {
return individualProfile?.value || entrepreneurProfile?.value
}
return organizationProfile?.value
})
</script>
const userProfile = computed(() => {
if (userType.value === 'individual' || userType.value === 'entrepreneur') {
return individualProfile?.value || entrepreneurProfile?.value
}
return organizationProfile?.value
})
</script>
@@ -1,5 +1,6 @@
<template lang="pug">
q-card(flat bordered).q-pa-md
//- p.text-bold.full-width.text-sm.text-center КОШЕЛЁК
WalletBalance
div.flex.justify-center.q-gutter-sm.q-pa-md
DepositButton
+10061 -12697
View File
File diff suppressed because it is too large Load Diff