diff --git a/package.json b/package.json index 08a7388..da7bac7 100644 --- a/package.json +++ b/package.json @@ -55,6 +55,7 @@ "@dcloudio/uni-quickapp-webview": "3.0.0-5020420260813003", "@wot-ui/ui": "^2.3.2", "miniprogram-api-typings": "^5.2.3", + "pinia": "^4.0.3", "vue": "^3.4.21", "vue-i18n": "^9.1.9" }, diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index c1d2813..6043782 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -62,6 +62,9 @@ importers: miniprogram-api-typings: specifier: ^5.2.3 version: 5.2.3 + pinia: + specifier: ^4.0.3 + version: 4.0.3(@vue/devtools-api@6.6.4)(typescript@4.9.5)(vue@3.5.42(typescript@4.9.5)) vue: specifier: ^3.4.21 version: 3.5.42(typescript@4.9.5) @@ -3578,6 +3581,16 @@ packages: resolution: {integrity: sha512-qcJu88Q2IWqJsDD529JKMdwGm/dvInW4HvQnRwiH9JtihJvzGOscDtHE3x1pBKeUOTysQ8kVmLnJ2kJu7yhcGA==} engines: {node: '>=12'} + pinia@4.0.3: + resolution: {integrity: sha512-XMQqpvjgG7LMqVhhFUzKLT4KEbsYbfZZ0CZU9PgdFm1O2VKBmIkykL8+SfNhOaT7sR0wT6BEgKT0YNDYWgmVRA==} + peerDependencies: + '@vue/devtools-api': ^8.1.5 + typescript: '>=5.6.0' + vue: ^3.5.11 + peerDependenciesMeta: + typescript: + optional: true + pirates@4.0.7: resolution: {integrity: sha512-TfySrs/5nm8fQJDcBDuUng3VOUKsd7S+zqvbOTiGXHfxX4wK31ard+hoNuvkicM/2YFzlpDgABOevKSsB4G/FA==} engines: {node: '>= 6'} @@ -9039,6 +9052,14 @@ snapshots: picomatch@4.0.7: {} + pinia@4.0.3(@vue/devtools-api@6.6.4)(typescript@4.9.5)(vue@3.5.42(typescript@4.9.5)): + dependencies: + '@vue/devtools-api': 6.6.4 + nostics: 1.2.0 + vue: 3.5.42(typescript@4.9.5) + optionalDependencies: + typescript: 4.9.5 + pirates@4.0.7: {} pixelmatch@4.0.2: diff --git a/project.config.json b/project.config.json new file mode 100644 index 0000000..da2a8b8 --- /dev/null +++ b/project.config.json @@ -0,0 +1,24 @@ +{ + "setting": { + "es6": true, + "postcss": true, + "minified": true, + "uglifyFileName": false, + "enhance": true, + "packNpmRelationList": [], + "babelSetting": { + "ignore": [], + "disablePlugins": [], + "outputPath": "" + }, + "useCompilerPlugins": false + }, + "compileType": "miniprogram", + "simulatorPluginLibVersion": {}, + "packOptions": { + "ignore": [], + "include": [] + }, + "appid": "wxf7a95cb4373170c1", + "editorSetting": {} +} \ No newline at end of file diff --git a/project.private.config.json b/project.private.config.json new file mode 100644 index 0000000..044e3e8 --- /dev/null +++ b/project.private.config.json @@ -0,0 +1,14 @@ +{ + "libVersion": "3.17.2", + "projectname": "patch-mp", + "setting": { + "urlCheck": true, + "coverView": true, + "lazyloadPlaceholderEnable": false, + "skylineRenderEnable": false, + "preloadBackgroundData": false, + "autoAudits": false, + "showShadowRootInWxmlPanel": true, + "compileHotReLoad": true + } +} \ No newline at end of file diff --git a/src/components/CropPopup.vue b/src/components/CropPopup.vue new file mode 100644 index 0000000..289242d --- /dev/null +++ b/src/components/CropPopup.vue @@ -0,0 +1,124 @@ + + + diff --git a/src/components/PatchPopup.vue b/src/components/PatchPopup.vue new file mode 100644 index 0000000..0f52975 --- /dev/null +++ b/src/components/PatchPopup.vue @@ -0,0 +1,106 @@ + + + diff --git a/src/components/RecordPopup.vue b/src/components/RecordPopup.vue new file mode 100644 index 0000000..cb9a109 --- /dev/null +++ b/src/components/RecordPopup.vue @@ -0,0 +1,256 @@ + + + diff --git a/src/main.ts b/src/main.ts index 8e387cd..f2e44e1 100644 --- a/src/main.ts +++ b/src/main.ts @@ -1,9 +1,13 @@ import 'uno.css' import { createSSRApp } from 'vue' +import { createPinia } from 'pinia' import App from './App.vue' export function createApp() { const app = createSSRApp(App) + const pinia = createPinia() - return { app } + app.use(pinia) + + return { app, pinia } } diff --git a/src/manifest.json b/src/manifest.json index 309b9ec..27112cd 100644 --- a/src/manifest.json +++ b/src/manifest.json @@ -1,6 +1,6 @@ { "name" : "", - "appid" : "", + "appid" : "wxf7a95cb4373170c1", "description" : "", "versionName" : "1.0.0", "versionCode" : "100", @@ -65,7 +65,7 @@ "mp-toutiao" : { "usingComponents" : true }, - "uniStatistics": { + "uniStatistics": { "enable": false }, "vueVersion" : "3" diff --git a/src/pages.json b/src/pages.json index 28df6e7..f1e170f 100644 --- a/src/pages.json +++ b/src/pages.json @@ -4,6 +4,10 @@ "path": "pages/index/index", "style": { "navigationBarTitleText": "首页" } }, + { + "path": "pages/record/index", + "style": { "navigationBarTitleText": "记录" } + }, { "path": "pages/user/index", "style": { "navigationBarTitleText": "我的" } diff --git a/src/pages/index/index.vue b/src/pages/index/index.vue index 8ca34f1..8087a0e 100644 --- a/src/pages/index/index.vue +++ b/src/pages/index/index.vue @@ -13,52 +13,51 @@ - - + + + + + + - - + - - + + + + @@ -67,9 +66,13 @@ import { computed } from 'vue' import { onShow } from '@dcloudio/uni-app' import appLogo from '@/static/logo.png' +import { usePatchStore } from "@/stores/patch"; +import type {ICrop, IPatch} from "@/types"; +import PatchPopup from "@/components/PatchPopup.vue"; defineOptions({ name: 'Home' }) +const patchStore = usePatchStore() const imgURL = appLogo // ===== 时间 ===== @@ -90,10 +93,48 @@ const today = computed(() => { return `${m}月${d}日 周${w}` }) +onShow(async () => { + await loadData() +}) -onShow(() => loadData()) +async function loadData() { + await patchStore.queryPatchList() +} -function loadData() { +function addPatchClick() { + patchStore.patchForm = { + id: 0, + name: '', + location: '', + status: '' + } + patchStore.patchApiType = 'ADD' + patchStore.showPatchPopup = true + patchStore.showPatchFab = false +} +function editPatchClick(patch: IPatch) { + patchStore.patchForm = JSON.parse(JSON.stringify(patch)) + patchStore.patchApiType = 'UPDATE' + patchStore.showPatchPopup = true + patchStore.showPatchFab = false +} + +async function viewDetailClick(patch: IPatch) { + patchStore.currentPatch = patch + + if (patch.crop) { + await patchStore.queryRecordList(patch.crop.id) + } else { + patchStore.recordList = [] + } + wx.navigateTo({ + url: '/pages/record/index' + }) +} + +function handlePreview(crop: ICrop) { + const fullUrls = crop.images?.map(url => `${patchStore.baseUrl}/${url}`) as string[] + uni.previewImage({ urls: fullUrls, current: fullUrls[0] }) } diff --git a/src/pages/record/index.vue b/src/pages/record/index.vue new file mode 100644 index 0000000..22ee0d6 --- /dev/null +++ b/src/pages/record/index.vue @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/pages/user/index.vue b/src/pages/user/index.vue index cb7c469..71e8d26 100644 --- a/src/pages/user/index.vue +++ b/src/pages/user/index.vue @@ -1,105 +1,8 @@ diff --git a/src/stores/patch.ts b/src/stores/patch.ts new file mode 100644 index 0000000..e3623ce --- /dev/null +++ b/src/stores/patch.ts @@ -0,0 +1,259 @@ +import { defineStore } from 'pinia' +import type { ICrop, IPatch, IRecord } from "@/types"; +import type { UploadFile } from "@wot-ui/ui/components/wd-upload/types"; + +export const usePatchStore = defineStore('patch', { + state: () => ({ + baseUrl: 'https://cxx0822.s.3q.hair', + showPatchFab: true, + patchList: [] as IPatch[], + patchApiType: 'ADD' as 'ADD' | 'UPDATE' | 'DELETE', + patchForm: { + + } as IPatch, + showPatchPopup: false, + currentPatch: {} as IPatch, + recordList: [] as IRecord[], + cropApiType: 'ADD' as 'ADD' | 'UPDATE' | 'DELETE', + cropForm: { + + } as ICrop, + showCropPopup: false, + showRecordFab: true, + showRecordPopup: false, + recordApiType: 'ADD' as 'ADD' | 'UPDATE' | 'DELETE', + recordForm: { + id: 0, + crop_id: 0, + type: '', + date: '', + content: '', + images: [], + videos: [], + stage: '', + } as IRecord, + imageFileList: [] as UploadFile[], + videoFileList: [] as UploadFile[], + }), + actions: { + async queryPatchList() { + this.patchList = await this.queryPatchListApi() + }, + async queryPatch(patchId: number) { + this.currentPatch = await this.queryPatchApi(patchId) + }, + async queryRecordList(cropId: number) { + this.recordList = await this.queryRecordListApi(cropId) + }, + async queryPatchListApi() { + return new Promise((resolve, reject) => { + wx.request({ + url: `${this.baseUrl}/patch-api/patches`, + method: 'GET', + header: { 'Content-Type': 'application/json' }, + success: (res) => { + if (res.statusCode >= 200 && res.statusCode < 300) { + resolve(res.data as IPatch[]) + } else { + reject({ status: res.statusCode, data: res.data }) + } + }, + fail: (err) => reject(err), + }) + }) + }, + async queryPatchApi(patchId: number) { + return new Promise((resolve, reject) => { + wx.request({ + url: `${this.baseUrl}/patch-api/patches/${patchId}`, + method: 'GET', + header: { 'Content-Type': 'application/json' }, + success: (res) => { + if (res.statusCode >= 200 && res.statusCode < 300) { + resolve(res.data as IPatch) + } else { + reject({ status: res.statusCode, data: res.data }) + } + }, + fail: (err) => reject(err), + }) + }) + }, + async addPatchApi() { + return new Promise((resolve, reject) => { + wx.request({ + url: `${this.baseUrl}/patch-api/patches`, + method: 'POST', + header: { 'Content-Type': 'application/json' }, + data: this.patchForm, + success: (res) => { + if (res.statusCode >= 200 && res.statusCode < 300) { + resolve(true) + } else { + reject({ status: res.statusCode, data: false }) + } + }, + fail: (err) => reject(err), + }) + }) + }, + async updatePatchApi(patchId: number) { + return new Promise((resolve, reject) => { + wx.request({ + url: `${this.baseUrl}/patch-api/patches/${patchId}`, + method: 'PUT', + header: { 'Content-Type': 'application/json' }, + data: this.patchForm, + success: (res) => { + if (res.statusCode >= 200 && res.statusCode < 300) { + resolve(true) + } else { + reject({ status: res.statusCode, data: false }) + } + }, + fail: (err) => reject(err), + }) + }) + }, + async deletePatchApi(patchId: number) { + return new Promise((resolve, reject) => { + wx.request({ + url: `${this.baseUrl}/patch-api/patches/${patchId}`, + method: 'DELETE', + header: { 'Content-Type': 'application/json' }, + success: (res) => { + if (res.statusCode >= 200 && res.statusCode < 300) { + resolve(true) + } else { + reject({ status: res.statusCode, data: false }) + } + }, + fail: (err) => reject(err), + }) + }) + }, + async addCropApi() { + return new Promise((resolve, reject) => { + wx.request({ + url: `${this.baseUrl}/patch-api/crops`, + method: 'POST', + header: { 'Content-Type': 'application/json' }, + data: this.cropForm, + success: (res) => { + if (res.statusCode >= 200 && res.statusCode < 300) { + resolve(true) + } else { + reject({ status: res.statusCode, data: false }) + } + }, + fail: (err) => reject(err), + }) + }) + }, + async updateCropApi(cropId: number) { + return new Promise((resolve, reject) => { + wx.request({ + url: `${this.baseUrl}/patch-api/crops/${cropId}`, + method: 'PUT', + header: { 'Content-Type': 'application/json' }, + data: this.cropForm, + success: (res) => { + if (res.statusCode >= 200 && res.statusCode < 300) { + resolve(true) + } else { + reject({ status: res.statusCode, data: false }) + } + }, + fail: (err) => reject(err), + }) + }) + }, + async deleteCropApi(cropId: number) { + return new Promise((resolve, reject) => { + wx.request({ + url: `${this.baseUrl}/patch-api/crops/${cropId}`, + method: 'DELETE', + header: { 'Content-Type': 'application/json' }, + success: (res) => { + if (res.statusCode >= 200 && res.statusCode < 300) { + resolve(true) + } else { + reject({ status: res.statusCode, data: false }) + } + }, + fail: (err) => reject(err), + }) + }) + }, + async queryRecordListApi(cropId: number) { + return new Promise((resolve, reject) => { + wx.request({ + url: `${this.baseUrl}/patch-api/records/crop/${cropId}`, + method: 'GET', + header: { 'Content-Type': 'application/json' }, + success: (res) => { + if (res.statusCode >= 200 && res.statusCode < 300) { + resolve(res.data as IRecord[]) + } else { + reject({ status: res.statusCode, data: res.data }) + } + }, + fail: (err) => reject(err), + }) + }) + }, + async addRecordApi() { + return new Promise((resolve, reject) => { + wx.request({ + url: `${this.baseUrl}/patch-api/records`, + method: 'POST', + header: { 'Content-Type': 'application/json' }, + data: this.recordForm, + success: (res) => { + if (res.statusCode >= 200 && res.statusCode < 300) { + resolve(true) + } else { + reject({ status: res.statusCode, data: false }) + } + }, + fail: (err) => reject(err), + }) + }) + }, + async updateRecordApi(recordId: number) { + return new Promise((resolve, reject) => { + wx.request({ + url: `${this.baseUrl}/patch-api/records/${recordId}`, + method: 'PUT', + header: { 'Content-Type': 'application/json' }, + data: this.recordForm, + success: (res) => { + if (res.statusCode >= 200 && res.statusCode < 300) { + resolve(true) + } else { + reject({ status: res.statusCode, data: false }) + } + }, + fail: (err) => reject(err), + }) + }) + }, + async deleteRecordApi(recordId: number) { + return new Promise((resolve, reject) => { + wx.request({ + url: `${this.baseUrl}/patch-api/records/${recordId}`, + method: 'DELETE', + header: { 'Content-Type': 'application/json' }, + success: (res) => { + if (res.statusCode >= 200 && res.statusCode < 300) { + resolve(true) + } else { + reject({ status: res.statusCode, data: false }) + } + }, + fail: (err) => reject(err), + }) + }) + }, + }, +}) diff --git a/src/types/index.ts b/src/types/index.ts new file mode 100644 index 0000000..8ddf0a1 --- /dev/null +++ b/src/types/index.ts @@ -0,0 +1,27 @@ +export interface ICrop { + id: number + patch_id: number + name: string + variety: string + date: string + images?: string[] +} + +export interface IPatch { + id: number + name: string + location: string + status: string + crop?: ICrop +} + +export interface IRecord { + id: number + crop_id: number + type: string + date: string + content: string + images: string[] + videos: string[] + stage: string +} diff --git a/src/uni_modules/liu-drag-button_1.0.5/changelog.md b/src/uni_modules/liu-drag-button_1.0.5/changelog.md new file mode 100644 index 0000000..f04925b --- /dev/null +++ b/src/uni_modules/liu-drag-button_1.0.5/changelog.md @@ -0,0 +1,12 @@ +## 1.0.5(2023-07-13) +优化 +## 1.0.4(2023-06-08) +增加预览二维码 +## 1.0.3(2023-05-31) +增加license +## 1.0.2(2023-04-28) +优化 +## 1.0.1(2023-04-26) +增加示例 +## 1.0.0(2023-04-26) +初始化发布 diff --git a/src/uni_modules/liu-drag-button_1.0.5/components/liu-drag-button/liu-drag-button.vue b/src/uni_modules/liu-drag-button_1.0.5/components/liu-drag-button/liu-drag-button.vue new file mode 100644 index 0000000..8b10e7c --- /dev/null +++ b/src/uni_modules/liu-drag-button_1.0.5/components/liu-drag-button/liu-drag-button.vue @@ -0,0 +1,143 @@ + + + + + diff --git a/src/uni_modules/liu-drag-button_1.0.5/license.md b/src/uni_modules/liu-drag-button_1.0.5/license.md new file mode 100644 index 0000000..029bf39 --- /dev/null +++ b/src/uni_modules/liu-drag-button_1.0.5/license.md @@ -0,0 +1,6 @@ +### 1、本插件可免费下载使用; +### 2、未经许可,严禁复制本插件派生同类插件上传插件市场; +### 3、未经许可,严禁在插件市场恶意复制抄袭本插件进行违规获利; +### 4、对本软件的任何使用都必须遵守这些条款,违反这些条款的个人或组织将面临法律追究。 + + diff --git a/src/uni_modules/liu-drag-button_1.0.5/package.json b/src/uni_modules/liu-drag-button_1.0.5/package.json new file mode 100644 index 0000000..61a3c70 --- /dev/null +++ b/src/uni_modules/liu-drag-button_1.0.5/package.json @@ -0,0 +1,85 @@ +{ + "id": "liu-drag-button", + "displayName": "可拖动悬浮按钮", + "version": "1.0.5", + "description": "可拖动的悬浮按钮,兼容小程序、H5,支持自动停靠,支持自定义样式,使用相当简单,源码简单易修改。", + "keywords": [ + "悬浮按钮", + "拖拽按钮", + "拖动", + "按钮", + "拖拽" + ], + "repository": "", + "engines": { + "HBuilderX": "^3.1.0" + }, + "dcloudext": { + "type": "component-vue", + "sale": { + "regular": { + "price": "0.00" + }, + "sourcecode": { + "price": "0.00" + } + }, + "contact": { + "qq": "" + }, + "declaration": { + "ads": "无", + "data": "无", + "permissions": "无" + }, + "npmurl": "" + }, + "uni_modules": { + "dependencies": [], + "encrypt": [], + "platforms": { + "cloud": { + "tcb": "y", + "aliyun": "y" + }, + "client": { + "Vue": { + "vue2": "y", + "vue3": "u" + }, + "App": { + "app-vue": "u", + "app-nvue": "u" + }, + "H5-mobile": { + "Safari": "y", + "Android Browser": "y", + "微信浏览器(Android)": "y", + "QQ浏览器(Android)": "y" + }, + "H5-pc": { + "Chrome": "u", + "IE": "u", + "Edge": "u", + "Firefox": "u", + "Safari": "u" + }, + "小程序": { + "微信": "y", + "阿里": "u", + "百度": "u", + "字节跳动": "u", + "QQ": "u", + "钉钉": "u", + "快手": "u", + "飞书": "u", + "京东": "u" + }, + "快应用": { + "华为": "u", + "联盟": "u" + } + } + } + } +} diff --git a/src/uni_modules/liu-drag-button_1.0.5/readme.md b/src/uni_modules/liu-drag-button_1.0.5/readme.md new file mode 100644 index 0000000..848af4d --- /dev/null +++ b/src/uni_modules/liu-drag-button_1.0.5/readme.md @@ -0,0 +1,36 @@ +# liu-drag-button适用于uni-app项目的可拖动悬浮按钮组件 +### 本组件目前兼容微信小程序、H5 +### 本组件是可拖动的悬浮按钮,兼容小程序、H5,支持自动停靠,支持自定义样式,源码简单易修改 +# --- 扫码预览、关注我们 --- + +## 扫码关注公众号,查看更多插件信息,预览插件效果! + +![](https://uni.ckapi.pro/uniapp/publicize.png) + +### 使用方式 +``` html +按钮 +``` +``` javascript +export default { + data() { + return { + + }; + }, + methods: { + //点击按钮 + clickBtn(){ + console.log('按钮被点击了') + }, + } +} +``` + +### 属性说明 +| 名称 | 类型 | 默认值 | 描述 | +| ----------------------------|--------------- | ------------------ | ---------------| +| disabled | Boolean | false | 是否禁用拖动 +| canDocking | Boolean | true | 是否自动停靠 +| bottomPx | Number | 30 | 按钮默认位置离底部距离(px) +| rightPx | Number | 0 | 按钮默认位置离右边距离(px) diff --git a/src/utils/index.ts b/src/utils/index.ts new file mode 100644 index 0000000..224ab83 --- /dev/null +++ b/src/utils/index.ts @@ -0,0 +1,19 @@ +export function formatDate(ts: string | number) { + if (!ts) + return '' + const d = new Date(ts) + const pad = (n: number) => String(n).padStart(2, '0') + return `${d.getFullYear()}-${pad(d.getMonth() + 1)}-${pad(d.getDate())}` +} + +export function formatDateTime(ts: string | number) { + if (!ts) + return '' + const d = new Date(ts) + const pad = (n: number) => String(n).padStart(2, '0') + return `${d.getFullYear()}-${pad(d.getMonth() + 1)}-${pad(d.getDate())} ${pad(d.getHours())}:${pad(d.getMinutes())}` +} + +export function generateUniqueId() { + return Date.now() + '-' + Math.random().toString(36).slice(2, 6); +}