@jzt-packages/components 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (145) hide show
  1. package/package.json +68 -0
  2. package/src/JztBackTop/index.vue +255 -0
  3. package/src/JztButtonList/index.vue +88 -0
  4. package/src/JztChart/index.vue +95 -0
  5. package/src/JztCharts/index.vue +317 -0
  6. package/src/JztClassTabs/index.vue +156 -0
  7. package/src/JztDateSelect/dateSelect.vue +186 -0
  8. package/src/JztDateSelect/dateType.vue +54 -0
  9. package/src/JztDateSelect/index.ts +135 -0
  10. package/src/JztDateSelect/interface/index.ts +13 -0
  11. package/src/JztDialog/index.vue +249 -0
  12. package/src/JztEllipsisTooltip/index.vue +61 -0
  13. package/src/JztEmpty/index.vue +45 -0
  14. package/src/JztErrorPage/403.vue +30 -0
  15. package/src/JztErrorPage/404.vue +19 -0
  16. package/src/JztErrorPage/500.vue +18 -0
  17. package/src/JztErrorPage/assets/401.png +0 -0
  18. package/src/JztErrorPage/assets/403.png +0 -0
  19. package/src/JztErrorPage/assets/404.png +0 -0
  20. package/src/JztErrorPage/assets/500.png +0 -0
  21. package/src/JztErrorPage/index.scss +35 -0
  22. package/src/JztErrorPage/index.vue +35 -0
  23. package/src/JztFilePreview/components/pdfViewer.vue +221 -0
  24. package/src/JztFilePreview/hooks/useImageMethod.ts +256 -0
  25. package/src/JztFilePreview/index.scss +171 -0
  26. package/src/JztFilePreview/index.vue +68 -0
  27. package/src/JztFilePreview/interface/index.ts +18 -0
  28. package/src/JztFilePreview/previewFile.vue +371 -0
  29. package/src/JztFormGrid/README.md +520 -0
  30. package/src/JztFormGrid/components/formItem.vue +209 -0
  31. package/src/JztFormGrid/components/formItemValue.vue +384 -0
  32. package/src/JztFormGrid/components/showDetailForm.vue +172 -0
  33. package/src/JztFormGrid/index.scss +60 -0
  34. package/src/JztFormGrid/index.vue +513 -0
  35. package/src/JztFormGrid/interface/index.ts +106 -0
  36. package/src/JztGrid/components/GridItem.vue +68 -0
  37. package/src/JztGrid/index.vue +179 -0
  38. package/src/JztGrid/interface/index.ts +6 -0
  39. package/src/JztImportExcel/assets/delete.png +0 -0
  40. package/src/JztImportExcel/index.scss +46 -0
  41. package/src/JztImportExcel/index.vue +430 -0
  42. package/src/JztImportExcel/interface/index.ts +25 -0
  43. package/src/JztLabelTitle/index.vue +65 -0
  44. package/src/JztLeftRightMode/components/CollapseButton.vue +80 -0
  45. package/src/JztLeftRightMode/components/LeftCard.vue +203 -0
  46. package/src/JztLeftRightMode/components/LeftLayout.vue +173 -0
  47. package/src/JztLeftRightMode/components/RightHeader.vue +186 -0
  48. package/src/JztLeftRightMode/components/RightLayout.vue +235 -0
  49. package/src/JztLeftRightMode/components/RightTableHeader.vue +43 -0
  50. package/src/JztLeftRightMode/hooks/useCollapse.ts +17 -0
  51. package/src/JztLeftRightMode/hooks/useDefaultProps.ts +19 -0
  52. package/src/JztLeftRightMode/hooks/useLeftLayout.ts +201 -0
  53. package/src/JztLeftRightMode/hooks/useMode.ts +20 -0
  54. package/src/JztLeftRightMode/hooks/usePrevNext.ts +60 -0
  55. package/src/JztLeftRightMode/hooks/useRightLayout.ts +215 -0
  56. package/src/JztLeftRightMode/hooks/useSlots.ts +15 -0
  57. package/src/JztLeftRightMode/index.ts +3 -0
  58. package/src/JztLeftRightMode/index.vue +494 -0
  59. package/src/JztLeftRightMode/types/index.ts +457 -0
  60. package/src/JztLoading/fullScreen.ts +45 -0
  61. package/src/JztLoading/index.scss +67 -0
  62. package/src/JztLoading/index.vue +18 -0
  63. package/src/JztLogin/components/LoginFooter.vue +17 -0
  64. package/src/JztLogin/components/LoginForm.vue +99 -0
  65. package/src/JztLogin/hooks/useLogin.ts +186 -0
  66. package/src/JztLogin/index.scss +142 -0
  67. package/src/JztLogin/index.vue +31 -0
  68. package/src/JztLogin/interface/index.ts +47 -0
  69. package/src/JztNumericalRange/index.vue +81 -0
  70. package/src/JztPageCard/comm/datePicker.vue +151 -0
  71. package/src/JztPageCard/comm/details.vue +60 -0
  72. package/src/JztPageCard/comm/export.vue +24 -0
  73. package/src/JztPageCard/comm/tabs.vue +94 -0
  74. package/src/JztPageCard/comm/tooltip.vue +31 -0
  75. package/src/JztPageCard/index.vue +287 -0
  76. package/src/JztPagination/index.vue +70 -0
  77. package/src/JztProductInfo/components/imagePreview.vue +275 -0
  78. package/src/JztProductInfo/components/qxUnique.vue +101 -0
  79. package/src/JztProductInfo/components/records.vue +265 -0
  80. package/src/JztProductInfo/hooks/useParams.ts +143 -0
  81. package/src/JztProductInfo/hooks/useQxUnique.tsx +466 -0
  82. package/src/JztProductInfo/images/defaultProduct.png +0 -0
  83. package/src/JztProductInfo/index.ts +116 -0
  84. package/src/JztProductInfo/index.vue +108 -0
  85. package/src/JztProductInfo/interface/index.ts +15 -0
  86. package/src/JztQueryDetailTable/index.scss +100 -0
  87. package/src/JztQueryDetailTable/index.vue +400 -0
  88. package/src/JztQueryDetailTable/interface/index.ts +10 -0
  89. package/src/JztQueryTable/QueryTable /345/212/237/350/203/275.md" +1580 -0
  90. package/src/JztQueryTable/README.md +567 -0
  91. package/src/JztQueryTable/components/ColSetting.vue +67 -0
  92. package/src/JztQueryTable/components/ColumnsSetting.vue +404 -0
  93. package/src/JztQueryTable/components/ColumnsSetting1.vue +220 -0
  94. package/src/JztQueryTable/components/DeployToAccountLevelSetting.vue +351 -0
  95. package/src/JztQueryTable/components/Pagination.vue +54 -0
  96. package/src/JztQueryTable/components/TableColumn.vue +109 -0
  97. package/src/JztQueryTable/const.ts +1 -0
  98. package/src/JztQueryTable/hooks/useQueryTable.ts +194 -0
  99. package/src/JztQueryTable/hooks/useSelection.ts +47 -0
  100. package/src/JztQueryTable/hooks/useTableSetting.ts +197 -0
  101. package/src/JztQueryTable/hooks/useTemplate.ts +127 -0
  102. package/src/JztQueryTable/index.scss +91 -0
  103. package/src/JztQueryTable/index.vue +1445 -0
  104. package/src/JztQueryTable/interface/index.ts +185 -0
  105. package/src/JztRegionSelect/index.vue +134 -0
  106. package/src/JztSearchForm/components/SearchFormItem.vue +473 -0
  107. package/src/JztSearchForm/index.vue +530 -0
  108. package/src/JztSearchForm/interface/index.ts +100 -0
  109. package/src/JztSelectFilter/index.scss +63 -0
  110. package/src/JztSelectFilter/index.vue +110 -0
  111. package/src/JztSelectTable/index.vue +257 -0
  112. package/src/JztTable/index.scss +72 -0
  113. package/src/JztTable/index.vue +353 -0
  114. package/src/JztTable/interface/index.ts +1 -0
  115. package/src/JztTime/comm/agencySelect.vue +112 -0
  116. package/src/JztTime/comm/collapseRow.vue +132 -0
  117. package/src/JztTime/comm/dateSelect.vue +292 -0
  118. package/src/JztTime/comm/deptSelect.vue +193 -0
  119. package/src/JztTime/comm/typeSelect.vue +97 -0
  120. package/src/JztTime/index.ts +216 -0
  121. package/src/JztTime/index.vue +303 -0
  122. package/src/JztTime/interface/index.ts +23 -0
  123. package/src/JztTreeFilter/index.scss +44 -0
  124. package/src/JztTreeFilter/index.vue +177 -0
  125. package/src/JztUploadFile/interface/index.ts +21 -0
  126. package/src/JztUploadFile/multiple.scss +215 -0
  127. package/src/JztUploadFile/multiple.vue +318 -0
  128. package/src/JztUploadFile/single.scss +226 -0
  129. package/src/JztUploadFile/single.vue +274 -0
  130. package/src/JztUploadImg/Img.vue +294 -0
  131. package/src/JztUploadImg/Imgs.vue +411 -0
  132. package/src/JztUploadImg/index.scss +138 -0
  133. package/src/JztUploadImg/interface/index.ts +22 -0
  134. package/src/SelectIcon/index.scss +39 -0
  135. package/src/SelectIcon/index.vue +106 -0
  136. package/src/SvgIcon/index.vue +22 -0
  137. package/src/hooks/useAuthButtons.ts +58 -0
  138. package/src/hooks/useFormByUserType.ts +90 -0
  139. package/src/hooks/useTableEvents.ts +30 -0
  140. package/src/hooks/useUploadFileHook.ts +262 -0
  141. package/src/index.ts +91 -0
  142. package/src/typings/global.d.ts +101 -0
  143. package/src/utils/index.ts +107 -0
  144. package/src/utils/tree.ts +57 -0
  145. package/tsconfig.json +45 -0
@@ -0,0 +1,186 @@
1
+ import {
2
+ loginApi,
3
+ getLoginModeApi,
4
+ getPwdPolicyLoginApi,
5
+ getCaptchaApi,
6
+ sendSmsCodeByUserNameApi,
7
+ verificationCodeByUserNameApi,
8
+ } from "@jzt-spd/utils/commonApi";
9
+ import { OMSEncryptedPubKey } from "@jzt-spd/utils/consts";
10
+ import JSEncrypt from "jsencrypt";
11
+ import { ref, reactive } from "vue";
12
+ import { Login } from "../interface";
13
+ import { ElNotification, ElMessage } from "element-plus";
14
+ import type { ElForm } from "element-plus";
15
+
16
+ const loginRules = reactive({
17
+ phone: [{ required: true, message: "请输入用户名", trigger: "blur" }],
18
+ password: [{ required: true, message: "请输入密码", trigger: "blur" }],
19
+ code: [
20
+ { required: true, message: "请输入验证码", trigger: "blur" },
21
+ { len: 6, message: "请输入6位验证码", trigger: "blur" },
22
+ ],
23
+ });
24
+
25
+ const isEncryption = ref(false);
26
+ // 0-用户名+密码 1-用户名+密码+手机验证码 2-用户名+密码+图形验证码
27
+ const loginMode = ref("0");
28
+ const sendLoading = ref(false);
29
+ const timer = ref();
30
+ const second = ref(0);
31
+ const sendDisabled = ref(false);
32
+ const graphicCodeUrl = ref("");
33
+ const savePassword = ref(false);
34
+
35
+ const errMsg = ref<string>("");
36
+ const loading = ref(false);
37
+
38
+ const loginForm = reactive<Login.ReqLoginForm>({
39
+ phone: "jztsystem", //用户名:admin / user
40
+ password: "JZTeya0",
41
+ systemId: "SPD",
42
+ });
43
+
44
+ export const useParams = () => {
45
+ return {
46
+ loginRules,
47
+ loginForm,
48
+ loginMode,
49
+ sendLoading,
50
+ second,
51
+ graphicCodeUrl,
52
+ sendDisabled,
53
+ savePassword,
54
+ loading,
55
+ errMsg
56
+ };
57
+ };
58
+
59
+ export const useEvents = () => {
60
+ // 获取登录密码是否加密策略
61
+ // 0-用户名+密码 1-用户名+密码+手机验证码 2-用户名+密码+图形验证码
62
+ const getLoginMode = async () => {
63
+ const res = await getLoginModeApi();
64
+ if (res && res.result) {
65
+ loginMode.value = res.result?.configValue || "0";
66
+ if (loginMode.value === "2") {
67
+ getCaptchaImg();
68
+ }
69
+ }
70
+ };
71
+ // 获取登录模式接口
72
+ const getPwdPolicyLogin = async () => {
73
+ try {
74
+ const res = await getPwdPolicyLoginApi()
75
+ if (res && res.result) {
76
+ isEncryption.value = res.result.isEncryption || false
77
+ }
78
+ } catch (error) {
79
+ console.log(error)
80
+ }
81
+ }
82
+
83
+ // 获取图像验证码
84
+ const getCaptchaImg = async () => {
85
+ try {
86
+ const res = await getCaptchaApi();
87
+ if (res && res.result) {
88
+ graphicCodeUrl.value = res.result.actionresult;
89
+ loginForm.id = res.result.id;
90
+ }
91
+ } catch (error) {
92
+ console.log(error);
93
+ }
94
+ };
95
+
96
+ // 根据用户名查找手机号发送短信验证码
97
+ const getSmsCode = async () => {
98
+ try {
99
+ sendLoading.value = true;
100
+ const res = await sendSmsCodeByUserNameApi({
101
+ userName: loginForm.phone,
102
+ });
103
+ ElMessage.success("验证码发送成功");
104
+ startTimerCode();
105
+ } catch (error) {
106
+ console.log(error);
107
+ } finally {
108
+ sendLoading.value = false;
109
+ }
110
+ };
111
+
112
+ // 倒计时效果
113
+ const startTimerCode = async () => {
114
+ let s = 10; //倒计时间
115
+ if (!timer.value) {
116
+ second.value = s
117
+ sendDisabled.value = true
118
+ timer.value = setInterval(() => {
119
+ if (second.value > 0 && second.value <= s) {
120
+ second.value--;
121
+ } else {
122
+ sendDisabled.value = false;
123
+ clearInterval(timer.value);
124
+ timer.value = null;
125
+ }
126
+ }, 1000);
127
+ }
128
+ };
129
+ const getLoginSetting = () => {
130
+ getLoginMode();
131
+ getPwdPolicyLogin();
132
+ };
133
+ return {
134
+ getLoginSetting,
135
+ getSmsCode,
136
+ getCaptchaImg,
137
+ };
138
+ };
139
+ // / 账号加密
140
+ function IsEncrypted(password: string) {
141
+ const encryptor = new JSEncrypt(); // 创建加密对象实例
142
+ encryptor.setPublicKey(OMSEncryptedPubKey); // 设置公钥
143
+ return encryptor.encrypt(password) as string; // 加密
144
+ }
145
+ export async function loginServer(loginCallBack) {
146
+ loading.value = true;
147
+ try {
148
+ if (loginMode.value === "1") {
149
+ // 验证短信验证码
150
+ await verificationCodeByUserNameApi({
151
+ type: 1,
152
+ userName: loginForm.phone || "",
153
+ code: loginForm.code || "",
154
+ });
155
+ }
156
+ // 1.执行登录接口
157
+ const { result } = await loginApi({
158
+ phone: loginForm.phone,
159
+ password: isEncryption.value
160
+ ? IsEncrypted(loginForm.password)
161
+ : loginForm.password,
162
+ systemId: loginForm.systemId,
163
+ ...(loginMode.value === "2"
164
+ ? { id: loginForm.id, code: loginForm.code }
165
+ : {}),
166
+ ...(loginMode.value === "1" ? { code: loginForm.code } : {}),
167
+ });
168
+ // 2.添加动态路由 3.清空 tabs、keepAlive 数据
169
+ loginCallBack && loginCallBack(result);
170
+ // 4.跳转到首页
171
+ setTimeout(() => {
172
+ // ElNotification({
173
+ // title: `亲爱的${result.userName},你好~`,
174
+ // message: '新站上线,欢迎体验,祝您今天工作愉快~',
175
+ // type: 'success',
176
+ // duration: 3000
177
+ // })
178
+ }, 500)
179
+ } catch (error: { code: number; message: string } | any) {
180
+ errMsg.value = error.message || "登录失败";
181
+ } finally {
182
+ setTimeout(() => {
183
+ loading.value = false;
184
+ }, 500);
185
+ }
186
+ }
@@ -0,0 +1,142 @@
1
+ .login-container {
2
+ height: 100%;
3
+ min-height: 550px;
4
+ background-color: #eeeeee;
5
+ background-image: url("@/assets/images/login/login_bg.svg");
6
+ background-size: 100% 100%;
7
+ background-size: cover;
8
+ &::before {
9
+ content: "";
10
+ display: block;
11
+ height: 68px;
12
+ background-image: url("@/assets/images/login/login_logo.svg");
13
+ background-repeat: no-repeat;
14
+ background-position: left center;
15
+ background-color: rgba(255, 255, 255, 0.8);
16
+ }
17
+ :deep(.el-input-group__append) {
18
+ padding: 0;
19
+ color: #fff;
20
+ overflow: hidden;
21
+ box-sizing: border-box;
22
+ .SmsCode {
23
+ width: 120px;
24
+ height: 54px;
25
+ .el-button {
26
+ width: 100%;
27
+ height: 100%;
28
+ margin: 0;
29
+ padding: 0;
30
+ background-color: var(--el-color-primary-light-1);
31
+ }
32
+ }
33
+ .login-graphic-img {
34
+ width: calc(100% - 2px);
35
+ min-width: 120px;
36
+ height: 52px;
37
+ object-fit: cover;
38
+ }
39
+ }
40
+ .login-box {
41
+ /* .dark {
42
+ position: absolute;
43
+ top: 13px;
44
+ right: 18px;
45
+ } */
46
+ .login-form {
47
+ width: 420px;
48
+ position: absolute;
49
+ top: 50%;
50
+ left: 0;
51
+ right: 0;
52
+ margin: 0 auto;
53
+ transform: translateY(-50%);
54
+ padding: 64px 70px 72px;
55
+ background-color: rgba(251, 251, 251, 0.88);
56
+ border-radius: 2px;
57
+ backdrop-filter: blur(16px);
58
+ box-sizing: content-box;
59
+ .login-logo {
60
+ text-align: center;
61
+ margin-bottom: 67px;
62
+
63
+ .logo-text {
64
+ // padding: 0 0 0 25px;
65
+ margin: 0;
66
+ font-size: 42px;
67
+ font-weight: 400;
68
+ color: var(--el-text-color-primary);
69
+ white-space: nowrap;
70
+ }
71
+
72
+ .logo-text-tips {
73
+ font-size: 24px;
74
+ font-weight: 400;
75
+ color: var(--el-text-color-primary);
76
+ margin: 8px;
77
+ }
78
+ }
79
+ .el-form-item {
80
+ margin-bottom: 30px;
81
+
82
+ &.login-form-password {
83
+ margin-bottom: 20px;
84
+ }
85
+
86
+ .el-input {
87
+ height: 56px;
88
+ }
89
+ .el-checkbox {
90
+ height: auto;
91
+
92
+ :deep {
93
+ .el-checkbox__input.is-checked .el-checkbox__inner {
94
+ background-color: var(--el-color-primary);
95
+ border-color: var(--el-color-primary);
96
+ }
97
+ .el-checkbox__label {
98
+ font-size: 16px;
99
+ }
100
+ // .el-checkbox__input.is-checked + .el-checkbox__label {
101
+ // color: var(--el-text-color-primary);
102
+ // }
103
+ }
104
+ }
105
+ }
106
+ .login-btn {
107
+ display: flex;
108
+ justify-content: space-between;
109
+ width: 100%;
110
+ margin-top: 30px;
111
+ white-space: nowrap;
112
+ .el-button {
113
+ width: 100%;
114
+ height: auto;
115
+ padding: 14px 0;
116
+ color: #ffffff;
117
+ font-size: 20px;
118
+ background: linear-gradient(90deg, #ff6b23 0%, #ff982a 100%);
119
+ border-radius: 8px;
120
+ border-color: transparent;
121
+ }
122
+ }
123
+ }
124
+ .err-msg {
125
+ height: 30px;
126
+ margin-top: 10px;
127
+ color: var(--el-color-error);
128
+ }
129
+ }
130
+ }
131
+
132
+ @media screen and (width <= 1250px) {
133
+ .login-left {
134
+ display: none;
135
+ }
136
+ }
137
+
138
+ @media screen and (width <= 600px) {
139
+ .login-form {
140
+ width: 97% !important;
141
+ }
142
+ }
@@ -0,0 +1,31 @@
1
+ <template>
2
+ <div class="login-container">
3
+ <div class="login-box">
4
+ <div class="login-form">
5
+ <div class="login-logo">
6
+ <h2 class="logo-text">九州通供应链管理平台</h2>
7
+ <h3 class="logo-text-tips">精益管理,高效协同每一环</h3>
8
+ </div>
9
+ <LoginForm :loginCallBack="loginCallBack" />
10
+ </div>
11
+ </div>
12
+ <LoginFooter />
13
+ </div>
14
+ </template>
15
+
16
+ <script setup lang="ts" name="login">
17
+ import LoginFooter from "./components/LoginFooter.vue";
18
+ import LoginForm from "./components/LoginForm.vue";
19
+
20
+ export interface LoginProps {
21
+ // loginApi: (params: any) => Promise<any>; // 请求表格数据的 api ==> 必传
22
+ loginCallBack?: (params: any) => Promise<any>;
23
+ }
24
+
25
+ // 接受父组件参数,配置默认值
26
+ const props = withDefaults(defineProps<LoginProps>(), {});
27
+ </script>
28
+
29
+ <style scoped lang="scss">
30
+ @use "./index";
31
+ </style>
@@ -0,0 +1,47 @@
1
+ // 登录模块
2
+ export namespace Login {
3
+ export interface ReqLoginForm {
4
+ phone: string;
5
+ password: string;
6
+ systemId: string;
7
+ code?: string;
8
+ id?: string;
9
+ }
10
+
11
+ export interface ResLogin {
12
+ agencyId: string;
13
+ agencyName: string;
14
+ isEncryption: boolean;
15
+ isFirstLogin: boolean;
16
+ isNotChangePwd: boolean;
17
+ loginResult: number | null;
18
+ loginResultStr: string;
19
+ notChangePwdErrorMessage: string;
20
+ refreshToken: string;
21
+ token: string;
22
+ userId: string;
23
+ userName: string;
24
+ }
25
+ export interface ResAuthButtons {
26
+ [key: string]: string[];
27
+ }
28
+
29
+ export interface ResUserInfo {
30
+ authLists: Menu.authButtonOptions[];
31
+ baseMenus: Menu.MenuOptions[];
32
+ collectMenuIds: string[];
33
+ name: string;
34
+ phoneNumber: string;
35
+ phoneNumberConfirmed: boolean | null;
36
+ rolesIds: string[];
37
+ rolesName: string[];
38
+ userName: string;
39
+ userType: number | null;
40
+ userTypeStr: string;
41
+ email: string;
42
+ extraProperties: {
43
+ userType: number | null;
44
+ AgencyId: string;
45
+ };
46
+ }
47
+ }
@@ -0,0 +1,81 @@
1
+ <template>
2
+ <div class="numerical-range">
3
+ <el-input-number
4
+ v-model="searchParam[startField]"
5
+ v-bind="handleSearchProps"
6
+ :controls="false"
7
+ :placeholder="queryItem?.search?.startPlaceholder || '请输入'"
8
+ :clearable="true"
9
+ />
10
+ <span class="range">{{ queryItem?.search?.rangeSeparator || '至' }}</span>
11
+ <el-input-number
12
+ v-model="searchParam[endField]"
13
+ v-bind="handleSearchProps"
14
+ :controls="false"
15
+ :placeholder="queryItem?.search?.endPlaceholder || '请输入'"
16
+ :clearable="queryItem?.search?.clearable"
17
+ />
18
+ </div>
19
+ </template>
20
+ <script setup lang="ts">
21
+ import { defineProps, ref, watch, computed } from 'vue'
22
+ const props = defineProps({
23
+ queryItem: {
24
+ type: Object,
25
+ default: () => {}
26
+ },
27
+ searchParam: {
28
+ type: Object,
29
+ default: () => {}
30
+ },
31
+ disabled: {
32
+ type: Boolean,
33
+ default: false
34
+ }
35
+ })
36
+ const startField = ref(props.queryItem.search?.startField)
37
+ const endField = ref(props.queryItem.search?.endField)
38
+ watch(
39
+ () => props.searchParam?.[props.queryItem.prop],
40
+ val => {
41
+ if (val && val.length) {
42
+ props.searchParam[startField.value] = val[0]
43
+ props.searchParam[endField.value] = val[1]
44
+ }
45
+ },
46
+ { deep: true, immediate: true }
47
+ )
48
+ const handleSearchProps = computed(() => {
49
+ let searchProps = props.queryItem.search?.props ?? {}
50
+ return searchProps
51
+ })
52
+ // watch(
53
+ // () => props.queryItem?.search?.defaultValue,
54
+ // val => {
55
+ // if (val && val.length) {
56
+ // props.searchParam[startField.value] = val[0]
57
+ // props.searchParam[endField.value] = val[1]
58
+ // console.log(112345, props.searchParam)
59
+ // }
60
+ // console.log(val)
61
+ // },
62
+ // { deep: true, immediate: true }
63
+ // )
64
+ </script>
65
+ <style lang="scss" scoped>
66
+ .numerical-range {
67
+ display: flex;
68
+ justify-content: flex-start;
69
+ align-items: center;
70
+ padding: 0;
71
+ .el-input-number {
72
+ flex: 1;
73
+ }
74
+ :deep(.el-input-number .el-input__inner) {
75
+ text-align: left;
76
+ }
77
+ .range {
78
+ margin: 0 8px;
79
+ }
80
+ }
81
+ </style>
@@ -0,0 +1,151 @@
1
+ <template>
2
+ <div v-if="isShow" class="flex-right-center item">
3
+ <div class="flex-right-center">
4
+ <div v-if="dateType1 === 'monthRange'">
5
+ <el-date-picker
6
+ v-model="selectMonth1"
7
+ type="month"
8
+ placeholder="请选择开始时间"
9
+ value-format="YYYY-MM"
10
+ format="YYYY-MM"
11
+ :clearable="false"
12
+ :disabled-date="disabledStartDate"
13
+ @change="changeMonth('start')"
14
+ style="width: 100px"
15
+ />
16
+ <span class="ml5 mr5">-</span>
17
+ <el-date-picker
18
+ v-model="selectMonth2"
19
+ type="month"
20
+ placeholder="请选择结束时间"
21
+ value-format="YYYY-MM"
22
+ format="YYYY-MM"
23
+ :clearable="false"
24
+ :disabled-date="disabledEndDate"
25
+ @change="changeMonth('end')"
26
+ style="width: 100px"
27
+ />
28
+ </div>
29
+ <el-date-picker
30
+ v-else
31
+ v-model="selectYear"
32
+ :type="dateType1"
33
+ :value-format="timeFormat"
34
+ format="YYYY"
35
+ @change="changeTime"
36
+ :clearable="false"
37
+ />
38
+ </div>
39
+ </div>
40
+ </template>
41
+
42
+ <script setup lang="ts" name="JztPageCard_DatePicker">
43
+ import dayjs from 'dayjs'
44
+ /**
45
+ * @component 时间组件
46
+ */
47
+ import { isBefore, isAfter, formatDateTime, formatDateRange } from '@jzt-spd/utils'
48
+ import { ref, onMounted, computed } from 'vue'
49
+
50
+ interface ProTableProps {
51
+ isShow?: boolean
52
+ timeList?: string | string[] //初始时间
53
+ timeInfo?: string[] //最终时间
54
+ dateType?: 'year' | 'monthRange'
55
+ valueFormat?: string
56
+ }
57
+ // 默认值
58
+ const props = withDefaults(defineProps<ProTableProps>(), {
59
+ isShow: false,
60
+ timeList: '',
61
+ timeInfo: () => ['', ''],
62
+ dateType: 'year',
63
+ valueFormat: 'YYYY-MM-DD HH:mm:ss'
64
+ })
65
+ const emit = defineEmits(['changeTime'])
66
+
67
+ const selectMonth1 = ref()
68
+ const selectMonth2 = ref()
69
+ const selectYear = ref() // props传入的初始时间
70
+ const dateType1 = ref(props.dateType) //
71
+ const timeFormat = ref() // 格式化日期格式模版
72
+
73
+ const initData = () => {
74
+ if (!props.isShow) return
75
+ if (dateType1.value === 'year') {
76
+ timeFormat.value = 'YYYY'
77
+ selectYear.value = props.timeList || dayjs().format(timeFormat.value)
78
+ } else if (dateType1.value === 'monthRange') {
79
+ timeFormat.value = 'YYYY-MM'
80
+ const isArr = Array.isArray(props.timeList)
81
+ let startTime = props.timeList || dayjs().startOf('year').format(timeFormat.value)
82
+ let endTime = props.timeList || dayjs().format(timeFormat.value)
83
+ if (isArr && props.timeList.length === 2) {
84
+ startTime = props.timeList[0] ?? ''
85
+ endTime = props.timeList[1] ?? ''
86
+ }
87
+ selectMonth1.value = dayjs(startTime).format(timeFormat.value)
88
+ selectMonth2.value = dayjs(endTime).format(timeFormat.value)
89
+ }
90
+ getFormatDate()
91
+ }
92
+ // 处理时间最终结果
93
+ const getFormatDate = () => {
94
+ // 1:格式化 2:获取时间
95
+ let yearInfo = { startTime: '', endTime: '', endTimeAdd: '' }
96
+ if (dateType1.value === 'year') {
97
+ yearInfo = formatDateRange({
98
+ formatStr: props.valueFormat,
99
+ startTime: selectYear.value,
100
+ endTime: selectYear.value,
101
+ type: 'year'
102
+ })
103
+ } else if (dateType1.value === 'monthRange') {
104
+ yearInfo = formatDateRange({
105
+ formatStr: props.valueFormat,
106
+ startTime: selectMonth1.value,
107
+ endTime: selectMonth2.value,
108
+ type: 'month'
109
+ })
110
+ }
111
+ emit('changeTime', yearInfo)
112
+ }
113
+ initData()
114
+
115
+ // 禁用结束时间之后的日期
116
+ const disabledStartDate = (time: Date) => {
117
+ return isAfter(time, selectMonth2.value)
118
+ }
119
+ // 禁用开始时间之钱的日期
120
+ const disabledEndDate = (time: Date) => {
121
+ return isBefore(time, selectMonth1.value)
122
+ }
123
+ // 年份范围变动
124
+ const changeMonth = (flag: string) => {
125
+ const startYear = formatDateTime(selectMonth1.value, 'YYYY')
126
+ const endYear = formatDateTime(selectMonth2.value, 'YYYY')
127
+ if (startYear != endYear && flag == 'start') {
128
+ selectMonth2.value = selectMonth1.value
129
+ } else if (startYear != endYear && flag == 'end') {
130
+ selectMonth1.value = selectMonth2.value
131
+ }
132
+ changeTime()
133
+ }
134
+ // 年份选择变动
135
+ const changeTime = () => {
136
+ getFormatDate()
137
+ }
138
+
139
+ onMounted(() => {
140
+ changeTime()
141
+ })
142
+ </script>
143
+ <style lang="scss" scoped>
144
+ .item {
145
+ margin-left: 10px;
146
+ }
147
+ :deep(.el-date-editor) {
148
+ width: 126px;
149
+ // margin-right: 10px;
150
+ }
151
+ </style>
@@ -0,0 +1,60 @@
1
+ <template>
2
+ <div class="flx-left-center" :class="[isRadius ? 'radius-title-right' : 'title-right']" @click="goDetails">
3
+ {{ title }}
4
+ <div class="flx-center circle ml6">
5
+ <el-icon color="var(--el-color-primary)"><ArrowRight /></el-icon>
6
+ </div>
7
+ </div>
8
+ </template>
9
+
10
+ <script setup lang="ts" name="JztPageCard_Details">
11
+ /**
12
+ * @component 【更多详情】组件
13
+ */
14
+ interface ProTableProps {
15
+ // isShow?: boolean // 是否显示标题右侧内容
16
+ title?: string //标题右侧内容
17
+ isRadius?: boolean
18
+ }
19
+ // 默认值
20
+ const props = withDefaults(defineProps<ProTableProps>(), {
21
+ // isShow: false,
22
+ title: '查看更多',
23
+ isRadius: true
24
+ })
25
+ const emits = defineEmits(['goDetails'])
26
+ // 更多详情
27
+ const goDetails = () => {
28
+ emits('goDetails')
29
+ }
30
+ </script>
31
+ <style lang="scss" scoped>
32
+ .title-right {
33
+ color: var(--el-color-primary);
34
+ font-size: 14px;
35
+ font-weight: 500;
36
+ cursor: pointer;
37
+ }
38
+ // .title-right,
39
+ .radius-title-right {
40
+ .circle {
41
+ width: 16px;
42
+ height: 16px;
43
+ border-radius: 50%;
44
+ background: #f3f7ff;
45
+ border: 1px solid #dee8ff;
46
+ }
47
+ }
48
+
49
+ .radius-title-right {
50
+ color: #fff;
51
+ // color: #178afe;
52
+ font-size: 14px;
53
+ font-weight: 500;
54
+ cursor: pointer;
55
+ border-radius: 14px;
56
+ padding: 2px 8px;
57
+ background: linear-gradient(177.5deg, #5f91ff 0%, #105afd 100%);
58
+ flex-shrink: 0;
59
+ }
60
+ </style>