feat: export excel open it in third app
This commit is contained in:
parent
8a4e1791b7
commit
2cce68fe0c
30
.metadata
30
.metadata
|
@ -4,7 +4,7 @@
|
||||||
# This file should be version controlled and should not be manually edited.
|
# This file should be version controlled and should not be manually edited.
|
||||||
|
|
||||||
version:
|
version:
|
||||||
revision: "300451adae589accbece3490f4396f10bdf15e6e"
|
revision: "41456452f29d64e8deb623a3c927524bcf9f111b"
|
||||||
channel: "stable"
|
channel: "stable"
|
||||||
|
|
||||||
project_type: app
|
project_type: app
|
||||||
|
@ -13,26 +13,26 @@ project_type: app
|
||||||
migration:
|
migration:
|
||||||
platforms:
|
platforms:
|
||||||
- platform: root
|
- platform: root
|
||||||
create_revision: 300451adae589accbece3490f4396f10bdf15e6e
|
create_revision: 41456452f29d64e8deb623a3c927524bcf9f111b
|
||||||
base_revision: 300451adae589accbece3490f4396f10bdf15e6e
|
base_revision: 41456452f29d64e8deb623a3c927524bcf9f111b
|
||||||
- platform: android
|
- platform: android
|
||||||
create_revision: 300451adae589accbece3490f4396f10bdf15e6e
|
create_revision: 41456452f29d64e8deb623a3c927524bcf9f111b
|
||||||
base_revision: 300451adae589accbece3490f4396f10bdf15e6e
|
base_revision: 41456452f29d64e8deb623a3c927524bcf9f111b
|
||||||
- platform: ios
|
- platform: ios
|
||||||
create_revision: 300451adae589accbece3490f4396f10bdf15e6e
|
create_revision: 41456452f29d64e8deb623a3c927524bcf9f111b
|
||||||
base_revision: 300451adae589accbece3490f4396f10bdf15e6e
|
base_revision: 41456452f29d64e8deb623a3c927524bcf9f111b
|
||||||
- platform: linux
|
- platform: linux
|
||||||
create_revision: 300451adae589accbece3490f4396f10bdf15e6e
|
create_revision: 41456452f29d64e8deb623a3c927524bcf9f111b
|
||||||
base_revision: 300451adae589accbece3490f4396f10bdf15e6e
|
base_revision: 41456452f29d64e8deb623a3c927524bcf9f111b
|
||||||
- platform: macos
|
- platform: macos
|
||||||
create_revision: 300451adae589accbece3490f4396f10bdf15e6e
|
create_revision: 41456452f29d64e8deb623a3c927524bcf9f111b
|
||||||
base_revision: 300451adae589accbece3490f4396f10bdf15e6e
|
base_revision: 41456452f29d64e8deb623a3c927524bcf9f111b
|
||||||
- platform: web
|
- platform: web
|
||||||
create_revision: 300451adae589accbece3490f4396f10bdf15e6e
|
create_revision: 41456452f29d64e8deb623a3c927524bcf9f111b
|
||||||
base_revision: 300451adae589accbece3490f4396f10bdf15e6e
|
base_revision: 41456452f29d64e8deb623a3c927524bcf9f111b
|
||||||
- platform: windows
|
- platform: windows
|
||||||
create_revision: 300451adae589accbece3490f4396f10bdf15e6e
|
create_revision: 41456452f29d64e8deb623a3c927524bcf9f111b
|
||||||
base_revision: 300451adae589accbece3490f4396f10bdf15e6e
|
base_revision: 41456452f29d64e8deb623a3c927524bcf9f111b
|
||||||
|
|
||||||
# User provided section
|
# User provided section
|
||||||
|
|
||||||
|
|
|
@ -31,7 +31,6 @@ android {
|
||||||
namespace "com.sdkj.skt"
|
namespace "com.sdkj.skt"
|
||||||
compileSdkVersion flutter.compileSdkVersion
|
compileSdkVersion flutter.compileSdkVersion
|
||||||
ndkVersion flutter.ndkVersion
|
ndkVersion flutter.ndkVersion
|
||||||
// compileSdkVersion 34
|
|
||||||
compileOptions {
|
compileOptions {
|
||||||
sourceCompatibility JavaVersion.VERSION_1_8
|
sourceCompatibility JavaVersion.VERSION_1_8
|
||||||
targetCompatibility JavaVersion.VERSION_1_8
|
targetCompatibility JavaVersion.VERSION_1_8
|
||||||
|
@ -77,4 +76,6 @@ flutter {
|
||||||
source '../..'
|
source '../..'
|
||||||
}
|
}
|
||||||
|
|
||||||
dependencies {}
|
dependencies {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
<manifest xmlns:android="http://schemas.android.com/apk/res/android">
|
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
xmlns:tools="http://schemas.android.com/tools">
|
||||||
<application
|
<application
|
||||||
android:label="山矿通"
|
android:label="山矿通"
|
||||||
android:name="${applicationName}"
|
android:name="${applicationName}"
|
||||||
|
@ -30,6 +31,17 @@
|
||||||
<meta-data
|
<meta-data
|
||||||
android:name="flutterEmbedding"
|
android:name="flutterEmbedding"
|
||||||
android:value="2" />
|
android:value="2" />
|
||||||
|
<provider
|
||||||
|
android:name="androidx.core.content.FileProvider"
|
||||||
|
android:authorities="${applicationId}.fileProvider"
|
||||||
|
android:exported="false"
|
||||||
|
android:grantUriPermissions="true"
|
||||||
|
tools:replace="android:authorities">
|
||||||
|
<meta-data
|
||||||
|
android:name="android.support.FILE_PROVIDER_PATHS"
|
||||||
|
android:resource="@xml/filepaths"
|
||||||
|
tools:replace="android:resource" />
|
||||||
|
</provider>
|
||||||
</application>
|
</application>
|
||||||
<uses-permission
|
<uses-permission
|
||||||
android:name="android.permission.READ_PHONE_STATE" />
|
android:name="android.permission.READ_PHONE_STATE" />
|
||||||
|
|
|
@ -0,0 +1,8 @@
|
||||||
|
<paths>
|
||||||
|
<external-path name="external-path" path="." />
|
||||||
|
<external-cache-path name="external-cache-path" path="." />
|
||||||
|
<external-files-path name="external-files-path" path="." />
|
||||||
|
<files-path name="files_path" path="." />
|
||||||
|
<cache-path name="cache-path" path="." />
|
||||||
|
<root-path name="root" path="." />
|
||||||
|
</paths>
|
|
@ -6,6 +6,7 @@ buildscript {
|
||||||
}
|
}
|
||||||
|
|
||||||
dependencies {
|
dependencies {
|
||||||
|
classpath 'com.android.tools.build:gradle:7.4.0' // Change this to a version that supports compileSdkVersion 34
|
||||||
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
|
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -24,7 +25,16 @@ subprojects {
|
||||||
subprojects {
|
subprojects {
|
||||||
project.evaluationDependsOn(':app')
|
project.evaluationDependsOn(':app')
|
||||||
}
|
}
|
||||||
|
subprojects {
|
||||||
|
project.configurations.all {
|
||||||
|
resolutionStrategy.eachDependency { details ->
|
||||||
|
if (details.requested.group == 'com.android.support'
|
||||||
|
&& !details.requested.name.contains('multidex') ) {
|
||||||
|
details.useVersion "27.1.1"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
tasks.register("clean", Delete) {
|
tasks.register("clean", Delete) {
|
||||||
delete rootProject.buildDir
|
delete rootProject.buildDir
|
||||||
}
|
}
|
||||||
|
|
|
@ -5,10 +5,10 @@ class GloablConfig {
|
||||||
// static const BASE_URL = "http://10.0.2.2:8001/api/";
|
// static const BASE_URL = "http://10.0.2.2:8001/api/";
|
||||||
// static const OSS_URL = "http://10.0.2.2:8001";
|
// static const OSS_URL = "http://10.0.2.2:8001";
|
||||||
|
|
||||||
static const BASE_URL = "http://144.123.43.138:3001/api/";
|
// static const BASE_URL = "http://144.123.43.138:3001/api/";
|
||||||
static const OSS_URL = "http://144.123.43.138:3001";
|
// static const OSS_URL = "http://144.123.43.138:3001";
|
||||||
// static const BASE_URL = "http://192.168.60.220:8001/api/";
|
static const BASE_URL = "http://192.168.60.220:8001/api/";
|
||||||
// static const OSS_URL = "http://192.168.60.220:8001";
|
static const OSS_URL = "http://192.168.60.220:8001";
|
||||||
static const DOMAIN_NAME = "山矿通";
|
static const DOMAIN_NAME = "山矿通";
|
||||||
static const DEBUG = true;
|
static const DEBUG = true;
|
||||||
static const PRIVACY_POLICY = 'http://h5.heeru.xyz/privacyPolicy.html';
|
static const PRIVACY_POLICY = 'http://h5.heeru.xyz/privacyPolicy.html';
|
||||||
|
|
|
@ -22,4 +22,5 @@ class Urls {
|
||||||
'sale_quotation/sale_quotation_component';
|
'sale_quotation/sale_quotation_component';
|
||||||
static String saleQuotationTemplate =
|
static String saleQuotationTemplate =
|
||||||
'sale_quotation/sale_quotation_template';
|
'sale_quotation/sale_quotation_template';
|
||||||
|
static String saleQuotation = 'sale_quotation/sale_quotation';
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,10 +1,8 @@
|
||||||
import 'dart:ui';
|
|
||||||
|
|
||||||
class WorkBenchModel {
|
class WorkBenchModel {
|
||||||
final String title;
|
final String title;
|
||||||
final String icon;
|
final String icon;
|
||||||
final String? route;
|
final String? route;
|
||||||
final VoidCallback? onTap;
|
final Function()? onTap;
|
||||||
WorkBenchModel(
|
WorkBenchModel(
|
||||||
{required this.title, required this.icon, this.route, this.onTap});
|
{required this.title, required this.icon, this.route, this.onTap});
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
import 'package:collection/collection.dart';
|
import 'package:collection/collection.dart';
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:flutter/scheduler.dart';
|
||||||
import 'package:flutter_svg/svg.dart';
|
import 'package:flutter_svg/svg.dart';
|
||||||
import 'package:get/get.dart';
|
import 'package:get/get.dart';
|
||||||
import 'package:sk_base_mobile/app_theme.dart';
|
import 'package:sk_base_mobile/app_theme.dart';
|
||||||
|
@ -17,12 +18,11 @@ import 'package:sk_base_mobile/widgets/core/sk_appbar.dart';
|
||||||
class SaleQuotationEndDrawer extends StatelessWidget {
|
class SaleQuotationEndDrawer extends StatelessWidget {
|
||||||
final controller = Get.find<SaleQuotationController>();
|
final controller = Get.find<SaleQuotationController>();
|
||||||
SaleQuotationEndDrawer({super.key});
|
SaleQuotationEndDrawer({super.key});
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
return Scaffold(
|
return Scaffold(
|
||||||
appBar: const SkAppbar(title: '', hideLeading: true),
|
appBar: const SkAppbar(title: '', hideLeading: true), body: buildBody()
|
||||||
body: buildBody(),
|
// Only render the body if '_isRendered' is true
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -33,7 +33,7 @@ class SaleQuotationEndDrawer extends StatelessWidget {
|
||||||
Expanded(
|
Expanded(
|
||||||
child: buildTemplatePicker(),
|
child: buildTemplatePicker(),
|
||||||
),
|
),
|
||||||
buildAction()
|
// buildAction()
|
||||||
],
|
],
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -59,8 +59,8 @@ class SaleQuotationEndDrawer extends StatelessWidget {
|
||||||
child: SkFlatButton(
|
child: SkFlatButton(
|
||||||
onPressed: () async {
|
onPressed: () async {
|
||||||
if (controller.templateName.value != '默认') {
|
if (controller.templateName.value != '默认') {
|
||||||
await RouterUtil.back();
|
|
||||||
await controller.saveToDatabase();
|
await controller.saveToDatabase();
|
||||||
|
await RouterUtil.back();
|
||||||
} else {
|
} else {
|
||||||
templateNameDialog();
|
templateNameDialog();
|
||||||
}
|
}
|
||||||
|
@ -117,15 +117,7 @@ class SaleQuotationEndDrawer extends StatelessWidget {
|
||||||
|
|
||||||
Widget buildItem(int index) {
|
Widget buildItem(int index) {
|
||||||
return SkInk(
|
return SkInk(
|
||||||
onTap: () {
|
onTap: controller.menus[index].onTap,
|
||||||
// final route = RouteConfig.getPages
|
|
||||||
// .map((e) => e.name)
|
|
||||||
// .firstWhereOrNull((name) => name == controller.menus[index].route);
|
|
||||||
// if (route != null) {
|
|
||||||
// } else {
|
|
||||||
// SnackBarUtil().info('您没有权限,请联系管理员。后期会隐藏没有权限的功能');
|
|
||||||
// }
|
|
||||||
},
|
|
||||||
child: Container(
|
child: Container(
|
||||||
alignment: Alignment.center,
|
alignment: Alignment.center,
|
||||||
padding: EdgeInsets.only(
|
padding: EdgeInsets.only(
|
||||||
|
@ -182,9 +174,11 @@ class SaleQuotationEndDrawer extends StatelessWidget {
|
||||||
}
|
}
|
||||||
|
|
||||||
Widget buildTemplateItem(SaleQuotationTemplateModel element, int index) {
|
Widget buildTemplateItem(SaleQuotationTemplateModel element, int index) {
|
||||||
return SkInk(
|
return Obx(() => SkInk(
|
||||||
|
color: controller.templateId.value == element.id
|
||||||
|
? AppTheme.primaryColorLight
|
||||||
|
: Colors.transparent,
|
||||||
onTap: () async {
|
onTap: () async {
|
||||||
await Future.delayed(const Duration(milliseconds: 150));
|
|
||||||
controller.changeTemplate(element);
|
controller.changeTemplate(element);
|
||||||
await RouterUtil.back();
|
await RouterUtil.back();
|
||||||
},
|
},
|
||||||
|
@ -238,7 +232,7 @@ class SaleQuotationEndDrawer extends StatelessWidget {
|
||||||
),
|
),
|
||||||
]),
|
]),
|
||||||
),
|
),
|
||||||
);
|
));
|
||||||
}
|
}
|
||||||
|
|
||||||
void templateNameDialog({String? title = ''}) {
|
void templateNameDialog({String? title = ''}) {
|
||||||
|
|
|
@ -1,10 +1,17 @@
|
||||||
import 'dart:convert';
|
import 'dart:convert';
|
||||||
|
import 'dart:io';
|
||||||
|
|
||||||
import 'package:decimal/decimal.dart';
|
import 'package:decimal/decimal.dart';
|
||||||
|
import 'package:dio/dio.dart';
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:get/get.dart';
|
import 'package:get/get.dart';
|
||||||
import 'package:math_expressions/math_expressions.dart';
|
import 'package:math_expressions/math_expressions.dart';
|
||||||
|
import 'package:open_filex/open_filex.dart';
|
||||||
|
import 'package:path_provider/path_provider.dart';
|
||||||
import 'package:sk_base_mobile/apis/api.dart';
|
import 'package:sk_base_mobile/apis/api.dart';
|
||||||
|
import 'package:sk_base_mobile/app_theme.dart';
|
||||||
|
import 'package:sk_base_mobile/config.dart';
|
||||||
|
import 'package:sk_base_mobile/constants/constants.dart';
|
||||||
import 'package:sk_base_mobile/models/base_search_more_controller.dart';
|
import 'package:sk_base_mobile/models/base_search_more_controller.dart';
|
||||||
import 'package:sk_base_mobile/models/sale_quotaion_component.model.dart';
|
import 'package:sk_base_mobile/models/sale_quotaion_component.model.dart';
|
||||||
import 'package:sk_base_mobile/models/sale_quotaion_group.model.dart';
|
import 'package:sk_base_mobile/models/sale_quotaion_group.model.dart';
|
||||||
|
@ -12,12 +19,16 @@ import 'package:sk_base_mobile/models/sale_quotation.model.dart';
|
||||||
import 'package:sk_base_mobile/models/sale_quotation_template.model.dart';
|
import 'package:sk_base_mobile/models/sale_quotation_template.model.dart';
|
||||||
import 'package:sk_base_mobile/models/workbench.model.dart';
|
import 'package:sk_base_mobile/models/workbench.model.dart';
|
||||||
import 'package:sk_base_mobile/screens/sale_quotation/components/sale_quotation_group_search.dart';
|
import 'package:sk_base_mobile/screens/sale_quotation/components/sale_quotation_group_search.dart';
|
||||||
|
import 'package:sk_base_mobile/services/dio.service.dart';
|
||||||
import 'package:sk_base_mobile/services/storage.service.dart';
|
import 'package:sk_base_mobile/services/storage.service.dart';
|
||||||
|
import 'package:sk_base_mobile/util/logger_util.dart';
|
||||||
import 'package:sk_base_mobile/util/snack_bar.util.dart';
|
import 'package:sk_base_mobile/util/snack_bar.util.dart';
|
||||||
|
import 'package:sk_base_mobile/widgets/core/sk_flat_button.dart';
|
||||||
import 'package:sk_base_mobile/widgets/form_item/sk_multi_search_more.dart';
|
import 'package:sk_base_mobile/widgets/form_item/sk_multi_search_more.dart';
|
||||||
import 'package:sk_base_mobile/util/modal.util.dart';
|
import 'package:sk_base_mobile/util/modal.util.dart';
|
||||||
import 'package:sk_base_mobile/util/screen_adaper_util.dart';
|
import 'package:sk_base_mobile/util/screen_adaper_util.dart';
|
||||||
import 'package:pinyin/pinyin.dart';
|
import 'package:pinyin/pinyin.dart';
|
||||||
|
import 'package:sk_base_mobile/widgets/loading_indicator.dart';
|
||||||
|
|
||||||
class SaleQuotationController extends GetxController {
|
class SaleQuotationController extends GetxController {
|
||||||
static SaleQuotationController get to => Get.find();
|
static SaleQuotationController get to => Get.find();
|
||||||
|
@ -29,22 +40,114 @@ class SaleQuotationController extends GetxController {
|
||||||
RxBool isFormulaEditing = false.obs;
|
RxBool isFormulaEditing = false.obs;
|
||||||
RxString formula = '成本 * 1.3 / 0.864'.obs;
|
RxString formula = '成本 * 1.3 / 0.864'.obs;
|
||||||
RxList<SaleQuotationTemplateModel> templates = RxList([]);
|
RxList<SaleQuotationTemplateModel> templates = RxList([]);
|
||||||
final List<WorkBenchModel> menus = [
|
final List<WorkBenchModel> menus = [];
|
||||||
WorkBenchModel(title: '导出明细', icon: 'export.svg'),
|
|
||||||
// WorkBenchModel(title: '模板', icon: 'sale_quotation_template.svg'),
|
|
||||||
WorkBenchModel(title: '配件管理', icon: 'product.svg'),
|
|
||||||
WorkBenchModel(title: '分组管理', icon: 'sale_quotation_group.svg'),
|
|
||||||
WorkBenchModel(title: '计算公式', icon: 'sale_quotation_formula.svg'),
|
|
||||||
];
|
|
||||||
RxString templateName = '默认'.obs;
|
RxString templateName = '默认'.obs;
|
||||||
int? templateId;
|
RxnInt templateId = RxnInt(null);
|
||||||
|
final downloadProgress = RxDouble(0.0);
|
||||||
@override
|
@override
|
||||||
void onReady() {
|
void onReady() {
|
||||||
init();
|
init();
|
||||||
super.onReady();
|
super.onReady();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Future export() async {
|
||||||
|
try {
|
||||||
|
final dir = await getDownloadsDirectory();
|
||||||
|
if (dir != null) {
|
||||||
|
String storagePath = dir.path;
|
||||||
|
File file = File('$storagePath/$templateName.xls');
|
||||||
|
if (!file.existsSync()) {
|
||||||
|
file.createSync();
|
||||||
|
}
|
||||||
|
CancelToken token = CancelToken();
|
||||||
|
ModalUtil.alert(
|
||||||
|
barrierDismissible: false,
|
||||||
|
contentPadding: EdgeInsets.zero,
|
||||||
|
showActions: false,
|
||||||
|
content:
|
||||||
|
// 进度条
|
||||||
|
Obx(() => Column(
|
||||||
|
mainAxisAlignment: MainAxisAlignment.center,
|
||||||
|
mainAxisSize: MainAxisSize.min,
|
||||||
|
children: [
|
||||||
|
Stack(
|
||||||
|
children: [
|
||||||
|
SizedBox(
|
||||||
|
height: ScreenAdaper.height(60),
|
||||||
|
child: LinearProgressIndicator(
|
||||||
|
value: downloadProgress.value,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
Positioned(
|
||||||
|
left: 0,
|
||||||
|
right: 0,
|
||||||
|
child: Row(
|
||||||
|
mainAxisAlignment: MainAxisAlignment.center,
|
||||||
|
children: [
|
||||||
|
Text(
|
||||||
|
'${downloadProgress.value * 100}%',
|
||||||
|
textAlign: TextAlign.center,
|
||||||
|
style: TextStyle(
|
||||||
|
fontSize: ScreenAdaper.height(30)),
|
||||||
|
),
|
||||||
|
const LoadingIndicator(
|
||||||
|
color: AppTheme.nearlyBlack)
|
||||||
|
],
|
||||||
|
)),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
SkFlatButton(
|
||||||
|
onPressed: () {
|
||||||
|
token.cancel('已取消下载');
|
||||||
|
Get.back();
|
||||||
|
},
|
||||||
|
textColor: AppTheme.nearlyBlack,
|
||||||
|
color: AppTheme.nearlyWhite,
|
||||||
|
buttonText: '取消',
|
||||||
|
)
|
||||||
|
],
|
||||||
|
)));
|
||||||
|
try {
|
||||||
|
await DioService.dio.download(
|
||||||
|
'${Urls.saleQuotation}/export/${templateId.value}', file.path,
|
||||||
|
cancelToken: token,
|
||||||
|
onReceiveProgress: onReceiveProgress,
|
||||||
|
options: Options(
|
||||||
|
responseType: ResponseType.bytes,
|
||||||
|
followRedirects: false,
|
||||||
|
));
|
||||||
|
Get.back();
|
||||||
|
await OpenFilex.open(file.path);
|
||||||
|
} catch (e) {
|
||||||
|
Get.back();
|
||||||
|
SnackBarUtil().error((e as dynamic).error ?? '暂时无法下载,请稍后重试或联系管理员');
|
||||||
|
LoggerUtil().error(e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} catch (e) {
|
||||||
|
SnackBarUtil().error('暂时无法下载,请稍后重试或联系管理员');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// 展示下载进度
|
||||||
|
void onReceiveProgress(num received, num total) {
|
||||||
|
LoggerUtil().info(received);
|
||||||
|
if (total != -1) {
|
||||||
|
downloadProgress.value =
|
||||||
|
Decimal.parse((received / total).toStringAsFixed(2))
|
||||||
|
.toDouble()
|
||||||
|
.toPrecision(2);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
Future<void> init() async {
|
Future<void> init() async {
|
||||||
|
menus.addAll([
|
||||||
|
WorkBenchModel(title: '导出明细', icon: 'export.svg', onTap: export),
|
||||||
|
// WorkBenchModel(title: '模板', icon: 'sale_quotation_template.svg'),
|
||||||
|
WorkBenchModel(title: '配件管理', icon: 'product.svg'),
|
||||||
|
WorkBenchModel(title: '分组管理', icon: 'sale_quotation_group.svg'),
|
||||||
|
WorkBenchModel(title: '计算公式', icon: 'sale_quotation_formula.svg'),
|
||||||
|
]);
|
||||||
String? salesQuotation = StorageService.to.getString('salesQuotation');
|
String? salesQuotation = StorageService.to.getString('salesQuotation');
|
||||||
if (salesQuotation != null) {
|
if (salesQuotation != null) {
|
||||||
SaleQuotationTemplateModel editTemplate =
|
SaleQuotationTemplateModel editTemplate =
|
||||||
|
@ -60,7 +163,7 @@ class SaleQuotationController extends GetxController {
|
||||||
formula.value = editTemplate.template.formula;
|
formula.value = editTemplate.template.formula;
|
||||||
totalPrice.value = editTemplate.template.totalPrice?.toDouble() ?? 0.0;
|
totalPrice.value = editTemplate.template.totalPrice?.toDouble() ?? 0.0;
|
||||||
totalCost.value = editTemplate.template.totalCost?.toDouble() ?? 0.0;
|
totalCost.value = editTemplate.template.totalCost?.toDouble() ?? 0.0;
|
||||||
templateId = editTemplate.id;
|
templateId.value = editTemplate.id;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// 切换报价模板
|
/// 切换报价模板
|
||||||
|
@ -153,15 +256,15 @@ class SaleQuotationController extends GetxController {
|
||||||
'formula': formula.value
|
'formula': formula.value
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
if (templateId != null) {
|
if (templateId.value != null) {
|
||||||
data['id'] = templateId;
|
data['id'] = templateId.value;
|
||||||
}
|
}
|
||||||
await StorageService.to.setString('salesQuotation', jsonEncode(data));
|
await StorageService.to.setString('salesQuotation', jsonEncode(data));
|
||||||
}
|
}
|
||||||
|
|
||||||
/// 保存到数据库
|
/// 保存到数据库
|
||||||
Future<bool> saveToDatabase() async {
|
Future<bool> saveToDatabase() async {
|
||||||
if (templateId == null) {
|
if (templateId.value == null) {
|
||||||
await Api.createSaleQuotationTemplate({
|
await Api.createSaleQuotationTemplate({
|
||||||
'name': templateName.value,
|
'name': templateName.value,
|
||||||
'template': {
|
'template': {
|
||||||
|
@ -172,7 +275,7 @@ class SaleQuotationController extends GetxController {
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
} else {
|
} else {
|
||||||
await Api.updateSaleQuotationTemplate(templateId!, {
|
await Api.updateSaleQuotationTemplate(templateId.value!, {
|
||||||
'name': templateName.value,
|
'name': templateName.value,
|
||||||
'template': {
|
'template': {
|
||||||
'data': groups.toJson(),
|
'data': groups.toJson(),
|
||||||
|
@ -188,8 +291,8 @@ class SaleQuotationController extends GetxController {
|
||||||
}
|
}
|
||||||
|
|
||||||
/// 删除模板
|
/// 删除模板
|
||||||
Future<void> deleteTemplate(int templateId) async {
|
Future<void> deleteTemplate(int deleteId) async {
|
||||||
await Api.deleteSaleQuotationTemplate(templateId);
|
await Api.deleteSaleQuotationTemplate(deleteId);
|
||||||
SnackBarUtil().success('已删除');
|
SnackBarUtil().success('已删除');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -321,7 +424,7 @@ class SaleQuotationController extends GetxController {
|
||||||
totalPrice.value = 0.0;
|
totalPrice.value = 0.0;
|
||||||
formula.value = '成本 * 1.3 / 0.864';
|
formula.value = '成本 * 1.3 / 0.864';
|
||||||
templateName.value = '默认';
|
templateName.value = '默认';
|
||||||
templateId = null;
|
templateId.value = null;
|
||||||
saveToLocal();
|
saveToLocal();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -234,6 +234,7 @@ class SaleQuotationPage extends StatelessWidget {
|
||||||
top: ScreenAdaper.height(10),
|
top: ScreenAdaper.height(10),
|
||||||
bottom: ScreenAdaper.height(10)),
|
bottom: ScreenAdaper.height(10)),
|
||||||
child: Row(
|
child: Row(
|
||||||
|
crossAxisAlignment: CrossAxisAlignment.center,
|
||||||
children: [
|
children: [
|
||||||
GestureDetector(
|
GestureDetector(
|
||||||
onTap: () {
|
onTap: () {
|
||||||
|
|
|
@ -14,7 +14,7 @@ class DioService extends get_package.GetxService {
|
||||||
static DioService get to => get_package.Get.find();
|
static DioService get to => get_package.Get.find();
|
||||||
static Dio get dio => _dio;
|
static Dio get dio => _dio;
|
||||||
static late Dio _dio;
|
static late Dio _dio;
|
||||||
List<String> whiteList = [Urls.login];
|
List<String> whiteList = [Urls.login, '${Urls.saleQuotation}/export'];
|
||||||
BaseOptions dioBaseOptions = BaseOptions(
|
BaseOptions dioBaseOptions = BaseOptions(
|
||||||
connectTimeout: const Duration(seconds: GloablConfig.DIO_TIMEOUT),
|
connectTimeout: const Duration(seconds: GloablConfig.DIO_TIMEOUT),
|
||||||
baseUrl: GloablConfig.BASE_URL,
|
baseUrl: GloablConfig.BASE_URL,
|
||||||
|
@ -129,7 +129,9 @@ class DioService extends get_package.GetxService {
|
||||||
void onResponse(Response response, ResponseInterceptorHandler handler) async {
|
void onResponse(Response response, ResponseInterceptorHandler handler) async {
|
||||||
/* LoggerUtil().info('[Service-dio] ${response.data}'); */
|
/* LoggerUtil().info('[Service-dio] ${response.data}'); */
|
||||||
|
|
||||||
if (whiteList.contains(response.requestOptions.path)) {
|
if (whiteList.firstWhereOrNull(
|
||||||
|
(item) => response.requestOptions.path.contains(item)) !=
|
||||||
|
null) {
|
||||||
handler.next(response);
|
handler.next(response);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
|
@ -5,6 +5,7 @@ import 'package:flutter/widgets.dart';
|
||||||
import 'package:get/get.dart';
|
import 'package:get/get.dart';
|
||||||
import 'package:sk_base_mobile/apis/api.dart';
|
import 'package:sk_base_mobile/apis/api.dart';
|
||||||
import 'package:sk_base_mobile/store/dict.store.dart';
|
import 'package:sk_base_mobile/store/dict.store.dart';
|
||||||
|
import 'package:sk_base_mobile/store/resource.store.dart';
|
||||||
import 'package:sk_base_mobile/util/logger_util.dart';
|
import 'package:sk_base_mobile/util/logger_util.dart';
|
||||||
import 'package:sk_base_mobile/widgets/tap_to_dismiss_keyboard.dart';
|
import 'package:sk_base_mobile/widgets/tap_to_dismiss_keyboard.dart';
|
||||||
import 'package:sk_base_mobile/models/auth.dart';
|
import 'package:sk_base_mobile/models/auth.dart';
|
||||||
|
@ -135,7 +136,8 @@ class AuthStore extends GetxService {
|
||||||
Future<void> getCommonInfo() async {
|
Future<void> getCommonInfo() async {
|
||||||
await AppInfoService.to.getAppConfig();
|
await AppInfoService.to.getAppConfig();
|
||||||
await Future.wait([
|
await Future.wait([
|
||||||
DictService.to.getDictTypes()
|
DictService.to.getDictTypes(),
|
||||||
|
ResourceService.to.getResources()
|
||||||
|
|
||||||
/// 依赖业务信息
|
/// 依赖业务信息
|
||||||
// Get.putAsync<BlockStore>(() => BlockStore().init()),
|
// Get.putAsync<BlockStore>(() => BlockStore().init()),
|
||||||
|
|
|
@ -11,11 +11,13 @@ class SkFlatButton extends StatelessWidget {
|
||||||
final String buttonText;
|
final String buttonText;
|
||||||
final Icon? icon;
|
final Icon? icon;
|
||||||
final Color? color;
|
final Color? color;
|
||||||
|
final Color? textColor;
|
||||||
final BorderRadiusGeometry? borderRadius;
|
final BorderRadiusGeometry? borderRadius;
|
||||||
const SkFlatButton(
|
const SkFlatButton(
|
||||||
{super.key,
|
{super.key,
|
||||||
this.buttonText = TextEnum.createInventoryInOutBtnText,
|
this.buttonText = TextEnum.createInventoryInOutBtnText,
|
||||||
this.onPressed,
|
this.onPressed,
|
||||||
|
this.textColor,
|
||||||
this.icon,
|
this.icon,
|
||||||
this.color,
|
this.color,
|
||||||
this.borderRadius,
|
this.borderRadius,
|
||||||
|
@ -45,7 +47,8 @@ class SkFlatButton extends StatelessWidget {
|
||||||
: Text(
|
: Text(
|
||||||
buttonText,
|
buttonText,
|
||||||
style: TextStyle(
|
style: TextStyle(
|
||||||
color: AppTheme.nearlyWhite,
|
color: textColor ??
|
||||||
|
Theme.of(context).colorScheme.onPrimary,
|
||||||
fontWeight: FontWeight.bold,
|
fontWeight: FontWeight.bold,
|
||||||
fontSize: ScreenAdaper.height(25),
|
fontSize: ScreenAdaper.height(25),
|
||||||
),
|
),
|
||||||
|
|
|
@ -6,8 +6,9 @@ import 'package:sk_base_mobile/util/screen_adaper_util.dart';
|
||||||
class LoadingIndicator extends StatelessWidget {
|
class LoadingIndicator extends StatelessWidget {
|
||||||
final bool animating;
|
final bool animating;
|
||||||
final bool common;
|
final bool common;
|
||||||
|
final Color? color;
|
||||||
const LoadingIndicator(
|
const LoadingIndicator(
|
||||||
{super.key, this.animating = true, this.common = false});
|
{super.key, this.animating = true, this.common = false, this.color});
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
|
@ -18,7 +19,7 @@ class LoadingIndicator extends StatelessWidget {
|
||||||
padding: EdgeInsets.all(ScreenAdaper.height(10)),
|
padding: EdgeInsets.all(ScreenAdaper.height(10)),
|
||||||
child: CupertinoActivityIndicator(
|
child: CupertinoActivityIndicator(
|
||||||
animating: animating,
|
animating: animating,
|
||||||
color: AppTheme.primaryColor,
|
color: color ?? AppTheme.primaryColor,
|
||||||
radius: ScreenAdaper.sp(25),
|
radius: ScreenAdaper.sp(25),
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
|
|
12
pubspec.lock
12
pubspec.lock
|
@ -351,10 +351,10 @@ packages:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: flutter_plugin_android_lifecycle
|
name: flutter_plugin_android_lifecycle
|
||||||
sha256: b068ffc46f82a55844acfa4fdbb61fad72fa2aef0905548419d97f0f95c456da
|
sha256: "592dc01a18961a51c24ae5d963b724b2b7fa4a95c100fe8eb6ca8a5a4732cadf"
|
||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "2.0.17"
|
version: "2.0.18"
|
||||||
flutter_screenutil:
|
flutter_screenutil:
|
||||||
dependency: "direct main"
|
dependency: "direct main"
|
||||||
description:
|
description:
|
||||||
|
@ -621,6 +621,14 @@ packages:
|
||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "2.0.0"
|
version: "2.0.0"
|
||||||
|
open_filex:
|
||||||
|
dependency: "direct main"
|
||||||
|
description:
|
||||||
|
name: open_filex
|
||||||
|
sha256: "74e2280754cf8161e860746c3181db2c996d6c1909c7057b738ede4a469816b8"
|
||||||
|
url: "https://pub.dev"
|
||||||
|
source: hosted
|
||||||
|
version: "4.4.0"
|
||||||
package_info:
|
package_info:
|
||||||
dependency: "direct main"
|
dependency: "direct main"
|
||||||
description:
|
description:
|
||||||
|
|
|
@ -72,6 +72,8 @@ dependencies:
|
||||||
sk_datetime_picker:
|
sk_datetime_picker:
|
||||||
git:
|
git:
|
||||||
url: https://gitee.com/lu-zixun/sk-date-time-picker.git
|
url: https://gitee.com/lu-zixun/sk-date-time-picker.git
|
||||||
|
open_filex: ^4.4.0
|
||||||
|
|
||||||
# sk_datetime_picker:
|
# sk_datetime_picker:
|
||||||
# path: ./lib/widgets/common/datetime_picker
|
# path: ./lib/widgets/common/datetime_picker
|
||||||
dev_dependencies:
|
dev_dependencies:
|
||||||
|
|
Loading…
Reference in New Issue