9.18/2
This commit is contained in:
@@ -54,6 +54,12 @@
|
||||
"navigationBarTitleText": "选择客户"
|
||||
}
|
||||
},
|
||||
{
|
||||
"path": "pages/customer/form",
|
||||
"style": {
|
||||
"navigationBarTitleText": "新增客户"
|
||||
}
|
||||
},
|
||||
{
|
||||
"path": "pages/supplier/select",
|
||||
"style": {
|
||||
|
||||
59
frontend/pages/customer/form.vue
Normal file
59
frontend/pages/customer/form.vue
Normal file
@@ -0,0 +1,59 @@
|
||||
<template>
|
||||
<view class="page">
|
||||
<view class="field"><text class="label">客户名称</text><input class="value" v-model="form.name" placeholder="必填" /></view>
|
||||
<view class="field"><text class="label">客户等级</text><input class="value" v-model="form.level" placeholder="可选,如 VIP/A/B" /></view>
|
||||
<view class="field">
|
||||
<text class="label">售价档位</text>
|
||||
<picker :range="priceLevels" :value="priceIdx" @change="onPriceChange">
|
||||
<view class="value">{{ priceLevels[priceIdx] }}</view>
|
||||
</picker>
|
||||
</view>
|
||||
<view class="field"><text class="label">联系人</text><input class="value" v-model="form.contactName" placeholder="可选" /></view>
|
||||
<view class="field"><text class="label">手机</text><input class="value" v-model="form.mobile" placeholder="可选" /></view>
|
||||
<view class="field"><text class="label">电话</text><input class="value" v-model="form.phone" placeholder="可选(座机)" /></view>
|
||||
<view class="field"><text class="label">送货地址</text><input class="value" v-model="form.address" placeholder="可选" /></view>
|
||||
<view class="field"><text class="label">初始应收</text><input class="value" type="digit" v-model.number="form.arOpening" placeholder="默认 0.00" /></view>
|
||||
<view class="textarea"><textarea v-model="form.remark" maxlength="200" placeholder="备注(最多200字)"></textarea></view>
|
||||
|
||||
<view class="bottom"><button class="primary" @click="save">保存</button></view>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { post, put } from '../../common/http.js'
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
id: null,
|
||||
form: { name:'', level:'', priceLevel:'retail', contactName:'', mobile:'', phone:'', address:'', arOpening:0, remark:'' },
|
||||
priceLevels: ['retail','distribution','wholesale','big_client'],
|
||||
priceIdx: 0
|
||||
}
|
||||
},
|
||||
onLoad(query) { if (query && query.id) { this.id = Number(query.id) } },
|
||||
methods: {
|
||||
onPriceChange(e){ this.priceIdx = Number(e.detail.value); this.form.priceLevel = this.priceLevels[this.priceIdx] },
|
||||
async save() {
|
||||
if (!this.form.name) return uni.showToast({ title:'请填写客户名称', icon:'none' })
|
||||
try {
|
||||
if (this.id) await put(`/api/customers/${this.id}`, this.form)
|
||||
else await post('/api/customers', this.form)
|
||||
uni.showToast({ title:'保存成功', icon:'success' })
|
||||
setTimeout(() => uni.navigateBack(), 500)
|
||||
} catch(e) { uni.showToast({ title: e?.message || '保存失败', icon:'none' }) }
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style>
|
||||
.page { padding-bottom: 140rpx; }
|
||||
.field { display:flex; justify-content: space-between; padding: 22rpx 24rpx; background:#fff; border-bottom:1rpx solid #eee; }
|
||||
.label { color:#666; }
|
||||
.value { color:#333; text-align: right; flex: 1; }
|
||||
.textarea { padding: 16rpx 24rpx; background:#fff; margin-top: 12rpx; }
|
||||
.bottom { position: fixed; left:0; right:0; bottom:0; background:#fff; padding: 16rpx 24rpx calc(env(safe-area-inset-bottom) + 16rpx); box-shadow: 0 -4rpx 12rpx rgba(0,0,0,0.06); }
|
||||
.primary { width: 100%; background: linear-gradient(135deg, #A0E4FF 0%, #17A2C4 100%); color:#fff; border-radius: 999rpx; padding: 20rpx 0; }
|
||||
</style>
|
||||
|
||||
|
||||
@@ -3,28 +3,37 @@
|
||||
<view class="search">
|
||||
<input v-model="kw" placeholder="搜索客户名称/电话" @confirm="search" />
|
||||
<button size="mini" @click="search">搜索</button>
|
||||
<button size="mini" :type="debtOnly ? 'primary' : 'default'" @click="toggleDebtOnly">只看欠款</button>
|
||||
</view>
|
||||
<scroll-view scroll-y class="list">
|
||||
<view class="item" v-for="c in customers" :key="c.id" @click="select(c)">
|
||||
<view class="name">{{ c.name }}</view>
|
||||
<view class="meta">{{ c.mobile || '—' }}</view>
|
||||
<view class="meta">
|
||||
{{ c.mobile || '—' }}
|
||||
<text v-if="typeof c.receivable === 'number'">|应收:¥ {{ Number(c.receivable).toFixed(2) }}</text>
|
||||
</view>
|
||||
</view>
|
||||
</scroll-view>
|
||||
<view class="bottom">
|
||||
<button class="primary" @click="createCustomer">新增客户</button>
|
||||
</view>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { get } from '../../common/http.js'
|
||||
export default {
|
||||
data() { return { kw: '', customers: [] } },
|
||||
data() { return { kw: '', debtOnly: false, customers: [] } },
|
||||
onLoad() { this.search() },
|
||||
methods: {
|
||||
toggleDebtOnly() { this.debtOnly = !this.debtOnly; this.search() },
|
||||
async search() {
|
||||
try {
|
||||
const res = await get('/api/customers', { kw: this.kw, page: 1, size: 50 })
|
||||
const res = await get('/api/customers', { kw: this.kw, debtOnly: this.debtOnly, page: 1, size: 50 })
|
||||
this.customers = Array.isArray(res?.list) ? res.list : (Array.isArray(res) ? res : [])
|
||||
} catch(e) { uni.showToast({ title: '加载失败', icon: 'none' }) }
|
||||
},
|
||||
createCustomer() { uni.navigateTo({ url: '/pages/customer/form' }) },
|
||||
select(c) {
|
||||
const opener = getCurrentPages()[getCurrentPages().length-2]
|
||||
if (opener && opener.$vm) {
|
||||
@@ -39,12 +48,14 @@
|
||||
|
||||
<style>
|
||||
.page { display:flex; flex-direction: column; height: 100vh; }
|
||||
.search { display:flex; gap: 12rpx; padding: 16rpx; background:#fff; }
|
||||
.search { display:flex; gap: 12rpx; padding: 16rpx; background:#fff; align-items:center; }
|
||||
.search input { flex:1; background:#f6f6f6; border-radius: 12rpx; padding: 12rpx; }
|
||||
.list { flex:1; }
|
||||
.item { padding: 20rpx 24rpx; background:#fff; border-bottom: 1rpx solid #f1f1f1; }
|
||||
.name { color:#333; margin-bottom: 6rpx; }
|
||||
.meta { color:#888; font-size: 24rpx; }
|
||||
.bottom { position: fixed; left:0; right:0; bottom:0; background:#fff; padding: 16rpx 24rpx calc(env(safe-area-inset-bottom) + 16rpx); box-shadow: 0 -4rpx 12rpx rgba(0,0,0,0.06); }
|
||||
.primary { width: 100%; background: linear-gradient(135deg, #A0E4FF 0%, #17A2C4 100%); color:#fff; border-radius: 999rpx; padding: 20rpx 0; }
|
||||
</style>
|
||||
|
||||
|
||||
|
||||
@@ -152,6 +152,10 @@
|
||||
uni.navigateTo({ url: '/pages/product/list' })
|
||||
return
|
||||
}
|
||||
if (item.key === 'customer') {
|
||||
uni.navigateTo({ url: '/pages/customer/select' })
|
||||
return
|
||||
}
|
||||
uni.showToast({ title: item.title + '(开发中)', icon: 'none' })
|
||||
},
|
||||
goProduct() {
|
||||
|
||||
@@ -1 +1 @@
|
||||
{"version":3,"file":"app.js","sources":["App.vue","main.js"],"sourcesContent":["<script>\r\n\texport default {\r\n\t\tonLaunch: function() {\r\n\t\t\tconsole.log('App Launch')\r\n\t\t},\r\n\t\tonShow: function() {\r\n\t\t\tconsole.log('App Show')\r\n\t\t},\r\n\t\tonHide: function() {\r\n\t\t\tconsole.log('App Hide')\r\n\t\t}\r\n\t}\r\n</script>\r\n\r\n<style>\r\n\t/*每个页面公共css */\r\n</style>\r\n","import App from './App'\r\n\r\n// #ifndef VUE3\r\nimport Vue from 'vue'\r\nimport './uni.promisify.adaptor'\r\nVue.config.productionTip = false\r\nApp.mpType = 'app'\r\nconst app = new Vue({\r\n ...App\r\n})\r\napp.$mount()\r\n// #endif\r\n\r\n// #ifdef VUE3\r\nimport { createSSRApp } from 'vue'\r\nexport function createApp() {\r\n const app = createSSRApp(App)\r\n return {\r\n app\r\n }\r\n}\r\n// #endif\r\n\r\n// 规范化 WebSocket 关闭码(仅微信小程序)\r\n// #ifdef MP-WEIXIN\r\nif (typeof uni !== 'undefined' && typeof uni.connectSocket === 'function') {\r\n const _connectSocket = uni.connectSocket\r\n uni.connectSocket = function(options) {\r\n const task = _connectSocket.call(this, options)\r\n if (task && typeof task.close === 'function') {\r\n const _close = task.close\r\n task.close = function(params = {}) {\r\n if (params && typeof params === 'object') {\r\n const codeNum = Number(params.code)\r\n const isValid = codeNum === 1000 || (codeNum >= 3000 && codeNum <= 4999)\r\n if (!isValid) {\r\n params.code = 1000\r\n if (!params.reason) params.reason = 'normalized from invalid close code'\r\n }\r\n }\r\n return _close.call(this, params)\r\n }\r\n }\r\n return task\r\n }\r\n}\r\n// #endif"],"names":["uni","createSSRApp","App"],"mappings":";;;;;;;;;;;;;;;;;AACC,MAAK,YAAU;AAAA,EACd,UAAU,WAAW;AACpBA,kBAAAA,MAAA,MAAA,OAAA,gBAAY,YAAY;AAAA,EACxB;AAAA,EACD,QAAQ,WAAW;AAClBA,kBAAAA,MAAY,MAAA,OAAA,gBAAA,UAAU;AAAA,EACtB;AAAA,EACD,QAAQ,WAAW;AAClBA,kBAAAA,MAAY,MAAA,OAAA,iBAAA,UAAU;AAAA,EACvB;AACD;ACIM,SAAS,YAAY;AAC1B,QAAM,MAAMC,cAAY,aAACC,SAAG;AAC5B,SAAO;AAAA,IACL;AAAA,EACD;AACH;AAKA,IAAI,OAAOF,cAAG,UAAK,eAAe,OAAOA,cAAAA,MAAI,kBAAkB,YAAY;AACzE,QAAM,iBAAiBA,cAAAA,MAAI;AAC3BA,sBAAI,gBAAgB,SAAS,SAAS;AACpC,UAAM,OAAO,eAAe,KAAK,MAAM,OAAO;AAC9C,QAAI,QAAQ,OAAO,KAAK,UAAU,YAAY;AAC5C,YAAM,SAAS,KAAK;AACpB,WAAK,QAAQ,SAAS,SAAS,IAAI;AACjC,YAAI,UAAU,OAAO,WAAW,UAAU;AACxC,gBAAM,UAAU,OAAO,OAAO,IAAI;AAClC,gBAAM,UAAU,YAAY,OAAS,WAAW,OAAQ,WAAW;AACnE,cAAI,CAAC,SAAS;AACZ,mBAAO,OAAO;AACd,gBAAI,CAAC,OAAO;AAAQ,qBAAO,SAAS;AAAA,UACrC;AAAA,QACF;AACD,eAAO,OAAO,KAAK,MAAM,MAAM;AAAA,MAChC;AAAA,IACF;AACD,WAAO;AAAA,EACR;AACH;;;"}
|
||||
{"version":3,"file":"app.js","sources":["App.vue","main.js"],"sourcesContent":["<script>\r\n\texport default {\r\n\t\tonLaunch: function() {\r\n\t\t\tconsole.log('App Launch')\r\n\t\t},\r\n\t\tonShow: function() {\r\n\t\t\tconsole.log('App Show')\r\n\t\t},\r\n\t\tonHide: function() {\r\n\t\t\tconsole.log('App Hide')\r\n\t\t}\r\n\t}\r\n</script>\r\n\r\n<style>\r\n\t/*每个页面公共css */\r\n</style>\r\n","import App from './App'\r\n\r\n// #ifndef VUE3\r\nimport Vue from 'vue'\r\nimport './uni.promisify.adaptor'\r\nVue.config.productionTip = false\r\nApp.mpType = 'app'\r\nconst app = new Vue({\r\n ...App\r\n})\r\napp.$mount()\r\n// #endif\r\n\r\n// #ifdef VUE3\r\nimport { createSSRApp } from 'vue'\r\nexport function createApp() {\r\n const app = createSSRApp(App)\r\n return {\r\n app\r\n }\r\n}\r\n// #endif\r\n\r\n// 规范化 WebSocket 关闭码(仅微信小程序)\r\n// #ifdef MP-WEIXIN\r\nif (typeof uni !== 'undefined' && typeof uni.connectSocket === 'function') {\r\n const _connectSocket = uni.connectSocket\r\n uni.connectSocket = function(options) {\r\n const task = _connectSocket.call(this, options)\r\n if (task && typeof task.close === 'function') {\r\n const _close = task.close\r\n task.close = function(params = {}) {\r\n if (params && typeof params === 'object') {\r\n const codeNum = Number(params.code)\r\n const isValid = codeNum === 1000 || (codeNum >= 3000 && codeNum <= 4999)\r\n if (!isValid) {\r\n params.code = 1000\r\n if (!params.reason) params.reason = 'normalized from invalid close code'\r\n }\r\n }\r\n return _close.call(this, params)\r\n }\r\n }\r\n return task\r\n }\r\n}\r\n// #endif"],"names":["uni","createSSRApp","App"],"mappings":";;;;;;;;;;;;;;;;;;AACC,MAAK,YAAU;AAAA,EACd,UAAU,WAAW;AACpBA,kBAAAA,MAAA,MAAA,OAAA,gBAAY,YAAY;AAAA,EACxB;AAAA,EACD,QAAQ,WAAW;AAClBA,kBAAAA,MAAY,MAAA,OAAA,gBAAA,UAAU;AAAA,EACtB;AAAA,EACD,QAAQ,WAAW;AAClBA,kBAAAA,MAAY,MAAA,OAAA,iBAAA,UAAU;AAAA,EACvB;AACD;ACIM,SAAS,YAAY;AAC1B,QAAM,MAAMC,cAAY,aAACC,SAAG;AAC5B,SAAO;AAAA,IACL;AAAA,EACD;AACH;AAKA,IAAI,OAAOF,cAAG,UAAK,eAAe,OAAOA,cAAAA,MAAI,kBAAkB,YAAY;AACzE,QAAM,iBAAiBA,cAAAA,MAAI;AAC3BA,sBAAI,gBAAgB,SAAS,SAAS;AACpC,UAAM,OAAO,eAAe,KAAK,MAAM,OAAO;AAC9C,QAAI,QAAQ,OAAO,KAAK,UAAU,YAAY;AAC5C,YAAM,SAAS,KAAK;AACpB,WAAK,QAAQ,SAAS,SAAS,IAAI;AACjC,YAAI,UAAU,OAAO,WAAW,UAAU;AACxC,gBAAM,UAAU,OAAO,OAAO,IAAI;AAClC,gBAAM,UAAU,YAAY,OAAS,WAAW,OAAQ,WAAW;AACnE,cAAI,CAAC,SAAS;AACZ,mBAAO,OAAO;AACd,gBAAI,CAAC,OAAO;AAAQ,qBAAO,SAAS;AAAA,UACrC;AAAA,QACF;AACD,eAAO,OAAO,KAAK,MAAM,MAAM;AAAA,MAChC;AAAA,IACF;AACD,WAAO;AAAA,EACR;AACH;;;"}
|
||||
1
frontend/unpackage/dist/dev/.sourcemap/mp-weixin/pages/customer/form.js.map
vendored
Normal file
1
frontend/unpackage/dist/dev/.sourcemap/mp-weixin/pages/customer/form.js.map
vendored
Normal file
@@ -0,0 +1 @@
|
||||
{"version":3,"file":"form.js","sources":["pages/customer/form.vue","../../../../Downloads/HBuilderX.4.76.2025082103/HBuilderX/plugins/uniapp-cli-vite/uniPage:/cGFnZXMvY3VzdG9tZXIvZm9ybS52dWU"],"sourcesContent":["<template>\r\n\t<view class=\"page\">\r\n\t\t<view class=\"field\"><text class=\"label\">客户名称</text><input class=\"value\" v-model=\"form.name\" placeholder=\"必填\" /></view>\r\n\t\t<view class=\"field\"><text class=\"label\">客户等级</text><input class=\"value\" v-model=\"form.level\" placeholder=\"可选,如 VIP/A/B\" /></view>\r\n\t\t<view class=\"field\">\r\n\t\t\t<text class=\"label\">售价档位</text>\r\n\t\t\t<picker :range=\"priceLevels\" :value=\"priceIdx\" @change=\"onPriceChange\">\r\n\t\t\t\t<view class=\"value\">{{ priceLevels[priceIdx] }}</view>\r\n\t\t\t</picker>\r\n\t\t</view>\r\n\t\t<view class=\"field\"><text class=\"label\">联系人</text><input class=\"value\" v-model=\"form.contactName\" placeholder=\"可选\" /></view>\r\n\t\t<view class=\"field\"><text class=\"label\">手机</text><input class=\"value\" v-model=\"form.mobile\" placeholder=\"可选\" /></view>\r\n\t\t<view class=\"field\"><text class=\"label\">电话</text><input class=\"value\" v-model=\"form.phone\" placeholder=\"可选(座机)\" /></view>\r\n\t\t<view class=\"field\"><text class=\"label\">送货地址</text><input class=\"value\" v-model=\"form.address\" placeholder=\"可选\" /></view>\r\n\t\t<view class=\"field\"><text class=\"label\">初始应收</text><input class=\"value\" type=\"digit\" v-model.number=\"form.arOpening\" placeholder=\"默认 0.00\" /></view>\r\n\t\t<view class=\"textarea\"><textarea v-model=\"form.remark\" maxlength=\"200\" placeholder=\"备注(最多200字)\"></textarea></view>\r\n\r\n\t\t<view class=\"bottom\"><button class=\"primary\" @click=\"save\">保存</button></view>\r\n\t</view>\r\n</template>\r\n\r\n<script>\r\nimport { post, put } from '../../common/http.js'\r\nexport default {\r\n\tdata() {\r\n\t\treturn {\r\n\t\t\tid: null,\r\n\t\t\tform: { name:'', level:'', priceLevel:'retail', contactName:'', mobile:'', phone:'', address:'', arOpening:0, remark:'' },\r\n\t\t\tpriceLevels: ['retail','distribution','wholesale','big_client'],\r\n\t\t\tpriceIdx: 0\r\n\t\t}\r\n\t},\r\n\tonLoad(query) { if (query && query.id) { this.id = Number(query.id) } },\r\n\tmethods: {\r\n\t\tonPriceChange(e){ this.priceIdx = Number(e.detail.value); this.form.priceLevel = this.priceLevels[this.priceIdx] },\r\n\t\tasync save() {\r\n\t\t\tif (!this.form.name) return uni.showToast({ title:'请填写客户名称', icon:'none' })\r\n\t\t\ttry {\r\n\t\t\t\tif (this.id) await put(`/api/customers/${this.id}`, this.form)\r\n\t\t\t\telse await post('/api/customers', this.form)\r\n\t\t\t\tuni.showToast({ title:'保存成功', icon:'success' })\r\n\t\t\t\tsetTimeout(() => uni.navigateBack(), 500)\r\n\t\t\t} catch(e) { uni.showToast({ title: e?.message || '保存失败', icon:'none' }) }\r\n\t\t}\r\n\t}\r\n}\r\n</script>\r\n\r\n<style>\r\n.page { padding-bottom: 140rpx; }\r\n.field { display:flex; justify-content: space-between; padding: 22rpx 24rpx; background:#fff; border-bottom:1rpx solid #eee; }\r\n.label { color:#666; }\r\n.value { color:#333; text-align: right; flex: 1; }\r\n.textarea { padding: 16rpx 24rpx; background:#fff; margin-top: 12rpx; }\r\n.bottom { position: fixed; left:0; right:0; bottom:0; background:#fff; padding: 16rpx 24rpx calc(env(safe-area-inset-bottom) + 16rpx); box-shadow: 0 -4rpx 12rpx rgba(0,0,0,0.06); }\r\n.primary { width: 100%; background: linear-gradient(135deg, #A0E4FF 0%, #17A2C4 100%); color:#fff; border-radius: 999rpx; padding: 20rpx 0; }\r\n</style>\r\n\r\n\r\n","import MiniProgramPage from 'C:/Users/21826/Desktop/Wj/PartsInquiry/frontend/pages/customer/form.vue'\nwx.createPage(MiniProgramPage)"],"names":["uni","put","post"],"mappings":";;;AAuBA,MAAK,YAAU;AAAA,EACd,OAAO;AACN,WAAO;AAAA,MACN,IAAI;AAAA,MACJ,MAAM,EAAE,MAAK,IAAI,OAAM,IAAI,YAAW,UAAU,aAAY,IAAI,QAAO,IAAI,OAAM,IAAI,SAAQ,IAAI,WAAU,GAAG,QAAO,GAAI;AAAA,MACzH,aAAa,CAAC,UAAS,gBAAe,aAAY,YAAY;AAAA,MAC9D,UAAU;AAAA,IACX;AAAA,EACA;AAAA,EACD,OAAO,OAAO;AAAE,QAAI,SAAS,MAAM,IAAI;AAAE,WAAK,KAAK,OAAO,MAAM,EAAE;AAAA,IAAE;AAAA,EAAG;AAAA,EACvE,SAAS;AAAA,IACR,cAAc,GAAE;AAAE,WAAK,WAAW,OAAO,EAAE,OAAO,KAAK;AAAG,WAAK,KAAK,aAAa,KAAK,YAAY,KAAK,QAAQ;AAAA,IAAG;AAAA,IAClH,MAAM,OAAO;AACZ,UAAI,CAAC,KAAK,KAAK;AAAM,eAAOA,cAAG,MAAC,UAAU,EAAE,OAAM,WAAW,MAAK,QAAQ;AAC1E,UAAI;AACH,YAAI,KAAK;AAAI,gBAAMC,YAAAA,IAAI,kBAAkB,KAAK,EAAE,IAAI,KAAK,IAAI;AAAA;AACxD,gBAAMC,iBAAK,kBAAkB,KAAK,IAAI;AAC3CF,sBAAG,MAAC,UAAU,EAAE,OAAM,QAAQ,MAAK,WAAW;AAC9C,mBAAW,MAAMA,cAAAA,MAAI,aAAY,GAAI,GAAG;AAAA,MACzC,SAAQ,GAAG;AAAEA,sBAAG,MAAC,UAAU,EAAE,QAAO,uBAAG,YAAW,QAAQ,MAAK,OAAQ,CAAA;AAAA,MAAE;AAAA,IAC1E;AAAA,EACD;AACD;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AC5CA,GAAG,WAAW,eAAe;"}
|
||||
@@ -1 +1 @@
|
||||
{"version":3,"file":"select.js","sources":["pages/customer/select.vue","../../../../Downloads/HBuilderX.4.76.2025082103/HBuilderX/plugins/uniapp-cli-vite/uniPage:/cGFnZXMvY3VzdG9tZXIvc2VsZWN0LnZ1ZQ"],"sourcesContent":["<template>\r\n\t<view class=\"page\">\r\n\t\t<view class=\"search\">\r\n\t\t\t<input v-model=\"kw\" placeholder=\"搜索客户名称/电话\" @confirm=\"search\" />\r\n\t\t\t<button size=\"mini\" @click=\"search\">搜索</button>\r\n\t\t</view>\r\n\t\t<scroll-view scroll-y class=\"list\">\r\n\t\t\t<view class=\"item\" v-for=\"c in customers\" :key=\"c.id\" @click=\"select(c)\">\r\n\t\t\t\t<view class=\"name\">{{ c.name }}</view>\r\n\t\t\t\t<view class=\"meta\">{{ c.mobile || '—' }}</view>\r\n\t\t\t</view>\r\n\t\t</scroll-view>\r\n\t</view>\r\n</template>\r\n\r\n<script>\r\n\timport { get } from '../../common/http.js'\r\n\texport default {\r\n\t\tdata() { return { kw: '', customers: [] } },\r\n\t\tonLoad() { this.search() },\r\n\t\tmethods: {\r\n\t\t\tasync search() {\r\n\t\t\t\ttry {\r\n\t\t\t\t\tconst res = await get('/api/customers', { kw: this.kw, page: 1, size: 50 })\r\n\t\t\t\t\tthis.customers = Array.isArray(res?.list) ? res.list : (Array.isArray(res) ? res : [])\r\n\t\t\t\t} catch(e) { uni.showToast({ title: '加载失败', icon: 'none' }) }\r\n\t\t\t},\r\n\t\t\tselect(c) {\r\n\t\t\t\tconst opener = getCurrentPages()[getCurrentPages().length-2]\r\n\t\t\t\tif (opener && opener.$vm) {\r\n\t\t\t\t\topener.$vm.order.customerId = c.id\r\n\t\t\t\t\topener.$vm.customerName = c.name\r\n\t\t\t\t}\r\n\t\t\t\tuni.navigateBack()\r\n\t\t\t}\r\n\t\t}\r\n\t}\r\n</script>\r\n\r\n<style>\r\n\t.page { display:flex; flex-direction: column; height: 100vh; }\r\n\t.search { display:flex; gap: 12rpx; padding: 16rpx; background:#fff; }\r\n\t.search input { flex:1; background:#f6f6f6; border-radius: 12rpx; padding: 12rpx; }\r\n\t.list { flex:1; }\r\n\t.item { padding: 20rpx 24rpx; background:#fff; border-bottom: 1rpx solid #f1f1f1; }\r\n\t.name { color:#333; margin-bottom: 6rpx; }\r\n\t.meta { color:#888; font-size: 24rpx; }\r\n</style>\r\n\r\n\r\n\r\n","import MiniProgramPage from 'C:/Users/21826/Desktop/Wj/PartsInquiry/frontend/pages/customer/select.vue'\nwx.createPage(MiniProgramPage)"],"names":["get","uni"],"mappings":";;;AAiBC,MAAK,YAAU;AAAA,EACd,OAAO;AAAE,WAAO,EAAE,IAAI,IAAI,WAAW,CAAA;EAAM;AAAA,EAC3C,SAAS;AAAE,SAAK;EAAU;AAAA,EAC1B,SAAS;AAAA,IACR,MAAM,SAAS;AACd,UAAI;AACH,cAAM,MAAM,MAAMA,gBAAI,kBAAkB,EAAE,IAAI,KAAK,IAAI,MAAM,GAAG,MAAM,GAAC,CAAG;AAC1E,aAAK,YAAY,MAAM,QAAQ,2BAAK,IAAI,IAAI,IAAI,OAAQ,MAAM,QAAQ,GAAG,IAAI,MAAM,CAAA;AAAA,eAC5E,GAAG;AAAEC,sBAAAA,MAAI,UAAU,EAAE,OAAO,QAAQ,MAAM,OAAO,CAAC;AAAA,MAAE;AAAA,IAC5D;AAAA,IACD,OAAO,GAAG;AACT,YAAM,SAAS,gBAAiB,EAAC,gBAAe,EAAG,SAAO,CAAC;AAC3D,UAAI,UAAU,OAAO,KAAK;AACzB,eAAO,IAAI,MAAM,aAAa,EAAE;AAChC,eAAO,IAAI,eAAe,EAAE;AAAA,MAC7B;AACAA,oBAAAA,MAAI,aAAa;AAAA,IAClB;AAAA,EACD;AACD;;;;;;;;;;;;;;;;;;ACnCD,GAAG,WAAW,eAAe;"}
|
||||
{"version":3,"file":"select.js","sources":["pages/customer/select.vue","../../../../Downloads/HBuilderX.4.76.2025082103/HBuilderX/plugins/uniapp-cli-vite/uniPage:/cGFnZXMvY3VzdG9tZXIvc2VsZWN0LnZ1ZQ"],"sourcesContent":["<template>\r\n\t<view class=\"page\">\r\n\t\t<view class=\"search\">\r\n\t\t\t<input v-model=\"kw\" placeholder=\"搜索客户名称/电话\" @confirm=\"search\" />\r\n\t\t\t<button size=\"mini\" @click=\"search\">搜索</button>\r\n\t\t\t<button size=\"mini\" :type=\"debtOnly ? 'primary' : 'default'\" @click=\"toggleDebtOnly\">只看欠款</button>\r\n\t\t</view>\r\n\t\t<scroll-view scroll-y class=\"list\">\r\n\t\t\t<view class=\"item\" v-for=\"c in customers\" :key=\"c.id\" @click=\"select(c)\">\r\n\t\t\t\t<view class=\"name\">{{ c.name }}</view>\r\n\t\t\t\t<view class=\"meta\">\r\n\t\t\t\t\t{{ c.mobile || '—' }}\r\n\t\t\t\t\t<text v-if=\"typeof c.receivable === 'number'\">|应收:¥ {{ Number(c.receivable).toFixed(2) }}</text>\r\n\t\t\t\t</view>\r\n\t\t\t</view>\r\n\t\t</scroll-view>\r\n\t\t<view class=\"bottom\">\r\n\t\t\t<button class=\"primary\" @click=\"createCustomer\">新增客户</button>\r\n\t\t</view>\r\n\t</view>\r\n</template>\r\n\r\n<script>\r\n\timport { get } from '../../common/http.js'\r\n\texport default {\r\n\t\tdata() { return { kw: '', debtOnly: false, customers: [] } },\r\n\t\tonLoad() { this.search() },\r\n\t\tmethods: {\r\n\t\t\ttoggleDebtOnly() { this.debtOnly = !this.debtOnly; this.search() },\r\n\t\t\tasync search() {\r\n\t\t\t\ttry {\r\n\t\t\t\t\tconst res = await get('/api/customers', { kw: this.kw, debtOnly: this.debtOnly, page: 1, size: 50 })\r\n\t\t\t\t\tthis.customers = Array.isArray(res?.list) ? res.list : (Array.isArray(res) ? res : [])\r\n\t\t\t\t} catch(e) { uni.showToast({ title: '加载失败', icon: 'none' }) }\r\n\t\t\t},\r\n\t\t\tcreateCustomer() { uni.navigateTo({ url: '/pages/customer/form' }) },\r\n\t\t\tselect(c) {\r\n\t\t\t\tconst opener = getCurrentPages()[getCurrentPages().length-2]\r\n\t\t\t\tif (opener && opener.$vm) {\r\n\t\t\t\t\topener.$vm.order.customerId = c.id\r\n\t\t\t\t\topener.$vm.customerName = c.name\r\n\t\t\t\t}\r\n\t\t\t\tuni.navigateBack()\r\n\t\t\t}\r\n\t\t}\r\n\t}\r\n</script>\r\n\r\n<style>\r\n\t.page { display:flex; flex-direction: column; height: 100vh; }\r\n\t.search { display:flex; gap: 12rpx; padding: 16rpx; background:#fff; align-items:center; }\r\n\t.search input { flex:1; background:#f6f6f6; border-radius: 12rpx; padding: 12rpx; }\r\n\t.list { flex:1; }\r\n\t.item { padding: 20rpx 24rpx; background:#fff; border-bottom: 1rpx solid #f1f1f1; }\r\n\t.name { color:#333; margin-bottom: 6rpx; }\r\n\t.meta { color:#888; font-size: 24rpx; }\r\n\t.bottom { position: fixed; left:0; right:0; bottom:0; background:#fff; padding: 16rpx 24rpx calc(env(safe-area-inset-bottom) + 16rpx); box-shadow: 0 -4rpx 12rpx rgba(0,0,0,0.06); }\r\n\t.primary { width: 100%; background: linear-gradient(135deg, #A0E4FF 0%, #17A2C4 100%); color:#fff; border-radius: 999rpx; padding: 20rpx 0; }\r\n</style>\r\n\r\n\r\n\r\n","import MiniProgramPage from 'C:/Users/21826/Desktop/Wj/PartsInquiry/frontend/pages/customer/select.vue'\nwx.createPage(MiniProgramPage)"],"names":["get","uni"],"mappings":";;;AAwBC,MAAK,YAAU;AAAA,EACd,OAAO;AAAE,WAAO,EAAE,IAAI,IAAI,UAAU,OAAO,WAAW,CAAA;EAAM;AAAA,EAC5D,SAAS;AAAE,SAAK;EAAU;AAAA,EAC1B,SAAS;AAAA,IACR,iBAAiB;AAAE,WAAK,WAAW,CAAC,KAAK;AAAU,WAAK;IAAU;AAAA,IAClE,MAAM,SAAS;AACd,UAAI;AACH,cAAM,MAAM,MAAMA,YAAG,IAAC,kBAAkB,EAAE,IAAI,KAAK,IAAI,UAAU,KAAK,UAAU,MAAM,GAAG,MAAM,IAAI;AACnG,aAAK,YAAY,MAAM,QAAQ,2BAAK,IAAI,IAAI,IAAI,OAAQ,MAAM,QAAQ,GAAG,IAAI,MAAM,CAAA;AAAA,eAC5E,GAAG;AAAEC,sBAAAA,MAAI,UAAU,EAAE,OAAO,QAAQ,MAAM,OAAO,CAAC;AAAA,MAAE;AAAA,IAC5D;AAAA,IACD,iBAAiB;AAAEA,oBAAAA,MAAI,WAAW,EAAE,KAAK,uBAAqB,CAAG;AAAA,IAAG;AAAA,IACpE,OAAO,GAAG;AACT,YAAM,SAAS,gBAAiB,EAAC,gBAAe,EAAG,SAAO,CAAC;AAC3D,UAAI,UAAU,OAAO,KAAK;AACzB,eAAO,IAAI,MAAM,aAAa,EAAE;AAChC,eAAO,IAAI,eAAe,EAAE;AAAA,MAC7B;AACAA,oBAAAA,MAAI,aAAa;AAAA,IAClB;AAAA,EACD;AACD;;;;;;;;;;;;;;;;;;;;;;;;;AC5CD,GAAG,WAAW,eAAe;"}
|
||||
File diff suppressed because one or more lines are too long
1
frontend/unpackage/dist/dev/mp-weixin/app.js
vendored
1
frontend/unpackage/dist/dev/mp-weixin/app.js
vendored
@@ -11,6 +11,7 @@ if (!Math) {
|
||||
"./pages/product/units.js";
|
||||
"./pages/product/settings.js";
|
||||
"./pages/customer/select.js";
|
||||
"./pages/customer/form.js";
|
||||
"./pages/supplier/select.js";
|
||||
"./pages/account/select.js";
|
||||
"./pages/detail/index.js";
|
||||
|
||||
@@ -9,6 +9,7 @@
|
||||
"pages/product/units",
|
||||
"pages/product/settings",
|
||||
"pages/customer/select",
|
||||
"pages/customer/form",
|
||||
"pages/supplier/select",
|
||||
"pages/account/select",
|
||||
"pages/detail/index"
|
||||
|
||||
68
frontend/unpackage/dist/dev/mp-weixin/pages/customer/form.js
vendored
Normal file
68
frontend/unpackage/dist/dev/mp-weixin/pages/customer/form.js
vendored
Normal file
@@ -0,0 +1,68 @@
|
||||
"use strict";
|
||||
const common_vendor = require("../../common/vendor.js");
|
||||
const common_http = require("../../common/http.js");
|
||||
const _sfc_main = {
|
||||
data() {
|
||||
return {
|
||||
id: null,
|
||||
form: { name: "", level: "", priceLevel: "retail", contactName: "", mobile: "", phone: "", address: "", arOpening: 0, remark: "" },
|
||||
priceLevels: ["retail", "distribution", "wholesale", "big_client"],
|
||||
priceIdx: 0
|
||||
};
|
||||
},
|
||||
onLoad(query) {
|
||||
if (query && query.id) {
|
||||
this.id = Number(query.id);
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
onPriceChange(e) {
|
||||
this.priceIdx = Number(e.detail.value);
|
||||
this.form.priceLevel = this.priceLevels[this.priceIdx];
|
||||
},
|
||||
async save() {
|
||||
if (!this.form.name)
|
||||
return common_vendor.index.showToast({ title: "请填写客户名称", icon: "none" });
|
||||
try {
|
||||
if (this.id)
|
||||
await common_http.put(`/api/customers/${this.id}`, this.form);
|
||||
else
|
||||
await common_http.post("/api/customers", this.form);
|
||||
common_vendor.index.showToast({ title: "保存成功", icon: "success" });
|
||||
setTimeout(() => common_vendor.index.navigateBack(), 500);
|
||||
} catch (e) {
|
||||
common_vendor.index.showToast({ title: (e == null ? void 0 : e.message) || "保存失败", icon: "none" });
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
function _sfc_render(_ctx, _cache, $props, $setup, $data, $options) {
|
||||
return {
|
||||
a: $data.form.name,
|
||||
b: common_vendor.o(($event) => $data.form.name = $event.detail.value),
|
||||
c: $data.form.level,
|
||||
d: common_vendor.o(($event) => $data.form.level = $event.detail.value),
|
||||
e: common_vendor.t($data.priceLevels[$data.priceIdx]),
|
||||
f: $data.priceLevels,
|
||||
g: $data.priceIdx,
|
||||
h: common_vendor.o((...args) => $options.onPriceChange && $options.onPriceChange(...args)),
|
||||
i: $data.form.contactName,
|
||||
j: common_vendor.o(($event) => $data.form.contactName = $event.detail.value),
|
||||
k: $data.form.mobile,
|
||||
l: common_vendor.o(($event) => $data.form.mobile = $event.detail.value),
|
||||
m: $data.form.phone,
|
||||
n: common_vendor.o(($event) => $data.form.phone = $event.detail.value),
|
||||
o: $data.form.address,
|
||||
p: common_vendor.o(($event) => $data.form.address = $event.detail.value),
|
||||
q: $data.form.arOpening,
|
||||
r: common_vendor.o(common_vendor.m(($event) => $data.form.arOpening = $event.detail.value, {
|
||||
number: true
|
||||
})),
|
||||
s: $data.form.remark,
|
||||
t: common_vendor.o(($event) => $data.form.remark = $event.detail.value),
|
||||
v: common_vendor.o((...args) => $options.save && $options.save(...args))
|
||||
};
|
||||
}
|
||||
const MiniProgramPage = /* @__PURE__ */ common_vendor._export_sfc(_sfc_main, [["render", _sfc_render]]);
|
||||
wx.createPage(MiniProgramPage);
|
||||
//# sourceMappingURL=../../../.sourcemap/mp-weixin/pages/customer/form.js.map
|
||||
4
frontend/unpackage/dist/dev/mp-weixin/pages/customer/form.json
vendored
Normal file
4
frontend/unpackage/dist/dev/mp-weixin/pages/customer/form.json
vendored
Normal file
@@ -0,0 +1,4 @@
|
||||
{
|
||||
"navigationBarTitleText": "新增客户",
|
||||
"usingComponents": {}
|
||||
}
|
||||
1
frontend/unpackage/dist/dev/mp-weixin/pages/customer/form.wxml
vendored
Normal file
1
frontend/unpackage/dist/dev/mp-weixin/pages/customer/form.wxml
vendored
Normal file
@@ -0,0 +1 @@
|
||||
<view class="page"><view class="field"><text class="label">客户名称</text><input class="value" placeholder="必填" value="{{a}}" bindinput="{{b}}"/></view><view class="field"><text class="label">客户等级</text><input class="value" placeholder="可选,如 VIP/A/B" value="{{c}}" bindinput="{{d}}"/></view><view class="field"><text class="label">售价档位</text><picker range="{{f}}" value="{{g}}" bindchange="{{h}}"><view class="value">{{e}}</view></picker></view><view class="field"><text class="label">联系人</text><input class="value" placeholder="可选" value="{{i}}" bindinput="{{j}}"/></view><view class="field"><text class="label">手机</text><input class="value" placeholder="可选" value="{{k}}" bindinput="{{l}}"/></view><view class="field"><text class="label">电话</text><input class="value" placeholder="可选(座机)" value="{{m}}" bindinput="{{n}}"/></view><view class="field"><text class="label">送货地址</text><input class="value" placeholder="可选" value="{{o}}" bindinput="{{p}}"/></view><view class="field"><text class="label">初始应收</text><input class="value" type="digit" placeholder="默认 0.00" value="{{q}}" bindinput="{{r}}"/></view><view class="textarea"><block wx:if="{{r0}}"><textarea maxlength="200" placeholder="备注(最多200字)" value="{{s}}" bindinput="{{t}}"></textarea></block></view><view class="bottom"><button class="primary" bindtap="{{v}}">保存</button></view></view>
|
||||
15
frontend/unpackage/dist/dev/mp-weixin/pages/customer/form.wxss
vendored
Normal file
15
frontend/unpackage/dist/dev/mp-weixin/pages/customer/form.wxss
vendored
Normal file
@@ -0,0 +1,15 @@
|
||||
|
||||
.page { padding-bottom: 140rpx;
|
||||
}
|
||||
.field { display:flex; justify-content: space-between; padding: 22rpx 24rpx; background:#fff; border-bottom:1rpx solid #eee;
|
||||
}
|
||||
.label { color:#666;
|
||||
}
|
||||
.value { color:#333; text-align: right; flex: 1;
|
||||
}
|
||||
.textarea { padding: 16rpx 24rpx; background:#fff; margin-top: 12rpx;
|
||||
}
|
||||
.bottom { position: fixed; left:0; right:0; bottom:0; background:#fff; padding: 16rpx 24rpx calc(env(safe-area-inset-bottom) + 16rpx); box-shadow: 0 -4rpx 12rpx rgba(0,0,0,0.06);
|
||||
}
|
||||
.primary { width: 100%; background: linear-gradient(135deg, #A0E4FF 0%, #17A2C4 100%); color:#fff; border-radius: 999rpx; padding: 20rpx 0;
|
||||
}
|
||||
@@ -3,20 +3,27 @@ const common_vendor = require("../../common/vendor.js");
|
||||
const common_http = require("../../common/http.js");
|
||||
const _sfc_main = {
|
||||
data() {
|
||||
return { kw: "", customers: [] };
|
||||
return { kw: "", debtOnly: false, customers: [] };
|
||||
},
|
||||
onLoad() {
|
||||
this.search();
|
||||
},
|
||||
methods: {
|
||||
toggleDebtOnly() {
|
||||
this.debtOnly = !this.debtOnly;
|
||||
this.search();
|
||||
},
|
||||
async search() {
|
||||
try {
|
||||
const res = await common_http.get("/api/customers", { kw: this.kw, page: 1, size: 50 });
|
||||
const res = await common_http.get("/api/customers", { kw: this.kw, debtOnly: this.debtOnly, page: 1, size: 50 });
|
||||
this.customers = Array.isArray(res == null ? void 0 : res.list) ? res.list : Array.isArray(res) ? res : [];
|
||||
} catch (e) {
|
||||
common_vendor.index.showToast({ title: "加载失败", icon: "none" });
|
||||
}
|
||||
},
|
||||
createCustomer() {
|
||||
common_vendor.index.navigateTo({ url: "/pages/customer/form" });
|
||||
},
|
||||
select(c) {
|
||||
const opener = getCurrentPages()[getCurrentPages().length - 2];
|
||||
if (opener && opener.$vm) {
|
||||
@@ -33,14 +40,21 @@ function _sfc_render(_ctx, _cache, $props, $setup, $data, $options) {
|
||||
b: $data.kw,
|
||||
c: common_vendor.o(($event) => $data.kw = $event.detail.value),
|
||||
d: common_vendor.o((...args) => $options.search && $options.search(...args)),
|
||||
e: common_vendor.f($data.customers, (c, k0, i0) => {
|
||||
return {
|
||||
e: $data.debtOnly ? "primary" : "default",
|
||||
f: common_vendor.o((...args) => $options.toggleDebtOnly && $options.toggleDebtOnly(...args)),
|
||||
g: common_vendor.f($data.customers, (c, k0, i0) => {
|
||||
return common_vendor.e({
|
||||
a: common_vendor.t(c.name),
|
||||
b: common_vendor.t(c.mobile || "—"),
|
||||
c: c.id,
|
||||
d: common_vendor.o(($event) => $options.select(c), c.id)
|
||||
};
|
||||
})
|
||||
c: typeof c.receivable === "number"
|
||||
}, typeof c.receivable === "number" ? {
|
||||
d: common_vendor.t(Number(c.receivable).toFixed(2))
|
||||
} : {}, {
|
||||
e: c.id,
|
||||
f: common_vendor.o(($event) => $options.select(c), c.id)
|
||||
});
|
||||
}),
|
||||
h: common_vendor.o((...args) => $options.createCustomer && $options.createCustomer(...args))
|
||||
};
|
||||
}
|
||||
const MiniProgramPage = /* @__PURE__ */ common_vendor._export_sfc(_sfc_main, [["render", _sfc_render]]);
|
||||
|
||||
@@ -1 +1 @@
|
||||
<view class="page"><view class="search"><input placeholder="搜索客户名称/电话" bindconfirm="{{a}}" value="{{b}}" bindinput="{{c}}"/><button size="mini" bindtap="{{d}}">搜索</button></view><scroll-view scroll-y class="list"><view wx:for="{{e}}" wx:for-item="c" wx:key="c" class="item" bindtap="{{c.d}}"><view class="name">{{c.a}}</view><view class="meta">{{c.b}}</view></view></scroll-view></view>
|
||||
<view class="page"><view class="search"><input placeholder="搜索客户名称/电话" bindconfirm="{{a}}" value="{{b}}" bindinput="{{c}}"/><button size="mini" bindtap="{{d}}">搜索</button><button size="mini" type="{{e}}" bindtap="{{f}}">只看欠款</button></view><scroll-view scroll-y class="list"><view wx:for="{{g}}" wx:for-item="c" wx:key="e" class="item" bindtap="{{c.f}}"><view class="name">{{c.a}}</view><view class="meta">{{c.b}} <text wx:if="{{c.c}}">|应收:¥ {{c.d}}</text></view></view></scroll-view><view class="bottom"><button class="primary" bindtap="{{h}}">新增客户</button></view></view>
|
||||
@@ -1,7 +1,7 @@
|
||||
|
||||
.page { display:flex; flex-direction: column; height: 100vh;
|
||||
}
|
||||
.search { display:flex; gap: 12rpx; padding: 16rpx; background:#fff;
|
||||
.search { display:flex; gap: 12rpx; padding: 16rpx; background:#fff; align-items:center;
|
||||
}
|
||||
.search input { flex:1; background:#f6f6f6; border-radius: 12rpx; padding: 12rpx;
|
||||
}
|
||||
@@ -13,3 +13,7 @@
|
||||
}
|
||||
.meta { color:#888; font-size: 24rpx;
|
||||
}
|
||||
.bottom { position: fixed; left:0; right:0; bottom:0; background:#fff; padding: 16rpx 24rpx calc(env(safe-area-inset-bottom) + 16rpx); box-shadow: 0 -4rpx 12rpx rgba(0,0,0,0.06);
|
||||
}
|
||||
.primary { width: 100%; background: linear-gradient(135deg, #A0E4FF 0%, #17A2C4 100%); color:#fff; border-radius: 999rpx; padding: 20rpx 0;
|
||||
}
|
||||
|
||||
@@ -63,6 +63,10 @@ const _sfc_main = {
|
||||
common_vendor.index.navigateTo({ url: "/pages/product/list" });
|
||||
return;
|
||||
}
|
||||
if (item.key === "customer") {
|
||||
common_vendor.index.navigateTo({ url: "/pages/customer/select" });
|
||||
return;
|
||||
}
|
||||
common_vendor.index.showToast({ title: item.title + "(开发中)", icon: "none" });
|
||||
},
|
||||
goProduct() {
|
||||
@@ -75,7 +79,7 @@ const _sfc_main = {
|
||||
goDetail() {
|
||||
this.activeTab = "detail";
|
||||
try {
|
||||
common_vendor.index.__f__("log", "at pages/index/index.vue:166", "[index] goDetail → /pages/detail/index");
|
||||
common_vendor.index.__f__("log", "at pages/index/index.vue:170", "[index] goDetail → /pages/detail/index");
|
||||
} catch (e) {
|
||||
}
|
||||
common_vendor.index.navigateTo({ url: "/pages/detail/index" });
|
||||
|
||||
Reference in New Issue
Block a user